1
0
鏡像自 https://github.com/Burrit0z/kai 已同步 2025-06-30 21:46:48 +00:00
Files
kai/Kai.xm
2020-05-24 18:58:35 -04:00

173 行
5.4 KiB
Plaintext

#import "Kai.h"
%hook KAITarget //This class is defined in %ctor, KAITarget is not a class name.
%property (nonatomic, assign) BOOL hasKai;
-(void)_layoutStackView {
NSInteger lastSlot = [[self stackView].subviews count] -1;
//this code is used to determine if kai is at the bottom of the stack view
if([[self stackView].subviews objectAtIndex:lastSlot] != [KAIBatteryStack sharedInstance] && belowMusic) {
//if it is not, but the option to have kai below music is on, i simply remove from it's current pos.
//and insert into last slot.
[[self stackView] removeArrangedSubview:[KAIBatteryStack sharedInstance]];
[[self stackView] insertArrangedSubview:[KAIBatteryStack sharedInstance] atIndex:lastSlot];
}
//makes kai lay itself out when the stack does
NSLog(@"kai: laying out stack view");
[self KaiUpdate];
%orig;
}
-(void)setStackView:(UIStackView *)arg1 {
if(!KAISelf.hasKai) {
KAIBatteryStack *battery = [[KAIBatteryStack alloc] init];
//Add noti observer
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(KaiInfo)
name:@"KaiInfoChanged"
object:nil];
KAISelf.hasKai = YES;
if(![arg1.subviews containsObject:battery]) { //if not added
//add kai to the stack view
[arg1 addArrangedSubview:battery];
}
[battery updateBattery];
//send the adjusted stackview as arg1
%orig(arg1);
}
}
%new
-(void)KaiUpdate {
KAIBatteryStack *battery = [KAIBatteryStack sharedInstance];
//battery.number = [battery.subviews count];
[UIView animateWithDuration:0.3 animations:^{
if(!battery.heightConstraint) {
battery.heightConstraint.active = NO;
battery.heightConstraint = [battery.heightAnchor constraintEqualToConstant:85];
//set an initial constraint
battery.heightConstraint.active = YES;
} else {
int height = (battery.number * (bannerHeight + spacing)); //big brain math
//battery.heightConstraint.active = NO; //deactivation
battery.heightConstraint.constant = height;
//battery.heightConstraint.active = YES; //forcing reactivation
UIStackView *s = [self stackView];
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)
}
}];
}
%new
-(void)KaiInfo {
if(!isUpdating) {
isUpdating = YES;
//NSLog(@"kai: kai info will update");
dispatch_async(dispatch_get_main_queue(), ^{
[[KAIBatteryStack sharedInstance] updateBattery];
[self KaiUpdate];
isUpdating = NO;
});
}
}
%end
%hook BCBatteryDevice
%property (nonatomic, strong) KAIBatteryCell *kaiCell;
- (id)initWithIdentifier:(id)arg1 vendor:(long long)arg2 productIdentifier:(long long)arg3 parts:(unsigned long long)arg4 matchIdentifier:(id)arg5 {
//Posts a notification to self when these keys change
[self addObserver:self forKeyPath:@"charging" options:NSKeyValueObservingOptionNew context:nil];
[self addObserver:self forKeyPath:@"batterySaverModeActive" options:NSKeyValueObservingOptionNew context:nil];
[self addObserver:self forKeyPath:@"percentCharge" options:NSKeyValueObservingOptionNew context:nil];
return %orig;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
//if([self isMemberOfClass:[objc_getClass("BCBatteryDevice") class]] && [self respondsToSelector:@selector(_kaiCell)] && object == self && ([keyPath isEqualToString:@"charging"] || [keyPath isEqualToString:@"percentCharge"] || [keyPath isEqualToString:@"batterySaverModeActive"])) {
//sends the noti to update battery info
[[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil];
//}
}
%new
-(id)kaiCellForDevice {
if(self && self.kaiCell == nil) {
self.kaiCell = [[KAIBatteryCell alloc] initWithFrame:CGRectMake(0,0,[KAIBatteryStack sharedInstance].frame.size.width,0) device:self]; }
((KAIBatteryCell *)self.kaiCell).translatesAutoresizingMaskIntoConstraints = NO;
[((KAIBatteryCell *)self.kaiCell).heightAnchor constraintEqualToConstant:bannerHeight].active = YES;
[(KAIBatteryCell *)self.kaiCell updateInfo];
return self.kaiCell;
}
%end
%hook KAICSTarget //Again, not a class
-(void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 {
if(hideChargingAnimation) {
//Yeah bro this just makes the method never call to show the charging thing
%orig(NO,NO,NO);
}
}
-(void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 force:(BOOL)arg4 { //might just be ios12
if(hideChargingAnimation) {
//Same idea
%orig(NO,NO,NO,NO);
}
}
%end
%ctor {
preferencesChanged();
CFNotificationCenterAddObserver(
CFNotificationCenterGetDarwinNotifyCenter(),
&observer,
(CFNotificationCallback)applyPrefs,
kSettingsChangedNotification,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately
);
//Bro Muirey helped me figure out a logical way to do this because iOS 12-13 classes have changed
Class cls = kCFCoreFoundationVersionNumber > 1600 ? ([objc_getClass("CSAdjunctListView") class]) : ([objc_getClass("SBDashBoardAdjunctListView") class]);
Class CSCls = kCFCoreFoundationVersionNumber > 1600 ? ([objc_getClass("CSCoverSheetViewController") class]) : ([objc_getClass("SBDashBoardViewController") class]);
if(enabled) {
%init(KAITarget = cls, KAICSTarget = CSCls); //BIG BRAIN BRO!!
}
}