您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

193 行
7.1KB

  1. #include "TFDTSRootListController.h"
  2. @implementation TFDTSRootListController
  3. - (instancetype)init {
  4. self = [super init];
  5. if (self) {
  6. }
  7. return self;
  8. }
  9. - (NSArray *)specifiers {
  10. if (!_specifiers) {
  11. _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self];
  12. }
  13. return _specifiers;
  14. }
  15. - (id)readPreferenceValue:(PSSpecifier*)specifier {
  16. NSString *path = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", specifier.properties[@"defaults"]];
  17. NSMutableDictionary *settings = [NSMutableDictionary dictionary];
  18. [settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]];
  19. return (settings[specifier.properties[@"key"]]) ?: specifier.properties[@"default"];
  20. }
  21. - (void)setPreferenceValue:(id)value specifier:(PSSpecifier*)specifier {
  22. NSString *path = [NSString stringWithFormat:@"/User/Library/Preferences/%@.plist", specifier.properties[@"defaults"]];
  23. NSMutableDictionary *settings = [NSMutableDictionary dictionary];
  24. [settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]];
  25. [settings setObject:value forKey:specifier.properties[@"key"]];
  26. [settings writeToFile:path atomically:YES];
  27. CFStringRef notificationName = (__bridge CFStringRef)specifier.properties[@"PostNotification"];
  28. if (notificationName) {
  29. CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), notificationName, NULL, NULL, YES);
  30. }
  31. }
  32. - (void)checkLatest:(PSSpecifier *)arg1 {
  33. NSIndexPath *indexPath = [self indexPathForSpecifier:arg1];
  34. UITableViewCell *cell = [self.table cellForRowAtIndexPath:indexPath];
  35. cell.userInteractionEnabled = NO;
  36. UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
  37. if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"13.0")) {
  38. activityView.activityIndicatorViewStyle = UIScreen.mainScreen.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ? UIActivityIndicatorViewStyleWhite : UIActivityIndicatorViewStyleGray;
  39. }
  40. [cell setAccessoryView:activityView];
  41. [activityView startAnimating];
  42. // removes latest time rows if they already exist
  43. if (_latestPostSpecifier) {
  44. [self removeSpecifier:_latestPostSpecifier animated:YES];
  45. _latestPostSpecifier = nil;
  46. }
  47. if (_latestCommentSpecifier) {
  48. [self removeSpecifier:_latestCommentSpecifier animated:YES];
  49. _latestCommentSpecifier = nil;
  50. }
  51. // performs the requests for the most recent comment and post
  52. [self performPushshiftRequest:YES insertAfterSpecifier:arg1];
  53. [self performPushshiftRequest:NO insertAfterSpecifier:arg1];
  54. }
  55. - (void)performPushshiftRequest:(BOOL)isComment insertAfterSpecifier:(PSSpecifier *)arg2 {
  56. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  57. //NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  58. if (isComment){
  59. [request setURL:[NSURL URLWithString:@"https://api.pushshift.io/reddit/search/comment/?fields=created_utc&size=1"]];
  60. } else {
  61. [request setURL:[NSURL URLWithString:@"https://api.pushshift.io/reddit/search/submission/?fields=created_utc&size=1"]];
  62. }
  63. NSMutableDictionary *prefs = [NSMutableDictionary dictionary];
  64. [prefs addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:@"/User/Library/Preferences/com.lint.undelete.prefs.plist"]];
  65. NSInteger timeout = [prefs objectForKey:@"requestTimeoutValue"] ? [[prefs objectForKey:@"requestTimeoutValue"] doubleValue] : 10;
  66. [request setHTTPMethod:@"GET"];
  67. [request setTimeoutInterval:timeout];
  68. NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  69. //[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  70. NSString *resultText;
  71. if (data) {
  72. id jsonData = [[NSJSONSerialization JSONObjectWithData:data options:0 error:&error] objectForKey:@"data"];
  73. if (jsonData && [jsonData count] != 0) {
  74. NSString *epochStr = jsonData[0][@"created_utc"];
  75. NSDate *creationDate = [NSDate dateWithTimeIntervalSince1970:[epochStr intValue]];
  76. // months and years? not really needed
  77. unsigned int unitFlags = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  78. NSDateComponents *components = [[NSCalendar currentCalendar] components:unitFlags fromDate:creationDate toDate:[NSDate date] options:0];
  79. NSInteger days = [components day];
  80. NSInteger hours = [components hour];
  81. NSInteger minutes = [components minute];
  82. NSInteger seconds = [components second];
  83. NSMutableString *timeSinceString = [NSMutableString string];
  84. BOOL prevComponentUsed = NO;
  85. if (days > 0) {
  86. [timeSinceString appendFormat:@"%lid, ", (long)days];
  87. prevComponentUsed = YES;
  88. }
  89. if (hours > 0 || prevComponentUsed) {
  90. [timeSinceString appendFormat:@"%lih, ", (long)hours];
  91. prevComponentUsed = YES;
  92. }
  93. if (minutes > 0 || prevComponentUsed) {
  94. [timeSinceString appendFormat:@"%lim, ", (long)minutes];
  95. prevComponentUsed = YES;
  96. }
  97. if (seconds > 0 || prevComponentUsed) {
  98. [timeSinceString appendFormat:@"%lis ", (long)seconds];
  99. }
  100. [timeSinceString appendString:@"ago"];
  101. resultText = timeSinceString;
  102. } else {
  103. resultText = @"no data returned";
  104. }
  105. }
  106. if (error) {
  107. resultText = [NSString stringWithFormat:@"HTTP Status: %li, Error: %@",
  108. (long)((NSHTTPURLResponse *)response).statusCode, [error localizedDescription]];
  109. }
  110. NSString *labelText = [NSString stringWithFormat:@"Last %@: %@", isComment ? @"Comment" : @"Post", resultText];
  111. // specifier to create new table row
  112. PSSpecifier *customSpecifier = [PSSpecifier preferenceSpecifierNamed:labelText target:self set:NULL get:NULL detail:Nil cell:PSStaticTextCell edit:Nil];
  113. [customSpecifier setProperty:labelText forKey:@"label"];
  114. [customSpecifier setProperty: @"PSStaticTextCell" forKey:@"cell"];
  115. if (isComment) {
  116. _latestCommentSpecifier = customSpecifier;
  117. } else {
  118. _latestPostSpecifier = customSpecifier;
  119. }
  120. NSDictionary *dataDict = @{@"custom_specifier" : customSpecifier, @"after_specifier" : arg2};
  121. [self performSelectorOnMainThread:@selector(insertLatestTimeCell:) withObject:dataDict waitUntilDone:NO];
  122. [self performSelectorOnMainThread:@selector(possiblyBothChecksComplete:) withObject:arg2 waitUntilDone:NO];
  123. }];
  124. [dataTask resume];
  125. }
  126. - (void)insertLatestTimeCell:(NSDictionary *)data {
  127. if (data[@"custom_specifier"] && data[@"after_specifier"]) {
  128. [self insertSpecifier:data[@"custom_specifier"] afterSpecifier:data[@"after_specifier"] animated:YES];
  129. }
  130. }
  131. - (void)possiblyBothChecksComplete:(PSSpecifier *)arg1 {
  132. // only when both the comment and the post request have finished
  133. if (_latestPostSpecifier && _latestCommentSpecifier) {
  134. NSIndexPath *indexPath = [self indexPathForSpecifier:arg1];
  135. UITableViewCell *cell = [self.table cellForRowAtIndexPath:indexPath];
  136. if (cell) {
  137. UIActivityIndicatorView *activityView = (UIActivityIndicatorView *)[cell accessoryView];
  138. [activityView stopAnimating];
  139. [cell setAccessoryView:nil];
  140. cell.userInteractionEnabled = YES;
  141. }
  142. }
  143. }
  144. @end