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.

200 lines
6.7KB

  1. #import "KAIBatteryStack.h"
  2. KAIBatteryStack *instance;
  3. NSTimer *queueTimer = nil;
  4. //NSMutableArray *showingCells = [[NSMutableArray alloc] init];
  5. @implementation KAIBatteryStack
  6. -(instancetype)init {
  7. self = [super init];
  8. instance = self;
  9. if (self) {
  10. self.displayingDevices = [[NSMutableArray alloc] init];
  11. self.axis = 1;
  12. self.distribution = 0;
  13. self.spacing = 0;
  14. self.alignment = 0;
  15. self.oldCountOfDevices = -100;
  16. self.queued = NO;
  17. [self updateBattery];
  18. //self.clipsToBounds = YES;
  19. self.userInteractionEnabled = NO;
  20. }
  21. return self;
  22. }
  23. long long batteryPercentage;
  24. long long lastPercentage;
  25. -(void)updateBattery {
  26. dispatch_async(dispatch_get_main_queue(), ^{
  27. BCBatteryDeviceController *bcb = [BCBatteryDeviceController sharedInstance];
  28. NSArray *devices = MSHookIvar<NSArray *>(bcb, "_sortedDevices");
  29. if(self.oldCountOfDevices == -100) {
  30. self.oldCountOfDevices = [devices count] + 1;
  31. }
  32. if(!self.isUpdating && self.oldCountOfDevices != 0 && ([devices count] + 1 == self.oldCountOfDevices || [devices count] - 1 == self.oldCountOfDevices || [devices count] == self.oldCountOfDevices)) {
  33. //if(!self.isUpdating) {
  34. self.isUpdating = YES;
  35. for (BCBatteryDevice *device in devices) {
  36. KAIBatteryCell *cell = [device kaiCellForDevice];
  37. BOOL charging = MSHookIvar<long long>(device, "_charging");
  38. BOOL internal = MSHookIvar<BOOL>(device, "_internal");
  39. BOOL shouldAdd = NO;
  40. if(showAll) {
  41. shouldAdd = YES;
  42. } else if(showAllMinusInternal && !internal) {
  43. shouldAdd = YES;
  44. } else if(!showAll && charging) {
  45. shouldAdd = YES;
  46. }
  47. if(![self.subviews containsObject:cell] && shouldAdd && [devices containsObject:device]) {
  48. //[cell setFrame:CGRectMake(0,0,self.frame.size.width, bannerHeight)];
  49. cell.alpha = 0;
  50. [self addSubview:cell];
  51. [self addArrangedSubview:cell];
  52. [UIView animateWithDuration:0.3 animations:^{
  53. cell.alpha = 1;
  54. }];
  55. } else if([self.subviews containsObject:cell] && !shouldAdd){
  56. [UIView animateWithDuration:0.3 animations:^{
  57. cell.alpha = 0;
  58. } completion:^(BOOL finished) {
  59. [cell removeFromSuperview];
  60. [self removeArrangedSubview:cell];
  61. cell.alpha = 1;
  62. }];
  63. }
  64. }
  65. for(KAIBatteryCell *cell in self.subviews) {
  66. if(![devices containsObject:cell.device]) {
  67. [UIView animateWithDuration:0.3 animations:^{
  68. cell.alpha = 0;
  69. } completion:^(BOOL finished) {
  70. [cell removeFromSuperview];
  71. [self removeArrangedSubview:cell];
  72. cell.alpha = 1;
  73. }];
  74. }
  75. }
  76. queueTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(dispatchQueue) userInfo:nil repeats:NO];
  77. self.isUpdating = NO;
  78. } else if(self.isUpdating) {
  79. self.queued = YES;
  80. }
  81. self.oldCountOfDevices = [devices count];
  82. self.number = [self.subviews count];
  83. if([self.superview.superview.superview respondsToSelector:@selector(fixComplicationsViewFrame)]) {
  84. [(NCNotificationListView *)(self.superview.superview.superview) fixComplicationsViewFrame];
  85. }
  86. });
  87. }
  88. -(void)setNumber:(NSInteger)arg1 {
  89. _number = arg1;
  90. [UIView animateWithDuration:0.3 animations:^{
  91. if(!self.heightConstraint) {
  92. self.heightConstraint = [self.heightAnchor constraintEqualToConstant:(self.number * (bannerHeight + spacing))];
  93. self.heightConstraint.active = YES;
  94. } else {
  95. int height;
  96. if([self.superview.subviews objectAtIndex:([self.superview.subviews count] - 1)] == self) {
  97. height = (self.number * (bannerHeight + spacing));
  98. } else {
  99. height = (self.number * (bannerHeight + spacing)) - spacing;
  100. }
  101. self.heightConstraint.constant = height;
  102. UIStackView *s = (UIStackView *)(self.superview);
  103. s.frame = CGRectMake(s.frame.origin.x, s.frame.origin.y, s.frame.size.width, (s.frame.size.height - 1));
  104. //literally does nothing but makes the stack view lay itself out (doesnt adjust frame because translatesAutoreszingMaskIntoConstraints = NO on stack views)
  105. }
  106. }];
  107. }
  108. -(void)addArrangedSubview:(UIView *)view {
  109. [super addArrangedSubview:view];
  110. self.number = [self.subviews count];
  111. if([self.superview.superview.superview respondsToSelector:@selector(fixComplicationsViewFrame)]) {
  112. [(NCNotificationListView *)(self.superview.superview.superview) fixComplicationsViewFrame];
  113. }
  114. if(textColor==0) {
  115. KAIBatteryCell *cell = (KAIBatteryCell *)view;
  116. if(@available(iOS 12.0, *)) {
  117. if(self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
  118. [cell.label setTextColor:[UIColor whiteColor]];
  119. [cell.percentLabel setTextColor:[UIColor whiteColor]];
  120. } else if(self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) {
  121. [cell.label setTextColor:[UIColor blackColor]];
  122. [cell.percentLabel setTextColor:[UIColor blackColor]];
  123. }
  124. }
  125. }
  126. }
  127. -(void)removeArrangedSubview:(UIView *)view {
  128. [super removeArrangedSubview:view];
  129. self.number = [self.subviews count];
  130. if([self.superview.superview.superview respondsToSelector:@selector(fixComplicationsViewFrame)]) {
  131. [(NCNotificationListView *)(self.superview.superview.superview) fixComplicationsViewFrame];
  132. }
  133. }
  134. -(void)refreshForPrefs {
  135. for( UIView *view in self.subviews ) {
  136. @try {
  137. [view removeFromSuperview];
  138. } @catch (NSException *exception) {
  139. //Panik
  140. }
  141. }
  142. BCBatteryDeviceController *bcb = [BCBatteryDeviceController sharedInstance];
  143. NSArray *devices = MSHookIvar<NSArray *>(bcb, "_sortedDevices");
  144. for(BCBatteryDevice *device in devices) {
  145. [device resetKaiCellForNewPrefs];
  146. }
  147. //self.spacing = spacing;
  148. [self updateBattery];
  149. }
  150. -(void)dispatchQueue {
  151. self.isUpdating = NO;
  152. if(self.queued) {
  153. [self updateBattery];
  154. if([self.superview.superview.superview respondsToSelector:@selector(fixComplicationsViewFrame)]) {
  155. [(NCNotificationListView *)(self.superview.superview.superview) fixComplicationsViewFrame];
  156. }
  157. self.queued = NO;
  158. }
  159. [queueTimer invalidate];
  160. queueTimer = nil;
  161. }
  162. +(KAIBatteryStack *)sharedInstance {
  163. return instance;
  164. }
  165. @end