summaryrefslogtreecommitdiff
path: root/Juick/ViewControllers/ChatViewController.m
blob: 195f178b1bb2582d95f5aa9514e01a37ee069b39 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
//  ChatViewController.m
//  Juick
//
//  Created by Vitaly Takmazov on 04/03/2018.
//  Copyright © 2018 com.juick. All rights reserved.
//

#import "ChatViewController.h"

#define kMessageInputInitialHeight 50

@interface ChatViewController ()

@property (nonatomic, readwrite, retain) MessageInputView *accessoryView;
@property (nonatomic, strong) NSString *me;

@end

@implementation ChatViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.navigationController.visibleViewController setTitle:self.uname];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.tableView registerNib:[UINib nibWithNibName:@"BubbleMessageCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"bubbleMessageCell"];
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
    self.tableView.allowsSelection = NO;
    self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentAutomatic;
    [self reloadChat];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
    [self addObserver:self forKeyPath:@"uname" options:0 context:nil];
#if TARGET_OS_MACCATALYST
    [self.stack addArrangedSubview:[self inputAccessoryView]];
#else
    self.tableView.refreshControl = [UIRefreshControl new];
    [self.tableView.refreshControl addTarget:self action:@selector(reloadChat) forControlEvents:UIControlEventValueChanged];
    self.stackBottomConstraint.constant = kMessageInputInitialHeight;
#endif
}

-(void) reloadChat {
    self.messages = [NSMutableArray array];
    [self.tableView reloadData];
    [[AppDelegate shared].api fetchChatWithUser:self.uname callback:^(NSArray *messages, NSError *err) {
        if (err == nil) {
            [self.messages addObjectsFromArray:[[messages reverseObjectEnumerator] allObjects]];
            NSMutableArray *indexPaths = [NSMutableArray new];
            NSInteger messagesCount = [self.messages count];
            for (NSUInteger index = 0; index < messagesCount; index++) {
                [indexPaths addObject:[NSIndexPath indexPathForRow:index inSection: 0]];
            }
            if (indexPaths > 0) {
                [self.tableView beginUpdates];
                [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:YES];
                [self.tableView endUpdates];
            }
            if (messagesCount > 0) {
                [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:[self.messages count]-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
            }
        }
        [self.tableView.refreshControl endRefreshing];
    }];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.messages count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    BubbleMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"bubbleMessageCell" forIndexPath:indexPath];
    Message *message = [self.messages objectAtIndex:indexPath.row];
    [cell configureWithMessage:message isMe:[self.me isEqualToString:message.user.uname]];
    return cell;
}

-(BOOL) canBecomeFirstResponder {
    return YES;
}

- (BOOL)canResignFirstResponder {
    return YES;
}

- (UIView *) inputAccessoryView {
    if (!_accessoryView) {
        _accessoryView = [[[NSBundle mainBundle] loadNibNamed:@"MessageInputView" owner:self options:nil] firstObject];
        _accessoryView.delegate = self;
    }
    return _accessoryView;
}

-(void) keyboardWillChangeFrame:(NSNotification *)notification {
    NSDictionary *userInfo = [notification userInfo];
    if (userInfo) {
        CGRect beginFrame = [userInfo [UIKeyboardFrameBeginUserInfoKey] CGRectValue];
        CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
        CGFloat keyboardHeight = endFrame.origin.y - beginFrame.origin.y;
        CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
        UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
        
        [UIView animateWithDuration:duration delay:0 options:(animationCurve << 16) animations:^{
            self.tableView.contentOffset = CGPointMake(0, self.tableView.contentOffset.y - keyboardHeight);
        } completion:nil];
    }
}

-(void) textSent:(NSString *)text {
    [[AppDelegate shared].api postPMToUser:self.uname text:text result:^(NSError *err) {
        if (!err) {
            NSLog(@"Success!");
            [self.accessoryView becomeFirstResponder];
            [self reloadChat];
        }
    }];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    [self reloadChat];
}

@end