WFCFavoriteTableViewController.m 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. //
  2. // FavoriteTableViewController.m
  3. // WildFireChat
  4. //
  5. // Created by Tom Lee on 2020/11/1.
  6. // Copyright © 2020 WildFireChat. All rights reserved.
  7. //
  8. #import "WFCFavoriteTableViewController.h"
  9. #import <WFChatUIKit/WFChatUIKit.h>
  10. #import "AppService.h"
  11. #import "WFCFavoriteBaseCell.h"
  12. #import "WFCFavoriteTextCell.h"
  13. #import "WFCFavoriteUnknownCell.h"
  14. #import "WFCFavoriteImageCell.h"
  15. #import "WFCFavoriteFileCell.h"
  16. #import "WFCFavoriteLocationCell.h"
  17. #import "WFCFavoriteSoundCell.h"
  18. #import "WFCFavoriteVideoCell.h"
  19. #import "WFCFavoriteLinkCell.h"
  20. #import "WFCFavoriteCompositeCell.h"
  21. #import "AFNetworking.h"
  22. #import <AVFoundation/AVFoundation.h>
  23. @interface WFCFavoriteTableViewController () <UITableViewDataSource, UITableViewDelegate, MWPhotoBrowserDelegate, AVAudioPlayerDelegate>
  24. @property(nonatomic, strong)UITableView *tableView;
  25. @property(nonatomic, strong)NSMutableArray<WFCUFavoriteItem *> *items;
  26. @property(nonatomic, strong)NSMutableArray<WFCUFavoriteItem *> *imageVideoItems;
  27. @property(nonatomic, assign)BOOL hasMore;
  28. @property(nonatomic, assign)BOOL loading;
  29. @property(nonatomic, strong)WFCFavoriteBaseCell *selectedCell;
  30. @property(nonatomic, strong)VideoPlayerKit *videoPlayerViewController;
  31. @property(nonatomic, strong)AVAudioPlayer *player;
  32. @property(nonatomic, assign)BOOL isPlayingSound;
  33. @property(nonatomic, strong)WFCUFavoriteItem *playingSoundItem;
  34. @end
  35. @implementation WFCFavoriteTableViewController
  36. - (void)viewDidLoad {
  37. [super viewDidLoad];
  38. self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStyleGrouped];
  39. if (@available(iOS 15, *)) {
  40. self.tableView.sectionHeaderTopPadding = 0;
  41. }
  42. self.tableView.delegate = self;
  43. self.tableView.dataSource = self;
  44. self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
  45. [self.tableView reloadData];
  46. [self.view addSubview:self.tableView];
  47. self.items = [[NSMutableArray alloc] init];
  48. [self loadMoreData];
  49. [self.tableView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapCell:)]];
  50. [self.tableView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongTapCell:)]];
  51. self.view.backgroundColor = [WFCUConfigManager globalManager].backgroudColor;
  52. self.title = LocalizedString(@"MyFarovrites");
  53. }
  54. - (void)viewDidAppear:(BOOL)animated {
  55. [super viewDidAppear:animated];
  56. }
  57. - (void)playSound:(WFCUFavoriteItem *)item {
  58. __weak typeof(self)ws = self;
  59. NSString *downloadDir = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
  60. NSString *filePath;
  61. if ([item.url.pathExtension isEqual:@"mp3"]) {
  62. filePath = [downloadDir stringByAppendingPathComponent:[NSString stringWithFormat:@"fav_sound_%d.mp3", item.favId]];
  63. } else {
  64. filePath = [downloadDir stringByAppendingPathComponent:[NSString stringWithFormat:@"fav_sound_%d.amr", item.favId]];
  65. }
  66. self.isPlayingSound = YES;
  67. self.playingSoundItem = item;
  68. [self downloadFileWithURL:item.url savedPath:filePath downloadSuccess:^(NSURLResponse *response, NSURL *path) {
  69. NSLog(@"sound downloaded!");
  70. if (!self.isPlayingSound || self.playingSoundItem != item) {
  71. return;
  72. }
  73. if (ws.player) {
  74. [ws.player stop];
  75. }
  76. ws.player = [[AVAudioPlayer alloc] initWithData:[[WFCCIMService sharedWFCIMService] getWavData:filePath] error:nil];
  77. [ws.player prepareToPlay];
  78. ws.player.delegate = self;
  79. [ws.player play];
  80. } downloadFailure:^(NSError *error) {
  81. [ws.view makeToast:@"下载失败!" duration:1 position:CSToastPositionCenter];
  82. }];
  83. }
  84. - (void)stopPlaySound {
  85. self.isPlayingSound = NO;
  86. self.playingSoundItem = nil;
  87. [self.player stop];
  88. self.player = nil;
  89. }
  90. - (void)downloadFileWithURL:(NSString*)requestURLString
  91. savedPath:(NSString*)savedPath
  92. downloadSuccess:(void (^)(NSURLResponse *response, NSURL *filePath))success
  93. downloadFailure:(void (^)(NSError *error))failure {
  94. AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
  95. NSMutableURLRequest *request =[serializer requestWithMethod:@"GET" URLString:requestURLString parameters:nil error:nil];
  96. NSURLSessionDownloadTask *task = [[AFHTTPSessionManager manager] downloadTaskWithRequest:request progress:nil destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
  97. return [NSURL fileURLWithPath:[savedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
  98. } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
  99. dispatch_async(dispatch_get_main_queue(), ^{
  100. if(error){
  101. failure(error);
  102. }else{
  103. success(response,filePath);
  104. }
  105. });
  106. }];
  107. [task resume];
  108. }
  109. - (void)showItem:(WFCUFavoriteItem *)item {
  110. switch (item.favType) {
  111. case MESSAGE_CONTENT_TYPE_TEXT:
  112. {
  113. UIView *textContainer = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
  114. textContainer.backgroundColor = self.view.backgroundColor;
  115. UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0, [WFCUUtilities wf_navigationFullHeight], [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - [WFCUUtilities wf_navigationFullHeight] - [WFCUUtilities wf_safeDistanceBottom])];
  116. textView.text = self.selectedCell.favoriteItem.title;
  117. textView.textAlignment = NSTextAlignmentCenter;
  118. textView.font = [UIFont systemFontOfSize:28];
  119. textView.editable = NO;
  120. textView.backgroundColor = self.view.backgroundColor;
  121. [textContainer addSubview:textView];
  122. [textView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapTextMessageDetailView:)]];
  123. [[UIApplication sharedApplication].keyWindow addSubview:textContainer];
  124. }
  125. break;
  126. case MESSAGE_CONTENT_TYPE_SOUND: {
  127. if (self.isPlayingSound) {
  128. [self stopPlaySound];
  129. } else {
  130. [self playSound:item];
  131. }
  132. }
  133. break;
  134. case MESSAGE_CONTENT_TYPE_VIDEO:
  135. case MESSAGE_CONTENT_TYPE_IMAGE:
  136. {
  137. MWPhotoBrowser *browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
  138. browser.displayActionButton = YES;
  139. browser.displayNavArrows = NO;
  140. browser.displaySelectionButtons = NO;
  141. browser.alwaysShowControls = NO;
  142. browser.zoomPhotosToFill = YES;
  143. browser.enableGrid = YES;
  144. browser.startOnGrid = NO;
  145. browser.enableSwipeToDismiss = NO;
  146. browser.autoPlayOnAppear = NO;
  147. NSUInteger index = [self.imageVideoItems indexOfObject:item];
  148. if(index >= self.imageVideoItems.count) {
  149. index = 0;
  150. }
  151. [browser setCurrentPhotoIndex:index];
  152. [self.navigationController pushViewController:browser animated:YES];
  153. }
  154. break;
  155. case MESSAGE_CONTENT_TYPE_LOCATION:
  156. {
  157. WFCCLocationMessageContent *locContent = (WFCCLocationMessageContent *)[self.selectedCell.favoriteItem toMessage].content;
  158. WFCULocationViewController *vc = [[WFCULocationViewController alloc] initWithLocationPoint:[[WFCULocationPoint alloc] initWithCoordinate:locContent.coordinate andTitle:locContent.title]];
  159. [self.navigationController pushViewController:vc animated:YES];
  160. }
  161. break;
  162. case MESSAGE_CONTENT_TYPE_LINK:
  163. {
  164. WFCUBrowserViewController *bvc = [[WFCUBrowserViewController alloc] init];
  165. bvc.url = self.selectedCell.favoriteItem.url;
  166. [self.navigationController pushViewController:bvc animated:YES];
  167. }
  168. break;
  169. case MESSAGE_CONTENT_TYPE_COMPOSITE_MESSAGE:
  170. {
  171. WFCUCompositeMessageViewController *vc = [[WFCUCompositeMessageViewController alloc] init];
  172. vc.message = [self.selectedCell.favoriteItem toMessage];
  173. [self.navigationController pushViewController:vc animated:YES];
  174. }
  175. break;
  176. case MESSAGE_CONTENT_TYPE_FILE:
  177. {
  178. WFCUBrowserViewController *bvc = [[WFCUBrowserViewController alloc] init];
  179. bvc.url = self.selectedCell.favoriteItem.url;
  180. [self.navigationController pushViewController:bvc animated:YES];
  181. }
  182. break;
  183. default:
  184. break;
  185. }
  186. }
  187. - (void)setIsPlayingSound:(BOOL)isPlayingSound {
  188. _isPlayingSound = isPlayingSound;
  189. [self.tableView reloadData];
  190. }
  191. - (void)didTapTextMessageDetailView:(id)sender {
  192. if ([sender isKindOfClass:[UIGestureRecognizer class]]) {
  193. UIGestureRecognizer *gesture = (UIGestureRecognizer *)sender;
  194. [gesture.view.superview removeFromSuperview];
  195. }
  196. NSLog(@"close windows");
  197. }
  198. - (void)onTapCell:(UITapGestureRecognizer *)gestureRecognizer {
  199. if (gestureRecognizer.state == UIGestureRecognizerStateRecognized) {
  200. CGPoint point = [gestureRecognizer locationInView:self.tableView];
  201. NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
  202. if (indexPath) {
  203. self.selectedCell = [self.tableView cellForRowAtIndexPath:indexPath];
  204. WFCUFavoriteItem *item = self.selectedCell.favoriteItem;
  205. [self showItem:item];
  206. }
  207. }
  208. }
  209. - (void)onLongTapCell:(UILongPressGestureRecognizer *)gestureRecognizer {
  210. if (gestureRecognizer.state == UIGestureRecognizerStateRecognized) {
  211. CGPoint point = [gestureRecognizer locationInView:self.tableView];
  212. NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:point];
  213. if (indexPath) {
  214. UIMenuController *menu = [UIMenuController sharedMenuController];
  215. UIMenuItem *deleteItem = [[UIMenuItem alloc]initWithTitle:@"删除" action:@selector(performDelete:)];
  216. UIMenuItem *forwardItem = [[UIMenuItem alloc]initWithTitle:@"转发" action:@selector(performForward:)];
  217. UIMenuItem *copyItem = [[UIMenuItem alloc]initWithTitle:@"拷贝" action:@selector(performCopy:)];
  218. self.selectedCell = [self.tableView cellForRowAtIndexPath:indexPath];
  219. if (@available(iOS 13.0, *)) {
  220. [menu showMenuFromView:self.tableView rect:CGRectMake(point.x, point.y, 1, 1)];
  221. } else {
  222. [menu setTargetRect:CGRectMake(point.x, point.y, 1, 1) inView:self.tableView];
  223. }
  224. WFCUFavoriteItem *item = self.selectedCell.favoriteItem;
  225. NSMutableArray *items = [[NSMutableArray alloc] init];
  226. if (item.favType == MESSAGE_CONTENT_TYPE_TEXT) {
  227. [items addObject:copyItem];
  228. }
  229. [items addObject:deleteItem];
  230. [items addObject:forwardItem];
  231. [menu setMenuItems:items];
  232. [menu setMenuVisible:YES];
  233. }
  234. }
  235. }
  236. - (NSMutableArray<WFCUFavoriteItem *> *)imageVideoItems {
  237. NSMutableArray *is = [[NSMutableArray alloc] init];
  238. [self.items enumerateObjectsUsingBlock:^(WFCUFavoriteItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
  239. if(obj.favType == MESSAGE_CONTENT_TYPE_IMAGE || obj.favType == MESSAGE_CONTENT_TYPE_VIDEO) {
  240. [is addObject:obj];
  241. }
  242. }];
  243. return is;
  244. }
  245. -(BOOL)canBecomeFirstResponder {
  246. return YES;
  247. }
  248. -(BOOL)canPerformAction:(SEL)action withSender:(id)sender {
  249. if (action == @selector(performDelete:) || action == @selector(performForward:)) {
  250. return YES; //显示自定义的菜单项
  251. } else {
  252. if (action == @selector(performCopy:)) {
  253. if (self.selectedCell && self.selectedCell.favoriteItem.favType == MESSAGE_CONTENT_TYPE_TEXT) {
  254. return YES;
  255. }
  256. }
  257. return NO;
  258. }
  259. return NO;//[super canPerformAction:action withSender:sender];
  260. }
  261. -(void)performDelete:(UIMenuController *)sender {
  262. WFCUFavoriteItem *favItem = self.selectedCell.favoriteItem;
  263. [[AppService sharedAppService] removeFavoriteItem:favItem.favId success:^{
  264. } error:^(int error_code) {
  265. }];
  266. NSIndexPath *indexPath = [self.tableView indexPathForCell:self.selectedCell];
  267. [self.items removeObjectAtIndex:indexPath.section];
  268. NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:indexPath.section];
  269. [self.tableView deleteSections:indexSet withRowAnimation:UITableViewRowAnimationFade];
  270. }
  271. -(void)performForward:(UIMenuController *)sender {
  272. WFCCMessage *message = [[WFCCMessage alloc] init];
  273. WFCUFavoriteItem *item = self.selectedCell.favoriteItem;
  274. message.content = [item toMessage].content;
  275. if (!message.content) {
  276. return;
  277. }
  278. WFCUForwardViewController *controller = [[WFCUForwardViewController alloc] init];
  279. controller.message = message;
  280. UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:controller];
  281. [self.navigationController presentViewController:navi animated:YES completion:nil];
  282. }
  283. -(void)performCopy:(UIMenuController *)sender {
  284. if (self.selectedCell && self.selectedCell.favoriteItem.favType == MESSAGE_CONTENT_TYPE_TEXT) {
  285. UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
  286. pasteboard.string = self.selectedCell.favoriteItem.title;
  287. [self.view makeToast:@"已拷贝" duration:1 position:CSToastPositionCenter];
  288. }
  289. }
  290. - (void)loadMoreData {
  291. if (!self.loading) {
  292. self.loading = YES;
  293. } else {
  294. return;
  295. }
  296. __weak typeof(self)ws = self;
  297. UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 20)];
  298. UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] init];
  299. activityView.center = CGPointMake(self.view.bounds.size.width/2, 10);
  300. [activityView startAnimating];
  301. [footer addSubview:activityView];
  302. self.tableView.tableFooterView =footer;
  303. [[AppService sharedAppService] getFavoriteItems:self.items.count ? [self.items lastObject].favId:0 count:100 success:^(NSArray<WFCUFavoriteItem *> * _Nonnull items, BOOL hasMore) {
  304. [ws.items addObjectsFromArray:items];
  305. [ws.tableView reloadData];
  306. ws.hasMore = hasMore;
  307. ws.tableView.tableFooterView = nil;
  308. ws.loading = NO;
  309. } error:^(int error_code) {
  310. ws.tableView.tableFooterView = nil;
  311. ws.loading = NO;
  312. ws.hasMore = NO;
  313. }];
  314. }
  315. - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
  316. if (self.hasMore && ceil(targetContentOffset->y)+1 >= ceil(scrollView.contentSize.height - scrollView.bounds.size.height)) {
  317. [self loadMoreData];
  318. }
  319. }
  320. - (WFCFavoriteBaseCell *)cellOfFavType:(int)favType tableView:(UITableView *)tableView {
  321. WFCFavoriteBaseCell *cell = nil;
  322. if (favType == MESSAGE_CONTENT_TYPE_TEXT) {
  323. cell = [tableView dequeueReusableCellWithIdentifier:@"text"];
  324. if (!cell) {
  325. cell = [[WFCFavoriteTextCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"text"];
  326. }
  327. } else if(favType == MESSAGE_CONTENT_TYPE_IMAGE) {
  328. cell = [tableView dequeueReusableCellWithIdentifier:@"image"];
  329. if (!cell) {
  330. cell = [[WFCFavoriteImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"image"];
  331. }
  332. } else if(favType == MESSAGE_CONTENT_TYPE_FILE) {
  333. cell = [tableView dequeueReusableCellWithIdentifier:@"file"];
  334. if (!cell) {
  335. cell = [[WFCFavoriteFileCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"file"];
  336. }
  337. } else if(favType == MESSAGE_CONTENT_TYPE_LOCATION) {
  338. cell = [tableView dequeueReusableCellWithIdentifier:@"location"];
  339. if (!cell) {
  340. cell = [[WFCFavoriteLocationCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"location"];
  341. }
  342. } else if(favType == MESSAGE_CONTENT_TYPE_SOUND) {
  343. cell = [tableView dequeueReusableCellWithIdentifier:@"sound"];
  344. if (!cell) {
  345. cell = [[WFCFavoriteSoundCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"sound"];
  346. }
  347. } else if(favType == MESSAGE_CONTENT_TYPE_VIDEO) {
  348. cell = [tableView dequeueReusableCellWithIdentifier:@"video"];
  349. if (!cell) {
  350. cell = [[WFCFavoriteVideoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"video"];
  351. }
  352. } else if(favType == MESSAGE_CONTENT_TYPE_LINK) {
  353. cell = [tableView dequeueReusableCellWithIdentifier:@"link"];
  354. if (!cell) {
  355. cell = [[WFCFavoriteLinkCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"link"];
  356. }
  357. } else if(favType == MESSAGE_CONTENT_TYPE_COMPOSITE_MESSAGE) {
  358. cell = [tableView dequeueReusableCellWithIdentifier:@"composite"];
  359. if (!cell) {
  360. cell = [[WFCFavoriteCompositeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"composite"];
  361. }
  362. } else {
  363. cell = [tableView dequeueReusableCellWithIdentifier:@"unknown"];
  364. if (!cell) {
  365. cell = [[WFCFavoriteUnknownCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"unknown"];
  366. }
  367. }
  368. return cell;
  369. }
  370. #pragma mark - UITableViewDataSource
  371. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  372. return self.items.count;
  373. }
  374. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  375. return 1;
  376. }
  377. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  378. WFCUFavoriteItem *favItem = self.items[indexPath.section];
  379. WFCFavoriteBaseCell *cell = [self cellOfFavType:favItem.favType tableView:tableView];
  380. cell.favoriteItem = favItem;
  381. if (favItem.favType == MESSAGE_CONTENT_TYPE_SOUND) {
  382. WFCFavoriteSoundCell *soundCell = (WFCFavoriteSoundCell *)cell;
  383. if (self.isPlayingSound && self.playingSoundItem == favItem) {
  384. soundCell.isPlaying = YES;
  385. } else {
  386. soundCell.isPlaying = NO;
  387. }
  388. }
  389. return cell;
  390. }
  391. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  392. return 0;
  393. }
  394. -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  395. return 10;
  396. }
  397. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  398. return [[UIView alloc] init];
  399. }
  400. -(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
  401. return [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 10)];
  402. }
  403. #pragma mark - UITableViewDelegate
  404. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  405. }
  406. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  407. WFCUFavoriteItem *favItem = self.items[indexPath.section];
  408. return [[[self cellOfFavType:favItem.favType tableView:tableView] class] heightOf:favItem];
  409. }
  410. - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
  411. if (editingStyle == UITableViewCellEditingStyleDelete) {
  412. WFCUFavoriteItem *favItem = self.items[indexPath.section];
  413. [[AppService sharedAppService] removeFavoriteItem:favItem.favId success:^{
  414. } error:^(int error_code) {
  415. }];
  416. [self.items removeObjectAtIndex:indexPath.section];
  417. NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:indexPath.section];
  418. [self.tableView deleteSections:indexSet withRowAnimation:UITableViewRowAnimationFade];
  419. }
  420. }
  421. #pragma mark - MWPhotoBrowser
  422. - (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
  423. return self.imageVideoItems.count;
  424. }
  425. - (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
  426. WFCUFavoriteItem *item = self.imageVideoItems[index];
  427. if(item.favType == MESSAGE_CONTENT_TYPE_IMAGE) {
  428. MWPhoto *photo = [MWPhoto photoWithURL:[NSURL URLWithString:item.url]];
  429. return photo;
  430. } else if(item.favType == MESSAGE_CONTENT_TYPE_VIDEO) {
  431. MWPhoto *photo = [MWPhoto videoWithURL:[NSURL URLWithString:item.url]];
  432. return photo;
  433. }
  434. return nil;
  435. }
  436. - (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index {
  437. WFCUFavoriteItem *item = self.imageVideoItems[index];
  438. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[item.data dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
  439. NSString *thumbStr = dict[@"thumb"];
  440. NSData *thumbData = [[NSData alloc] initWithBase64EncodedString:thumbStr options:NSDataBase64DecodingIgnoreUnknownCharacters];
  441. UIImage *image = [UIImage imageWithData:thumbData];
  442. BOOL video = NO;
  443. if(item.favType == MESSAGE_CONTENT_TYPE_VIDEO) {
  444. video = YES;
  445. }
  446. MWPhoto *photo = [MWPhoto photoWithImage:image];
  447. photo.isVideo = video;
  448. return photo;
  449. }
  450. - (void)photoBrowser:(MWPhotoBrowser *)photoBrowser didDisplayPhotoAtIndex:(NSUInteger)index {
  451. NSLog(@"Did start viewing photo at index %lu", (unsigned long)index);
  452. }
  453. - (BOOL)photoBrowser:(MWPhotoBrowser *)photoBrowser isPhotoSelectedAtIndex:(NSUInteger)index {
  454. return NO;
  455. }
  456. - (void)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index selectedChanged:(BOOL)selected {
  457. NSLog(@"Photo at index %lu selected %@", (unsigned long)index, selected ? @"YES" : @"NO");
  458. }
  459. - (void)photoBrowserDidFinishModalPresentation:(MWPhotoBrowser *)photoBrowser {
  460. // If we subscribe to this method we must dismiss the view controller ourselves
  461. NSLog(@"Did finish modal presentation");
  462. [self dismissViewControllerAnimated:YES completion:nil];
  463. }
  464. #pragma mark - AVAudioPlayerDelegate
  465. - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
  466. [self stopPlaySound];
  467. }
  468. - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error {
  469. [self stopPlaySound];
  470. }
  471. @end