diff --git a/matrixConsole.xcodeproj/project.pbxproj b/matrixConsole.xcodeproj/project.pbxproj index 8d8b3dde0..16b5dd86b 100644 --- a/matrixConsole.xcodeproj/project.pbxproj +++ b/matrixConsole.xcodeproj/project.pbxproj @@ -22,6 +22,8 @@ F02900BB1A63C71E00356F7D /* ConsoleTools.m in Sources */ = {isa = PBXBuildFile; fileRef = F02900BA1A63C71E00356F7D /* ConsoleTools.m */; }; F02BCE231A1A5A2B00543B47 /* play.png in Resources */ = {isa = PBXBuildFile; fileRef = F02BCE221A1A5A2B00543B47 /* play.png */; }; F02D707619F1DC9E007B47D3 /* RoomMemberTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F02D707519F1DC9E007B47D3 /* RoomMemberTableCell.m */; }; + F030974C1A6580D70090BC00 /* icon_keyboard.png in Resources */ = {isa = PBXBuildFile; fileRef = F030974A1A6580D70090BC00 /* icon_keyboard.png */; }; + F030974D1A6580D70090BC00 /* icon_keyboard@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F030974B1A6580D70090BC00 /* icon_keyboard@2x.png */; }; F03C47111A02952800E445AB /* CustomAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = F03C47101A02952800E445AB /* CustomAlert.m */; }; F03EF5F619F171EB00A0EE52 /* HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F03EF5EB19F171EB00A0EE52 /* HomeViewController.m */; }; F03EF5F719F171EB00A0EE52 /* LoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F03EF5ED19F171EB00A0EE52 /* LoginViewController.m */; }; @@ -92,6 +94,8 @@ F02BCE221A1A5A2B00543B47 /* play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = play.png; sourceTree = ""; }; F02D707419F1DC9E007B47D3 /* RoomMemberTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomMemberTableCell.h; sourceTree = ""; }; F02D707519F1DC9E007B47D3 /* RoomMemberTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomMemberTableCell.m; sourceTree = ""; }; + F030974A1A6580D70090BC00 /* icon_keyboard.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_keyboard.png; sourceTree = ""; }; + F030974B1A6580D70090BC00 /* icon_keyboard@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon_keyboard@2x.png"; sourceTree = ""; }; F03C470F1A02952800E445AB /* CustomAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomAlert.h; sourceTree = ""; }; F03C47101A02952800E445AB /* CustomAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomAlert.m; sourceTree = ""; }; F03EF5EA19F171EB00A0EE52 /* HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeViewController.h; sourceTree = ""; }; @@ -187,6 +191,8 @@ F01628B519E298710071C473 /* Assets */ = { isa = PBXGroup; children = ( + F030974A1A6580D70090BC00 /* icon_keyboard.png */, + F030974B1A6580D70090BC00 /* icon_keyboard@2x.png */, F05C3A3C1A3F3D7F002B698E /* icon_users.png */, F05C3A3D1A3F3D7F002B698E /* icon_users@2x.png */, F0F90C6A1A325ABF00455977 /* icon_search@2x.png */, @@ -434,6 +440,8 @@ F013EEEC1A40D437002BB093 /* matrixConsole-Defaults.plist in Resources */, F07A80E919DD9DE700B621A1 /* LaunchScreen.xib in Resources */, F0CEA5AF19E6895E00E47915 /* tab_recents.png in Resources */, + F030974D1A6580D70090BC00 /* icon_keyboard@2x.png in Resources */, + F030974C1A6580D70090BC00 /* icon_keyboard.png in Resources */, F05C3A3F1A3F3D7F002B698E /* icon_users@2x.png in Resources */, F01628C319E29C660071C473 /* logo.png in Resources */, F01628C119E29C660071C473 /* default-profile.png in Resources */, diff --git a/matrixConsole/Assets/icon_keyboard.png b/matrixConsole/Assets/icon_keyboard.png new file mode 100644 index 000000000..f6aae79f7 Binary files /dev/null and b/matrixConsole/Assets/icon_keyboard.png differ diff --git a/matrixConsole/Assets/icon_keyboard@2x.png b/matrixConsole/Assets/icon_keyboard@2x.png new file mode 100644 index 000000000..4cbb14d56 Binary files /dev/null and b/matrixConsole/Assets/icon_keyboard@2x.png differ diff --git a/matrixConsole/Base.lproj/Main.storyboard b/matrixConsole/Base.lproj/Main.storyboard index 94b67438f..ebcaf5e53 100644 --- a/matrixConsole/Base.lproj/Main.storyboard +++ b/matrixConsole/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -60,6 +60,9 @@ + @@ -168,6 +171,7 @@ + @@ -1302,6 +1306,7 @@ + diff --git a/matrixConsole/View/RoomMessageTableCell.h b/matrixConsole/View/RoomMessageTableCell.h index ac6a83760..e00762c2a 100644 --- a/matrixConsole/View/RoomMessageTableCell.h +++ b/matrixConsole/View/RoomMessageTableCell.h @@ -46,6 +46,7 @@ @end @interface IncomingMessageTableCell : RoomMessageTableCell +@property (weak, nonatomic) IBOutlet UIImageView *typingBadge; @property (weak, nonatomic) IBOutlet UILabel *userNameLabel; @end diff --git a/matrixConsole/ViewController/RoomViewController.m b/matrixConsole/ViewController/RoomViewController.m index af6e8f5fa..08f61994b 100644 --- a/matrixConsole/ViewController/RoomViewController.m +++ b/matrixConsole/ViewController/RoomViewController.m @@ -62,6 +62,8 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; // Typing notification NSDate *lastTypingDate; NSTimer* typingTimer; + id typingNotifListener; + NSArray *typingUsers; // Back pagination BOOL isBackPaginationInProgress; @@ -154,6 +156,11 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; lastTypingDate = nil; [typingTimer invalidate]; typingTimer = nil; + if (typingNotifListener) { + [self.mxRoom removeListener:typingNotifListener]; + typingNotifListener = nil; + } + typingUsers = nil; // Release local echo resources pendingOutgoingEvents = nil; @@ -390,12 +397,18 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; return; } - // Remove potential listener - if (messagesListener && self.mxRoom) { - [self.mxRoom removeListener:messagesListener]; - messagesListener = nil; - [[AppSettings sharedSettings] removeObserver:self forKeyPath:@"hideUnsupportedMessages"]; - [[MatrixHandler sharedHandler] removeObserver:self forKeyPath:@"isResumeDone"]; + if (self.mxRoom) { + // Remove potential listener + if (messagesListener){ + [self.mxRoom removeListener:messagesListener]; + messagesListener = nil; + [[AppSettings sharedSettings] removeObserver:self forKeyPath:@"hideUnsupportedMessages"]; + [[MatrixHandler sharedHandler] removeObserver:self forKeyPath:@"isResumeDone"]; + } + typingUsers = nil; + if (typingNotifListener) { + [self.mxRoom removeListener:typingNotifListener]; + } } // The whole room history is flushed here to rebuild it from the current instant (live) messages = nil; @@ -565,6 +578,18 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; } }]; + // Add typing notification listener + typingNotifListener = [self.mxRoom listenToEventsOfTypes:@[kMXEventTypeStringTypingNotification] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + // Handle only live events + if (direction == MXEventDirectionForwards) { + // Refresh typing users list + typingUsers = self.mxRoom.typingUsers; + // Refresh tableView + [self.messagesTableView reloadData]; + } + }]; + typingUsers = self.mxRoom.typingUsers; + // Trigger a back pagination by reseting first backState to get room history from live [self.mxRoom resetBackState]; [self triggerBackPagination]; @@ -1534,6 +1559,8 @@ NSString *const kCmdResetUserPowerLevel = @"/deop"; // Display user's display name except if the name appears in the displayed text (see emote and membership event) incomingMsgCell.userNameLabel.hidden = (shouldHideSenderInfo || message.startsWithSenderName); incomingMsgCell.userNameLabel.text = message.senderName; + // Set typing badge visibility + incomingMsgCell.typingBadge.hidden = (cell.pictureView.hidden || ([typingUsers indexOfObject:message.senderId] == NSNotFound)); } else { // Add unsent label for failed components CGFloat yPosition = (message.messageType == RoomMessageTypeText) ? ROOM_MESSAGE_TEXTVIEW_MARGIN : -ROOM_MESSAGE_TEXTVIEW_MARGIN;