Device battery indicators on your Lock Screen
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
7.3KB

  1. #import "Kai.h"
  2. CSAdjunctListView *list;
  3. %group main
  4. %hook SBMediaController
  5. - (BOOL)isPlaying {
  6. Class cls = kCFCoreFoundationVersionNumber > 1600 ? ([objc_getClass("CSAdjunctListView") class]) : ([objc_getClass("SBDashBoardAdjunctListView") class]);
  7. BOOL playing = %orig;
  8. if(!removeForMedia) {
  9. [cls reorderKai];
  10. return playing;
  11. }
  12. // if removeForMedia
  13. if(self.nowPlayingApplication && shouldBeAdded) {
  14. // a valid playing app, and it was shown
  15. shouldBeAdded = NO;
  16. [[KAIBatteryPlatter sharedInstance] removeFromSuperview];
  17. [[[cls sharedListViewForKai] stackView] removeArrangedSubview:[KAIBatteryPlatter sharedInstance]];
  18. [[cls sharedListViewForKai] _layoutStackView];
  19. return playing;
  20. } else if(!playing && self.nowPlayingApplication == nil) {
  21. // not playing and the app is nil
  22. shouldBeAdded = YES;
  23. // if we don't want to hide kai, fix its order
  24. [cls reorderKai];
  25. }
  26. return playing;
  27. }
  28. %end
  29. %hook KAITarget // This class is defined in %ctor, KAITarget is not a class name.
  30. %property (nonatomic, assign) BOOL hasKai;
  31. - (void)setClipsToBounds:(BOOL)arg1 {
  32. %orig(YES);
  33. }
  34. - (void)setStackView:(UIStackView *)arg1 {
  35. KAISelf.clipsToBounds = YES;
  36. if(!KAISelf.hasKai) {
  37. list = self;
  38. KAIBatteryPlatter *battery = [[KAIBatteryPlatter alloc] initWithFrame:[self stackView].frame];
  39. // Add noti observer
  40. [[NSNotificationCenter defaultCenter] addObserver:self
  41. selector:@selector(KaiInfo)
  42. name:@"KaiInfoChanged"
  43. object:nil];
  44. KAISelf.hasKai = YES;
  45. if(![arg1.subviews containsObject:battery]) { // if not added
  46. // add kai to the stack view
  47. [self performReorder];
  48. }
  49. [battery updateBattery];
  50. // send the adjusted stackview as arg1
  51. %orig(arg1);
  52. }
  53. }
  54. %new
  55. - (void)KaiInfo {
  56. if(!isUpdating) {
  57. isUpdating = YES;
  58. dispatch_async(dispatch_get_main_queue(), ^{
  59. [[KAIBatteryPlatter sharedInstance] updateBattery];
  60. if([KAIBatteryPlatter sharedInstance].number == 0) {
  61. [[KAIBatteryPlatter sharedInstance] removeFromSuperview];
  62. [[self stackView] removeArrangedSubview:[KAIBatteryPlatter sharedInstance]];
  63. } else if(![[self stackView].subviews containsObject:[KAIBatteryPlatter sharedInstance]] && shouldBeAdded) {
  64. [[self stackView] addSubview:[KAIBatteryPlatter sharedInstance]];
  65. [[self stackView] addArrangedSubview:[KAIBatteryPlatter sharedInstance]];
  66. }
  67. if([KAISelf.superview respondsToSelector:@selector(fixComplicationsViewFrame)]) {
  68. [KAISelf.superview performSelector:@selector(fixComplicationsViewFrame) withObject:KAISelf.superview afterDelay:0.35];
  69. }
  70. isUpdating = NO;
  71. });
  72. }
  73. }
  74. %new
  75. - (NSInteger)getMediaIndexForClass:(Class)cls {
  76. UIView *mediaPlayer;
  77. int index = 0;
  78. for(UIView *subview in [self stackView].subviews) {
  79. if([subview isKindOfClass:cls]) {
  80. return index;
  81. }
  82. index++;
  83. }
  84. return NSNotFound;
  85. }
  86. %new
  87. - (void)performReorder {
  88. UIStackView *stack = [self stackView];
  89. if(placement == 1) { //top
  90. BOOL isAperio = NO;
  91. @try {
  92. isAperio = [stack.subviews[0] isKindOfClass:%c(APEPlatter)];
  93. // index 0 would be the platter, 1 would be placeholder
  94. } @catch(NSException *exc) {}
  95. [stack removeArrangedSubview:[KAIBatteryPlatter sharedInstance]];
  96. [stack insertArrangedSubview:[KAIBatteryPlatter sharedInstance] atIndex:isAperio];
  97. // so, 0 if not aperio, 1 if aperio
  98. } else if(placement == 2) { //after media
  99. Class mediaClass = kCFCoreFoundationVersionNumber > 1600 ? %c(CSAdjunctItemView) : %c(SBDashBoardAdjunctItemView);
  100. NSInteger mediaIndex = [self getMediaIndexForClass:mediaClass];
  101. if(mediaIndex == NSNotFound) mediaIndex = 0;
  102. [stack removeArrangedSubview:[KAIBatteryPlatter sharedInstance]];
  103. [stack insertArrangedSubview:[KAIBatteryPlatter sharedInstance] atIndex:mediaIndex];
  104. } else if(placement == 3) { // bottom
  105. [stack removeArrangedSubview:[KAIBatteryPlatter sharedInstance]];
  106. [stack addArrangedSubview:[KAIBatteryPlatter sharedInstance]];
  107. }
  108. [self _layoutStackView];
  109. }
  110. %new
  111. + (id)sharedListViewForKai {
  112. return list;
  113. }
  114. %new
  115. + (void)reorderKai {
  116. NSLog(@"[Kai]: Reordering kai");
  117. [[self sharedListViewForKai] performReorder];
  118. }
  119. %end
  120. %hook SBCoverSheetPrimarySlidingViewController
  121. - (void)viewDidDisappear:(BOOL)animated {
  122. if(reAlignSelf)
  123. [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiResetOffset" object:nil userInfo:nil];
  124. %orig;
  125. }
  126. - (void)viewDidAppear:(BOOL)animated {
  127. if(reAlignSelf)
  128. [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiResetOffset" object:nil userInfo:nil];
  129. %orig;
  130. }
  131. %end
  132. %hook BCBatteryDevice
  133. %property (nonatomic, strong) KAIBatteryCell *kaiCell;
  134. - (void)setCharging:(BOOL)arg1 {
  135. // sends the noti to update battery info
  136. [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil];
  137. %orig;
  138. }
  139. - (void)setBatterySaverModeActive:(BOOL)arg1 {
  140. // sends the noti to update battery info
  141. [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil];
  142. %orig;
  143. }
  144. - (void)setPercentCharge:(NSInteger)arg1 {
  145. // sends the noti to update battery info
  146. if(arg1 != 0) {
  147. [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil];
  148. }
  149. %orig;
  150. }
  151. - (void)dealloc {
  152. %orig;
  153. [[NSNotificationCenter defaultCenter] postNotificationName:@"KaiInfoChanged" object:nil userInfo:nil];
  154. }
  155. %new
  156. - (id)kaiCellForDevice {
  157. if(self && self.kaiCell == nil) {
  158. self.kaiCell = [[KAIBatteryCell alloc] initWithFrame:CGRectMake(0,0,[KAIBatteryPlatter sharedInstance].frame.size.width,0) device:self]; }
  159. ((KAIBatteryCell *)self.kaiCell).translatesAutoresizingMaskIntoConstraints = NO;
  160. [(KAIBatteryCell *)self.kaiCell updateInfo];
  161. return self.kaiCell;
  162. }
  163. %new
  164. - (void)resetKaiCellForNewPrefs {
  165. self.kaiCell = [[KAIBatteryCell alloc] initWithFrame:CGRectMake(0,0,[KAIBatteryPlatter sharedInstance].frame.size.width,0) device:self];
  166. ((KAIBatteryCell *)self.kaiCell).translatesAutoresizingMaskIntoConstraints = NO;
  167. [(KAIBatteryCell *)self.kaiCell updateInfo];
  168. }
  169. %end
  170. %hook KAICSTarget // Again, not a class
  171. - (void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 {
  172. if(hideChargingAnimation) {
  173. // Yeah bro this just makes the method never call to show the charging thing
  174. %orig(NO,NO,NO);
  175. } else {
  176. %orig(arg1, arg2, arg3);
  177. }
  178. }
  179. - (void)_transitionChargingViewToVisible:(BOOL)arg1 showBattery:(BOOL)arg2 animated:(BOOL)arg3 force:(BOOL)arg4 { // might just be ios12
  180. if(hideChargingAnimation) {
  181. // Same idea
  182. %orig(NO,NO,NO,NO);
  183. } else {
  184. %orig(arg1, arg2, arg3, arg4);
  185. }
  186. }
  187. %end
  188. %end
  189. %ctor {
  190. preferencesChanged();
  191. CFNotificationCenterAddObserver(
  192. CFNotificationCenterGetDarwinNotifyCenter(),
  193. &observer,
  194. (CFNotificationCallback)applyPrefs,
  195. kSettingsChangedNotification,
  196. NULL,
  197. CFNotificationSuspensionBehaviorDeliverImmediately
  198. );
  199. // Bro Muirey helped me figure out a logical way to do this because iOS 12-13 classes have changed
  200. Class cls = kCFCoreFoundationVersionNumber > 1600 ? %c(CSAdjunctListView) : %c(SBDashBoardAdjunctListView);
  201. Class CSCls = kCFCoreFoundationVersionNumber > 1600 ? %c(CSCoverSheetViewController) : %c(SBDashBoardViewController);
  202. if(kCFCoreFoundationVersionNumber < 1740) {
  203. ios13 = YES; // wow very pog version you have
  204. }
  205. if(enabled) {
  206. %init(main, KAITarget = cls, KAICSTarget = CSCls); // BIG BRAIN BRO!!
  207. }
  208. NSLog(@"[kai]: loaded into %@", [NSBundle mainBundle].bundleIdentifier);
  209. }