1.3.1: | 1.3.1: | ||||
- Fix very unoptimized code, made it more-ish optimized | - Fix very unoptimized code, made it more-ish optimized | ||||
- Below music option now moves kai just below the media controls, and not to the very bottom. | - Below music option now moves kai just below the media controls, and not to the very bottom. | ||||
- Fixed kai going below Axon with below music player option on | |||||
- Fixed kai going below Axon with below music player option on | |||||
1.4.0: | |||||
- Adds iOS 14 support | |||||
1.5.0: | |||||
- Replace the code that handles hiding kai when media plays | |||||
- Fix edge cases where battery info would not update completely until an update was called for again |
if (bannerStyle == 1) { | if (bannerStyle == 1) { | ||||
if (kCFCoreFoundationVersionNumber > 1600 && kCFCoreFoundationVersionNumber < 1740) { | if (kCFCoreFoundationVersionNumber > 1600 && kCFCoreFoundationVersionNumber < 1740) { | ||||
blur = [[[objc_getClass("MTMaterialView") class] alloc] _initWithRecipe:1 configuration:1 initialWeighting:1 scaleAdjustment:nil]; | blur = [[[objc_getClass("MTMaterialView") class] alloc] _initWithRecipe:1 configuration:1 initialWeighting:1 scaleAdjustment:nil]; | ||||
} else if (kCFCoreFoundationVersionNumber < 1600) { //ios 12 | |||||
} else if (kCFCoreFoundationVersionNumber < 1600) { // ios 12 | |||||
blur = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]]; | blur = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]]; | ||||
} else if(kCFCoreFoundationVersionNumber >= 1740) { //ios 14 :fr: | |||||
} else if(kCFCoreFoundationVersionNumber >= 1740) { // ios 14 :fr: | |||||
blur = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular]]; | blur = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular]]; | ||||
} | } | ||||
} else if (bannerStyle == 2) { | } else if (bannerStyle == 2) { | ||||
[self addSubview:self.battery]; | [self addSubview:self.battery]; | ||||
[self addSubview:self.glyphView]; | [self addSubview:self.glyphView]; | ||||
// Blur Platter | |||||
// Blur Platter | |||||
blurPlatter.translatesAutoresizingMaskIntoConstraints = NO; | blurPlatter.translatesAutoresizingMaskIntoConstraints = NO; | ||||
if (bannerAlign == 2) { //center | |||||
if (bannerAlign == 2) { // center | |||||
[blurPlatter.centerXAnchor constraintEqualToAnchor:self.centerXAnchor].active = YES; | [blurPlatter.centerXAnchor constraintEqualToAnchor:self.centerXAnchor].active = YES; | ||||
} else if (bannerAlign == 1) { //left | |||||
} else if (bannerAlign == 1) { // left | |||||
[blurPlatter.leftAnchor constraintEqualToAnchor:self.leftAnchor].active = YES; | [blurPlatter.leftAnchor constraintEqualToAnchor:self.leftAnchor].active = YES; | ||||
} else if (bannerAlign == 3) { //right | |||||
} else if (bannerAlign == 3) { // right | |||||
[blurPlatter.rightAnchor constraintEqualToAnchor:self.rightAnchor].active = YES; | [blurPlatter.rightAnchor constraintEqualToAnchor:self.rightAnchor].active = YES; | ||||
} | } | ||||
[NSLayoutConstraint activateConstraints:@[ | [NSLayoutConstraint activateConstraints:@[ | ||||
[self.widthAnchor constraintEqualToAnchor:blurPlatter.widthAnchor].active = YES; | [self.widthAnchor constraintEqualToAnchor:blurPlatter.widthAnchor].active = YES; | ||||
// Blur | |||||
// Blur | |||||
blur.translatesAutoresizingMaskIntoConstraints = NO; | blur.translatesAutoresizingMaskIntoConstraints = NO; | ||||
[NSLayoutConstraint activateConstraints:@[ | [NSLayoutConstraint activateConstraints:@[ | ||||
[blur.centerXAnchor constraintEqualToAnchor:blurPlatter.centerXAnchor], | [blur.centerXAnchor constraintEqualToAnchor:blurPlatter.centerXAnchor], | ||||
[blur.heightAnchor constraintEqualToAnchor:blurPlatter.heightAnchor] | [blur.heightAnchor constraintEqualToAnchor:blurPlatter.heightAnchor] | ||||
]]; | ]]; | ||||
// Percent label | |||||
// Percent label | |||||
self.percentLabel.translatesAutoresizingMaskIntoConstraints = NO; | self.percentLabel.translatesAutoresizingMaskIntoConstraints = NO; | ||||
[NSLayoutConstraint activateConstraints:@[ | [NSLayoutConstraint activateConstraints:@[ | ||||
[self.percentLabel.centerYAnchor constraintEqualToAnchor:blurPlatter.centerYAnchor], | [self.percentLabel.centerYAnchor constraintEqualToAnchor:blurPlatter.centerYAnchor], | ||||
[self.percentLabel.heightAnchor constraintEqualToConstant:12] | [self.percentLabel.heightAnchor constraintEqualToConstant:12] | ||||
]]; | ]]; | ||||
// Label | |||||
// Label | |||||
self.label.translatesAutoresizingMaskIntoConstraints = NO; | self.label.translatesAutoresizingMaskIntoConstraints = NO; | ||||
[NSLayoutConstraint activateConstraints:@[ | [NSLayoutConstraint activateConstraints:@[ | ||||
[self.label.leftAnchor constraintEqualToAnchor:self.glyphView.rightAnchor | [self.label.leftAnchor constraintEqualToAnchor:self.glyphView.rightAnchor | ||||
[self.label.rightAnchor constraintEqualToAnchor:self.label.leftAnchor].active = YES; | [self.label.rightAnchor constraintEqualToAnchor:self.label.leftAnchor].active = YES; | ||||
} | } | ||||
// Glyph View | |||||
// Glyph View | |||||
self.glyphView.translatesAutoresizingMaskIntoConstraints = NO; | self.glyphView.translatesAutoresizingMaskIntoConstraints = NO; | ||||
[NSLayoutConstraint activateConstraints:@[ | [NSLayoutConstraint activateConstraints:@[ | ||||
[self.glyphView.leftAnchor constraintEqualToAnchor:blurPlatter.leftAnchor | [self.glyphView.leftAnchor constraintEqualToAnchor:blurPlatter.leftAnchor | ||||
[self.glyphView.heightAnchor constraintEqualToConstant:glyphSize] | [self.glyphView.heightAnchor constraintEqualToConstant:glyphSize] | ||||
]]; | ]]; | ||||
// Battery | |||||
// Battery | |||||
self.battery.translatesAutoresizingMaskIntoConstraints = NO; | self.battery.translatesAutoresizingMaskIntoConstraints = NO; | ||||
if (!hideBatteryIcon) { | if (!hideBatteryIcon) { | ||||
[self.battery.widthAnchor constraintEqualToConstant:20].active = YES; | [self.battery.widthAnchor constraintEqualToConstant:20].active = YES; | ||||
[super removeFromSuperview]; | [super removeFromSuperview]; | ||||
} | } | ||||
@end | |||||
@end |
[self setContentSize:self.stack.frame.size]; | [self setContentSize:self.stack.frame.size]; | ||||
[self resetOffset]; | [self resetOffset]; | ||||
//Add noti observer | |||||
// Add noti observer | |||||
[[NSNotificationCenter defaultCenter] addObserver:self | [[NSNotificationCenter defaultCenter] addObserver:self | ||||
selector:@selector(resetOffset) | selector:@selector(resetOffset) | ||||
name:@"KaiResetOffset" | name:@"KaiResetOffset" | ||||
[self.stackHolder.centerYAnchor constraintEqualToAnchor:self.centerYAnchor].active = YES; | [self.stackHolder.centerYAnchor constraintEqualToAnchor:self.centerYAnchor].active = YES; | ||||
if (kaiAlign == 0) { | if (kaiAlign == 0) { | ||||
if (bannerAlign == 2) { //center | |||||
if (bannerAlign == 2) { // center | |||||
self.subviewAligner = [self.stack.centerXAnchor constraintEqualToAnchor:self.stackHolder.centerXAnchor constant:horizontalOffset]; | self.subviewAligner = [self.stack.centerXAnchor constraintEqualToAnchor:self.stackHolder.centerXAnchor constant:horizontalOffset]; | ||||
} else if (bannerAlign == 1) { //left | |||||
} else if (bannerAlign == 1) { // left | |||||
self.subviewAligner = [self.stack.leftAnchor constraintEqualToAnchor:self.stackHolder.leftAnchor constant:horizontalOffset]; | self.subviewAligner = [self.stack.leftAnchor constraintEqualToAnchor:self.stackHolder.leftAnchor constant:horizontalOffset]; | ||||
} else if (bannerAlign == 3) { //right | |||||
} else if (bannerAlign == 3) { // right | |||||
self.subviewAligner = [self.stack.rightAnchor constraintEqualToAnchor:self.stackHolder.rightAnchor constant:horizontalOffset]; | self.subviewAligner = [self.stack.rightAnchor constraintEqualToAnchor:self.stackHolder.rightAnchor constant:horizontalOffset]; | ||||
} | } | ||||
return self; | return self; | ||||
} | } | ||||
- (void)resetOffset { | |||||
- (void)resetOffset { // holy fucking shit i just read this method, what is this garbage???? | |||||
if (kaiAlign != 0 && reAlignSelf) { | if (kaiAlign != 0 && reAlignSelf) { | ||||
[UIView animateWithDuration:0.2 | |||||
animations:^{ | |||||
if (bannerAlign == 1) { //left | |||||
[self setContentOffset:CGPointMake(0 + horizontalOffset, self.contentOffset.y)]; | |||||
self.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); | |||||
} else if (bannerAlign == 2) { //center | |||||
[self setContentOffset:CGPointMake(((-1 * self.stackHolder.frame.size.width) / 2) + (self.stack.frame.size.width / 2) + horizontalOffset, self.contentOffset.y)]; | |||||
CGFloat top = 0, left = 0; | |||||
if (self.contentSize.width < self.bounds.size.width) { | |||||
left = (self.bounds.size.width - self.contentSize.width) * 0.5f; | |||||
} | |||||
if (self.contentSize.height < self.bounds.size.height) { | |||||
top = (self.bounds.size.height - self.contentSize.height) * 0.5f; | |||||
} | |||||
self.contentInset = UIEdgeInsetsMake(top, left, top, left); | |||||
} else if (bannerAlign == 3) { //right | |||||
[self setContentOffset:CGPointMake((-1 * self.stackHolder.frame.size.width) + self.stack.frame.size.width + horizontalOffset, self.contentOffset.y)]; | |||||
CGFloat top = 0, left = 0; | |||||
if (self.contentSize.width < self.bounds.size.width) { | |||||
left = (self.bounds.size.width - self.contentSize.width); | |||||
} | |||||
if (self.contentSize.height < self.bounds.size.height) { | |||||
top = (self.bounds.size.height - self.contentSize.height); | |||||
} | |||||
self.contentInset = UIEdgeInsetsMake(top, left, top, left); | |||||
} | |||||
}]; | |||||
[UIView animateWithDuration:0.2 animations:^{ | |||||
if (bannerAlign == 1) { // left | |||||
[self setContentOffset:CGPointMake(0 + horizontalOffset, self.contentOffset.y)]; | |||||
self.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); | |||||
} else if (bannerAlign == 2) { // center | |||||
[self setContentOffset:CGPointMake(((-1 * self.stackHolder.frame.size.width) / 2) + (self.stack.frame.size.width / 2) + horizontalOffset, self.contentOffset.y)]; | |||||
CGFloat top = 0, left = 0; | |||||
if (self.contentSize.width < self.bounds.size.width) left = (self.bounds.size.width - self.contentSize.width) * 0.5f; | |||||
if (self.contentSize.height < self.bounds.size.height) top = (self.bounds.size.height - self.contentSize.height) * 0.5f; | |||||
self.contentInset = UIEdgeInsetsMake(top, left, top, left); | |||||
} else if (bannerAlign == 3) { // right | |||||
[self setContentOffset:CGPointMake((-1 * self.stackHolder.frame.size.width) + self.stack.frame.size.width + horizontalOffset, self.contentOffset.y)]; | |||||
CGFloat top = 0, left = 0; | |||||
if(self.contentSize.width < self.bounds.size.width) left = (self.bounds.size.width - self.contentSize.width); | |||||
if(self.contentSize.height < self.bounds.size.height) top = (self.bounds.size.height - self.contentSize.height); | |||||
self.contentInset = UIEdgeInsetsMake(top, left, top, left); | |||||
} | |||||
}]; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
- (void)updateBattery { | - (void)updateBattery { | ||||
if(self.isUpdating == YES) { | |||||
self.queued = YES; | |||||
return; | |||||
} | |||||
dispatch_async(dispatch_get_main_queue(), ^{ | dispatch_async(dispatch_get_main_queue(), ^{ | ||||
BCBatteryDeviceController *bcb = [BCBatteryDeviceController sharedInstance]; | BCBatteryDeviceController *bcb = [BCBatteryDeviceController sharedInstance]; | ||||
NSArray *devices = [bcb connectedDevices]; | NSArray *devices = [bcb connectedDevices]; | ||||
} | } | ||||
if (!self.isUpdating && self.oldCountOfDevices != 0 && ([devices count] + 1 == self.oldCountOfDevices || [devices count] - 1 == self.oldCountOfDevices || [devices count] == self.oldCountOfDevices)) { | if (!self.isUpdating && self.oldCountOfDevices != 0 && ([devices count] + 1 == self.oldCountOfDevices || [devices count] - 1 == self.oldCountOfDevices || [devices count] == self.oldCountOfDevices)) { | ||||
//if(!self.isUpdating) { | |||||
self.isUpdating = YES; | self.isUpdating = YES; | ||||
} | } | ||||
for (KAIBatteryCell *cell in self.stack.subviews) { | for (KAIBatteryCell *cell in self.stack.subviews) { | ||||
if (![devices containsObject:cell.device] || cell.device == nil) { //not existing, remove | |||||
if (![devices containsObject:cell.device] || cell.device == nil) { // not existing, remove | |||||
NSString *deviceName = cell.label.text; | NSString *deviceName = cell.label.text; | ||||
[UIView animateWithDuration:0.3 | [UIView animateWithDuration:0.3 | ||||
animations:^{ | animations:^{ | ||||
} | } | ||||
} | } | ||||
// isUpdating is set to NO in this block | |||||
// adds a cooldown, essentially | |||||
queueTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(dispatchQueue) userInfo:nil repeats:NO]; | queueTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(dispatchQueue) userInfo:nil repeats:NO]; | ||||
//self.isUpdating = NO; | |||||
} else if (self.isUpdating) { | |||||
self.queued = YES; | |||||
} | |||||
} | |||||
self.oldCountOfDevices = [devices count]; | self.oldCountOfDevices = [devices count]; | ||||
} | } | ||||
- (void)setContentOffset:(CGPoint)arg1 { | - (void)setContentOffset:(CGPoint)arg1 { | ||||
[self setContentSize:self.stack.frame.size]; //sometimes the view gets "stuck", this fixes it | |||||
[self setContentSize:self.stack.frame.size]; // sometimes the view gets "stuck", this fixes it | |||||
[super setContentOffset:CGPointMake(arg1.x, 0)]; | [super setContentOffset:CGPointMake(arg1.x, 0)]; | ||||
} | } | ||||
[self removeFromSuperview]; | [self removeFromSuperview]; | ||||
} else if (self.number != 0 && self.superview == nil && shouldBeAdded == YES) { | } else if (self.number != 0 && self.superview == nil && shouldBeAdded == YES) { | ||||
[[[[objc_getClass("CSAdjunctListView") class] sharedListViewForKai] stackView] addArrangedSubview:self]; | [[[[objc_getClass("CSAdjunctListView") class] sharedListViewForKai] stackView] addArrangedSubview:self]; | ||||
//[self performSelector:@selector(calculateHeight) withObject:self afterDelay:0.1]; | |||||
// [self performSelector:@selector(calculateHeight) withObject:self afterDelay:0.1]; | |||||
} | } | ||||
[UIView animateWithDuration:0.3 | [UIView animateWithDuration:0.3 | ||||
int height = (self.number * (bannerHeight + spacing)); | int height = (self.number * (bannerHeight + spacing)); | ||||
int extra = extraPaddingAfter ? spacing : 0; | int extra = extraPaddingAfter ? spacing : 0; | ||||
if (kaiAlign == 0) { | if (kaiAlign == 0) { | ||||
//self.stack.widthConstraint.constant = bannerWidthFactor; | |||||
// self.stack.widthConstraint.constant = bannerWidthFactor; | |||||
} else { | } else { | ||||
height = bannerHeight + spacing; | height = bannerHeight + spacing; | ||||
} | } | ||||
} | } | ||||
self.heightConstraint.constant = height; | self.heightConstraint.constant = height; | ||||
self.stack.heightConstraint.constant = height - extra; //minus extra because it will stretch cell spacing otherwise | |||||
self.stack.heightConstraint.constant = height - extra; // minus extra because it will stretch cell spacing otherwise | |||||
UIStackView *s = (UIStackView *)(self.superview); | UIStackView *s = (UIStackView *)(self.superview); | ||||
s.frame = CGRectMake(s.frame.origin.x, s.frame.origin.y, s.frame.size.width, (s.frame.size.height - 1)); | s.frame = CGRectMake(s.frame.origin.x, s.frame.origin.y, s.frame.size.width, (s.frame.size.height - 1)); | ||||
//literally does nothing but makes the stack view lay itself out (doesnt adjust frame because translatesAutoreszingMaskIntoConstraints = NO on stack views) | |||||
// literally does nothing but makes the stack view lay itself out (doesnt adjust frame because translatesAutoreszingMaskIntoConstraints = NO on stack views) | |||||
} | } | ||||
[self setContentSize:self.stack.frame.size]; | [self setContentSize:self.stack.frame.size]; | ||||
@try { | @try { | ||||
[view removeFromSuperview]; | [view removeFromSuperview]; | ||||
} @catch (NSException *exception) { | } @catch (NSException *exception) { | ||||
//Panik | |||||
// Panik | |||||
} | } | ||||
} | } | ||||
if (kaiAlign == 0) { | if (kaiAlign == 0) { | ||||
self.subviewAligner.active = NO; | self.subviewAligner.active = NO; | ||||
if (bannerAlign == 2) { //center | |||||
if (bannerAlign == 2) { // center | |||||
self.subviewAligner = [self.stack.centerXAnchor constraintEqualToAnchor:self.stackHolder.centerXAnchor constant:horizontalOffset]; | self.subviewAligner = [self.stack.centerXAnchor constraintEqualToAnchor:self.stackHolder.centerXAnchor constant:horizontalOffset]; | ||||
} else if (bannerAlign == 1) { //left | |||||
} else if (bannerAlign == 1) { // left | |||||
self.subviewAligner = [self.stack.leftAnchor constraintEqualToAnchor:self.stackHolder.leftAnchor constant:horizontalOffset]; | self.subviewAligner = [self.stack.leftAnchor constraintEqualToAnchor:self.stackHolder.leftAnchor constant:horizontalOffset]; | ||||
} else if (bannerAlign == 3) { //right | |||||
} else if (bannerAlign == 3) { // right | |||||
self.subviewAligner = [self.stack.rightAnchor constraintEqualToAnchor:self.stackHolder.rightAnchor constant:horizontalOffset]; | self.subviewAligner = [self.stack.rightAnchor constraintEqualToAnchor:self.stackHolder.rightAnchor constant:horizontalOffset]; | ||||
} | } | ||||
} | } | ||||
- (void)dispatchQueue { | - (void)dispatchQueue { | ||||
[queueTimer invalidate]; | |||||
queueTimer = nil; | |||||
self.isUpdating = NO; | self.isUpdating = NO; | ||||
if (self.queued) { | if (self.queued) { | ||||
self.queued = NO; | |||||
[self updateBattery]; | [self updateBattery]; | ||||
if ([self.superview.superview.superview respondsToSelector:@selector(fixComplicationsViewFrame)]) { | if ([self.superview.superview.superview respondsToSelector:@selector(fixComplicationsViewFrame)]) { | ||||
[(NCNotificationListView *)(self.superview.superview.superview) fixComplicationsViewFrame]; | [(NCNotificationListView *)(self.superview.superview.superview) fixComplicationsViewFrame]; | ||||
} | } | ||||
self.queued = NO; | |||||
} | } | ||||
[queueTimer invalidate]; | |||||
queueTimer = nil; | |||||
} | } | ||||
+ (KAIBatteryPlatter *)sharedInstance { | + (KAIBatteryPlatter *)sharedInstance { | ||||
return instance; | return instance; | ||||
} | } | ||||
//This is for compatibility (did i spell that right?) | |||||
//basically this fixes it crashing in landscape: | |||||
// This is for compatibility (did i spell that right?) | |||||
// basically this fixes it crashing in landscape: | |||||
- (void)setSizeToMimic:(CGSize)arg1 { | - (void)setSizeToMimic:(CGSize)arg1 { | ||||
} | } | ||||
@end | |||||
@end |
@property (nonatomic, assign, getter=isInternal) BOOL internal; | @property (nonatomic, assign, getter=isInternal) BOOL internal; | ||||
@property (nonatomic, assign, getter=isBatterySaverModeActive) BOOL batterySaverModeActive; | @property (nonatomic, assign, getter=isBatterySaverModeActive) BOOL batterySaverModeActive; | ||||
@property (nonatomic, strong) NSString *identifier; | @property (nonatomic, strong) NSString *identifier; | ||||
- (id)glyph; //ios 13 | |||||
- (id)batteryWidgetGlyph; //ios 14 | |||||
- (id)glyph; // ios 13 | |||||
- (id)batteryWidgetGlyph; // ios 14 | |||||
- (id)kaiCellForDevice; | - (id)kaiCellForDevice; | ||||
- (void)resetKaiCellForNewPrefs; | - (void)resetKaiCellForNewPrefs; | ||||
@end | @end | ||||
@interface UIView (kai) | @interface UIView (kai) | ||||
- (void)_didRemoveSubview:(UIView *)arg1; | - (void)_didRemoveSubview:(UIView *)arg1; | ||||
@end | |||||
@end |
#import <UIKit/UIKit.h> | #import <UIKit/UIKit.h> | ||||
#import <objc/runtime.h> | #import <objc/runtime.h> | ||||
#define KAISelf ((CSAdjunctListView *)self) //for use when calling self in KAITarget | |||||
#define afterMusicIndex(cls, obj) [[[cls sharedListViewForKai] stackView].subviews indexOfObject:obj] | |||||
#define KAISelf ((CSAdjunctListView *)self) // for use when calling self in KAITarget | |||||
@interface CSAdjunctListView : UIView | @interface CSAdjunctListView : UIView | ||||
@property (nonatomic, assign) BOOL hasKai; | @property (nonatomic, assign) BOOL hasKai; | ||||
- (void)_layoutStackView; | - (void)_layoutStackView; | ||||
- (void)setStackView:(UIStackView *)arg1; | - (void)setStackView:(UIStackView *)arg1; | ||||
+ (id)sharedListViewForKai; | + (id)sharedListViewForKai; | ||||
+ (void)reorderKai; | |||||
@end | |||||
@interface SBMediaController : NSObject | |||||
@property (nonatomic, strong) id nowPlayingApplication; | |||||
- (BOOL)isPlaying; | |||||
@end | @end | ||||
@interface CALayer (kai) | @interface CALayer (kai) | ||||
BOOL isUpdating = NO; | BOOL isUpdating = NO; | ||||
BOOL shouldBeAdded = YES; | BOOL shouldBeAdded = YES; | ||||
//prefs | |||||
// prefs | |||||
BOOL enabled; | BOOL enabled; | ||||
BOOL disableGlyphs; | BOOL disableGlyphs; | ||||
BOOL hidePercent; | BOOL hidePercent; | ||||
double kaiAlign; | double kaiAlign; | ||||
double spacingHorizontal; | double spacingHorizontal; | ||||
//by importing here, I can use vars in the .mm files | |||||
// by importing here, I can use vars in the .mm files | |||||
#import "KAIBatteryCell.mm" | #import "KAIBatteryCell.mm" | ||||
#import "KAIBatteryPlatter.mm" | #import "KAIBatteryPlatter.mm" | ||||
#import "KAIStackView.mm" | #import "KAIStackView.mm" | ||||
isUpdating = YES; | isUpdating = YES; | ||||
[[KAIBatteryPlatter sharedInstance] refreshForPrefs]; //so hard (not) | |||||
[[KAIBatteryPlatter sharedInstance] refreshForPrefs]; // so hard (not) | |||||
[(CSAdjunctListView *)([KAIBatteryPlatter sharedInstance].superview.superview) _layoutStackView]; | [(CSAdjunctListView *)([KAIBatteryPlatter sharedInstance].superview.superview) _layoutStackView]; | ||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"KaiResetOffset" object:nil userInfo:nil]; | [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiResetOffset" object:nil userInfo:nil]; | ||||
isUpdating = NO; | isUpdating = NO; | ||||
} | |||||
} |
#import "Kai.h" | #import "Kai.h" | ||||
CSAdjunctListView *list; | CSAdjunctListView *list; | ||||
Class mediaClass; | |||||
%group main | %group main | ||||
%hook Media | |||||
%hook SBMediaController | |||||
- (void)dealloc { | |||||
%orig; | |||||
if(removeForMedia) { | |||||
shouldBeAdded = YES; | |||||
[[KAIBatteryPlatter sharedInstance] updateBattery]; | |||||
Class cls = kCFCoreFoundationVersionNumber > 1600 ? ([objc_getClass("CSAdjunctListView") class]) : ([objc_getClass("SBDashBoardAdjunctListView") class]); | |||||
- (BOOL)isPlaying { | |||||
Class cls = kCFCoreFoundationVersionNumber > 1600 ? ([objc_getClass("CSAdjunctListView") class]) : ([objc_getClass("SBDashBoardAdjunctListView") class]); | |||||
BOOL playing = %orig; | |||||
if(!belowMusic) { //cursed | |||||
[[[cls sharedListViewForKai] stackView] removeArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
[[[cls sharedListViewForKai] stackView] insertArrangedSubview:[KAIBatteryPlatter sharedInstance] atIndex:0]; | |||||
} | |||||
if(!removeForMedia) { | |||||
[cls reorderKai]; | |||||
return playing; | |||||
} | } | ||||
} | |||||
- (void)didMoveToSuperview { | |||||
%orig; | |||||
Class cls = kCFCoreFoundationVersionNumber > 1600 ? ([objc_getClass("CSAdjunctListView") class]) : ([objc_getClass("SBDashBoardAdjunctListView") class]); | |||||
// if removeForMedia | |||||
if(self.nowPlayingApplication && shouldBeAdded) { | |||||
// a valid playing app, and it was shown | |||||
shouldBeAdded = NO; | |||||
if([[[cls sharedListViewForKai] stackView].arrangedSubviews containsObject:self]) { | |||||
if(belowMusic) {//cursed | |||||
[[[cls sharedListViewForKai] stackView] removeArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
[[[cls sharedListViewForKai] stackView] insertArrangedSubview:[KAIBatteryPlatter sharedInstance] atIndex:afterMusicIndex(cls, self)]; | |||||
} else { | |||||
[[[cls sharedListViewForKai] stackView] removeArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
[[[cls sharedListViewForKai] stackView] insertArrangedSubview:[KAIBatteryPlatter sharedInstance] atIndex:0]; | |||||
} | |||||
[[KAIBatteryPlatter sharedInstance] removeFromSuperview]; | |||||
[[[cls sharedListViewForKai] stackView] removeArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
if(removeForMedia) { | |||||
shouldBeAdded = NO; | |||||
return playing; | |||||
} else if(!playing && self.nowPlayingApplication == nil) { | |||||
// not playing and the app is nil | |||||
shouldBeAdded = YES; | |||||
[[KAIBatteryPlatter sharedInstance] removeFromSuperview]; | |||||
[[[cls sharedListViewForKai] stackView] removeArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
} | |||||
// if we don't want to hide kai, fix its order | |||||
[cls reorderKai]; | |||||
} | } | ||||
return playing; | |||||
} | } | ||||
%end | %end | ||||
%hook KAITarget //This class is defined in %ctor, KAITarget is not a class name. | |||||
%hook KAITarget // This class is defined in %ctor, KAITarget is not a class name. | |||||
%property (nonatomic, assign) BOOL hasKai; | %property (nonatomic, assign) BOOL hasKai; | ||||
KAIBatteryPlatter *battery = [[KAIBatteryPlatter alloc] initWithFrame:[self stackView].frame]; | KAIBatteryPlatter *battery = [[KAIBatteryPlatter alloc] initWithFrame:[self stackView].frame]; | ||||
//Add noti observer | |||||
// Add noti observer | |||||
[[NSNotificationCenter defaultCenter] addObserver:self | [[NSNotificationCenter defaultCenter] addObserver:self | ||||
selector:@selector(KaiInfo) | selector:@selector(KaiInfo) | ||||
name:@"KaiInfoChanged" | name:@"KaiInfoChanged" | ||||
object:nil]; | object:nil]; | ||||
KAISelf.hasKai = YES; | KAISelf.hasKai = YES; | ||||
if(![arg1.subviews containsObject:battery]) { //if not added | |||||
//add kai to the stack view | |||||
if(![arg1.subviews containsObject:battery]) { // if not added | |||||
// add kai to the stack view | |||||
[arg1 addArrangedSubview:battery]; | [arg1 addArrangedSubview:battery]; | ||||
} | } | ||||
[battery updateBattery]; | [battery updateBattery]; | ||||
//send the adjusted stackview as arg1 | |||||
// send the adjusted stackview as arg1 | |||||
%orig(arg1); | %orig(arg1); | ||||
} | } | ||||
isUpdating = YES; | isUpdating = YES; | ||||
//NSLog(@"kai: kai info will update"); | |||||
dispatch_async(dispatch_get_main_queue(), ^{ | dispatch_async(dispatch_get_main_queue(), ^{ | ||||
[[KAIBatteryPlatter sharedInstance] updateBattery]; | [[KAIBatteryPlatter sharedInstance] updateBattery]; | ||||
return list; | return list; | ||||
} | } | ||||
%new | |||||
+ (void)reorderKai { | |||||
NSLog(@"[Kai]: Reordering kai"); | |||||
UIStackView *stack = [[self sharedListViewForKai] stackView]; | |||||
if(belowMusic) { // cursed | |||||
[stack removeArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
[stack addArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
} else { | |||||
[stack removeArrangedSubview:[KAIBatteryPlatter sharedInstance]]; | |||||
[stack insertArrangedSubview:[KAIBatteryPlatter sharedInstance] atIndex:0]; | |||||
} | |||||
} | |||||
%end | %end | ||||
%hook SBCoverSheetPrimarySlidingViewController | %hook SBCoverSheetPrimarySlidingViewController | ||||
%property (nonatomic, strong) KAIBatteryCell *kaiCell; | %property (nonatomic, strong) KAIBatteryCell *kaiCell; | ||||
- (void)setCharging:(BOOL)arg1 { | - (void)setCharging:(BOOL)arg1 { | ||||
//sends the noti to update battery info | |||||
// sends the noti to update battery info | |||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil]; | [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil]; | ||||
%orig; | %orig; | ||||
} | } | ||||
- (void)setBatterySaverModeActive:(BOOL)arg1 { | - (void)setBatterySaverModeActive:(BOOL)arg1 { | ||||
//sends the noti to update battery info | |||||
// sends the noti to update battery info | |||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil]; | [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil]; | ||||
%orig; | %orig; | ||||
} | } | ||||
- (void)setPercentCharge:(NSInteger)arg1 { | - (void)setPercentCharge:(NSInteger)arg1 { | ||||
//sends the noti to update battery info | |||||
if(arg1!=0) { | |||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil]; | |||||
// sends the noti to update battery info | |||||
if(arg1 != 0) { | |||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil]; | |||||
} | } | ||||
%orig; | %orig; | ||||
} | } | ||||
%new | %new | ||||
- (void)resetKaiCellForNewPrefs { | - (void)resetKaiCellForNewPrefs { | ||||
self.kaiCell = [[KAIBatteryCell alloc] initWithFrame:CGRectMake(0,0,[KAIBatteryPlatter sharedInstance].frame.size.width,0) device:self]; | |||||
self.kaiCell = [[KAIBatteryCell alloc] initWithFrame:CGRectMake(0,0,[KAIBatteryPlatter sharedInstance].frame.size.width,0) device:self]; | |||||
((KAIBatteryCell *)self.kaiCell).translatesAutoresizingMaskIntoConstraints = NO; | ((KAIBatteryCell *)self.kaiCell).translatesAutoresizingMaskIntoConstraints = NO; | ||||
[(KAIBatteryCell *)self.kaiCell updateInfo]; | [(KAIBatteryCell *)self.kaiCell updateInfo]; | ||||
} | } | ||||
%end | %end | ||||
%hook KAICSTarget //Again, not a class | |||||
%hook KAICSTarget // Again, not a class | |||||
- (void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 { | - (void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 { | ||||
if(hideChargingAnimation) { | if(hideChargingAnimation) { | ||||
//Yeah bro this just makes the method never call to show the charging thing | |||||
// Yeah bro this just makes the method never call to show the charging thing | |||||
%orig(NO,NO,NO); | %orig(NO,NO,NO); | ||||
} else { | |||||
%orig(arg1, arg2, arg3); | |||||
} | } | ||||
} | } | ||||
- (void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 force:(BOOL)arg4 { //might just be ios12 | |||||
- (void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 force:(BOOL)arg4 { // might just be ios12 | |||||
if(hideChargingAnimation) { | if(hideChargingAnimation) { | ||||
//Same idea | |||||
// Same idea | |||||
%orig(NO,NO,NO,NO); | %orig(NO,NO,NO,NO); | ||||
} else { | |||||
%orig(arg1, arg2, arg3, arg4); | |||||
} | } | ||||
} | } | ||||
CFNotificationSuspensionBehaviorDeliverImmediately | CFNotificationSuspensionBehaviorDeliverImmediately | ||||
); | ); | ||||
//Bro Muirey helped me figure out a logical way to do this because iOS 12-13 classes have changed | |||||
mediaClass = kCFCoreFoundationVersionNumber > 1600 ? %c(CSAdjunctItemView) : %c(SBDashBoardAdjunctItemView); | |||||
// Bro Muirey helped me figure out a logical way to do this because iOS 12-13 classes have changed | |||||
Class cls = kCFCoreFoundationVersionNumber > 1600 ? %c(CSAdjunctListView) : %c(SBDashBoardAdjunctListView); | Class cls = kCFCoreFoundationVersionNumber > 1600 ? %c(CSAdjunctListView) : %c(SBDashBoardAdjunctListView); | ||||
Class CSCls = kCFCoreFoundationVersionNumber > 1600 ? %c(CSCoverSheetViewController) : %c(SBDashBoardViewController); | Class CSCls = kCFCoreFoundationVersionNumber > 1600 ? %c(CSCoverSheetViewController) : %c(SBDashBoardViewController); | ||||
if(kCFCoreFoundationVersionNumber < 1740) { | if(kCFCoreFoundationVersionNumber < 1740) { | ||||
ios13 = YES; //wow very pog version you have | |||||
ios13 = YES; // wow very pog version you have | |||||
} | } | ||||
if(enabled) { | if(enabled) { | ||||
%init(main, Media = mediaClass, KAITarget = cls, KAICSTarget = CSCls); //BIG BRAIN BRO!! | |||||
%init(main, KAITarget = cls, KAICSTarget = CSCls); // BIG BRAIN BRO!! | |||||
} | } | ||||
NSLog(@"[kai]: loaded into %@", [NSBundle mainBundle].bundleIdentifier); | NSLog(@"[kai]: loaded into %@", [NSBundle mainBundle].bundleIdentifier); |
Package: com.burritoz.kai | Package: com.burritoz.kai | ||||
Name: Kai | Name: Kai | ||||
Version: 1.4.0 | |||||
Version: 1.5.0 | |||||
Architecture: iphoneos-arm | Architecture: iphoneos-arm | ||||
Description: Device battery indicators on your lock screen! | Description: Device battery indicators on your lock screen! | ||||
Maintainer: burrit0z | Maintainer: burrit0z |