265 lines
8.4 KiB
Mathematica
265 lines
8.4 KiB
Mathematica
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||
|
|
||
|
#import <BlocksKit/UIActionSheet+BlocksKit.h>
|
||
|
#import <BlocksKit/UIAlertView+BlocksKit.h>
|
||
|
#import <BlocksKit/UIBarButtonItem+BlocksKit.h>
|
||
|
|
||
|
#import "OCTFriendsViewController.h"
|
||
|
#import "OCTFriend.h"
|
||
|
#import "OCTFriendRequest.h"
|
||
|
#import "OCTSubmanagerObjects.h"
|
||
|
#import "OCTSubmanagerChats.h"
|
||
|
#import "OCTSubmanagerFriends.h"
|
||
|
|
||
|
typedef NS_ENUM(NSUInteger, SectionType) {
|
||
|
SectionTypeFriends = 0,
|
||
|
SectionTypeFriendRequests,
|
||
|
SectionTypeCount,
|
||
|
};
|
||
|
|
||
|
@interface OCTFriendsViewController ()
|
||
|
|
||
|
@property (strong, nonatomic) RLMResults<OCTFriend *> *friends;
|
||
|
@property (strong, nonatomic) RLMNotificationToken *friendsNotificationToken;
|
||
|
@property (strong, nonatomic) RLMResults<OCTFriendRequest *> *friendRequests;
|
||
|
@property (strong, nonatomic) RLMNotificationToken *friendRequestsNotificationToken;
|
||
|
|
||
|
@end
|
||
|
|
||
|
@implementation OCTFriendsViewController
|
||
|
|
||
|
#pragma mark - Lifecycle
|
||
|
|
||
|
- (instancetype)initWithManager:(id<OCTManager>)manager
|
||
|
{
|
||
|
self = [super initWithManager:manager];
|
||
|
|
||
|
if (! self) {
|
||
|
return nil;
|
||
|
}
|
||
|
|
||
|
_friends = [self.manager.objects objectsForType:OCTFetchRequestTypeFriend predicate:nil];
|
||
|
_friendRequests = [self.manager.objects objectsForType:OCTFetchRequestTypeFriendRequest predicate:nil];
|
||
|
|
||
|
self.title = @"Friends";
|
||
|
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
- (void)dealloc
|
||
|
{
|
||
|
[self.friendsNotificationToken invalidate];
|
||
|
[self.friendRequestsNotificationToken invalidate];
|
||
|
}
|
||
|
|
||
|
- (void)viewDidLoad
|
||
|
{
|
||
|
[super viewDidLoad];
|
||
|
|
||
|
__weak typeof(self)weakSelf = self;
|
||
|
|
||
|
self.friendsNotificationToken = [self.friends addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
||
|
[weakSelf realmWasUpdated:changes sectionType:SectionTypeFriends error:error];
|
||
|
}];
|
||
|
|
||
|
self.friendRequestsNotificationToken = [self.friendRequests addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
||
|
[weakSelf realmWasUpdated:changes sectionType:SectionTypeFriendRequests error:error];
|
||
|
}];
|
||
|
|
||
|
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
|
||
|
bk_initWithBarButtonSystemItem:UIBarButtonSystemItemAdd handler:^(id handler) {
|
||
|
[weakSelf sendFriendRequest];
|
||
|
}];
|
||
|
}
|
||
|
|
||
|
#pragma mark - UITableViewDelegate
|
||
|
|
||
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||
|
{
|
||
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||
|
|
||
|
SectionType type = indexPath.section;
|
||
|
|
||
|
switch (type) {
|
||
|
case SectionTypeFriends:
|
||
|
[self didSelectFriend:self.friends[indexPath.row]];
|
||
|
break;
|
||
|
case SectionTypeFriendRequests:
|
||
|
[self didSelectFriendRequest:self.friendRequests[indexPath.row]];
|
||
|
break;
|
||
|
case SectionTypeCount:
|
||
|
// nop
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#pragma mark - UITableViewDataSource
|
||
|
|
||
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||
|
{
|
||
|
return SectionTypeCount;
|
||
|
}
|
||
|
|
||
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||
|
{
|
||
|
SectionType type = section;
|
||
|
|
||
|
switch (type) {
|
||
|
case SectionTypeFriends:
|
||
|
return self.friends.count;
|
||
|
case SectionTypeFriendRequests:
|
||
|
return self.friendRequests.count;
|
||
|
case SectionTypeCount:
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
||
|
{
|
||
|
SectionType type = section;
|
||
|
|
||
|
switch (type) {
|
||
|
case SectionTypeFriends:
|
||
|
return @"Friends";
|
||
|
case SectionTypeFriendRequests:
|
||
|
return @"FriendRequests";
|
||
|
case SectionTypeCount:
|
||
|
return nil;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||
|
{
|
||
|
SectionType type = indexPath.section;
|
||
|
|
||
|
switch (type) {
|
||
|
case SectionTypeFriends:
|
||
|
return [self friendCellAtIndexPath:indexPath];
|
||
|
case SectionTypeFriendRequests:
|
||
|
return [self friendRequestCellAtIndexPath:indexPath];
|
||
|
case SectionTypeCount:
|
||
|
return nil;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#pragma mark - Private
|
||
|
|
||
|
- (UITableViewCell *)friendCellAtIndexPath:(NSIndexPath *)indexPath
|
||
|
{
|
||
|
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||
|
OCTFriend *friend = self.friends[indexPath.row];
|
||
|
|
||
|
cell.textLabel.text = [NSString stringWithFormat:@"Friend\n"
|
||
|
@"friendNumber %u\n"
|
||
|
@"publicKey %@\n"
|
||
|
@"name %@\n"
|
||
|
@"nickname %@\n"
|
||
|
@"statusMessage %@\n"
|
||
|
@"status %@\n"
|
||
|
@"isConnected %d\n"
|
||
|
@"connectionStatus %@\n"
|
||
|
@"lastSeenOnline %@\n"
|
||
|
@"isTyping %d",
|
||
|
friend.friendNumber,
|
||
|
friend.publicKey,
|
||
|
friend.name,
|
||
|
friend.nickname,
|
||
|
friend.statusMessage,
|
||
|
[self stringFromUserStatus:friend.status],
|
||
|
friend.isConnected,
|
||
|
[self stringFromConnectionStatus:friend.connectionStatus],
|
||
|
friend.lastSeenOnline,
|
||
|
friend.isTyping];
|
||
|
|
||
|
return cell;
|
||
|
}
|
||
|
|
||
|
- (UITableViewCell *)friendRequestCellAtIndexPath:(NSIndexPath *)indexPath
|
||
|
{
|
||
|
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||
|
OCTFriendRequest *request = self.friendRequests[indexPath.row];
|
||
|
|
||
|
cell.textLabel.text = [NSString stringWithFormat:@"Friend request\n"
|
||
|
@"publicKey %@\n"
|
||
|
@"message %@\n",
|
||
|
request.publicKey, request.message];
|
||
|
|
||
|
return cell;
|
||
|
}
|
||
|
|
||
|
- (void)didSelectFriend:(OCTFriend *)friend
|
||
|
{
|
||
|
__weak OCTFriendsViewController *weakSelf = self;
|
||
|
|
||
|
[self showActionSheet:^(UIActionSheet *sheet) {
|
||
|
[sheet bk_addButtonWithTitle:@"Create chat" handler:^{
|
||
|
[weakSelf.manager.chats getOrCreateChatWithFriend:friend];
|
||
|
}];
|
||
|
|
||
|
[sheet bk_addButtonWithTitle:@"Remove" handler:^{
|
||
|
[weakSelf.manager.friends removeFriend:friend error:nil];
|
||
|
}];
|
||
|
}];
|
||
|
}
|
||
|
|
||
|
- (void)didSelectFriendRequest:(OCTFriendRequest *)request
|
||
|
{
|
||
|
__weak OCTFriendsViewController *weakSelf = self;
|
||
|
|
||
|
[self showActionSheet:^(UIActionSheet *sheet) {
|
||
|
[sheet bk_addButtonWithTitle:@"Add" handler:^{
|
||
|
[weakSelf.manager.friends approveFriendRequest:request error:nil];
|
||
|
}];
|
||
|
|
||
|
[sheet bk_addButtonWithTitle:@"Remove" handler:^{
|
||
|
[weakSelf.manager.friends removeFriendRequest:request];
|
||
|
}];
|
||
|
}];
|
||
|
}
|
||
|
|
||
|
- (void)sendFriendRequest
|
||
|
{
|
||
|
UIAlertView *alert = [UIAlertView bk_alertViewWithTitle:@"Send friend request" message:nil];
|
||
|
|
||
|
alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
|
||
|
UITextField *addressField = [alert textFieldAtIndex:0];
|
||
|
addressField.placeholder = @"Address";
|
||
|
UITextField *messageField = [alert textFieldAtIndex:1];
|
||
|
messageField.placeholder = @"Message";
|
||
|
messageField.secureTextEntry = NO;
|
||
|
|
||
|
__weak OCTFriendsViewController *weakSelf = self;
|
||
|
[alert bk_addButtonWithTitle:@"OK" handler:^{
|
||
|
[weakSelf.manager.friends sendFriendRequestToAddress:addressField.text message:messageField.text error:nil];
|
||
|
[weakSelf.tableView reloadData];
|
||
|
}];
|
||
|
|
||
|
[alert bk_setCancelButtonWithTitle:@"Cancel" handler:nil];
|
||
|
|
||
|
[alert show];
|
||
|
}
|
||
|
|
||
|
- (void)realmWasUpdated:(RLMCollectionChange *)changes sectionType:(SectionType)sectionType error:(NSError *)error
|
||
|
{
|
||
|
if (error) {
|
||
|
NSLog(@"Failed to open Realm on background worker: %@", error);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Initial run of the query will pass nil for the change information
|
||
|
if (! changes) {
|
||
|
[self.tableView reloadData];
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
[self.tableView beginUpdates];
|
||
|
[self.tableView deleteRowsAtIndexPaths:[changes deletionsInSection:sectionType] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||
|
[self.tableView insertRowsAtIndexPaths:[changes insertionsInSection:sectionType] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||
|
[self.tableView reloadRowsAtIndexPaths:[changes modificationsInSection:sectionType] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||
|
[self.tableView endUpdates];
|
||
|
}
|
||
|
|
||
|
@end
|