+(id)materialViewWithRecipe:(NSInteger)arg1 options:(NSInteger)arg2 initialWeighting:(CGFloat)arg3 scaleAdjustment:(id)arg4; | +(id)materialViewWithRecipe:(NSInteger)arg1 options:(NSInteger)arg2 initialWeighting:(CGFloat)arg3 scaleAdjustment:(id)arg4; | ||||
@end | @end | ||||
@interface BCBatteryDeviceController | |||||
@interface BCBatteryDeviceController : NSObject | |||||
@property (nonatomic, strong) NSArray *sortedDevices; | @property (nonatomic, strong) NSArray *sortedDevices; | ||||
-(id)_sortedDevices; | -(id)_sortedDevices; | ||||
+(id)sharedInstance; | +(id)sharedInstance; | ||||
@end | @end | ||||
@interface BCBatteryDevice : NSObject | @interface BCBatteryDevice : NSObject | ||||
@property (nonatomic, strong) id kaiCell; | |||||
@property (nonatomic, strong) NSString *name; | |||||
@property (nonatomic, assign) long long percentCharge; | |||||
@property (nonatomic, assign) BOOL charging; | |||||
@property (nonatomic, assign) BOOL batterySaverModeActive; | |||||
@property (nonatomic, strong) NSString *identifier; | @property (nonatomic, strong) NSString *identifier; | ||||
-(id)glyph; | -(id)glyph; | ||||
@end | @end |
-(instancetype)initWithFrame:(CGRect)arg1 device:(BCBatteryDevice *)device { | -(instancetype)initWithFrame:(CGRect)arg1 device:(BCBatteryDevice *)device { | ||||
self = [super initWithFrame:arg1]; | self = [super initWithFrame:arg1]; | ||||
if(self) { | |||||
if(self && device!=nil) { | |||||
self.device = device; | self.device = device; | ||||
NSString *deviceName = MSHookIvar<NSString *>(device, "_name"); | |||||
double batteryPercentage = MSHookIvar<long long>(device, "_percentCharge"); | |||||
BOOL charging = MSHookIvar<long long>(device, "_charging"); | |||||
BOOL LPM = MSHookIvar<BOOL>(device, "_batterySaverModeActive"); | |||||
NSString *deviceName = device.name; | |||||
double batteryPercentage = device.percentCharge; | |||||
BOOL charging = device.charging; | |||||
BOOL LPM = device.batterySaverModeActive; | |||||
UIView *blank; | UIView *blank; | ||||
if(bannerStyle==1) { | if(bannerStyle==1) { |
#import "KAIBatteryStack.h" | |||||
KAIBatteryStack *instance; | |||||
//NSMutableArray *showingCells = [[NSMutableArray alloc] init]; | |||||
@implementation KAIBatteryStack | |||||
-(instancetype)init { | |||||
self = [super init]; | |||||
instance = self; | |||||
if (self) { | |||||
self.displayingDevices = [[NSMutableArray alloc] init]; | |||||
self.axis = 1; | |||||
self.distribution = 0; | |||||
self.spacing = spacing; | |||||
self.alignment = 0; | |||||
[self updateBattery]; | |||||
self.clipsToBounds = YES; | |||||
self.userInteractionEnabled = NO; | |||||
} | |||||
return self; | |||||
} | |||||
long long batteryPercentage; | |||||
long long lastPercentage; | |||||
-(void)updateBattery { | |||||
self.spacing = spacing; | |||||
dispatch_async(dispatch_get_main_queue(), ^{ | |||||
//NSLog(@"kai: battery platter called to update"); | |||||
if(!self.isUpdating) { | |||||
//NSLog(@"kai: IS Updating"); | |||||
self.isUpdating = YES; | |||||
//self.number = 0; | |||||
float y = 0; | |||||
BCBatteryDeviceController *bcb = [BCBatteryDeviceController sharedInstance]; | |||||
NSArray *devices = MSHookIvar<NSArray *>(bcb, "_sortedDevices"); | |||||
if([devices count]!=0) { | |||||
//NSLog(@"kai: info is good, will proceed"); | |||||
float ytwo = 0; | |||||
for(KAIBatteryStackCell *cell in self.subviews) { | |||||
if([cell respondsToSelector:@selector(updateInfo)] && ![devices containsObject:cell.device]) { //to confirm is a cell and battery device does not exist | |||||
//dispatch_async(dispatch_get_main_queue(), ^{ | |||||
[UIView animateWithDuration:0.2 animations:^{ | |||||
cell.alpha = 0; | |||||
} completion:^(BOOL finished){ | |||||
[cell removeFromSuperview]; | |||||
}]; | |||||
//}); | |||||
} else if([cell respondsToSelector:@selector(updateInfo)]) { | |||||
cell.frame = CGRectMake(0, y, self.frame.size.width, bannerHeight); | |||||
[cell updateInfo]; | |||||
ytwo+= bannerHeight + spacing; | |||||
} | |||||
} | |||||
for (BCBatteryDevice *device in devices) { | |||||
NSString *deviceName = MSHookIvar<NSString *>(device, "_name"); | |||||
//double batteryPercentage = MSHookIvar<long long>(device, "_percentCharge"); | |||||
BOOL charging = MSHookIvar<long long>(device, "_charging"); | |||||
//BOOL LPM = MSHookIvar<BOOL>(device, "_batterySaverModeActive"); | |||||
BOOL shouldAdd = NO; | |||||
if(showAll) { | |||||
shouldAdd = YES; | |||||
//NSLog(@"Kai: SHOULD ADD"); | |||||
} else if(!showAll && charging) { | |||||
shouldAdd = YES; | |||||
//NSLog(@"Kai: SHOULD ADD"); | |||||
} | |||||
KAIBatteryStackCell *cell = [KAIBatteryStackCell cellForDeviceIfExists:device frameToCreateNew:CGRectMake(0, y, self.frame.size.width, bannerHeight)]; | |||||
cell.frame = CGRectMake(0, y, self.frame.size.width, bannerHeight); | |||||
if(cell) { | |||||
cell.device = device; | |||||
//cell.frame = cell.frame = CGRectMake(0, y, self.frame.size.width, bannerHeight); //bro im like creating my own stack view | |||||
//[cell updateInfo]; | |||||
} | |||||
if(shouldAdd && [deviceName length]!=0) { | |||||
if(![self.subviews containsObject:cell]) { | |||||
cell.frame = CGRectMake(0, y, self.frame.size.width, bannerHeight); | |||||
cell.alpha = 0; | |||||
[self addSubview:cell]; | |||||
[UIView animateWithDuration:0.3 animations:^{ | |||||
cell.alpha = 1; | |||||
}]; | |||||
} | |||||
y+=bannerHeight + spacing; | |||||
} else if(!shouldAdd) { | |||||
//dispatch_async(dispatch_get_main_queue(), ^{ | |||||
[UIView animateWithDuration:0.2 animations:^{ | |||||
cell.alpha = 0; | |||||
} completion:^(BOOL finished){ | |||||
[cell removeFromSuperview]; | |||||
}]; | |||||
//}); | |||||
} | |||||
} | |||||
//[self.heightAnchor constraintEqualToConstant:(self.number * 85)].active = YES; | |||||
self.number = [self.subviews count]; | |||||
//[(CSAdjunctListView *)self.superview.superview KaiUpdate]; | |||||
} | |||||
self.isUpdating = NO; | |||||
//NSLog(@"kai: finished update"); | |||||
//[(CSAdjunctListView *)self.superview.superview KaiUpdate]; | |||||
[(CSAdjunctListView *)self.superview.superview performSelector:@selector(KaiUpdate) withObject:(CSAdjunctListView *)self.superview.superview afterDelay:0.2]; | |||||
} | |||||
}); | |||||
} | |||||
-(void)removeAllAndRefresh { | |||||
for( UIView *view in self.subviews ) { | |||||
@try { | |||||
[view removeFromSuperview]; | |||||
} @catch (NSException *exception) { | |||||
//Panik | |||||
} | |||||
} | |||||
[KAIBatteryStackCell resetArray]; | |||||
//self.displayingDevices = [[NSMutableArray alloc] init]; | |||||
//addedCells = nil; | |||||
[self updateBattery]; | |||||
} | |||||
+(KAIBatteryStack *)sharedInstance { | |||||
return instance; | |||||
} | |||||
@end |
@interface KAIBattery : UIView | |||||
@interface KAIBatteryStack : UIStackView | |||||
@property (nonatomic, strong) NSMutableArray *displayingDevices; | @property (nonatomic, strong) NSMutableArray *displayingDevices; | ||||
@property (nonatomic, assign) NSInteger number; | @property (nonatomic, assign) NSInteger number; | ||||
@property (nonatomic, strong) NSLayoutConstraint *heightConstraint; | @property (nonatomic, strong) NSLayoutConstraint *heightConstraint; | ||||
@property (nonatomic, assign) BOOL isUpdating; | @property (nonatomic, assign) BOOL isUpdating; | ||||
+(KAIBattery *)sharedInstance; | |||||
+(KAIBatteryStack *)sharedInstance; | |||||
-(instancetype)init; | -(instancetype)init; | ||||
-(void)removeAllAndRefresh; | -(void)removeAllAndRefresh; | ||||
-(void)updateBattery; | -(void)updateBattery; |
#import "KAIBattery.h" | |||||
#import "KAIBatteryStack.h" | |||||
KAIBattery *instance; | |||||
KAIBatteryStack *instance; | |||||
//NSMutableArray *showingCells = [[NSMutableArray alloc] init]; | //NSMutableArray *showingCells = [[NSMutableArray alloc] init]; | ||||
@implementation KAIBattery | |||||
@implementation KAIBatteryStack | |||||
-(instancetype)init { | -(instancetype)init { | ||||
self = [super init]; | self = [super init]; | ||||
instance = self; | instance = self; | ||||
if (self) { | if (self) { | ||||
self.displayingDevices = [[NSMutableArray alloc] init]; | self.displayingDevices = [[NSMutableArray alloc] init]; | ||||
self.axis = 1; | |||||
self.distribution = 0; | |||||
self.spacing = spacing; | |||||
self.alignment = 0; | |||||
[self updateBattery]; | [self updateBattery]; | ||||
self.clipsToBounds = YES; | |||||
//self.clipsToBounds = YES; | |||||
self.userInteractionEnabled = NO; | self.userInteractionEnabled = NO; | ||||
} | } | ||||
return self; | return self; | ||||
long long lastPercentage; | long long lastPercentage; | ||||
-(void)updateBattery { | -(void)updateBattery { | ||||
/* | |||||
self.spacing = spacing; | |||||
dispatch_async(dispatch_get_main_queue(), ^{ | dispatch_async(dispatch_get_main_queue(), ^{ | ||||
//NSLog(@"kai: battery platter called to update"); | //NSLog(@"kai: battery platter called to update"); | ||||
if(!self.isUpdating) { | if(!self.isUpdating) { | ||||
//[(CSAdjunctListView *)self.superview.superview KaiUpdate]; | //[(CSAdjunctListView *)self.superview.superview KaiUpdate]; | ||||
[(CSAdjunctListView *)self.superview.superview performSelector:@selector(KaiUpdate) withObject:(CSAdjunctListView *)self.superview.superview afterDelay:0.2]; | [(CSAdjunctListView *)self.superview.superview performSelector:@selector(KaiUpdate) withObject:(CSAdjunctListView *)self.superview.superview afterDelay:0.2]; | ||||
} | } | ||||
}); | |||||
});*/ | |||||
self.number = [self.subviews count]; | |||||
} | } | ||||
-(void)removeAllAndRefresh { | -(void)removeAllAndRefresh { | ||||
[self updateBattery]; | [self updateBattery]; | ||||
} | } | ||||
+(KAIBattery *)sharedInstance { | |||||
+(KAIBatteryStack *)sharedInstance { | |||||
return instance; | return instance; | ||||
} | } | ||||
#import <UIKit/UIKit.h> | #import <UIKit/UIKit.h> | ||||
#define KAISelf ((CSAdjunctListView *)self) //for use when calling self in KAITarget | #define KAISelf ((CSAdjunctListView *)self) //for use when calling self in KAITarget | ||||
#define KAIBattery UHDUEIHGCEBCHYDEICVKEVSAGJKBCXAHJGKVXHAS //lmao | |||||
//#define KAIBatteryStack UHDUEIHGCEBCHYDEICVKEVSAGJKBCXAHJGKVXHAS //lmao | |||||
//#define KAIBatteryCell HDEIUOGEUBGUYOEXHNOPUSZIOJIGECEXIUSHXJXBE //very good | |||||
@interface CSAdjunctListView : UIView | @interface CSAdjunctListView : UIView | ||||
@property (nonatomic, assign) BOOL hasKai; | @property (nonatomic, assign) BOOL hasKai; | ||||
//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 "KAIBattery.mm" | |||||
#import "KAIBatteryStack.mm" | |||||
#define PLIST_PATH @"/User/Library/Preferences/com.burritoz.kaiprefs.plist" | #define PLIST_PATH @"/User/Library/Preferences/com.burritoz.kaiprefs.plist" | ||||
#define kIdentifier @"com.burritoz.kaiprefs" | #define kIdentifier @"com.burritoz.kaiprefs" | ||||
isUpdating = YES; | isUpdating = YES; | ||||
[[KAIBattery sharedInstance] removeAllAndRefresh]; | |||||
[(CSAdjunctListView *)([KAIBattery sharedInstance].superview.superview) KaiUpdate]; | |||||
[[KAIBatteryStack sharedInstance] removeAllAndRefresh]; | |||||
[(CSAdjunctListView *)([KAIBatteryStack sharedInstance].superview.superview) KaiUpdate]; | |||||
isUpdating = NO; | isUpdating = NO; | ||||
//here I remotely refresh the KAIView. | //here I remotely refresh the KAIView. | ||||
/*isUpdating = YES; | /*isUpdating = YES; | ||||
[UIView animateWithDuration:0.3 animations:^{ | [UIView animateWithDuration:0.3 animations:^{ | ||||
[KAIBattery sharedInstance].alpha = 0; | |||||
[KAIBatteryStack sharedInstance].alpha = 0; | |||||
} completion:^(BOOL finished){ | } completion:^(BOOL finished){ | ||||
[[KAIBattery sharedInstance] updateBattery]; | |||||
[(CSAdjunctListView *)([KAIBattery sharedInstance].superview.superview) KaiUpdate]; | |||||
[[KAIBatteryStack sharedInstance] updateBattery]; | |||||
[(CSAdjunctListView *)([KAIBatteryStack sharedInstance].superview.superview) KaiUpdate]; | |||||
[UIView animateWithDuration:0.35 animations:^{ | [UIView animateWithDuration:0.35 animations:^{ | ||||
[KAIBattery sharedInstance].alpha = 1; | |||||
[KAIBatteryStack sharedInstance].alpha = 1; | |||||
} completion:^(BOOL finished){ | } completion:^(BOOL finished){ | ||||
isUpdating = NO; | isUpdating = NO; | ||||
}]; | }]; |
NSInteger lastSlot = [[self stackView].subviews count] -1; | NSInteger lastSlot = [[self stackView].subviews count] -1; | ||||
//this code is used to determine if kai is at the bottom of the stack view | //this code is used to determine if kai is at the bottom of the stack view | ||||
if([[self stackView].subviews objectAtIndex:lastSlot] != [KAIBattery sharedInstance] && belowMusic) { | |||||
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. | //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. | //and insert into last slot. | ||||
[[self stackView] removeArrangedSubview:[KAIBattery sharedInstance]]; | |||||
[[self stackView] insertArrangedSubview:[KAIBattery sharedInstance] atIndex:lastSlot]; | |||||
[[self stackView] removeArrangedSubview:[KAIBatteryStack sharedInstance]]; | |||||
[[self stackView] insertArrangedSubview:[KAIBatteryStack sharedInstance] atIndex:lastSlot]; | |||||
} | } | ||||
//makes kai lay itself out when the stack does | //makes kai lay itself out when the stack does | ||||
-(void)setStackView:(UIStackView *)arg1 { | -(void)setStackView:(UIStackView *)arg1 { | ||||
if(!KAISelf.hasKai) { | if(!KAISelf.hasKai) { | ||||
KAIBattery *battery = [[KAIBattery alloc] init]; | |||||
KAIBatteryStack *battery = [[KAIBatteryStack alloc] init]; | |||||
//Add noti observer | //Add noti observer | ||||
[[NSNotificationCenter defaultCenter] addObserver:self | [[NSNotificationCenter defaultCenter] addObserver:self | ||||
%new | %new | ||||
-(void)KaiUpdate { | -(void)KaiUpdate { | ||||
KAIBattery *battery = [KAIBattery sharedInstance]; | |||||
KAIBatteryStack *battery = [KAIBatteryStack sharedInstance]; | |||||
battery.number = [battery.subviews count]; | battery.number = [battery.subviews count]; | ||||
[UIView animateWithDuration:0.3 animations:^{ | [UIView animateWithDuration:0.3 animations:^{ | ||||
//NSLog(@"kai: kai info will update"); | //NSLog(@"kai: kai info will update"); | ||||
dispatch_async(dispatch_get_main_queue(), ^{ | dispatch_async(dispatch_get_main_queue(), ^{ | ||||
[[KAIBattery sharedInstance] updateBattery]; | |||||
[[KAIBatteryStack sharedInstance] updateBattery]; | |||||
[self KaiUpdate]; | [self KaiUpdate]; | ||||
isUpdating = NO; | isUpdating = NO; | ||||
}); | }); | ||||
/*isUpdating = YES; | |||||
[UIView animateWithDuration:0.3 animations:^{ | |||||
//nice fade out | |||||
[KAIBattery sharedInstance].alpha = 0; | |||||
} completion:^(BOOL finished){ | |||||
[[KAIBattery sharedInstance] updateBattery]; | |||||
[self KaiUpdate]; | |||||
[UIView animateWithDuration:0.35 animations:^{ | |||||
//fade back in | |||||
[KAIBattery sharedInstance].alpha = 1; | |||||
} completion:^(BOOL finished){ | |||||
isUpdating = NO; | |||||
}]; | |||||
}];*/ | |||||
} | } | ||||
} | } | ||||
%hook BCBatteryDevice | %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 { | - (id)initWithIdentifier:(id)arg1 vendor:(long long)arg2 productIdentifier:(long long)arg3 parts:(unsigned long long)arg4 matchIdentifier:(id)arg5 { | ||||
} | } | ||||
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ | -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ | ||||
if(self && self.kaiCell == nil) { | |||||
self.kaiCell = [[KAIBatteryCell alloc] initWithFrame:CGRectMake(0,0,0,0) device:self]; } | |||||
((KAIBatteryCell *)self.kaiCell).translatesAutoresizingMaskIntoConstraints = NO; | |||||
[((KAIBatteryCell *)self.kaiCell).heightAnchor constraintEqualToConstant:bannerHeight].active = YES; | |||||
dispatch_async(dispatch_get_main_queue(), ^{ | dispatch_async(dispatch_get_main_queue(), ^{ | ||||
//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]; | ||||
[(KAIBatteryCell *)self.kaiCell updateInfo]; | |||||
BOOL shouldAdd = NO; | |||||
if(showAll) { | |||||
shouldAdd = YES; | |||||
} else if(!showAll && self.charging) { | |||||
shouldAdd = YES; | |||||
} | |||||
if(![[KAIBatteryStack sharedInstance].subviews containsObject:self.kaiCell] && shouldAdd) { | |||||
[[KAIBatteryStack sharedInstance] addArrangedSubview:self.kaiCell]; | |||||
} else if([[KAIBatteryStack sharedInstance].subviews containsObject:self.kaiCell] && !shouldAdd) { | |||||
[[KAIBatteryStack sharedInstance] removeArrangedSubview:self.kaiCell]; | |||||
} | |||||
}); | }); | ||||
} | } |
Package: com.burritoz.kai | Package: com.burritoz.kai | ||||
Name: Kai | Name: Kai | ||||
Version: 0.2.0~alpha | |||||
Version: 0.2.5~alpha | |||||
Architecture: iphoneos-arm | Architecture: iphoneos-arm | ||||
Description: Show charging banners on your lock screen! | Description: Show charging banners on your lock screen! | ||||
Maintainer: burrit0z | Maintainer: burrit0z |