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.

TFDTSRootListController.m 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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. [request setHTTPMethod:@"GET"];
  64. [request setTimeoutInterval:10];
  65. NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  66. //[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
  67. NSString *resultText;
  68. if (data) {
  69. id jsonData = [[NSJSONSerialization JSONObjectWithData:data options:0 error:&error] objectForKey:@"data"];
  70. if (jsonData && [jsonData count] != 0) {
  71. NSString *epochStr = jsonData[0][@"created_utc"];
  72. NSDate *creationDate = [NSDate dateWithTimeIntervalSince1970:[epochStr intValue]];
  73. // months and years? not really needed
  74. unsigned int unitFlags = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
  75. NSDateComponents *components = [[NSCalendar currentCalendar] components:unitFlags fromDate:creationDate toDate:[NSDate date] options:0];
  76. NSInteger days = [components day];
  77. NSInteger hours = [components hour];
  78. NSInteger minutes = [components minute];
  79. NSInteger seconds = [components second];
  80. NSMutableString *timeSinceString = [NSMutableString string];
  81. BOOL prevComponentUsed = NO;
  82. if (days > 0) {
  83. [timeSinceString appendFormat:@"%lid, ", (long)days];
  84. prevComponentUsed = YES;
  85. }
  86. if (hours > 0 || prevComponentUsed) {
  87. [timeSinceString appendFormat:@"%lih, ", (long)hours];
  88. prevComponentUsed = YES;
  89. }
  90. if (minutes > 0 || prevComponentUsed) {
  91. [timeSinceString appendFormat:@"%lim, ", (long)minutes];
  92. prevComponentUsed = YES;
  93. }
  94. if (seconds > 0 || prevComponentUsed) {
  95. [timeSinceString appendFormat:@"%lis ", (long)seconds];
  96. }
  97. [timeSinceString appendString:@"ago"];
  98. resultText = timeSinceString;
  99. } else {
  100. resultText = @"no data returned";
  101. }
  102. }
  103. if (error) {
  104. resultText = [NSString stringWithFormat:@"an error occurred. HTTP Status Code: %li, Error Description: %@",
  105. (long)((NSHTTPURLResponse *)response).statusCode, [error localizedDescription]];
  106. }
  107. NSString *labelText = [NSString stringWithFormat:@"Last %@: %@", isComment ? @"Comment" : @"Post", resultText];
  108. // specifier to create new table row
  109. PSSpecifier *customSpecifier = [PSSpecifier preferenceSpecifierNamed:labelText target:self set:NULL get:NULL detail:Nil cell:PSStaticTextCell edit:Nil];
  110. [customSpecifier setProperty:labelText forKey:@"label"];
  111. [customSpecifier setProperty: @"PSStaticTextCell" forKey:@"cell"];
  112. if (isComment) {
  113. _latestCommentSpecifier = customSpecifier;
  114. } else {
  115. _latestPostSpecifier = customSpecifier;
  116. }
  117. NSDictionary *dataDict = @{@"custom_specifier" : customSpecifier, @"after_specifier" : arg2};
  118. [self performSelectorOnMainThread:@selector(insertLatestTimeCell:) withObject:dataDict waitUntilDone:NO];
  119. [self performSelectorOnMainThread:@selector(possiblyBothChecksComplete:) withObject:arg2 waitUntilDone:NO];
  120. }];
  121. [dataTask resume];
  122. }
  123. - (void)insertLatestTimeCell:(NSDictionary *)data {
  124. if (data[@"custom_specifier"] && data[@"after_specifier"]) {
  125. [self insertSpecifier:data[@"custom_specifier"] afterSpecifier:data[@"after_specifier"] animated:YES];
  126. }
  127. }
  128. - (void)possiblyBothChecksComplete:(PSSpecifier *)arg1 {
  129. // only when both the comment and the post request have finished
  130. if (_latestPostSpecifier && _latestCommentSpecifier) {
  131. NSIndexPath *indexPath = [self indexPathForSpecifier:arg1];
  132. UITableViewCell *cell = [self.table cellForRowAtIndexPath:indexPath];
  133. if (cell) {
  134. UIActivityIndicatorView *activityView = (UIActivityIndicatorView *)[cell accessoryView];
  135. [activityView stopAnimating];
  136. [cell setAccessoryView:nil];
  137. cell.userInteractionEnabled = YES;
  138. }
  139. }
  140. }
  141. @end