// // MasterViewController.m // Juick // // Created by Vitaly Takmazov on 26.10.13. // Copyright (c) 2013 com.juick. All rights reserved. // #import "SWRevealViewController/SWRevealViewController.h" #import "MessagesViewController.h" #import "MessageCell.h" #import "Message.h" #import "ColorScheme.h" #import "NewPostViewController.h" #import "NSURL+PathParameters.h" static NSString *CellIdentifier = @"MessageCell"; @interface MessagesViewController (); @property(nonatomic, strong) NSMutableArray *messages; @property(nonatomic, assign) Boolean dataLoading; @property(nonatomic, strong) NSString *path; @property(nonatomic, strong) NSMutableDictionary *params; @property(nonatomic, strong) dispatch_queue_t concurrent_queue; @property (nonatomic, readwrite, retain) UIView *inputAccessoryView; @end @implementation MessagesViewController - (id)init { if (self = [super init]) { self.concurrent_queue = dispatch_queue_create("Queue", DISPATCH_QUEUE_SERIAL); }; return self; } - (void)loadFromPath:(NSString *)messagesPath withParams:(NSDictionary *)params withTitle:(NSString *)title { [self setPath:messagesPath]; [self setParams:[[NSMutableDictionary alloc] initWithDictionary:params]]; self.title = title; __weak MessagesViewController * weakSelf = self; dispatch_sync(self.concurrent_queue, ^{ [self.messages removeAllObjects]; [weakSelf refreshData]; }); } - (void) refreshData { self.dataLoading = YES; [Message pullNextFromPath:self.path params:self.params callback:^(NSArray *next) { NSArray *newMsgs = next; if ([self.path isEqualToString:[Message threadUrl]]) { NSUInteger lastRid = [((Message *)[self.messages lastObject]).rid unsignedIntegerValue]; NSUInteger count = [next count] - 1; NSUInteger oldCount = [self.messages count]; if (oldCount > 0) { if (lastRid && lastRid < count) { newMsgs = [next subarrayWithRange:NSMakeRange(lastRid, count - lastRid)]; } else { return; } } } [self.messages addObjectsFromArray:newMsgs]; [self.tableView reloadData]; [self.refreshControl endRefreshing]; self.dataLoading = NO; }]; } - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } - (void)viewDidLoad { [super viewDidLoad]; self.dataLoading = NO; [self.view setBackgroundColor:[ColorScheme mainBackground]]; self.messages = [NSMutableArray array]; SWRevealViewController *revealController = [self revealViewController]; if (revealController) { // TODO: add to thread view too [self.view addGestureRecognizer:[revealController panGestureRecognizer]]; } [self.tableView registerNib:[UINib nibWithNibName:@"MessageCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]; self.tableView.rowHeight = UITableViewAutomaticDimension; self.tableView.estimatedRowHeight = 500.0f; self.refreshControl = [UIRefreshControl new]; [self.refreshControl addTarget:self action:@selector(refreshData) forControlEvents:UIControlEventValueChanged];} - (void) composePressed { CATransition* transition = [CATransition animation]; transition.duration = 0.3; transition.type = kCATransitionFade; transition.subtype = kCATransitionFromTop; [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; [self.navigationController pushViewController:[[NewPostViewController alloc] init] animated:NO]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentSizeCategoryChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil]; } - (void)contentSizeCategoryChanged:(NSNotification *)notification { [self.tableView reloadData]; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { __block NSInteger count; dispatch_sync(self.concurrent_queue, ^{ count = self.messages.count; }); return count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MessageCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; __block Message *msg; dispatch_sync(self.concurrent_queue, ^{ msg = [self.messages objectAtIndex:indexPath.row]; }); cell.layer.borderWidth = 6; cell.layer.borderColor = [ColorScheme mainBackground].CGColor; [cell setMessage:msg]; if ([msg.attach length] > 0) { [cell.attach yy_setImageWithURL:[NSURL URLWithString:msg.attach] placeholder:[UIImage imageNamed:@"AttachPlaceholder"] options:YYWebImageOptionProgressiveBlur | YYWebImageOptionSetImageWithFadeAnimation completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) { [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [cell setNeedsUpdateConstraints]; [cell updateConstraintsIfNeeded]; [cell setNeedsLayout]; [cell layoutIfNeeded]; }]; }]; } else { cell.attach.image = nil; } return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([self.path isEqualToString:[Message threadUrl]]) return; __block Message *msg; dispatch_sync(self.concurrent_queue, ^{ msg = [self.messages objectAtIndex:indexPath.row]; }); MessagesViewController *threadViewController = [[MessagesViewController alloc] init]; [threadViewController loadFromPath:[Message threadUrl] withParams:[NSDictionary dictionaryWithObjectsAndKeys:msg.mid, @"mid", nil] withTitle:@"Thread"]; [self.navigationController pushViewController:threadViewController animated:NO]; } -(void)scrollViewDidScroll:(UIScrollView *)scrollView_ { CGFloat actualPosition = scrollView_.contentOffset.y; CGFloat contentHeight = scrollView_.contentSize.height - scrollView_.contentSize.height / 2; if (actualPosition >= contentHeight && !self.dataLoading) { __block Message *lastMsg; dispatch_sync(self.concurrent_queue, ^{ lastMsg = [self.messages lastObject]; NSNumber *lastMid = lastMsg.mid; if (![self.path isEqualToString:[Message threadUrl]]) { [self.params setValue:lastMid forKey:@"before_mid"]; } [self refreshData]; }); } } - (BOOL) canBecomeFirstResponder { return [self.path isEqualToString:[Message threadUrl]]; } - (UIView *)inputAccessoryView { if (!_inputAccessoryView) { CGRect viewBounds = self.view.bounds; CGRect frame = CGRectMake(0, viewBounds.size.height - PHFComposeBarViewInitialHeight, viewBounds.size.width, PHFComposeBarViewInitialHeight); PHFComposeBarView *_view = [[PHFComposeBarView alloc] initWithFrame:frame]; _view.backgroundColor = [UIColor whiteColor]; _view.buttonTintColor = [ColorScheme linkColor]; _view.maxLinesCount = 4; _view.utilityButtonImage = [UIImage imageNamed:@"Camera"]; _view.delegate = self; _inputAccessoryView = _view; } return _inputAccessoryView; } @end