Handle live stream in current room

This commit is contained in:
giomfo
2014-10-16 01:34:46 +02:00
parent cf8df32a7e
commit 6d038a5d41

View File

@@ -19,7 +19,7 @@
#import "MatrixHandler.h" #import "MatrixHandler.h"
#import "AppDelegate.h" #import "AppDelegate.h"
// Table view cells // Table view cell
@interface RoomMessageCell : UITableViewCell @interface RoomMessageCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *userPicture; @property (weak, nonatomic) IBOutlet UIImageView *userPicture;
@property (weak, nonatomic) IBOutlet UITextView *messageTextView; @property (weak, nonatomic) IBOutlet UITextView *messageTextView;
@@ -41,6 +41,11 @@
@interface RoomViewController () @interface RoomViewController ()
{ {
BOOL isFirstDisplay; BOOL isFirstDisplay;
MXRoomData *mxRoomData;
NSMutableArray *messages;
id registeredListener;
} }
@property (weak, nonatomic) IBOutlet UINavigationItem *roomNavItem; @property (weak, nonatomic) IBOutlet UINavigationItem *roomNavItem;
@@ -52,35 +57,10 @@
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *controlViewBottomConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *controlViewBottomConstraint;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator; @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
@property (strong, nonatomic) MXRoomData *mxRoomData;
@end @end
@implementation RoomViewController @implementation RoomViewController
#pragma mark - Managing the detail item
- (void)setRoomId:(NSString *)roomId {
_roomId = roomId;
// Update the view
[self configureView];
}
- (void)configureView {
// Update room data
if (self.roomId) {
self.mxRoomData = [[MatrixHandler sharedHandler].mxData getRoomData:self.roomId];
} else {
self.mxRoomData = nil;
}
[self.tableView reloadData];
// Update room title
self.roomNavItem.title = self.mxRoomData.displayname;
}
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. // Do any additional setup after loading the view, typically from a nib.
@@ -91,7 +71,12 @@
} }
- (void)dealloc { - (void)dealloc {
_mxRoomData = nil; messages = nil;
if (registeredListener) {
[mxRoomData unregisterListener:registeredListener];
registeredListener = nil;
}
mxRoomData = nil;
} }
- (void)didReceiveMemoryWarning { - (void)didReceiveMemoryWarning {
@@ -102,7 +87,7 @@
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated]; [super viewWillAppear:animated];
// Update the view // Reload room data
[self configureView]; [self configureView];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
@@ -114,6 +99,11 @@
- (void)viewWillDisappear:(BOOL)animated { - (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated]; [super viewWillDisappear:animated];
if (registeredListener) {
[mxRoomData unregisterListener:registeredListener];
registeredListener = nil;
}
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
@@ -129,6 +119,65 @@
} }
} }
#pragma mark -
- (void)setRoomId:(NSString *)roomId {
_roomId = roomId;
// Load room data
[self configureView];
}
#pragma mark - Internal methods
- (void)configureView {
// Flush messages
messages = nil;
// Remove potential roomData listener
if (registeredListener && mxRoomData) {
[mxRoomData unregisterListener:registeredListener];
registeredListener = nil;
}
// Update room data
if (self.roomId) {
mxRoomData = [[MatrixHandler sharedHandler].mxData getRoomData:self.roomId];
messages = [NSMutableArray arrayWithArray:mxRoomData.messages];
// Register a listener for all events
registeredListener = [mxRoomData registerEventListenerForTypes:nil block:^(MXRoomData *roomData, MXEvent *event, BOOL isLive) {
// consider only live event
if (isLive) {
// For outgoing message, remove the temporary event
if ([event.user_id isEqualToString:[MatrixHandler sharedHandler].userId]) {
NSUInteger index = messages.count;
while (index--) {
MXEvent *mxEvent = [messages objectAtIndex:index];
if ([mxEvent.event_id isEqualToString:event.event_id]) {
[messages replaceObjectAtIndex:index withObject:event];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
return;
}
}
}
// Here a new event is added
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:messages.count inSection:0];
[messages addObject:event];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
[self scrollToBottomAnimated:YES];
}
}];
} else {
mxRoomData = nil;
}
[self.tableView reloadData];
// Update room title
self.roomNavItem.title = mxRoomData.displayname;
}
- (void)onKeyboardWillShow:(NSNotification *)notif { - (void)onKeyboardWillShow:(NSNotification *)notif {
NSValue *rectVal = notif.userInfo[UIKeyboardFrameEndUserInfoKey]; NSValue *rectVal = notif.userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect endRect = rectVal.CGRectValue; CGRect endRect = rectVal.CGRectValue;
@@ -160,7 +209,7 @@
- (void)scrollToBottomAnimated:(BOOL)animated { - (void)scrollToBottomAnimated:(BOOL)animated {
// Scroll table view to the bottom // Scroll table view to the bottom
NSInteger rowNb = [self tableView:self.tableView numberOfRowsInSection:0]; NSInteger rowNb = messages.count;
if (rowNb) { if (rowNb) {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(rowNb - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:animated]; [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(rowNb - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:animated];
} }
@@ -173,11 +222,7 @@
} }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger rowNb = 0; return messages.count;
if (self.mxRoomData){
rowNb = self.mxRoomData.messages.count;
}
return rowNb;
} }
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
@@ -190,7 +235,7 @@
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RoomMessageCell *cell; RoomMessageCell *cell;
MatrixHandler *mxHandler = [MatrixHandler sharedHandler]; MatrixHandler *mxHandler = [MatrixHandler sharedHandler];
MXEvent *mxEvent = [self.mxRoomData.messages objectAtIndex:indexPath.row]; MXEvent *mxEvent = [messages objectAtIndex:indexPath.row];
if ([mxEvent.user_id isEqualToString:mxHandler.userId]) { if ([mxEvent.user_id isEqualToString:mxHandler.userId]) {
cell = [aTableView dequeueReusableCellWithIdentifier:@"OutgoingMessageCell" forIndexPath:indexPath]; cell = [aTableView dequeueReusableCellWithIdentifier:@"OutgoingMessageCell" forIndexPath:indexPath];
@@ -215,25 +260,26 @@
// paginate ? // paginate ?
if ((scrollView.contentOffset.y < -64) && (_activityIndicator.isAnimating == NO)) if ((scrollView.contentOffset.y < -64) && (_activityIndicator.isAnimating == NO))
{ {
if (self.mxRoomData.canPaginate) if (mxRoomData.canPaginate)
{ {
[_activityIndicator startAnimating]; [_activityIndicator startAnimating];
[self.mxRoomData paginateBackMessages:20 success:^(NSArray *messages) { [mxRoomData paginateBackMessages:20 success:^(NSArray *oldMessages) {
// Update room data // Update messages array
self.mxRoomData = [[[MatrixHandler sharedHandler] mxData] getRoomData:self.roomId]; NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, oldMessages.count)];
[messages insertObjects:oldMessages atIndexes:indexSet];
// Refresh display // Refresh display
[self.tableView beginUpdates]; [self.tableView beginUpdates];
NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:messages.count]; NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:oldMessages.count];
for (NSUInteger index = 0; index < messages.count; index++) { for (NSUInteger index = 0; index < oldMessages.count; index++) {
[indexPaths addObject:[NSIndexPath indexPathForRow:index inSection:0]]; [indexPaths addObject:[NSIndexPath indexPathForRow:index inSection:0]];
} }
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone]; [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates]; [self.tableView endUpdates];
// Maintain the current message in visible area // Maintain the current message in visible area
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(messages.count - 1) inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(oldMessages.count - 1) inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
[_activityIndicator stopAnimating]; [_activityIndicator stopAnimating];
} failure:^(NSError *error) { } failure:^(NSError *error) {
[_activityIndicator stopAnimating]; [_activityIndicator stopAnimating];
@@ -270,17 +316,32 @@
- (IBAction)onButtonPressed:(id)sender { - (IBAction)onButtonPressed:(id)sender {
if (sender == _sendBtn) { if (sender == _sendBtn) {
NSString *msgTxt = self.messageTextField.text;
// Send message to the room // Send message to the room
[[[MatrixHandler sharedHandler] mxSession] postTextMessage:self.roomId text:self.messageTextField.text success:^(NSString *event_id) { [[[MatrixHandler sharedHandler] mxSession] postTextMessage:self.roomId text:msgTxt success:^(NSString *event_id) {
self.messageTextField.text = nil; // Create a temporary event to displayed outgoing message
// disable send button MXEvent *mxEvent = [[MXEvent alloc] init];
[self onTextFieldChange:nil]; mxEvent.room_id = self.roomId;
[self configureView]; mxEvent.event_id = event_id;
mxEvent.eventType = MXEventTypeRoomMessage;
mxEvent.type = kMXEventTypeStringRoomMessage;
mxEvent.content = @{@"msgtype":@"m.text", @"body":msgTxt};
mxEvent.user_id = [MatrixHandler sharedHandler].userId;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:messages.count inSection:0];
[messages addObject:mxEvent];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
[self scrollToBottomAnimated:YES];
} failure:^(NSError *error) { } failure:^(NSError *error) {
NSLog(@"Failed to send message (%@): %@", self.messageTextField.text, error); NSLog(@"Failed to send message (%@): %@", self.messageTextField.text, error);
//Alert user //Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error]; [[AppDelegate theDelegate] showErrorAsAlert:error];
}]; }];
self.messageTextField.text = nil;
// disable send button
[self onTextFieldChange:nil];
} else if (sender == _optionBtn) { } else if (sender == _optionBtn) {
[self dismissKeyboard]; [self dismissKeyboard];
//TODO: display option menu (Attachments...) //TODO: display option menu (Attachments...)