From 8072956eedc693b7cf690496a00c66d18b5b034e Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 13 Jan 2015 18:32:52 +0100 Subject: [PATCH] SYIOS-30 - iOS needs typing notifs like the web client We highlight here the avatar of the user who's typing --- matrixConsole.xcodeproj/project.pbxproj | 8 ++++ matrixConsole/Assets/icon_keyboard.png | Bin 0 -> 3305 bytes matrixConsole/Assets/icon_keyboard@2x.png | Bin 0 -> 550 bytes matrixConsole/Base.lproj/Main.storyboard | 7 +++- matrixConsole/View/RoomMessageTableCell.h | 1 + .../ViewController/RoomViewController.m | 39 +++++++++++++++--- 6 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 matrixConsole/Assets/icon_keyboard.png create mode 100644 matrixConsole/Assets/icon_keyboard@2x.png 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 0000000000000000000000000000000000000000..f6aae79f7a0e0fadd320277f728d4dedb0b77de0 GIT binary patch literal 3305 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 literal 0 HcmV?d00001 diff --git a/matrixConsole/Assets/icon_keyboard@2x.png b/matrixConsole/Assets/icon_keyboard@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..4cbb14d56e51f964a995fd9192ffab0f7effc23a GIT binary patch literal 550 zcmV+>0@?kEP)F^fO)4`5v9^2YvUpi*-fR+4g#~yi1o1Bq?XNIdif^cm(H>;TTeA5?%$OWZ#VVjuJIV z!$DE|huO|V8b*1a+gi;CJ2*IoOf(6I5=x8rgR`j7=??mV$U+#zaS-Vn!~q=zGZT7$ zWNMYqA@;Kny$N-^WZ0bVgpEV&&?jE*3nAsd6-xP6`?o^J0X}Sce-e0@wGQvjL^=$9 o< - + @@ -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;