Room details - change messages layout: successive text messages from the same sender are concatenated in only one textView.

This commit is contained in:
giomfo
2014-11-27 10:50:09 +01:00
parent b0cf813e46
commit 7752f0ddd2
9 changed files with 963 additions and 511 deletions
+130 -84
View File
@@ -236,13 +236,14 @@ static MatrixHandler *sharedHandler = nil;
eventsListener = [self.mxSession listenToEventsOfTypes:self.mxSession.eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, id customObject) {
// Consider only live event (Ignore presence event)
if (direction == MXEventDirectionForwards && (event.eventType != MXEventTypePresence)) {
MXRoomState* roomState = (MXRoomState*)customObject;
// If we are running on background, show a local notif
if (UIApplicationStateBackground == [UIApplication sharedApplication].applicationState)
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
localNotification.hasAction = YES;
[localNotification setAlertBody:[self displayTextFor:event inSubtitleMode:YES]];
[localNotification setAlertBody:[self displayTextForEvent:event withRoomState:roomState inSubtitleMode:YES]];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
} else if ([[AppDelegate theDelegate].masterTabBarController.visibleRoomId isEqualToString:event.roomId] == NO) {
// The concerned room is not presently visible, we display a notification by removing existing one (if any)
@@ -250,8 +251,8 @@ static MatrixHandler *sharedHandler = nil;
[self.mxNotification dismiss:NO];
}
self.mxNotification = [[CustomAlert alloc] initWithTitle:[self.mxSession room:event.roomId].state.displayname
message:[self displayTextFor:event inSubtitleMode:YES]
self.mxNotification = [[CustomAlert alloc] initWithTitle:roomState.displayname
message:[self displayTextForEvent:event withRoomState:roomState inSubtitleMode:YES]
style:CustomAlertStyleAlert];
self.mxNotification.cancelButtonIndex = [self.mxNotification addActionWithTitle:@"OK"
style:CustomAlertActionStyleDefault
@@ -383,68 +384,80 @@ static MatrixHandler *sharedHandler = nil;
[[NSUserDefaults standardUserDefaults] synchronize];
}
#pragma mark - messages handler
#pragma mark - events handler
- (BOOL)isAttachment:(MXEvent*)message {
if (message.eventType == MXEventTypeRoomMessage) {
NSString *msgtype = message.content[@"msgtype"];
if ([msgtype isEqualToString:kMXMessageTypeImage]
|| [msgtype isEqualToString:kMXMessageTypeAudio]
|| [msgtype isEqualToString:kMXMessageTypeVideo]
|| [msgtype isEqualToString:kMXMessageTypeLocation]) {
// Checks whether the event is related to an attachment and if it is supported
- (BOOL)isSupportedAttachment:(MXEvent*)event {
BOOL isSupportedAttachment = NO;
if (event.eventType == MXEventTypeRoomMessage) {
NSString *msgtype = event.content[@"msgtype"];
NSString *requiredField;
if ([msgtype isEqualToString:kMXMessageTypeImage]) {
requiredField = event.content[@"url"];
if (requiredField.length) {
isSupportedAttachment = YES;
}
} else if ([msgtype isEqualToString:kMXMessageTypeAudio]) {
// Not supported yet
} else if ([msgtype isEqualToString:kMXMessageTypeVideo]) {
requiredField = event.content[@"url"];
if (requiredField) {
isSupportedAttachment = YES;
}
} else if ([msgtype isEqualToString:kMXMessageTypeLocation]) {
// Not supported yet
}
}
return isSupportedAttachment;
}
// Check whether the event is emote event
- (BOOL)isEmote:(MXEvent*)event {
if (event.eventType == MXEventTypeRoomMessage) {
NSString *msgtype = event.content[@"msgtype"];
if ([msgtype isEqualToString:kMXMessageTypeEmote]) {
return YES;
}
}
return NO;
}
- (BOOL)isNotification:(MXEvent*)message {
// We consider as notification mxEvent which is not a text message or an attachment
if (message.eventType == MXEventTypeRoomMessage) {
NSString *msgtype = message.content[@"msgtype"];
if ([msgtype isEqualToString:kMXMessageTypeEmote]) {
return YES;
}
return NO;
}
return YES;
}
- (NSString*)displayTextFor:(MXEvent*)message inSubtitleMode:(BOOL)isSubtitle {
- (NSString*)displayTextForEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState inSubtitleMode:(BOOL)isSubtitle {
NSString *displayText = nil;
// Retrieve roomData related to the message
MXRoom *room = [self.mxSession room:message.roomId];
// Prepare display name for concerned users
NSString *memberDisplayName = [room.state memberName:message.userId];
NSString *memberDisplayName = [roomState memberName:event.userId];
NSString *targetDisplayName = nil;
if (message.stateKey) {
targetDisplayName = [room.state memberName:message.stateKey];
if (event.stateKey) {
targetDisplayName = [roomState memberName:event.stateKey];
}
switch (message.eventType) {
switch (event.eventType) {
case MXEventTypeRoomName: {
displayText = [NSString stringWithFormat:@"%@ changed the room name to: %@", memberDisplayName, message.content[@"name"]];
displayText = [NSString stringWithFormat:@"%@ changed the room name to: %@", memberDisplayName, event.content[@"name"]];
break;
}
case MXEventTypeRoomTopic: {
displayText = [NSString stringWithFormat:@"%@ changed the topic to: %@", memberDisplayName, message.content[@"topic"]];
displayText = [NSString stringWithFormat:@"%@ changed the topic to: %@", memberDisplayName, event.content[@"topic"]];
break;
}
case MXEventTypeRoomMember: {
// Presently only change on membership, display name and avatar are supported
// Retrieve membership
NSString* membership = message.content[@"membership"];
NSString* membership = event.content[@"membership"];
NSString *prevMembership = nil;
if (message.prevContent) {
prevMembership = message.prevContent[@"membership"];
if (event.prevContent) {
prevMembership = event.prevContent[@"membership"];
}
// Check whether the membership is unchanged
if (prevMembership && membership && [membership isEqualToString:prevMembership]) {
// Check whether the display name has been changed
NSString *displayname = message.content[@"displayname"];
NSString *prevDisplayname = message.prevContent[@"displayname"];
NSString *displayname = event.content[@"displayname"];
NSString *prevDisplayname = event.prevContent[@"displayname"];
if (!displayname.length) {
displayname = nil;
}
@@ -452,12 +465,12 @@ static MatrixHandler *sharedHandler = nil;
prevDisplayname = nil;
}
if ((displayname || prevDisplayname) && ([displayname isEqualToString:prevDisplayname] == NO)) {
displayText = [NSString stringWithFormat:@"%@ changed their display name from %@ to %@", message.userId, prevDisplayname, displayname];
displayText = [NSString stringWithFormat:@"%@ changed their display name from %@ to %@", event.userId, prevDisplayname, displayname];
}
// Check whether the avatar has been changed
NSString *avatar = message.content[@"avatar_url"];
NSString *prevAvatar = message.prevContent[@"avatar_url"];
NSString *avatar = event.content[@"avatar_url"];
NSString *prevAvatar = event.prevContent[@"avatar_url"];
if (!avatar.length) {
avatar = nil;
}
@@ -478,13 +491,13 @@ static MatrixHandler *sharedHandler = nil;
} else if ([membership isEqualToString:@"join"]) {
displayText = [NSString stringWithFormat:@"%@ joined", memberDisplayName];
} else if ([membership isEqualToString:@"leave"]) {
if ([message.userId isEqualToString:message.stateKey]) {
if ([event.userId isEqualToString:event.stateKey]) {
displayText = [NSString stringWithFormat:@"%@ left", memberDisplayName];
} else if (prevMembership) {
if ([prevMembership isEqualToString:@"join"] || [prevMembership isEqualToString:@"invite"]) {
displayText = [NSString stringWithFormat:@"%@ kicked %@", memberDisplayName, targetDisplayName];
if (message.content[@"reason"]) {
displayText = [NSString stringWithFormat:@"%@: %@", displayText, message.content[@"reason"]];
if (event.content[@"reason"]) {
displayText = [NSString stringWithFormat:@"%@: %@", displayText, event.content[@"reason"]];
}
} else if ([prevMembership isEqualToString:@"ban"]) {
displayText = [NSString stringWithFormat:@"%@ unbanned %@", memberDisplayName, targetDisplayName];
@@ -492,22 +505,22 @@ static MatrixHandler *sharedHandler = nil;
}
} else if ([membership isEqualToString:@"ban"]) {
displayText = [NSString stringWithFormat:@"%@ banned %@", memberDisplayName, targetDisplayName];
if (message.content[@"reason"]) {
displayText = [NSString stringWithFormat:@"%@: %@", displayText, message.content[@"reason"]];
if (event.content[@"reason"]) {
displayText = [NSString stringWithFormat:@"%@: %@", displayText, event.content[@"reason"]];
}
}
}
break;
}
case MXEventTypeRoomCreate: {
NSString *creatorId = message.content[@"creator"];
NSString *creatorId = event.content[@"creator"];
if (creatorId) {
displayText = [NSString stringWithFormat:@"%@ created the room", [room.state memberName:creatorId]];
displayText = [NSString stringWithFormat:@"%@ created the room", [roomState memberName:creatorId]];
}
break;
}
case MXEventTypeRoomJoinRules: {
NSString *joinRule = message.content[@"join_rule"];
NSString *joinRule = event.content[@"join_rule"];
if (joinRule) {
displayText = [NSString stringWithFormat:@"The join rule is: %@", joinRule];
}
@@ -515,47 +528,47 @@ static MatrixHandler *sharedHandler = nil;
}
case MXEventTypeRoomPowerLevels: {
displayText = @"The power level of room members are:";
NSDictionary *users = message.content[@"users"];
NSDictionary *users = event.content[@"users"];
for (NSString *key in users.allKeys) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, key, [users objectForKey:key]];
}
if (message.content[@"users_default"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, @"default", message.content[@"users_default"]];
if (event.content[@"users_default"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, @"default", event.content[@"users_default"]];
}
displayText = [NSString stringWithFormat:@"%@\r\nThe minimum power levels that a user must have before acting are:", displayText];
if (message.content[@"ban"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 ban: %@", displayText, message.content[@"ban"]];
if (event.content[@"ban"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 ban: %@", displayText, event.content[@"ban"]];
}
if (message.content[@"kick"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 kick: %@", displayText, message.content[@"kick"]];
if (event.content[@"kick"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 kick: %@", displayText, event.content[@"kick"]];
}
if (message.content[@"redact"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 redact: %@", displayText, message.content[@"redact"]];
if (event.content[@"redact"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 redact: %@", displayText, event.content[@"redact"]];
}
displayText = [NSString stringWithFormat:@"%@\r\nThe minimum power levels related to events are:", displayText];
NSDictionary *events = message.content[@"events"];
NSDictionary *events = event.content[@"events"];
for (NSString *key in events.allKeys) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, key, [events objectForKey:key]];
}
if (message.content[@"events_default"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, @"events_default", message.content[@"events_default"]];
if (event.content[@"events_default"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, @"events_default", event.content[@"events_default"]];
}
if (message.content[@"state_default"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, @"state_default", message.content[@"state_default"]];
if (event.content[@"state_default"]) {
displayText = [NSString stringWithFormat:@"%@\r\n\u2022 %@: %@", displayText, @"state_default", event.content[@"state_default"]];
}
break;
}
// case MXEventTypeRoomAddStateLevel: {
// NSString *minLevel = message.content[@"level"];
// NSString *minLevel = event.content[@"level"];
// if (minLevel) {
// displayText = [NSString stringWithFormat:@"The minimum power level a user needs to add state is: %@", minLevel];
// }
// break;
// }
// case MXEventTypeRoomSendEventLevel: {
// NSString *minLevel = message.content[@"level"];
// NSString *minLevel = event.content[@"level"];
// if (minLevel) {
// displayText = [NSString stringWithFormat:@"The minimum power level a user needs to send an event is: %@", minLevel];
// }
@@ -563,32 +576,67 @@ static MatrixHandler *sharedHandler = nil;
// }
// case MXEventTypeRoomOpsLevel: {
// displayText = @"The minimum power levels that a user must have before acting are:";
// for (NSString *key in message.content.allKeys) {
// displayText = [NSString stringWithFormat:@"%@\r\n%@:%@", displayText, key, [message.content objectForKey:key]];
// for (NSString *key in event.content.allKeys) {
// displayText = [NSString stringWithFormat:@"%@\r\n%@:%@", displayText, key, [event.content objectForKey:key]];
// }
// break;
// }
case MXEventTypeRoomAliases: {
NSArray *aliases = message.content[@"aliases"];
NSArray *aliases = event.content[@"aliases"];
if (aliases) {
displayText = [NSString stringWithFormat:@"The room aliases are: %@", aliases];
}
break;
}
case MXEventTypeRoomMessage: {
NSString *msgtype = message.content[@"msgtype"];
if ([msgtype isEqualToString:kMXMessageTypeText]) {
displayText = message.content[@"body"];
} else if ([msgtype isEqualToString:kMXMessageTypeEmote]) {
displayText = [NSString stringWithFormat:@"* %@ %@", memberDisplayName, message.content[@"body"]];
NSString *msgtype = event.content[@"msgtype"];
displayText = [event.content[@"body"] isKindOfClass:[NSString class]] ? event.content[@"body"] : nil;
if ([msgtype isEqualToString:kMXMessageTypeEmote]) {
displayText = [NSString stringWithFormat:@"* %@ %@", memberDisplayName, displayText];
} else if ([msgtype isEqualToString:kMXMessageTypeImage]) {
displayText = @"image attachment";
displayText = displayText? displayText : @"image attachment";
// Check attachment validity
if (![self isSupportedAttachment:event]) {
NSLog(@"ERROR: Unsupported attachment %@", event.description);
// Check whether unsupported/unexpected messages should be exposed
if (isSubtitle || [AppSettings sharedSettings].hideUnsupportedMessages) {
displayText = @"invalid image attachment";
} else {
// Display event content as unsupported message
displayText = [NSString stringWithFormat:@"%@%@", kMatrixHandlerUnsupportedMessagePrefix, event.description];
}
}
} else if ([msgtype isEqualToString:kMXMessageTypeAudio]) {
displayText = @"audio attachment";
displayText = displayText? displayText : @"audio attachment";
if (![self isSupportedAttachment:event]) {
NSLog(@"ERROR: Unsupported attachment %@", event.description);
if (isSubtitle || [AppSettings sharedSettings].hideUnsupportedMessages) {
displayText = @"invalid audio attachment";
} else {
displayText = [NSString stringWithFormat:@"%@%@", kMatrixHandlerUnsupportedMessagePrefix, event.description];
}
}
} else if ([msgtype isEqualToString:kMXMessageTypeVideo]) {
displayText = @"video attachment";
displayText = displayText? displayText : @"video attachment";
if (![self isSupportedAttachment:event]) {
NSLog(@"ERROR: Unsupported attachment %@", event.description);
if (isSubtitle || [AppSettings sharedSettings].hideUnsupportedMessages) {
displayText = @"invalid video attachment";
} else {
displayText = [NSString stringWithFormat:@"%@%@", kMatrixHandlerUnsupportedMessagePrefix, event.description];
}
}
} else if ([msgtype isEqualToString:kMXMessageTypeLocation]) {
displayText = @"location attachment";
displayText = displayText? displayText : @"location attachment";
if (![self isSupportedAttachment:event]) {
NSLog(@"ERROR: Unsupported attachment %@", event.description);
if (isSubtitle || [AppSettings sharedSettings].hideUnsupportedMessages) {
displayText = @"invalid location attachment";
} else {
displayText = [NSString stringWithFormat:@"%@%@", kMatrixHandlerUnsupportedMessagePrefix, event.description];
}
}
}
// Check whether the sender name has to be added
@@ -599,8 +647,8 @@ static MatrixHandler *sharedHandler = nil;
break;
}
case MXEventTypeRoomMessageFeedback: {
NSString *type = message.content[@"type"];
NSString *eventId = message.content[@"target_event_id"];
NSString *type = event.content[@"type"];
NSString *eventId = event.content[@"target_event_id"];
if (type && eventId) {
displayText = [NSString stringWithFormat:@"Feedback event (id: %@): %@", eventId, type];
}
@@ -612,13 +660,11 @@ static MatrixHandler *sharedHandler = nil;
break;
}
if (displayText == nil) {
NSLog(@"ERROR: Unsupported message %@)", message.description);
if (isSubtitle || [AppSettings sharedSettings].hideUnsupportedMessages) {
displayText = @"";
} else {
// Return event content as unsupported message
displayText = [NSString stringWithFormat:@"%@%@", kMatrixHandlerUnsupportedMessagePrefix, message.description];
if (!displayText) {
NSLog(@"ERROR: Unsupported event %@)", event.description);
if (!isSubtitle && ![AppSettings sharedSettings].hideUnsupportedMessages) {
// Return event content as unsupported event
displayText = [NSString stringWithFormat:@"%@%@", kMatrixHandlerUnsupportedMessagePrefix, event.description];
}
}