271 lines
8.0 KiB
Objective-C
271 lines
8.0 KiB
Objective-C
// 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 "OCTConversationViewController.h"
|
|
#import "OCTSubmanagerObjects.h"
|
|
#import "OCTSubmanagerChats.h"
|
|
#import "OCTFriend.h"
|
|
#import "OCTChat.h"
|
|
#import "OCTMessageAbstract.h"
|
|
#import "OCTSubmanagerUser.h"
|
|
#import "OCTSubmanagerCalls.h"
|
|
#import "OCTSubmanagerFiles.h"
|
|
#import "OCTMessageText.h"
|
|
#import "RLMCollectionChange+IndexSet.h"
|
|
|
|
static NSString *const kCellIdent = @"cellIdent";
|
|
|
|
@interface OCTConversationViewController () <NSTableViewDataSource,
|
|
NSTableViewDelegate,
|
|
NSTextFieldDelegate>
|
|
|
|
@property (weak) IBOutlet NSTableView *chatsViewController;
|
|
@property (weak, nonatomic) id<OCTManager> manager;
|
|
|
|
@property (strong, nonatomic) RLMResults<OCTChat *> *allChats;
|
|
@property (strong, nonatomic) RLMNotificationToken *allChatsNotificationToken;
|
|
@property (strong, nonatomic) RLMResults<OCTMessageAbstract *> *conversationMessages;
|
|
@property (strong, nonatomic) RLMNotificationToken *conversationMessagesNotificationToken;
|
|
|
|
@property (weak) IBOutlet NSTableView *chatsTableView;
|
|
@property (weak) IBOutlet NSTableView *conversationTableView;
|
|
|
|
@end
|
|
|
|
@implementation OCTConversationViewController
|
|
|
|
- (instancetype)initWithManager:(id<OCTManager>)manager
|
|
{
|
|
self = [super init];
|
|
|
|
if (! self) {
|
|
return nil;
|
|
}
|
|
|
|
_manager = manager;
|
|
|
|
_allChats = [self.manager.objects objectsForType:OCTFetchRequestTypeChat predicate:nil];
|
|
_conversationMessages = nil;
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[self.allChatsNotificationToken invalidate];
|
|
[self.conversationMessagesNotificationToken invalidate];
|
|
}
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
|
|
__weak typeof(self)weakSelf = self;
|
|
|
|
self.allChatsNotificationToken = [self.allChats addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
|
if (error) {
|
|
NSLog(@"Failed to open Realm on background worker: %@", error);
|
|
return;
|
|
}
|
|
|
|
NSTableView *tableView = weakSelf.chatsTableView;
|
|
|
|
// Initial run of the query will pass nil for the change information
|
|
if (! changes) {
|
|
[tableView reloadData];
|
|
return;
|
|
}
|
|
|
|
[tableView beginUpdates];
|
|
[tableView removeRowsAtIndexes:[changes deletionsSet] withAnimation:NSTableViewAnimationSlideLeft];
|
|
[tableView insertRowsAtIndexes:[changes insertionsSet] withAnimation:NSTableViewAnimationSlideRight];
|
|
[tableView reloadDataForRowIndexes:[changes modificationsSet] columnIndexes:[NSIndexSet indexSetWithIndex:0]];
|
|
[tableView endUpdates];
|
|
}];
|
|
}
|
|
|
|
#pragma mark - Actions
|
|
|
|
- (IBAction)deleteChatButtonPressed:(NSButton *)sender
|
|
{
|
|
NSInteger selectedRow = self.chatsTableView.selectedRow;
|
|
|
|
if (selectedRow < 0) {
|
|
return;
|
|
}
|
|
|
|
OCTChat *chat = self.allChats[selectedRow];
|
|
|
|
[self.manager.chats removeAllMessagesInChat:chat removeChat:YES];
|
|
}
|
|
|
|
- (IBAction)callUserButtonPressed:(NSButton *)sender
|
|
{
|
|
NSInteger selectedRow = self.chatsTableView.selectedRow;
|
|
|
|
if (selectedRow < 0) {
|
|
return;
|
|
}
|
|
|
|
OCTChat *chat = self.allChats[selectedRow];
|
|
|
|
[self.manager.calls callToChat:chat enableAudio:YES enableVideo:YES error:nil];
|
|
}
|
|
|
|
- (IBAction)sendFileButtonPressed:(id)sender
|
|
{
|
|
NSInteger selectedRow = self.chatsTableView.selectedRow;
|
|
|
|
if (selectedRow < 0) {
|
|
return;
|
|
}
|
|
|
|
OCTChat *chat = self.allChats[selectedRow];
|
|
|
|
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
|
|
|
[panel runModal];
|
|
|
|
NSString *path = [panel.URL path];
|
|
|
|
[self.manager.files sendFileAtPath:path moveToUploads:NO toChat:chat failureBlock:nil];
|
|
}
|
|
|
|
#pragma mark - NSTextFieldDelegate
|
|
|
|
- (IBAction)chatTextFieldEntered:(NSTextField *)sender
|
|
{
|
|
NSInteger selectedRow = self.chatsTableView.selectedRow;
|
|
|
|
if (selectedRow < 0) {
|
|
return;
|
|
}
|
|
|
|
OCTChat *chat = self.allChats[selectedRow];
|
|
|
|
[self.manager.chats sendMessageToChat:chat
|
|
text:sender.stringValue
|
|
type:OCTToxMessageTypeNormal
|
|
successBlock:nil
|
|
failureBlock:nil];
|
|
sender.stringValue = @"";
|
|
}
|
|
|
|
#pragma mark - NSTableViewDelegate
|
|
|
|
- (NSView *) tableView:(NSTableView *)tableView
|
|
viewForTableColumn:(NSTableColumn *)tableColumn
|
|
row:(NSInteger)row
|
|
{
|
|
NSTextField *field = [tableView
|
|
makeViewWithIdentifier:kCellIdent
|
|
owner:self];
|
|
|
|
if (! field) {
|
|
field = [NSTextField new];
|
|
field.identifier = kCellIdent;
|
|
}
|
|
|
|
field.selectable = YES;
|
|
field.editable = NO;
|
|
|
|
|
|
if (tableView == self.chatsTableView) {
|
|
OCTChat *chat = self.allChats[row];
|
|
OCTFriend *friend = [chat.friends firstObject];
|
|
|
|
field.stringValue = (friend.isConnected) ? ([NSString stringWithFormat:@"%@ : Online", friend.nickname]) : friend.nickname;
|
|
|
|
}
|
|
else {
|
|
OCTMessageAbstract *messageAbstract = self.conversationMessages[row];
|
|
if (messageAbstract.messageText) {
|
|
if ([messageAbstract isOutgoing]) {
|
|
field.stringValue = [NSString stringWithFormat:@"%@: %@", self.manager.user.userName, messageAbstract.messageText.text];
|
|
}
|
|
else {
|
|
OCTFriend *friend = (OCTFriend *)[self.manager.objects objectWithUniqueIdentifier:messageAbstract.senderUniqueIdentifier
|
|
forType:OCTFetchRequestTypeFriend];
|
|
|
|
field.stringValue = [NSString stringWithFormat:@"%@: %@", friend.nickname, messageAbstract.messageText.text];
|
|
}
|
|
}
|
|
}
|
|
|
|
return field;
|
|
}
|
|
|
|
- (void)tableViewSelectionDidChange:(NSNotification *)notification
|
|
{
|
|
if (notification.object != self.chatsTableView) {
|
|
return;
|
|
}
|
|
|
|
NSInteger selectedRow = self.chatsTableView.selectedRow;
|
|
|
|
if (selectedRow < 0) {
|
|
return;
|
|
}
|
|
|
|
OCTChat *chat = self.allChats[selectedRow];
|
|
|
|
[self updateConversationControllerForChat:chat];
|
|
|
|
[self.conversationTableView reloadData];
|
|
}
|
|
|
|
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
|
|
{
|
|
return 50.0;
|
|
}
|
|
|
|
#pragma mark - NSTableViewDataSource
|
|
|
|
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
|
{
|
|
if (tableView == self.chatsTableView) {
|
|
return self.allChats.count;
|
|
}
|
|
else {
|
|
return self.conversationMessages.count;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#pragma mark - Private
|
|
|
|
- (void)updateConversationControllerForChat:(OCTChat *)chat
|
|
{
|
|
[self.conversationMessagesNotificationToken invalidate];
|
|
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"chatUniqueIdentifier == %@", chat.uniqueIdentifier];
|
|
self.conversationMessages = [self.manager.objects objectsForType:OCTFetchRequestTypeMessageAbstract predicate:predicate];
|
|
|
|
__weak typeof(self)weakSelf = self;
|
|
|
|
self.conversationMessagesNotificationToken = [self.conversationMessages addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
|
if (error) {
|
|
NSLog(@"Failed to open Realm on background worker: %@", error);
|
|
return;
|
|
}
|
|
|
|
NSTableView *tableView = weakSelf.conversationTableView;
|
|
|
|
// Initial run of the query will pass nil for the change information
|
|
if (! changes) {
|
|
[tableView reloadData];
|
|
return;
|
|
}
|
|
|
|
[tableView beginUpdates];
|
|
[tableView removeRowsAtIndexes:[changes deletionsSet] withAnimation:NSTableViewAnimationSlideLeft];
|
|
[tableView insertRowsAtIndexes:[changes insertionsSet] withAnimation:NSTableViewAnimationSlideRight];
|
|
[tableView reloadDataForRowIndexes:[changes modificationsSet] columnIndexes:[NSIndexSet indexSetWithIndex:0]];
|
|
[tableView endUpdates];
|
|
}];
|
|
}
|
|
|
|
@end
|