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.

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