PageRenderTime 84ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/WHAMBUSH/wbSingleMissionView.m

https://gitlab.com/urbanjunglestudio/whambush-ios
Objective C | 802 lines | 664 code | 72 blank | 66 comment | 167 complexity | 09205adea12250849c0799f19e9dd131 MD5 | raw file
  1. //
  2. // wbSingleMissionView.m
  3. // WHAMBUSH
  4. //
  5. // Created by Jari Kalinainen on 26/10/15.
  6. // Copyright © 2015 Jari Kalinainen. All rights reserved.
  7. //
  8. #import "wbSingleMissionView.h"
  9. @implementation wbSingleMissionView
  10. @synthesize controller;
  11. @synthesize mission;
  12. @synthesize missionTimer;
  13. @synthesize hideByShare;
  14. @synthesize videoPlayerController;
  15. #define kTimerRowHeight 35
  16. #define kVideoRowHeight (self.frame.size.width/16)*9
  17. #define kActionRowHeight 40
  18. #define kEnterRowHeight 35
  19. #define kWhoRowHeight 50
  20. #define kDescRowHeight [self descriptionRow].frame.size.height
  21. #define kInfoRowHeight 40
  22. #define kMissionVideoRowHeight 96
  23. #define kFirstVideoRow 7
  24. -(id)initWithFrame:(CGRect)frame
  25. {
  26. self = [super initWithFrame:frame];
  27. if (self) {
  28. [self setDelegate:self];
  29. [self setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
  30. [self setSeparatorColor:kSEPRATORUICOLOR];
  31. [self setSeparatorInset:UIEdgeInsetsZero];
  32. [self setBackgroundColor:kBKGUICOLOR];
  33. [self setClipsToBounds:YES];
  34. [self setHidden:NO];
  35. [self setCanCancelContentTouches:YES];
  36. refreshing = NO;
  37. number_of_videos = 0;
  38. togleEndTime = NO;
  39. hideByShare = NO;
  40. missionVideoCells = [NSMutableDictionary new];
  41. missionVideos = [NSMutableArray new];
  42. allowLoad = YES;
  43. }
  44. return self;
  45. }
  46. - (UIEdgeInsets)layoutMargins
  47. {
  48. return UIEdgeInsetsZero;
  49. }
  50. -(void)setGAIViewName
  51. {
  52. [[wbAPI sharedAPI] registerGoogleAnalytics:[NSString stringWithFormat:@"Mission:id=%@",[mission mission_id]]];
  53. }
  54. -(void)scrollTableTop
  55. {
  56. [self setContentOffset:CGPointZero animated:YES];
  57. }
  58. -(void)setMission:(wbMission *)_mission
  59. {
  60. mission = _mission;
  61. [mission setDelegate:self];
  62. [self waitForMissionReady];
  63. }
  64. -(void)waitForMissionReady
  65. {
  66. if ([mission ready]) {
  67. [self setGAIViewName];
  68. [self setDataSource:self];
  69. number_of_videos = [[mission number_of_submissions] integerValue];
  70. if (number_of_videos > 0) {
  71. kSHOWWAIT;
  72. videoUrl = [[wbAPI sharedAPI] urlWithEndpoint:[NSString stringWithFormat:kMISSIONVIDEOSAPI,[mission mission_id]]];
  73. [self getMissionVideosWithURL:videoUrl];
  74. }
  75. [self reloadData];
  76. } else {
  77. double delayInSeconds = 0.2;
  78. dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
  79. dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
  80. //code to be executed on the main queue after delay
  81. [self waitForMissionReady];
  82. });
  83. }
  84. }
  85. // Only override drawRect: if you perform custom drawing.
  86. // An empty implementation adversely affects performance during animation.
  87. - (void)drawRect:(CGRect)rect {
  88. // Drawing code
  89. if (refreshController == nil) {
  90. refreshController = [[UIRefreshControl alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
  91. [refreshController addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
  92. UIImageView *rBkg = [[UIImageView alloc] init];
  93. [refreshController setBackgroundColor:[UIColor colorWithPatternImage:[UIImage ch_imageNamed:@"refresh_bg_image"]]];
  94. NSURL *refreshPicURL = [mission mission_image_2_url];
  95. [rBkg setImageWithURLRequest:[NSMutableURLRequest requestWithURL:refreshPicURL] placeholderImage:[UIImage ch_imageNamed:@"refresh_bg_image"] success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
  96. if (image != nil) {
  97. refreshBkgImage = image;
  98. [refreshController setBackgroundColor:[UIColor colorWithPatternImage:[self scaleImage:image withScale:1]]];
  99. }
  100. } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
  101. }];
  102. /*[rBkg setImageWithURL:refreshPicURL placeholderImage:[UIImage ch_imageNamed:@"refresh_bg_image"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
  103. if (image != nil) {
  104. refreshBkgImage = image;
  105. [refreshController setBackgroundColor:[UIColor colorWithPatternImage:[self scaleImage:image withScale:1]]];
  106. }
  107. }];*/
  108. [self addSubview:refreshController];
  109. }
  110. }
  111. -(UIImage*)scaleImage:(UIImage*)image withScale:(CGFloat)scale
  112. {
  113. CGFloat widht = self.frame.size.width*scale;
  114. CGSize scaleSize = CGSizeMake(widht, widht*(image.size.height/image.size.width));
  115. UIGraphicsBeginImageContextWithOptions(scaleSize, YES, 0.0);
  116. [image drawInRect:CGRectMake((self.frame.size.width-scaleSize.width)/2, 0, scaleSize.width, scaleSize.height) blendMode:kCGBlendModeNormal alpha:0.3];
  117. UIImage * resizedImage = UIGraphicsGetImageFromCurrentImageContext();
  118. UIGraphicsEndImageContext();
  119. return resizedImage;
  120. }
  121. -(void)scrollViewDidScroll:(UIScrollView *)scrollView
  122. {
  123. if (refreshBkgImage != nil && !refreshing) {
  124. float offset = self.contentOffset.y;
  125. if (offset < 0) {
  126. CGFloat scale = 1+fabs(offset)/190;
  127. //NSLog(@"%f",scale);
  128. [refreshController setBackgroundColor:[UIColor colorWithPatternImage:[self scaleImage:refreshBkgImage withScale:scale]]];
  129. }
  130. }
  131. }
  132. -(void)refresh:(UIRefreshControl *)refreshControl
  133. {
  134. refreshing = YES;
  135. [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
  136. [self setScrollEnabled:NO];
  137. if (videoUrl != nil) {
  138. NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^(void){
  139. [[wbWaitView sharedWait] performSelectorOnMainThread:@selector(show) withObject:NULL waitUntilDone:YES];
  140. }];
  141. [op setCompletionBlock:^(void){
  142. [self performSelectorOnMainThread:@selector(doRefresh:) withObject:refreshController waitUntilDone:NO];
  143. }];
  144. [op start];
  145. } else {
  146. refreshing = NO;
  147. [[UIApplication sharedApplication] endIgnoringInteractionEvents];
  148. [self setScrollEnabled:YES];
  149. [self setContentOffset:CGPointMake(0, 0) animated:YES];
  150. }
  151. }
  152. -(void)doRefresh:(UIRefreshControl*)refreshControl
  153. {
  154. [refreshControl beginRefreshing];
  155. [self beginUpdates];
  156. for (NSInteger i = kFirstVideoRow; i < [missionVideos count]+kFirstVideoRow; i++) {
  157. [self deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
  158. }
  159. [missionVideos removeAllObjects];
  160. [self endUpdates];
  161. [self getMissionVideosWithURL:videoUrl];
  162. [refreshControl endRefreshing];
  163. }
  164. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
  165. {
  166. if ([indexPath row] == 0) {
  167. return kTimerRowHeight;
  168. } else if ([indexPath row] == 1) {
  169. return kVideoRowHeight;
  170. } else if ([indexPath row] == 2) {
  171. return kActionRowHeight;
  172. } else if ([indexPath row] == 3) {
  173. if ([mission isActive] && ![[wbAPI sharedAPI] uploading]) {
  174. return kEnterRowHeight;
  175. } else {
  176. return 0;
  177. }
  178. } else if ([indexPath row] == 4) {
  179. return kWhoRowHeight;
  180. } else if ([indexPath row] == 5) {
  181. return kDescRowHeight;
  182. } else if ([indexPath row] == 6) {
  183. return kInfoRowHeight;
  184. } else { // submission videos
  185. return kMissionVideoRowHeight;
  186. }
  187. }
  188. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  189. {
  190. return kFirstVideoRow+[missionVideos count];
  191. }
  192. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  193. {
  194. if (![mission ready]) {
  195. return nil;
  196. }
  197. NSString *identifier = [NSString stringWithFormat:@"mission_%@_%ld_%ld",[mission mission_id],(long)[indexPath row],(long)[indexPath section]];
  198. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
  199. if ([indexPath row] == 1) {
  200. cell = nil;
  201. }
  202. if (cell == nil){
  203. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
  204. [cell setFrame:CGRectMake(0, 0, self.frame.size.width, [self tableView:self heightForRowAtIndexPath:indexPath])];
  205. [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
  206. [cell setClipsToBounds:YES];
  207. if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
  208. [cell setSeparatorInset:UIEdgeInsetsZero];
  209. }
  210. if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
  211. [cell setPreservesSuperviewLayoutMargins:NO];
  212. }
  213. if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
  214. [cell setLayoutMargins:UIEdgeInsetsZero];
  215. }
  216. [cell setBackgroundColor:kTRANSPARENTUICOLOR];
  217. [cell setClipsToBounds:YES];
  218. }
  219. if ([indexPath row] == 0) {
  220. [cell addSubview:[self timerRow]];
  221. } else if ([indexPath row] == 1) {
  222. [cell addSubview:[self videoRow]];
  223. } else if ([indexPath row] == 2) {
  224. [cell addSubview:[self actionRow]];
  225. } else if ([indexPath row] == 3) {
  226. [cell addSubview:[self enterRow]];
  227. } else if ([indexPath row] == 4) {
  228. [cell addSubview:[self whoRow]];
  229. } else if ([indexPath row] == 5) {
  230. [cell addSubview:[self descriptionRow]];
  231. } else if ([indexPath row] == 6) {
  232. [cell addSubview:[self infoRow]];
  233. } else if ([indexPath row] > kFirstVideoRow-1 ) { // submission videos
  234. [cell addSubview:[self missionVideoRowWithId:[NSNumber numberWithInteger:[indexPath row]-kFirstVideoRow]]];
  235. }
  236. return cell;
  237. }
  238. ///////////////////
  239. -(UIView*)timerRow
  240. {
  241. if (timerLabel == nil) {
  242. timerLabel = [[wbLabel alloc] init];
  243. [timerLabel setUserInteractionEnabled:YES];
  244. }
  245. [self updateTime];
  246. if (endTime == nil) {
  247. endTime = [wbButton buttonWithType:UIButtonTypeSystem];
  248. [endTime setFrame:CGRectMake(0, 0, timerLabel.frame.size.width, timerLabel.frame.size.height)];
  249. [endTime setBackgroundColor:kTRANSPARENTUICOLOR];
  250. [endTime setShowsTouchWhenHighlighted:YES];
  251. [endTime addTarget:self action:@selector(toggleEndTime) forControlEvents:UIControlEventTouchUpInside];
  252. }
  253. if ([mission isActive]) {
  254. missionTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];
  255. [endTime setUserInteractionEnabled:YES];
  256. } else {
  257. [endTime setUserInteractionEnabled:NO];
  258. }
  259. [timerLabel addSubview:endTime];
  260. return timerLabel;
  261. }
  262. -(void)updateTime
  263. {
  264. if (togleEndTime) {
  265. [timerLabel setAttributedText:[mission endTimeAString]];
  266. } else {
  267. [timerLabel setAttributedText:[mission getMissionEndString]];
  268. }
  269. [timerLabel sizeToFit];
  270. [timerLabel setCenter:CGPointMake(self.frame.size.width/2, kTimerRowHeight/2)];
  271. }
  272. -(void)toggleEndTime
  273. {
  274. togleEndTime = !togleEndTime;
  275. [self updateTime];
  276. [endTime setFrame:CGRectMake(0, 0, timerLabel.frame.size.width, timerLabel.frame.size.height)];
  277. }
  278. ///////////////////
  279. -(UIView*)videoRow
  280. {
  281. if (videoRowView == nil) {
  282. videoRowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, kVideoRowHeight)];
  283. }
  284. if ([mission linked_video_id] != nil) {
  285. if (videoPlayerController == nil) {
  286. videoPlayerController = [[wbVideoPlayerViewController alloc] init];
  287. }
  288. [videoPlayerController setVideoURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://view.vzaar.com/%@/video",[[mission linked_video_dictionary] valueForKey:@"external_id"]]]];
  289. if ([[[mission mission_image_1_url] absoluteString] isEqualToString:@""]) {
  290. [videoPlayerController setVideoThumbURL:[NSURL URLWithString:[[mission linked_video_dictionary] valueForKey:@"thumbnail_url"]]];
  291. } else {
  292. [videoPlayerController setVideoThumbURL:[mission mission_image_1_url]];
  293. }
  294. [videoPlayerController.view setHidden:NO];
  295. [(wbVideoPlayerView*)videoPlayerController.view setShowShare:NO];
  296. [videoPlayerController setDelegate:nil];
  297. [videoRowView addSubview:videoPlayerController.view];
  298. } else {
  299. if (noVideoImageView == nil) {
  300. noVideoImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, kVideoRowHeight)];
  301. }
  302. UIImage *placeHolder;
  303. if ([[[mission created_by] userId] integerValue] == 1 ) {
  304. placeHolder = [UIImage imageNamed:@"default1.jpg"];
  305. } else {
  306. placeHolder = [UIImage imageNamed:@"default3.jpg"];
  307. }
  308. [noVideoImageView setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.width*(placeHolder.size.height/placeHolder.size.width))];
  309. __weak typeof(self) weakSelf = self;
  310. [noVideoImageView setImageWithURLRequest:[NSMutableURLRequest requestWithURL:[mission mission_image_1_url]] placeholderImage:placeHolder success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
  311. __strong typeof(self) strongSelf = weakSelf;
  312. if (image != nil) {
  313. [strongSelf->noVideoImageView setFrame:CGRectMake(0, 0, strongSelf.frame.size.width, strongSelf.frame.size.width*(image.size.height/image.size.width))];
  314. [strongSelf->noVideoImageView setImage:image];
  315. }
  316. } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
  317. }];
  318. /*[noVideoImageView setImageWithURL:[mission mission_image_1_url] placeholderImage:placeHolder completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){
  319. if (image != nil) {
  320. [noVideoImageView setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.width*(image.size.height/image.size.width))];
  321. }
  322. }];*/
  323. [videoRowView addSubview:noVideoImageView];
  324. }
  325. return videoRowView;
  326. }
  327. ///////////////////
  328. -(UIView*)actionRow
  329. {
  330. if (actionRowView == nil) {
  331. actionRowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, kActionRowHeight)];
  332. }
  333. if (shareBtn == nil) {
  334. shareBtn = [wbButton buttonWithType:UIButtonTypeSystem];
  335. [shareBtn setFrame:CGRectMake(self.frame.size.width-self.frame.size.width/5, 0, self.frame.size.width/5 ,kActionRowHeight)];//(0, 0, self.frame.size.width/5 ,kActionRowHeight)];
  336. [shareBtn setShowsTouchWhenHighlighted:YES];
  337. //[shareBtn setImageScale:1.2];
  338. [shareBtn setButtonImage:[UIImage imageNamed:@"share_grey"]];
  339. [shareBtn addTarget:self action:@selector(showShareSelect) forControlEvents:UIControlEventTouchUpInside];
  340. [actionRowView addSubview:shareBtn];
  341. }
  342. /*if (cameraBtn == nil) {
  343. cameraBtn = [wbButton buttonWithType:UIButtonTypeSystem];
  344. [cameraBtn setFrame:CGRectMake(self.frame.size.width-self.frame.size.width/5, 0, self.frame.size.width/5 ,kActionRowHeight)];
  345. [cameraBtn setShowsTouchWhenHighlighted:YES];
  346. [cameraBtn setImageScale:1.4];
  347. [cameraBtn addTarget:self action:@selector(startCamera) forControlEvents:UIControlEventTouchUpInside];
  348. [actionRowView addSubview:cameraBtn];
  349. }
  350. if ([mission isActive]) {
  351. [cameraBtn setButtonImage:[UIImage imageNamed:@"camera_grey"]];
  352. [cameraBtn setEnabled:YES];
  353. } else {
  354. [cameraBtn setButtonImage:[UIImage imageNamed:@"camera_grey_no"]];
  355. [cameraBtn setEnabled:NO];
  356. }*/
  357. if (likeBtn == nil) {
  358. likeBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  359. [likeBtn setTintColor:kTRANSPARENTUICOLOR];
  360. [actionRowView addSubview:likeBtn];
  361. }
  362. [likeBtn setBackgroundImage:[UIImage ch_imageNamed:@"banana_inactive.png"] forState:UIControlStateNormal];
  363. [likeBtn setBackgroundImage:[UIImage ch_imageNamed:@"banana_active.png"] forState:UIControlStateSelected];
  364. [likeBtn setTitle:@"like" forState:UIControlStateDisabled];
  365. [likeBtn addTarget:self action:@selector(doLikeAction:) forControlEvents:UIControlEventTouchUpInside];
  366. [likeBtn setSelected:[[mission has_liked] boolValue]];
  367. [likeBtn setFrame:CGRectMake(self.frame.size.width/5/*CGRectGetMaxX(shareBtn.frame)*/, 0, kActionRowHeight, kActionRowHeight)];
  368. if (dislikeBtn == nil) {
  369. dislikeBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  370. [dislikeBtn setTintColor:kTRANSPARENTUICOLOR];
  371. [actionRowView addSubview:dislikeBtn];
  372. }
  373. [dislikeBtn setBackgroundImage:[UIImage ch_imageNamed:@"shit_inactive.png"] forState:UIControlStateNormal];
  374. [dislikeBtn setBackgroundImage:[UIImage ch_imageNamed:@"shit_active.png"] forState:UIControlStateSelected];
  375. [dislikeBtn setTitle:@"dislike" forState:UIControlStateDisabled];
  376. [dislikeBtn addTarget:self action:@selector(doLikeAction:) forControlEvents:UIControlEventTouchUpInside];
  377. [dislikeBtn setSelected:[[mission has_disliked] boolValue]];
  378. [dislikeBtn setFrame:CGRectMake(CGRectGetMinX(shareBtn.frame)-[dislikeBtn backgroundImageForState:UIControlStateNormal].size.width, 0, kActionRowHeight, kActionRowHeight)];
  379. DCMSG([mission like_count]);
  380. if (likeDislikeCount == nil) {
  381. likeDislikeCount = [[wbLabel alloc] init];
  382. [likeDislikeCount setFont:kFONT(24)];
  383. [likeDislikeCount setBackgroundColor:kTRANSPARENTUICOLOR];
  384. [likeDislikeCount setTextAlignment:NSTextAlignmentCenter];
  385. [actionRowView addSubview:likeDislikeCount];
  386. }
  387. [likeDislikeCount setText:[mission like_count_string]];
  388. [likeDislikeCount setEdgeInsets:UIEdgeInsetsMake(4, 0, 0, 0)];
  389. [likeDislikeCount sizeToFit];
  390. [likeDislikeCount setCenter:CGPointMake(self.frame.size.width/2, kActionRowHeight/2)];
  391. BOOL bOrS;
  392. if ([[mission like_count] integerValue] < 0) {
  393. bOrS = NO;
  394. [likeDislikeCount setTextColor:kREDUICOLOR];
  395. } else {
  396. bOrS = YES;
  397. [likeDislikeCount setTextColor:kGREENUICOLOR];
  398. }
  399. if (ai == nil) {
  400. ai = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
  401. [actionRowView addSubview:ai];
  402. [ai setFrame:CGRectMake(0, 0, kActionRowHeight, kActionRowHeight)];
  403. [ai setHidden:YES];
  404. [ai setHidesWhenStopped:YES];
  405. }
  406. if (likeBubble != nil) {
  407. [likeBubble removeFromSuperview];
  408. }
  409. likeBubble = [[wbAPI sharedAPI] giveBubleWithBanana:bOrS frame:CGRectMake(CGRectGetMinX(likeBtn.frame), 0, self.frame.size.width-(CGRectGetMinX(likeBtn.frame)+(self.frame.size.width-CGRectGetMaxX(dislikeBtn.frame))), kActionRowHeight)];
  410. [actionRowView addSubview:likeBubble];
  411. return actionRowView;
  412. }
  413. -(void)showShareSelect
  414. {
  415. if (activityViewController == nil) {
  416. NSArray *excludedServices = [NSArray arrayWithObjects:
  417. //UIActivityTypePostToFacebook,
  418. //UIActivityTypePostToTwitter,
  419. //UIActivityTypePostToWeibo,
  420. //UIActivityTypeMessage,
  421. //UIActivityTypeMail,
  422. UIActivityTypePrint,
  423. //UIActivityTypeCopyToPasteboard,
  424. UIActivityTypeAssignToContact,
  425. UIActivityTypeSaveToCameraRoll,
  426. //UIActivityTypeAddToReadingList,
  427. UIActivityTypePostToFlickr,
  428. UIActivityTypePostToVimeo,
  429. //UIActivityTypePostToTencentWeibo,
  430. UIActivityTypeAirDrop,
  431. nil];
  432. NSString *shareString = [NSString stringWithFormat:NSLocalizedString(@"MISSIONS_SHARE_MESSAGE", @""),[mission title]];
  433. NSURL *shareURL = [mission mission_url];
  434. activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[shareString, shareURL] applicationActivities:nil];
  435. [activityViewController setExcludedActivityTypes:excludedServices];
  436. [activityViewController setValue:NSLocalizedString(@"GENERAL_APP_NAME", @"") forKey:@"subject"];
  437. }
  438. hideByShare = YES;
  439. [kROOTVC presentViewController:activityViewController animated:YES completion:nil];
  440. }
  441. -(void)doLikeAction:(id)sender
  442. {
  443. UIButton *button = sender;
  444. [ai setCenter:button.center];
  445. [ai startAnimating];
  446. [ai setHidden:NO];
  447. if ([button isSelected]) {
  448. if ([[button titleForState:UIControlStateDisabled] isEqualToString:@"dislike"]) {
  449. [mission undislikeMission];
  450. } else {
  451. [mission unlikeMission];
  452. }
  453. } else {
  454. if ([[button titleForState:UIControlStateDisabled] isEqualToString:@"dislike"]) {
  455. [mission dislikeMission];
  456. } else {
  457. [mission likeMission];
  458. }
  459. }
  460. }
  461. -(void)updateReady
  462. {
  463. if ([mission ready]) {
  464. [ai stopAnimating];
  465. [ai setHidden:YES];
  466. (void)[self actionRow];
  467. } else {
  468. double delayInSeconds = 0.5;
  469. dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
  470. dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
  471. //code to be executed on the main queue after delay
  472. [self updateReady];
  473. });
  474. }
  475. }
  476. ///////////////////
  477. -(UIView*)enterRow
  478. {
  479. if (cameraBtn == nil) {
  480. cameraBtn = [wbButton buttonWithType:UIButtonTypeSystem];
  481. [cameraBtn setFrame:CGRectMake(0, 0, self.frame.size.width ,kActionRowHeight)];
  482. [cameraBtn setShowsTouchWhenHighlighted:YES];
  483. [cameraBtn addTarget:self action:@selector(startCamera) forControlEvents:UIControlEventTouchUpInside];
  484. [cameraBtn setTitle:NSLocalizedString(@"MISSIONS_CREATE_MISSION_VIDEO", @"") forState:UIControlStateNormal];
  485. [cameraBtn setTitle:NSLocalizedString(@"MISSIONS_COMPLETED", @"") forState:UIControlStateDisabled];
  486. [[cameraBtn titleLabel] setFont:kFONTHelvetica(15)];
  487. [cameraBtn setTitleColor:kBKGUICOLOR forState:UIControlStateNormal];
  488. [cameraBtn setTitleColor:kBKGUICOLOR forState:UIControlStateDisabled];
  489. }
  490. if ([[mission submissions_left] integerValue] > 1) {
  491. NSString *string = [NSString stringWithFormat:NSLocalizedString(@"MISSIONS_SUBMISSIONS_LEFT", @""),[[mission submissions_left] integerValue]];
  492. [cameraBtn setTitle:[NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"MISSIONS_CREATE_MISSION_VIDEO", @""), string] forState:UIControlStateNormal];
  493. } else {
  494. [cameraBtn setTitle:NSLocalizedString(@"MISSIONS_CREATE_MISSION_VIDEO", @"") forState:UIControlStateNormal];
  495. }
  496. [cameraBtn setTitleEdgeInsets:UIEdgeInsetsMake(0, 0, 4, 0)];
  497. if ([[mission submissions_left] integerValue] == 0) {
  498. [cameraBtn setEnabled:NO];
  499. [cameraBtn setBackgroundColor:kYELLOWUICOLOR];
  500. } else {
  501. [cameraBtn setEnabled:YES];
  502. [cameraBtn setBackgroundColor:kGREENUICOLOR];
  503. }
  504. return cameraBtn;
  505. }
  506. -(void)startCamera
  507. {
  508. if ([[mission submissions_left] integerValue] > 0) {
  509. hideByShare = YES;
  510. [[wbAPI sharedAPI] setMissionData:[mission mission_dictionary]];
  511. [kROOTVC performSelector:@selector(startCamera:) withObject:nil];
  512. }
  513. }
  514. ///////////////////
  515. -(UIView*)whoRow
  516. {
  517. if (whoRowView == nil) {
  518. whoRowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, kWhoRowHeight)];
  519. }
  520. if (userPicture == nil) {
  521. userPicture = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kWhoRowHeight-4, kWhoRowHeight-4)];
  522. [[mission created_by] userProfilePictureImageView:userPicture];
  523. [userPicture setCenter:CGPointMake(15+kWhoRowHeight/2, kWhoRowHeight/2)];
  524. [whoRowView addSubview:userPicture];
  525. }
  526. if (username == nil) {
  527. username = [[wbButton alloc] init];
  528. [[mission created_by] getUserButton:username];
  529. [username sizeToFit];
  530. [username setFrame:CGRectMake(CGRectGetMaxX(userPicture.frame)+6, kWhoRowHeight/2, username.frame.size.width, username.frame.size.height)];
  531. [whoRowView addSubview:username];
  532. }
  533. if (title == nil) {
  534. title = [[wbLabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width-CGRectGetMaxX(userPicture.frame), 0)];
  535. [title setText:[[mission title] uppercaseString]];
  536. [title setFont:kFONT(20)];
  537. [title setTextColor:kWHITEUICOLOR];
  538. [title setEdgeInsets:UIEdgeInsetsMake(0, 0, -6, 15)];
  539. [title setNumberOfLines:1];
  540. [title setPreserveWidth:YES];
  541. [title sizeToFit];
  542. [title setFrame:CGRectMake(username.frame.origin.x, CGRectGetMinY(username.frame)-title.frame.size.height, title.frame.size.width, title.frame.size.height)];
  543. [whoRowView addSubview:title];
  544. }
  545. return whoRowView;
  546. }
  547. ///////////////////
  548. -(UIView*)descriptionRow
  549. {
  550. if (description == nil) {
  551. description = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0)];
  552. [description setText:[mission text]];
  553. [description setFont:kFONTHelveticaReg(15)];
  554. [description setTextColor:kWHITEUICOLOR];
  555. [description setDataDetectorTypes:UIDataDetectorTypeLink];
  556. if ([[mission text] length] > 0) {
  557. [description setTextContainerInset:UIEdgeInsetsMake(6, 6, 6, 6)];
  558. [description sizeToFit];
  559. }
  560. [description setScrollEnabled:NO];
  561. [description setEditable:NO];
  562. [description setUserInteractionEnabled:YES];
  563. [description setTintColor:kGREENUICOLOR];
  564. [description setBackgroundColor:kTRANSPARENTUICOLOR];
  565. }
  566. return description;
  567. }
  568. ///////////////////
  569. -(UIView*)infoRow
  570. {
  571. if (infoRowView == nil) {
  572. infoRowView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, kWhoRowHeight)];
  573. }
  574. if (videoLabel == nil) {
  575. videoLabel = [[wbLabel alloc] init];
  576. if ([mission max_submissions] > 0) {
  577. [videoLabel setText:[NSString stringWithFormat:NSLocalizedString(@"MISSIONS_VIDEO_COUNT_COUNT", @""),[mission number_of_submissions_string],[mission max_submissions_string]]];
  578. } else {
  579. [videoLabel setText:[NSString stringWithFormat:NSLocalizedString(@"MISSIONS_VIDEO_COUNT", @""),[[mission number_of_submissions_string] integerValue]]];
  580. }
  581. [videoLabel setFont:kFONTHelveticaReg(15)];
  582. [videoLabel setTextColor:kWHITEUICOLOR];
  583. [videoLabel sizeToFit];
  584. [videoLabel setCenter:CGPointMake(15+videoLabel.frame.size.width/2, kInfoRowHeight/2)];
  585. [infoRowView addSubview:videoLabel];
  586. }
  587. if (rulesButton == nil) {
  588. rulesButton = [[wbButton alloc] init];
  589. [rulesButton setTitle:NSLocalizedString(@"MISSIONS_RULES_LINK_TEXT", @"") forState:UIControlStateNormal];
  590. [[rulesButton titleLabel] setFont:kFONTHelvetica(15)];
  591. [rulesButton setTitleColor:kWHITEUICOLOR forState:UIControlStateNormal];
  592. [rulesButton sizeToFit];
  593. [rulesButton setCenter:CGPointMake(self.frame.size.width-(15+rulesButton.frame.size.width/2), kInfoRowHeight/2)];
  594. [rulesButton addTarget:self action:@selector(openRulesLink) forControlEvents:UIControlEventTouchUpInside];
  595. [infoRowView addSubview:rulesButton];
  596. }
  597. return infoRowView;
  598. }
  599. -(void)openRulesLink
  600. {
  601. /*NSString *string = NSLocalizedString(@"GENERAL_WARNING_TITLE", @"");
  602. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:string
  603. message:NSLocalizedString(@"SETTINGS_CONFIRM_BROWSER", @"")
  604. delegate:self
  605. cancelButtonTitle:NSLocalizedString(@"GENERAL_CANCEL",@"")
  606. otherButtonTitles:NSLocalizedString(@"GENERAL_OK",@""),nil];
  607. [alert setTag:0];
  608. [alert show];*/
  609. if (wv == nil) {
  610. wv = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height)];
  611. UIButton *close = [UIButton buttonWithType:UIButtonTypeSystem];
  612. [close setFrame:CGRectMake(wv.frame.size.width-40, 30, 30, 30)];
  613. [close addTarget:self action:@selector(closeWebView) forControlEvents:UIControlEventTouchUpInside];
  614. [close setBackgroundImage:[UIImage imageNamed:@"cancel_profile_pic"] forState:UIControlStateNormal];
  615. [close setTintColor:kTRANSPARENTUICOLOR];
  616. if (aiweb == nil) {
  617. aiweb = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  618. }
  619. [aiweb startAnimating];
  620. [aiweb setHidden:NO];
  621. [aiweb setCenter:wv.center];
  622. [wv addSubview:aiweb];
  623. [wv addSubview:close];
  624. }
  625. [wv setBackgroundColor:kBKGUICOLORAlpha];
  626. [wv setOpaque:NO];
  627. [wv setDelegate:self];
  628. [wv loadRequest:[NSMutableURLRequest requestWithURL:[mission mission_rules_url_ios]]];
  629. [wv setHidden:NO];
  630. [[[[UIApplication sharedApplication] delegate] window] addSubview:wv];
  631. }
  632. -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
  633. {
  634. if (buttonIndex == 1) {
  635. [self closeWebView];
  636. [[UIApplication sharedApplication] openURL:rulesLinkUrl];
  637. }
  638. }
  639. -(void)closeWebView
  640. {
  641. allowLoad = YES;
  642. [wv setHidden:YES];
  643. [wv removeFromSuperview];
  644. }
  645. - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
  646. if (!allowLoad) {
  647. NSLog(@"url: %@",[request URL]);
  648. rulesLinkUrl = [request URL];
  649. DCMSG([rulesLinkUrl pathComponents]);
  650. if ([[[rulesLinkUrl pathComponents] objectAtIndex:1] isEqualToString:@"u"]) {
  651. [self closeWebView];
  652. [[mission created_by] openUserFeed:self];
  653. return NO;
  654. } else if ([[[rulesLinkUrl pathComponents] objectAtIndex:1] isEqualToString:@"m"]) {
  655. [self closeWebView];
  656. [self scrollTableTop];
  657. return NO;
  658. } else {
  659. NSString *string = NSLocalizedString(@"GENERAL_WARNING_TITLE", @"");
  660. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:string
  661. message:NSLocalizedString(@"SETTINGS_CONFIRM_BROWSER", @"")
  662. delegate:self
  663. cancelButtonTitle:NSLocalizedString(@"GENERAL_CANCEL",@"")
  664. otherButtonTitles:NSLocalizedString(@"GENERAL_OK",@""),nil];
  665. [alert setTag:0];
  666. [alert show];
  667. }
  668. }
  669. return allowLoad;
  670. }
  671. - (void)webViewDidFinishLoad:(UIWebView*)webView {
  672. allowLoad = NO;
  673. [aiweb stopAnimating];
  674. [aiweb setHidden:YES];
  675. }
  676. ///////////////////
  677. -(UIView*)missionVideoRowWithId:(NSNumber*)videoid
  678. {
  679. if ([missionVideos count] == [videoid integerValue] + 1) {
  680. if (next != nil) {
  681. [self getMissionVideosWithURL:next];
  682. }
  683. }
  684. wbVideoCell *videoCell = [[wbVideoCell alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, kMissionVideoRowHeight)];
  685. [missionVideoCells setObject:videoCell forKey:videoid];
  686. [videoCell setCellContent:[missionVideos objectAtIndex:[videoid integerValue]]];
  687. return [missionVideoCells objectForKey:videoid];
  688. }
  689. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  690. {
  691. if ([indexPath row] >= kFirstVideoRow) {
  692. [[wbData sharedData] setSingleVideoData:[missionVideos objectAtIndex:[indexPath row]-kFirstVideoRow]];
  693. NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^(void){
  694. [[wbWaitView sharedWait] performSelectorOnMainThread:@selector(show) withObject:NULL waitUntilDone:YES];
  695. }];
  696. [op setCompletionBlock:^(void){
  697. [kROOTVC performSelectorOnMainThread:@selector(startSingleVideo:) withObject:self waitUntilDone:NO];
  698. }];
  699. [op start];
  700. DMSG;
  701. [self deselectRowAtIndexPath:indexPath animated:NO];
  702. }
  703. }
  704. -(void)getMissionVideosWithURL:(NSURL*)url
  705. {
  706. [[wbAPI sharedAPI] getJSONWithURL:url response:^(id data) {
  707. NSInteger oldCount = [missionVideos count];
  708. [missionVideos addObjectsFromArray:[data objectForKey:@"results"]];
  709. if (![[data objectForKey:@"next"] isKindOfClass:[NSNull class]]) {
  710. next = [NSURL URLWithString:[data objectForKey:@"next"]];
  711. } else {
  712. next = nil;
  713. }
  714. [self beginUpdates];
  715. for (NSInteger i = oldCount+kFirstVideoRow; i < [missionVideos count]+kFirstVideoRow; i++) {
  716. [self insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationBottom];
  717. }
  718. [self endUpdates];
  719. if (refreshing) {
  720. [self setContentOffset:CGPointZero animated:YES];
  721. }
  722. refreshing = NO;
  723. [[UIApplication sharedApplication] endIgnoringInteractionEvents];
  724. [self setScrollEnabled:YES];
  725. kHIDEWAIT;
  726. }];
  727. }
  728. ///////////////////
  729. ///////////////////
  730. @end