Merge branch 'master' into patch-1
@@ -22,7 +22,10 @@ Denis Morozov <dmorozkn at gmail.com>
|
||||
* Fix default room avatar for an empty room #1044
|
||||
* PR #1090, PR #1113, PR #1123: UX improvements
|
||||
* PR #1132: Check email validity during reset password operation
|
||||
* VoIP improvements
|
||||
|
||||
Aram Sargsyan <aram.sargsyan.1997 at gmail.com>
|
||||
* PR #1341: Read receipts details
|
||||
|
||||
Nathan van Beelen <nathan at vanbeelen.org>
|
||||
* PR #1317: Dutch translation of the strings
|
||||
|
||||
|
||||
46
CHANGES.rst
@@ -1,3 +1,49 @@
|
||||
Changes in 0.4.3 (2017-07-05)
|
||||
===============================================
|
||||
|
||||
Improvement:
|
||||
* Update the application title with "Riot.im".
|
||||
|
||||
|
||||
Changes in 0.4.2 (2017-06-30)
|
||||
===============================================
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version (v0.5.2).
|
||||
* Chat: Expand read receipts when user taps on it #59, thanks to @aramsargsyan (#1341).
|
||||
* GA: Disable GA in debug as it pollutes stats and crashes.
|
||||
* Home: Display room name on 2 lines.
|
||||
|
||||
Bug fixes:
|
||||
* Fix: Crash when scrolling in the public rooms from Unified Search (#1355).
|
||||
* Chat screen: the message overlaps its timestamp.
|
||||
* Chat screen: several encryption icons are displayed on the same event.
|
||||
* Blank pages with random "unread msgs" bars whilst they load.
|
||||
* Fix a crash when rotating + debackgrounding the app (#1362).
|
||||
* Bug report: Remove the old requirement for an existing email account.
|
||||
* Crash report: Do not loose what the user typed when debackgrounding the app.
|
||||
|
||||
Changes in 0.4.1 (2017-06-23)
|
||||
===============================================
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version (v0.5.1).
|
||||
|
||||
Bug fixes:
|
||||
* Room Chat: Scrolling manually to the bottom of the no live timeline doesn't flip it to read/write view (#1312).
|
||||
* Enhancement - UX Rework: Update the buttons of the room expanded header (vector-im/riot-meta#76).
|
||||
* Contact search: Unexpected empty search result.
|
||||
* tap-on-tab should include the top-of-page location in its cycle of options (#1316).
|
||||
* Fix crash on decline button, thanks to @morozkin (#1330).
|
||||
* Room directory: stuck after the 20 first items (#1329).
|
||||
* Room directory: "No public rooms available" is displayed while loading (#1336).
|
||||
* Room directory: Clicking on "No public rooms available" make the app crash.
|
||||
* Crash when hitting a room header after some special steps (#1340).
|
||||
* Chat screen: the search icon is missing after switching in live from a non live timeline (#1344).
|
||||
* Crash when hitting room from unified search/browse directory (#1342).
|
||||
* tapping on an unread room on home page takes you to the wrong room (#1304).
|
||||
* Read marker: when being kicked, the "Jump to first unread message" shouldn't be displayed (#1338).
|
||||
|
||||
Changes in 0.4.0 (2017-06-16)
|
||||
===============================================
|
||||
|
||||
|
||||
2
Podfile
@@ -8,7 +8,7 @@ target "Riot" do
|
||||
|
||||
# Different flavours of pods to MatrixKit
|
||||
# The tagged version on which this version of Riot has been built
|
||||
pod 'MatrixKit', '0.5.0'
|
||||
pod 'MatrixKit', '0.5.2'
|
||||
|
||||
# The lastest release available on the CocoaPods repository
|
||||
#pod 'MatrixKit'
|
||||
|
||||
22
Podfile.lock
@@ -39,13 +39,13 @@ PODS:
|
||||
- GZIP (1.1.1)
|
||||
- HPGrowingTextView (1.1)
|
||||
- libPhoneNumber-iOS (0.9.10)
|
||||
- MatrixKit (0.5.0):
|
||||
- MatrixKit (0.5.2):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.17)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.10)
|
||||
- MatrixSDK (= 0.8.0)
|
||||
- MatrixSDK (0.8.0):
|
||||
- MatrixSDK (= 0.8.2)
|
||||
- MatrixSDK (0.8.2):
|
||||
- AFNetworking (~> 3.1.0)
|
||||
- GZIP (~> 1.1.1)
|
||||
- OLMKit (2.2.2):
|
||||
@@ -53,9 +53,9 @@ PODS:
|
||||
- OLMKit/olmcpp (= 2.2.2)
|
||||
- OLMKit/olmc (2.2.2)
|
||||
- OLMKit/olmcpp (2.2.2)
|
||||
- Realm (2.8.1):
|
||||
- Realm/Headers (= 2.8.1)
|
||||
- Realm/Headers (2.8.1)
|
||||
- Realm (2.8.3):
|
||||
- Realm/Headers (= 2.8.3)
|
||||
- Realm/Headers (2.8.3)
|
||||
- WebRTC (58.17.16937)
|
||||
|
||||
DEPENDENCIES:
|
||||
@@ -63,7 +63,7 @@ DEPENDENCIES:
|
||||
- DTCoreText
|
||||
- GBDeviceInfo (~> 4.3.0)
|
||||
- GoogleAnalytics
|
||||
- MatrixKit (= 0.5.0)
|
||||
- MatrixKit (= 0.5.2)
|
||||
- OLMKit
|
||||
- Realm (~> 2.8.1)
|
||||
- WebRTC (= 58.17.16937)
|
||||
@@ -78,12 +78,12 @@ SPEC CHECKSUMS:
|
||||
GZIP: f8beb59597f651e6970a45b816508a9c6d700b77
|
||||
HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19
|
||||
libPhoneNumber-iOS: f721ae4d5854bce60934f9fb9b0b28e8e68913cb
|
||||
MatrixKit: 3783ee9b8b049a05a5856c66f749319ec1592161
|
||||
MatrixSDK: 6d1bf7ffc4792622da5441b4ddc6d5c02a0675b3
|
||||
MatrixKit: daad23e5724d8f26a44a322f4d259a26b614ddc6
|
||||
MatrixSDK: 1f9b5fa6334485c431884d2d2ea9ac5f65557528
|
||||
OLMKit: b9d8c0ffee9ea8c45bc0aaa9afb47f93fba7efbd
|
||||
Realm: 2627602ad6818451f0cb8c2a6e072f7f10a5f360
|
||||
Realm: 3601ef091c8c499a31101d8563b991e75546cdce
|
||||
WebRTC: 1e9a85bf75509eec44be6478c64e9de65ac82332
|
||||
|
||||
PODFILE CHECKSUM: 24c0a0406f24e3ba56478f5e9322cda986a7c199
|
||||
PODFILE CHECKSUM: ba9311a74b4af32f75db5053d87c9f7181a42d17
|
||||
|
||||
COCOAPODS: 1.2.1
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
24B5103E1EFA7083004C6AD2 /* ReadReceiptsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24B5103D1EFA7083004C6AD2 /* ReadReceiptsViewController.m */; };
|
||||
24B510401EFA88CC004C6AD2 /* ReadReceiptsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 24B5103F1EFA88CC004C6AD2 /* ReadReceiptsViewController.xib */; };
|
||||
3205ED7D1E976C8A003D65FA /* DirectoryServerPickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3205ED7C1E976C8A003D65FA /* DirectoryServerPickerViewController.m */; };
|
||||
3205ED841E97725E003D65FA /* DirectoryServerTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3205ED821E97725E003D65FA /* DirectoryServerTableViewCell.m */; };
|
||||
3205ED851E97725E003D65FA /* DirectoryServerTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3205ED831E97725E003D65FA /* DirectoryServerTableViewCell.xib */; };
|
||||
@@ -422,6 +424,9 @@
|
||||
F083BEA21E7009ED00A9B29C /* TableViewCellWithPhoneNumberTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BD1B1E7009ED00A9B29C /* TableViewCellWithPhoneNumberTextField.m */; };
|
||||
F083BEA31E7009ED00A9B29C /* TableViewCellWithPhoneNumberTextField.xib in Resources */ = {isa = PBXBuildFile; fileRef = F083BD1C1E7009ED00A9B29C /* TableViewCellWithPhoneNumberTextField.xib */; };
|
||||
F083BEA51E70356E00A9B29C /* RiotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BB041E7005FD00A9B29C /* RiotTests.m */; };
|
||||
F0A4A1671EF7CB66003630DB /* members_list_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = F0A4A1641EF7CB66003630DB /* members_list_icon.png */; };
|
||||
F0A4A1681EF7CB66003630DB /* members_list_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0A4A1651EF7CB66003630DB /* members_list_icon@2x.png */; };
|
||||
F0A4A1691EF7CB66003630DB /* members_list_icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0A4A1661EF7CB66003630DB /* members_list_icon@3x.png */; };
|
||||
F0D869EB1EC455A100BB0A2B /* create_direct_chat.png in Resources */ = {isa = PBXBuildFile; fileRef = F0D869E81EC455A100BB0A2B /* create_direct_chat.png */; };
|
||||
F0D869EC1EC455A100BB0A2B /* create_direct_chat@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0D869E91EC455A100BB0A2B /* create_direct_chat@2x.png */; };
|
||||
F0D869ED1EC455A100BB0A2B /* create_direct_chat@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0D869EA1EC455A100BB0A2B /* create_direct_chat@3x.png */; };
|
||||
@@ -468,6 +473,9 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1129C74A281B080432B1A1A1 /* Pods-Riot.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Riot.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Riot/Pods-Riot.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
24B5103C1EFA7083004C6AD2 /* ReadReceiptsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadReceiptsViewController.h; sourceTree = "<group>"; };
|
||||
24B5103D1EFA7083004C6AD2 /* ReadReceiptsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReadReceiptsViewController.m; sourceTree = "<group>"; };
|
||||
24B5103F1EFA88CC004C6AD2 /* ReadReceiptsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ReadReceiptsViewController.xib; sourceTree = "<group>"; };
|
||||
3205ED7B1E976C8A003D65FA /* DirectoryServerPickerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryServerPickerViewController.h; sourceTree = "<group>"; };
|
||||
3205ED7C1E976C8A003D65FA /* DirectoryServerPickerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectoryServerPickerViewController.m; sourceTree = "<group>"; };
|
||||
3205ED811E97725E003D65FA /* DirectoryServerTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryServerTableViewCell.h; sourceTree = "<group>"; };
|
||||
@@ -1006,6 +1014,9 @@
|
||||
F083BD1C1E7009ED00A9B29C /* TableViewCellWithPhoneNumberTextField.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TableViewCellWithPhoneNumberTextField.xib; sourceTree = "<group>"; };
|
||||
F094A9A21B78D8F000B1FBBF /* Riot.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Riot.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F094A9BE1B78D8F000B1FBBF /* RiotTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RiotTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F0A4A1641EF7CB66003630DB /* members_list_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = members_list_icon.png; sourceTree = "<group>"; };
|
||||
F0A4A1651EF7CB66003630DB /* members_list_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "members_list_icon@2x.png"; sourceTree = "<group>"; };
|
||||
F0A4A1661EF7CB66003630DB /* members_list_icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "members_list_icon@3x.png"; sourceTree = "<group>"; };
|
||||
F0D869E81EC455A100BB0A2B /* create_direct_chat.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = create_direct_chat.png; sourceTree = "<group>"; };
|
||||
F0D869E91EC455A100BB0A2B /* create_direct_chat@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "create_direct_chat@2x.png"; sourceTree = "<group>"; };
|
||||
F0D869EA1EC455A100BB0A2B /* create_direct_chat@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "create_direct_chat@3x.png"; sourceTree = "<group>"; };
|
||||
@@ -1156,6 +1167,9 @@
|
||||
F083BB151E7009EC00A9B29C /* Images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F0A4A1641EF7CB66003630DB /* members_list_icon.png */,
|
||||
F0A4A1651EF7CB66003630DB /* members_list_icon@2x.png */,
|
||||
F0A4A1661EF7CB66003630DB /* members_list_icon@3x.png */,
|
||||
F0614A101EDEE65000F5DC9A /* cancel.png */,
|
||||
F0614A111EDEE65000F5DC9A /* cancel@2x.png */,
|
||||
F0614A121EDEE65000F5DC9A /* cancel@3x.png */,
|
||||
@@ -1576,6 +1590,9 @@
|
||||
F083BC541E7009EC00A9B29C /* StartChatViewController.xib */,
|
||||
F083BC551E7009EC00A9B29C /* UsersDevicesViewController.h */,
|
||||
F083BC561E7009EC00A9B29C /* UsersDevicesViewController.m */,
|
||||
24B5103C1EFA7083004C6AD2 /* ReadReceiptsViewController.h */,
|
||||
24B5103D1EFA7083004C6AD2 /* ReadReceiptsViewController.m */,
|
||||
24B5103F1EFA88CC004C6AD2 /* ReadReceiptsViewController.xib */,
|
||||
);
|
||||
path = ViewController;
|
||||
sourceTree = "<group>";
|
||||
@@ -2032,6 +2049,7 @@
|
||||
F083BD881E7009ED00A9B29C /* file_doc_icon@3x.png in Resources */,
|
||||
F083BDAB1E7009ED00A9B29C /* placeholder@2x.png in Resources */,
|
||||
F083BE4D1E7009ED00A9B29C /* RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib in Resources */,
|
||||
24B510401EFA88CC004C6AD2 /* ReadReceiptsViewController.xib in Resources */,
|
||||
F083BDC81E7009ED00A9B29C /* search_icon.png in Resources */,
|
||||
F083BDE91E7009ED00A9B29C /* ring.mp3 in Resources */,
|
||||
F083BE431E7009ED00A9B29C /* RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib in Resources */,
|
||||
@@ -2130,6 +2148,7 @@
|
||||
F083BD891E7009ED00A9B29C /* file_music_icon.png in Resources */,
|
||||
F083BDD11E7009ED00A9B29C /* settings_icon.png in Resources */,
|
||||
F083BD811E7009ED00A9B29C /* favourite@2x.png in Resources */,
|
||||
F0A4A1681EF7CB66003630DB /* members_list_icon@2x.png in Resources */,
|
||||
F083BD9F1E7009ED00A9B29C /* mod_icon@2x.png in Resources */,
|
||||
F083BD801E7009ED00A9B29C /* favourite.png in Resources */,
|
||||
F083BD4B1E7009ED00A9B29C /* camera_capture.png in Resources */,
|
||||
@@ -2266,6 +2285,7 @@
|
||||
F083BD631E7009ED00A9B29C /* direct_icon@2x.png in Resources */,
|
||||
F083BE991E7009ED00A9B29C /* MessagesSearchResultTextMsgBubbleCell.xib in Resources */,
|
||||
F083BD711E7009ED00A9B29C /* e2e_unencrypted.png in Resources */,
|
||||
F0A4A1671EF7CB66003630DB /* members_list_icon.png in Resources */,
|
||||
F083BE731E7009ED00A9B29C /* RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib in Resources */,
|
||||
F083BD251E7009ED00A9B29C /* admin_icon.png in Resources */,
|
||||
F083BDBE1E7009ED00A9B29C /* riot_icon@3x.png in Resources */,
|
||||
@@ -2328,6 +2348,7 @@
|
||||
F083BDE01E7009ED00A9B29C /* video_icon.png in Resources */,
|
||||
F083BD601E7009ED00A9B29C /* details_icon@2x.png in Resources */,
|
||||
F083BE5F1E7009ED00A9B29C /* RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib in Resources */,
|
||||
F0A4A1691EF7CB66003630DB /* members_list_icon@3x.png in Resources */,
|
||||
F083BE8D1E7009ED00A9B29C /* PreviewRoomTitleView.xib in Resources */,
|
||||
F083BD561E7009ED00A9B29C /* camera_video_capture.png in Resources */,
|
||||
F083BD651E7009ED00A9B29C /* directChatOff.png in Resources */,
|
||||
@@ -2445,6 +2466,7 @@
|
||||
F083BE761E7009ED00A9B29C /* RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m in Sources */,
|
||||
F083BE5A1E7009ED00A9B29C /* RoomIncomingAttachmentBubbleCell.m in Sources */,
|
||||
F083BE541E7009ED00A9B29C /* RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.m in Sources */,
|
||||
24B5103E1EFA7083004C6AD2 /* ReadReceiptsViewController.m in Sources */,
|
||||
F083BE621E7009ED00A9B29C /* RoomIncomingTextMsgWithoutSenderInfoBubbleCell.m in Sources */,
|
||||
F083BE881E7009ED00A9B29C /* RoomMemberTitleView.m in Sources */,
|
||||
F083BE701E7009ED00A9B29C /* RoomOutgoingTextMsgBubbleCell.m in Sources */,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -61,9 +62,10 @@ static RageShakeManager* sharedInstance = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)promptCrashReportInViewController:(UIViewController*)viewController {
|
||||
if ([MXLogger crashLog] && [MFMailComposeViewController canSendMail]) {
|
||||
|
||||
- (void)promptCrashReportInViewController:(UIViewController*)viewController
|
||||
{
|
||||
if ([MXLogger crashLog])
|
||||
{
|
||||
confirmationAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"bug_report_prompt", @"Vector", nil) message:nil style:MXKAlertStyleAlert];
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
@@ -101,14 +103,15 @@ static RageShakeManager* sharedInstance = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopShaking:(UIResponder*)responder {
|
||||
|
||||
- (void)stopShaking:(UIResponder*)responder
|
||||
{
|
||||
NSLog(@"[RageShakeManager] Stop shaking with [%@]", [responder class]);
|
||||
|
||||
if (isShaking && [AppDelegate theDelegate].isAppForeground && !confirmationAlert
|
||||
&& (([[NSDate date] timeIntervalSince1970] - startShakingTimeStamp) > RAGESHAKEMANAGER_MINIMUM_SHAKING_DURATION)) {
|
||||
|
||||
if ([responder isKindOfClass:[UIViewController class]] && [MFMailComposeViewController canSendMail]) {
|
||||
&& (([[NSDate date] timeIntervalSince1970] - startShakingTimeStamp) > RAGESHAKEMANAGER_MINIMUM_SHAKING_DURATION))
|
||||
{
|
||||
if ([responder isKindOfClass:[UIViewController class]])
|
||||
{
|
||||
confirmationAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"rage_shake_prompt", @"Vector", nil) message:nil style:MXKAlertStyleAlert];
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#import "SettingsViewController.h"
|
||||
#import "ContactDetailsViewController.h"
|
||||
|
||||
#import "BugReportViewController.h"
|
||||
|
||||
#import "NSBundle+MatrixKit.h"
|
||||
#import "MatrixSDK/MatrixSDK.h"
|
||||
|
||||
@@ -790,6 +792,11 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
|
||||
// Set Google Analytics dispatch interval to e.g. 20 seconds.
|
||||
gai.dispatchInterval = 20;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Disable GAI in debug as it pollutes stats and crashes in GA
|
||||
gai.dryRun = YES;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -824,6 +831,13 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
NSString *filePath = [MXLogger crashLog];
|
||||
if (filePath)
|
||||
{
|
||||
// Do not show the crash report dialog if it is already displayed
|
||||
if ([self.window.rootViewController.childViewControllers[0] isKindOfClass:[UINavigationController class]]
|
||||
&& [((UINavigationController*)self.window.rootViewController.childViewControllers[0]).visibleViewController isKindOfClass:[BugReportViewController class]])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *description = [[NSString alloc] initWithContentsOfFile:filePath
|
||||
usedEncoding:nil
|
||||
error:nil];
|
||||
@@ -2314,7 +2328,6 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
|
||||
// Release properly
|
||||
[currentCallViewController destroy];
|
||||
currentCallViewController = nil;
|
||||
|
||||
if (completion)
|
||||
{
|
||||
|
||||
BIN
Riot/Assets/Images/logo.png
Executable file → Normal file
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 6.9 KiB |
BIN
Riot/Assets/Images/logo@2x.png
Executable file → Normal file
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 24 KiB |
BIN
Riot/Assets/Images/logo@3x.png
Executable file → Normal file
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 38 KiB |
BIN
Riot/Assets/Images/members_list_icon.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Riot/Assets/Images/members_list_icon@2x.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Riot/Assets/Images/members_list_icon@3x.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
@@ -414,6 +414,10 @@
|
||||
"room_details_copy_room_address" = "Copy Room Address";
|
||||
"room_details_copy_room_url" = "Copy Room URL";
|
||||
|
||||
// Read Receipts
|
||||
"read_receipts_list" = "Read Receipts List";
|
||||
"receipt_status_read" = "Read: ";
|
||||
|
||||
// Media picker
|
||||
"media_picker_library" = "Library";
|
||||
"media_picker_select" = "Select";
|
||||
@@ -470,3 +474,5 @@
|
||||
"bug_report_send_screenshot" = "Send screenshot";
|
||||
"bug_report_progress_zipping" = "Collecting logs";
|
||||
"bug_report_progress_uploading" = "Uploading report";
|
||||
"bug_report_send" = "Send";
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<segue destination="nDS-pp-sWM" kind="show" identifier="showMemberDetails" id="cUw-vU-gJq"/>
|
||||
<segue destination="gkO-rP-nGK" kind="show" identifier="showContactDetails" action="showDetailViewController:sender:" id="f5u-Y1-7nt"/>
|
||||
<segue destination="ZZb-IS-a1F" kind="presentation" identifier="showUnknownDevices" id="wUx-4y-ybn"/>
|
||||
<segue destination="udm-55-AMb" kind="show" identifier="showContactPicker" id="Q6y-9M-Ugl"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="94y-cU-qQD" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
@@ -80,12 +81,12 @@
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<barButtonItem key="rightBarButtonItem" image="search_icon.png" id="Koy-mU-PTG" userLabel="Menu Bar Button Item"/>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="roomTitleViewContainer" destination="djN-zB-Vni" id="VQG-Mp-hSa"/>
|
||||
<segue destination="nDS-pp-sWM" kind="show" identifier="showMemberDetails" id="fNQ-S3-DbZ"/>
|
||||
<segue destination="gkO-rP-nGK" kind="show" identifier="showContactDetails" id="ziz-Xl-QVg"/>
|
||||
<segue destination="e7G-NU-7ck" kind="show" identifier="showRoomDetails" id="mFs-HA-7Oo"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Yjg-uP-Hcy" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
@@ -153,7 +154,7 @@
|
||||
<tableViewController id="e7G-NU-7ck" customClass="SegmentedViewController" sceneMemberID="viewController"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="fXh-hO-Zgf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2558" y="-546"/>
|
||||
<point key="canvasLocation" x="3326" y="-442"/>
|
||||
</scene>
|
||||
<!--People View Controller-->
|
||||
<scene sceneID="Qba-PP-lco">
|
||||
@@ -396,7 +397,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="01q-h6-40E" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3326" y="-420"/>
|
||||
<point key="canvasLocation" x="5046" y="-711"/>
|
||||
</scene>
|
||||
<!--RoomNav-->
|
||||
<scene sceneID="r7l-gg-dq7">
|
||||
@@ -524,6 +525,24 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1385" y="180"/>
|
||||
</scene>
|
||||
<!--Contacts Table View Controller-->
|
||||
<scene sceneID="2zi-xJ-RQo">
|
||||
<objects>
|
||||
<viewController id="udm-55-AMb" customClass="ContactsTableViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Jch-ZS-1Mm"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="7q1-ig-sPp"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="6G9-nj-ktC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="uv3-zI-b3q" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="374" y="449"/>
|
||||
</scene>
|
||||
<!--Directory Server Picker View Controller-->
|
||||
<scene sceneID="t8d-GX-ntZ">
|
||||
<objects>
|
||||
@@ -558,9 +577,10 @@
|
||||
<image name="tab_rooms_selected.png" width="25" height="25"/>
|
||||
</resources>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="0ws-cL-0tk"/>
|
||||
<segue reference="tk8-vF-K4T"/>
|
||||
<segue reference="Tfl-tq-LQp"/>
|
||||
<segue reference="ziz-Xl-QVg"/>
|
||||
<segue reference="mFs-HA-7Oo"/>
|
||||
<segue reference="fNQ-S3-DbZ"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
</document>
|
||||
|
||||
@@ -23,6 +23,13 @@
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellRiotEditButtonPressed;
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on receipts area.
|
||||
|
||||
The 'userInfo' disctionary contains an 'MXKReceiptSendersContainer' object under the 'kMXKRoomBubbleCellReceiptsContainerKey' key, representing the receipts container which was tapped on.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnReceiptsContainer;
|
||||
|
||||
/**
|
||||
Define a `MXKRoomBubbleTableViewCell` category at Riot level to handle bubble customisation.
|
||||
*/
|
||||
@@ -56,6 +63,11 @@ extern NSString *const kMXKRoomBubbleCellRiotEditButtonPressed;
|
||||
*/
|
||||
- (void)addDateLabel;
|
||||
|
||||
/**
|
||||
Called when the user taps on the Receipt Container.
|
||||
*/
|
||||
- (IBAction)onReceiptContainerTap:(UITapGestureRecognizer *)sender;
|
||||
|
||||
/**
|
||||
Blur the view by adding a transparent overlay. Default is NO.
|
||||
*/
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define VECTOR_ROOMBUBBLETABLEVIEWCELL_MARK_WIDTH 4
|
||||
|
||||
NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRiotEditButtonPressed";
|
||||
NSString *const kMXKRoomBubbleCellTapOnReceiptsContainer = @"kMXKRoomBubbleCellTapOnReceiptsContainer";
|
||||
|
||||
@implementation MXKRoomBubbleTableViewCell (Riot)
|
||||
|
||||
@@ -47,8 +48,15 @@ NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRi
|
||||
|
||||
if (component && component.date)
|
||||
{
|
||||
// Check whether this is the first displayed component.
|
||||
BOOL isFirstDisplayedComponent = (componentIndex == 0);
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
isFirstDisplayedComponent = (componentIndex == ((RoomBubbleCellData*)bubbleData).oldestComponentIndex);
|
||||
}
|
||||
|
||||
CGFloat timeLabelPosX = self.bubbleInfoContainer.frame.size.width - VECTOR_ROOMBUBBLETABLEVIEWCELL_TIMELABEL_WIDTH;
|
||||
CGFloat timeLabelPosY = componentIndex ? component.position.y + self.msgTextViewTopConstraint.constant - self.bubbleInfoContainerTopConstraint.constant: 0;
|
||||
CGFloat timeLabelPosY = isFirstDisplayedComponent ? 0 : component.position.y + self.msgTextViewTopConstraint.constant - self.bubbleInfoContainerTopConstraint.constant;
|
||||
UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(timeLabelPosX, timeLabelPosY, VECTOR_ROOMBUBBLETABLEVIEWCELL_TIMELABEL_WIDTH , 18)];
|
||||
|
||||
timeLabel.text = [bubbleData.eventFormatter timeStringFromDate:component.date];
|
||||
@@ -104,7 +112,7 @@ NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRi
|
||||
[NSLayoutConstraint activateConstraints:@[rightConstraint, topConstraint, widthConstraint, heightConstraint]];
|
||||
|
||||
// Check whether a vertical whitespace was applied to display correctly the timestamp.
|
||||
if (componentIndex || bubbleData.shouldHideSenderInformation || bubbleData.shouldHideSenderName)
|
||||
if (!isFirstDisplayedComponent || bubbleData.shouldHideSenderInformation || bubbleData.shouldHideSenderName)
|
||||
{
|
||||
// Adjust the position of the potential encryption icon in this case.
|
||||
if (self.encryptionStatusContainerView)
|
||||
@@ -146,7 +154,7 @@ NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRi
|
||||
|
||||
// Retrieve the read receipts container related to the selected component (if any)
|
||||
// Blur the others
|
||||
for (UIView* view in self.bubbleOverlayContainer.subviews)
|
||||
for (UIView* view in self.tmpSubviews)
|
||||
{
|
||||
// Note read receipt container tag is equal to the index of the related component.
|
||||
if (view.tag != componentIndex)
|
||||
@@ -171,18 +179,29 @@ NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRi
|
||||
// Define the marker frame
|
||||
CGFloat markPosY = component.position.y + self.msgTextViewTopConstraint.constant;
|
||||
|
||||
CGFloat markHeight;
|
||||
if (componentIndex == bubbleComponents.count - 1)
|
||||
NSInteger mostRecentComponentIndex = bubbleComponents.count - 1;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
// There is no component after this component in the cell,
|
||||
// use the rest of the cell height
|
||||
markHeight = self.contentView.frame.size.height - markPosY;
|
||||
mostRecentComponentIndex = ((RoomBubbleCellData*)bubbleData).mostRecentComponentIndex;
|
||||
}
|
||||
else
|
||||
|
||||
// Compute the mark height.
|
||||
// Use the rest of the cell height by default.
|
||||
CGFloat markHeight = self.contentView.frame.size.height - markPosY;
|
||||
if (componentIndex != mostRecentComponentIndex)
|
||||
{
|
||||
// There is another component (with display) after this component in the cell.
|
||||
// Stop the marker height to the top of this component.
|
||||
for (NSInteger index = componentIndex + 1; index < bubbleComponents.count; index ++)
|
||||
{
|
||||
MXKRoomBubbleComponent *nextComponent = bubbleComponents[index];
|
||||
|
||||
if (nextComponent.attributedTextMessage)
|
||||
{
|
||||
// Stop the marker height to the top of the next component in the cell
|
||||
MXKRoomBubbleComponent *nextComponent = bubbleComponents[componentIndex + 1];
|
||||
markHeight = nextComponent.position.y - component.position.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UIView *markerView = [[UIView alloc] initWithFrame:CGRectMake(VECTOR_ROOMBUBBLETABLEVIEWCELL_MARK_X,
|
||||
@@ -305,11 +324,14 @@ NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRi
|
||||
self.bubbleOverlayContainer.alpha = 0.8;
|
||||
self.bubbleOverlayContainer.userInteractionEnabled = YES;
|
||||
|
||||
// Blur read receipts if any
|
||||
// Blur subviews if any
|
||||
for (UIView* view in self.bubbleOverlayContainer.subviews)
|
||||
{
|
||||
view.alpha = 0.2;
|
||||
}
|
||||
|
||||
// Move this view in front
|
||||
[self.contentView bringSubviewToFront:self.bubbleOverlayContainer];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -320,7 +342,7 @@ NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRi
|
||||
self.bubbleOverlayContainer.alpha = 1;
|
||||
self.bubbleOverlayContainer.userInteractionEnabled = NO;
|
||||
|
||||
// Restore read receipts display
|
||||
// Restore subviews display
|
||||
for (UIView* view in self.bubbleOverlayContainer.subviews)
|
||||
{
|
||||
view.alpha = 1;
|
||||
@@ -388,16 +410,31 @@ NSString *const kMXKRoomBubbleCellRiotEditButtonPressed = @"kMXKRoomBubbleCellRi
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)onReceiptContainerTap:(UITapGestureRecognizer *)sender
|
||||
{
|
||||
if (self.delegate)
|
||||
{
|
||||
[self.delegate cell:self didRecognizeAction:kMXKRoomBubbleCellTapOnReceiptsContainer userInfo:@{kMXKRoomBubbleCellReceiptsContainerKey : sender.view}];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Internals
|
||||
|
||||
- (void)addEditButtonForComponent:(NSUInteger)componentIndex completion:(void (^ __nullable)(BOOL finished))completion
|
||||
{
|
||||
MXKRoomBubbleComponent *component = bubbleData.bubbleComponents[componentIndex];
|
||||
|
||||
// Check whether this is the first displayed component.
|
||||
BOOL isFirstDisplayedComponent = (componentIndex == 0);
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
isFirstDisplayedComponent = (componentIndex == ((RoomBubbleCellData*)bubbleData).oldestComponentIndex);
|
||||
}
|
||||
|
||||
// Define 'Edit' button frame
|
||||
UIImage *editIcon = [UIImage imageNamed:@"edit_icon"];
|
||||
CGFloat editBtnPosX = self.bubbleInfoContainer.frame.size.width - VECTOR_ROOMBUBBLETABLEVIEWCELL_TIMELABEL_WIDTH - 22 - editIcon.size.width / 2;
|
||||
CGFloat editBtnPosY = componentIndex ? component.position.y + self.msgTextViewTopConstraint.constant - self.bubbleInfoContainerTopConstraint.constant - 13 : -13;
|
||||
CGFloat editBtnPosY = isFirstDisplayedComponent ? -13 : component.position.y + self.msgTextViewTopConstraint.constant - self.bubbleInfoContainerTopConstraint.constant - 13;
|
||||
UIButton *editButton = [[UIButton alloc] initWithFrame:CGRectMake(editBtnPosX, editBtnPosY, 44, 44)];
|
||||
|
||||
[editButton setImage:editIcon forState:UIControlStateNormal];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Riot</string>
|
||||
<string>Riot.im</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -17,11 +17,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.4.0</string>
|
||||
<string>0.4.3</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.4.0</string>
|
||||
<string>0.4.3</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<true/>
|
||||
<key>ITSEncryptionExportComplianceCode</key>
|
||||
|
||||
@@ -148,14 +148,13 @@
|
||||
{
|
||||
// Update search results.
|
||||
searchText = [searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
NSMutableArray<MXKContact*> *unfilteredLocalContacts;
|
||||
NSMutableArray<MXKContact*> *unfilteredMatrixContacts;
|
||||
|
||||
searchProcessingCount++;
|
||||
|
||||
if (!searchText.length)
|
||||
{
|
||||
searchProcessingLocalContacts = nil;
|
||||
searchProcessingMatrixContacts = nil;
|
||||
|
||||
// Disclose by default the sections if a search was in progress.
|
||||
if (searchProcessingText.length)
|
||||
{
|
||||
@@ -164,11 +163,9 @@
|
||||
}
|
||||
else if (forceRefresh || !searchProcessingText.length || [searchText hasPrefix:searchProcessingText] == NO)
|
||||
{
|
||||
// Retrieve all the local contacts
|
||||
searchProcessingLocalContacts = [self unfilteredLocalContactsArray];
|
||||
|
||||
// Retrieve all known matrix users
|
||||
searchProcessingMatrixContacts = [self unfilteredMatrixContactsArray];
|
||||
// Prepare on the main thread the arrays used to initialize the search on the processing queue.
|
||||
unfilteredLocalContacts = [self unfilteredLocalContactsArray];
|
||||
unfilteredMatrixContacts = [self unfilteredMatrixContactsArray];
|
||||
|
||||
// Disclose the sections
|
||||
shrinkedSectionsBitMask = 0;
|
||||
@@ -176,6 +173,18 @@
|
||||
|
||||
dispatch_async(searchProcessingQueue, ^{
|
||||
|
||||
// Reset the current arrays if it is required
|
||||
if (!searchText.length)
|
||||
{
|
||||
searchProcessingLocalContacts = nil;
|
||||
searchProcessingMatrixContacts = nil;
|
||||
}
|
||||
else if (unfilteredLocalContacts)
|
||||
{
|
||||
searchProcessingLocalContacts = unfilteredLocalContacts;
|
||||
searchProcessingMatrixContacts = unfilteredMatrixContacts;
|
||||
}
|
||||
|
||||
for (NSUInteger index = 0; index < searchProcessingLocalContacts.count;)
|
||||
{
|
||||
MXKContact* contact = searchProcessingLocalContacts[index];
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
*/
|
||||
@property(nonatomic) NSString *selectedEventId;
|
||||
|
||||
/**
|
||||
The index of the oldest component (component with a timestamp, and an actual display). NSNotFound by default.
|
||||
*/
|
||||
@property(nonatomic, readonly) NSInteger oldestComponentIndex;
|
||||
|
||||
/**
|
||||
The index of the most recent component (component with a timestamp, and an actual display). NSNotFound by default.
|
||||
*/
|
||||
|
||||
@@ -348,6 +348,27 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)oldestComponentIndex
|
||||
{
|
||||
// Update the related component index
|
||||
NSInteger oldestComponentIndex = NSNotFound;
|
||||
|
||||
NSArray *components = self.bubbleComponents;
|
||||
NSInteger index = 0;
|
||||
while (index < components.count)
|
||||
{
|
||||
MXKRoomBubbleComponent *component = components[index];
|
||||
if (component.attributedTextMessage && component.date)
|
||||
{
|
||||
oldestComponentIndex = index;
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return oldestComponentIndex;
|
||||
}
|
||||
|
||||
- (NSInteger)mostRecentComponentIndex
|
||||
{
|
||||
// Update the related component index
|
||||
|
||||
@@ -144,13 +144,8 @@
|
||||
// Ignore the read receipts on the bubble without actual display.
|
||||
if ((self.showBubbleReceipts && cellData.hasReadReceipts) || self.showReadMarker)
|
||||
{
|
||||
// Read receipts container are inserted here on the right side into the overlay container.
|
||||
// Read receipts container are inserted here on the right side into the content view.
|
||||
// Some vertical whitespaces are added in message text view (see RoomBubbleCellData class) to insert correctly multiple receipts.
|
||||
bubbleCell.bubbleOverlayContainer.backgroundColor = [UIColor clearColor];
|
||||
bubbleCell.bubbleOverlayContainer.alpha = 1;
|
||||
bubbleCell.bubbleOverlayContainer.userInteractionEnabled = NO;
|
||||
bubbleCell.bubbleOverlayContainer.hidden = NO;
|
||||
|
||||
NSInteger index = bubbleComponents.count;
|
||||
CGFloat bottomPositionY = bubbleCell.frame.size.height;
|
||||
while (index--)
|
||||
@@ -199,10 +194,26 @@
|
||||
avatarsContainer.tag = index;
|
||||
|
||||
[avatarsContainer refreshReceiptSenders:roomMembers withPlaceHolders:placeholders andAlignment:ReadReceiptAlignmentRight];
|
||||
avatarsContainer.readReceipts = receipts;
|
||||
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:cell action:@selector(onReceiptContainerTap:)];
|
||||
[tapRecognizer setNumberOfTapsRequired:1];
|
||||
[tapRecognizer setNumberOfTouchesRequired:1];
|
||||
[avatarsContainer addGestureRecognizer:tapRecognizer];
|
||||
avatarsContainer.userInteractionEnabled = YES;
|
||||
|
||||
avatarsContainer.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
avatarsContainer.accessibilityIdentifier = @"readReceiptsContainer";
|
||||
[bubbleCell.bubbleOverlayContainer addSubview:avatarsContainer];
|
||||
|
||||
// Add this read receipts container in the content view
|
||||
if (!bubbleCell.tmpSubviews)
|
||||
{
|
||||
bubbleCell.tmpSubviews = [NSMutableArray arrayWithArray:@[avatarsContainer]];
|
||||
}
|
||||
else
|
||||
{
|
||||
[bubbleCell.tmpSubviews addObject:avatarsContainer];
|
||||
}
|
||||
[bubbleCell.contentView addSubview:avatarsContainer];
|
||||
|
||||
// Force receipts container size
|
||||
NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:avatarsContainer
|
||||
@@ -224,14 +235,14 @@
|
||||
NSLayoutConstraint *trailingConstraint = [NSLayoutConstraint constraintWithItem:avatarsContainer
|
||||
attribute:NSLayoutAttributeTrailing
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:bubbleCell.bubbleOverlayContainer
|
||||
toItem:avatarsContainer.superview
|
||||
attribute:NSLayoutAttributeTrailing
|
||||
multiplier:1.0
|
||||
constant:-6];
|
||||
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:avatarsContainer
|
||||
attribute:NSLayoutAttributeTop
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:bubbleCell.bubbleOverlayContainer
|
||||
toItem:avatarsContainer.superview
|
||||
attribute:NSLayoutAttributeTop
|
||||
multiplier:1.0
|
||||
constant:bottomPositionY - 13];
|
||||
@@ -244,6 +255,13 @@
|
||||
// Check whether the read marker must be displayed here.
|
||||
if (self.showReadMarker)
|
||||
{
|
||||
// The read marker is added into the overlay container.
|
||||
// CAUTION: Keep disabled the user interaction on this container to not disturb tap gesture handling.
|
||||
bubbleCell.bubbleOverlayContainer.backgroundColor = [UIColor clearColor];
|
||||
bubbleCell.bubbleOverlayContainer.alpha = 1;
|
||||
bubbleCell.bubbleOverlayContainer.userInteractionEnabled = NO;
|
||||
bubbleCell.bubbleOverlayContainer.hidden = NO;
|
||||
|
||||
if ([component.event.eventId isEqualToString:self.room.accountData.readMarkerEventId])
|
||||
{
|
||||
bubbleCell.readMarkerView = [[UIView alloc] initWithFrame:CGRectMake(0, bottomPositionY - 2, bubbleCell.bubbleOverlayContainer.frame.size.width, 2)];
|
||||
|
||||
@@ -214,6 +214,10 @@ double const kPublicRoomsDirectoryDataExpiration = 10;
|
||||
{
|
||||
if (_hasReachedPaginationEnd)
|
||||
{
|
||||
if (complete)
|
||||
{
|
||||
complete(0);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -339,6 +343,8 @@ double const kPublicRoomsDirectoryDataExpiration = 10;
|
||||
tableViewCell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
}
|
||||
|
||||
if (state == MXKDataSourceStateReady)
|
||||
{
|
||||
if (_searchPattern.length)
|
||||
{
|
||||
tableViewCell.textLabel.text = NSLocalizedStringFromTable(@"search_no_result", @"Vector", nil);
|
||||
@@ -347,6 +353,12 @@ double const kPublicRoomsDirectoryDataExpiration = 10;
|
||||
{
|
||||
tableViewCell.textLabel.text = NSLocalizedStringFromTable(@"room_directory_no_public_room", @"Vector", nil);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show nothing while loading and in other cases
|
||||
tableViewCell.textLabel.text = @"";
|
||||
}
|
||||
|
||||
return tableViewCell;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina5_5" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -48,11 +48,11 @@
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="5rn-KE-plm">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="k7D-Gy-yBR">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="GiL-7R-Wm2"/>
|
||||
</constraints>
|
||||
@@ -71,31 +71,31 @@
|
||||
</userDefinedRuntimeAttributes>
|
||||
</navigationBar>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="izX-ya-hXh">
|
||||
<rect key="frame" x="0.0" y="63" width="375" height="1"/>
|
||||
<rect key="frame" x="0.0" y="63" width="414" height="1"/>
|
||||
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="ZiW-uP-cgo"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" keyboardDismissMode="onDrag" translatesAutoresizingMaskIntoConstraints="NO" id="OHV-KQ-Ww0">
|
||||
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
|
||||
<rect key="frame" x="0.0" y="64" width="414" height="672"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rhx-dD-4EJ" userLabel="Content View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="485"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="d8r-TX-pwX" userLabel="Welcome Image View">
|
||||
<rect key="frame" x="127.5" y="25" width="120" height="99"/>
|
||||
<rect key="frame" x="127.66666666666666" y="25" width="120" height="101"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCWelcomeImageView"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="120" id="ZFx-Mn-Kzq"/>
|
||||
<constraint firstAttribute="height" constant="99" id="zA1-WN-LdU"/>
|
||||
<constraint firstAttribute="height" constant="101" id="zA1-WN-LdU"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xWb-IJ-v7F" userLabel="AuthInputsContainerView">
|
||||
<rect key="frame" x="0.0" y="160" width="375" height="200"/>
|
||||
<subviews>
|
||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="30E-gm-z6O">
|
||||
<rect key="frame" x="177.5" y="90" width="20" height="20"/>
|
||||
<rect key="frame" x="177.66666666666666" y="90" width="20" height="20"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="AuthenticationVCActivityIndicator"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
@@ -107,7 +107,7 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wIH-Kd-r7q" userLabel="retryButton">
|
||||
<rect key="frame" x="165.5" y="30" width="45" height="30"/>
|
||||
<rect key="frame" x="165.66666666666666" y="30" width="45" height="30"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCRetryButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="30" id="WtO-NT-ei8"/>
|
||||
@@ -391,10 +391,10 @@
|
||||
</userDefinedRuntimeAttributes>
|
||||
</scrollView>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="q1e-Wg-6t7" userLabel="Authentication Fallback ContentView">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<rect key="frame" x="0.0" y="20" width="414" height="716"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9qj-5c-Sfb">
|
||||
<rect key="frame" x="317" y="5" width="50" height="35"/>
|
||||
<rect key="frame" x="356" y="5" width="50" height="35"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCCancelAuthFallbackButton"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="50" id="GMq-PF-fBv"/>
|
||||
@@ -408,7 +408,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<webView contentMode="scaleToFill" scalesPageToFit="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vhh-m0-nXN" userLabel="fallback WebView" customClass="MXKAuthenticationFallbackWebView">
|
||||
<rect key="frame" x="0.0" y="40" width="375" height="607"/>
|
||||
<rect key="frame" x="0.0" y="40" width="414" height="676"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="accessibilityIdentifier" value="AuthenticationVCFallbackWebView"/>
|
||||
@@ -448,7 +448,7 @@
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="logo.png" width="120" height="99"/>
|
||||
<image name="logo.png" width="120" height="101"/>
|
||||
<image name="selection_untick.png" width="22" height="22"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -90,6 +90,11 @@
|
||||
_sendButton.enabled = NO;
|
||||
}
|
||||
|
||||
[_cancelButton setTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] forState:UIControlStateNormal];
|
||||
[_cancelButton setTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] forState:UIControlStateHighlighted];
|
||||
[_sendButton setTitle:NSLocalizedStringFromTable(@"bug_report_send", @"Vector", nil) forState:UIControlStateNormal];
|
||||
[_sendButton setTitle:NSLocalizedStringFromTable(@"bug_report_send", @"Vector", nil) forState:UIControlStateHighlighted];
|
||||
|
||||
_sendingContainer.hidden = YES;
|
||||
|
||||
self.sendLogs = YES;
|
||||
@@ -127,6 +132,8 @@
|
||||
{
|
||||
[super viewWillDisappear:animated];
|
||||
|
||||
[self dismissKeyboard];
|
||||
|
||||
if (screenShotFile)
|
||||
{
|
||||
[[NSFileManager defaultManager] removeItemAtURL:screenShotFile error:nil];
|
||||
@@ -161,6 +168,12 @@
|
||||
}
|
||||
|
||||
#pragma mark - MXKViewController
|
||||
- (void)dismissKeyboard
|
||||
{
|
||||
// Hide the keyboard
|
||||
[_bugReportDescriptionTextView resignFirstResponder];
|
||||
}
|
||||
|
||||
- (void)onKeyboardShowAnimationComplete
|
||||
{
|
||||
self.keyboardView = _bugReportDescriptionTextView.inputAccessoryView.superview;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina5_5" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -102,7 +102,7 @@
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="252" verticalHuggingPriority="251" image="imageView:hcc-ve-8OC:image" translatesAutoresizingMaskIntoConstraints="NO" id="hcc-ve-8OC">
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="252" verticalHuggingPriority="251" image="selection_tick.png" translatesAutoresizingMaskIntoConstraints="NO" id="hcc-ve-8OC">
|
||||
<rect key="frame" x="20" y="1" width="22" height="22"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
@@ -125,7 +125,7 @@
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="252" verticalHuggingPriority="251" image="imageView:hcc-ve-8OC:image" translatesAutoresizingMaskIntoConstraints="NO" id="wmW-9T-6xp">
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="252" verticalHuggingPriority="251" image="selection_tick.png" translatesAutoresizingMaskIntoConstraints="NO" id="wmW-9T-6xp">
|
||||
<rect key="frame" x="20" y="1" width="22" height="21.999999999999943"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
@@ -243,88 +243,6 @@
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="imageView:hcc-ve-8OC:image" width="22" height="22">
|
||||
<mutableData key="keyedArchiveRepresentation">
|
||||
YnBsaXN0MDDUAQIDBAUGPT5YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK4HCBMU
|
||||
GR4fIyQrLjE3OlUkbnVsbNUJCgsMDQ4PEBESVk5TU2l6ZVYkY2xhc3NcTlNJbWFnZUZsYWdzVk5TUmVw
|
||||
c1dOU0NvbG9ygAKADRIgwAAAgAOAC1h7MjIsIDIyfdIVChYYWk5TLm9iamVjdHOhF4AEgArSFQoaHaIb
|
||||
HIAFgAaACRAA0iAKISJfEBROU1RJRkZSZXByZXNlbnRhdGlvboAHgAhPERAuTU0AKgAAB5gAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAADiEXLCliRX8/mGnGTbh97E22fuw/mGnGKWJFfw4hFywAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASLR87OIlfr1C+hPJWzY//VcmM
|
||||
/1TIi/9UyIv/VcmM/1bNj/9QvoTyOIlfrxItHzsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAEEAgYoYkR/UcKH9ljPkP9VyYv/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VcmL/1jPkP9Rwof2KGJE
|
||||
fwEEAgYAAAAAAAAAAAAAAAAAAAAAAAAAAAEEAgYyeFOcV8+Q/1XJjP9Uxor/VMaK/1TGiv9Uxor/VMaK
|
||||
/1TGiv9Uxor/VMaK/1TGiv9Uxor/VcmM/1fPkP8yeFOcAQQCBgAAAAAAAAAAAAAAAAAAAAAoYkR/V8+Q
|
||||
/1TIi/9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9UyIv/V8+Q
|
||||
/yhiRH8AAAAAAAAAAAAAAAASLR46UsOH91XJjP9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK
|
||||
/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1XJjP9Sw4f3Ei0eOgAAAAABAgIEOYlfslfPkP9Uxor/VMaK
|
||||
/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1PGif9Uxor/UsWJ/1TGiv9Uxor/V8+Q
|
||||
/zmJX7IBAgIEDSAWK1C/hfRVyYv/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK
|
||||
/1LFif9XyIz/uenQ/5XfuP9Txon/VMaK/1XJi/9Qv4X0DSAWKyhiRX9WzY//VMaK/1TGiv9Uxor/VMaK
|
||||
/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1LFif9Xxoz/vOrT///////i9uz/X8uS/1PGif9Uxor/Vs2P
|
||||
/yhiRX8/mGnGVcmM/1TGiv9Uxor/VMaK/1TGiv9Uxor/U8aJ/1TGiv9Uxor/VMaK/1LFif9XyIz/vOrT
|
||||
///////p+PH/ctKg/1HFiP9Uxor/VMaK/1XJjP8/mGnGTrd+7VTIiv9Uxor/VMaK/1TGiv9Uxor/U8aK
|
||||
/1nJj/9RxYn/VMaK/1LFif9XyIz/vOrT///////p+PD/cdGf/0/Eh/9Uxor/VMaK/1TGiv9UyIr/Trd+
|
||||
7U22fuxUyIr/VMaK/1TGiv9Uxor/U8aJ/57hv//X8+X/Zs2X/07Ehv9XyIz/wOvV///////n+O//b8+e
|
||||
/0/Eh/9Uxor/VMaK/1TGiv9Uxor/VMiK/022fuw/mmnGVcmM/1TGiv9Uxor/U8aK/1fIjP/K79z/////
|
||||
/9nz5v9s0Jz/uurR///////m9+//b9Ge/0/Eh/9Uxor/VMaK/1TGiv9Uxor/VMaK/1XJjP8/mmnGKGJF
|
||||
f1bNj/9Uxor/VMaK/1TGiv9SxYn/X8qT/8zw3///////9fv3///////n+O//b9Ge/0/Eh/9Uxor/VMaK
|
||||
/1TGiv9Uxor/VMaK/1TGiv9WzY//KGJFfw0gFitQv4X0VcmL/1TGiv9Uxor/VMaK/1HFiP9eypL/zPDf
|
||||
///////o+PD/b9Ge/0/Eh/9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9VyYv/UL+F9A0gFisBAgIEOohf
|
||||
sVfPkP9Uxor/VMaK/1TGiv9Uxor/UcWI/2DLk/+76tH/ddOj/0/Fh/9Uxor/VMaK/1TGiv9Uxor/VMaK
|
||||
/1TGiv9Uxor/V8+Q/zqIX7EBAgIEAAAAABItHjpSw4f3VcmM/1TGiv9Uxor/VMaK/1TGiv9SxYn/UsWI
|
||||
/1LFiP9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VcmM/1LDh/cSLR46AAAAAAAAAAAAAAAAKGJE
|
||||
f1fPkP9UyIv/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9Uxor/VMiL
|
||||
/1fPkP8oYkR/AAAAAAAAAAAAAAAAAAAAAAEEAgYyeFOcV8+Q/1XJjP9Uxor/VMaK/1TGiv9Uxor/VMaK
|
||||
/1TGiv9Uxor/VMaK/1TGiv9Uxor/VcmM/1fPkP8yeFOcAQQCBgAAAAAAAAAAAAAAAAAAAAAAAAAAAQQC
|
||||
BihiRH9Rwof2WM+Q/1XJi/9Uxor/VMaK/1TGiv9Uxor/VMaK/1TGiv9VyYv/WM+Q/1HCh/YoYkR/AQQC
|
||||
BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEi0fOzqJX69Qv4TzVs2P/1XJjP9UyIv/VMiL
|
||||
/1XJjP9WzY//UL+E8zqJX68SLR87AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAADiEXLCliRX8/mGnGTbh97E24few/mGnGKWJFfw4hFywAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAA4BAAADAAAAAQAWAAABAQADAAAAAQAWAAABAgADAAAABAAACEYBAwADAAAAAQABAAAB
|
||||
BgADAAAAAQACAAABEQAEAAAAAQAAAAgBEgADAAAAAQABAAABFQADAAAAAQAEAAABFgADAAAAAQAWAAAB
|
||||
FwAEAAAAAQAAB5ABHAADAAAAAQABAAABUgADAAAAAQABAAABUwADAAAABAAACE6HcwAHAAAH2AAACFYA
|
||||
AAAAAAgACAAIAAgAAQABAAEAAQAAB9hhcHBsAiAAAG1udHJSR0IgWFlaIAfZAAIAGQALABoAC2Fjc3BB
|
||||
UFBMAAAAAGFwcGwAAAAAAAAAAAAAAAAAAAAAAAD21gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2Rlc2MAAAEIAAAAb2RzY20AAAF4AAAFnGNwcnQA
|
||||
AAcUAAAAOHd0cHQAAAdMAAAAFHJYWVoAAAdgAAAAFGdYWVoAAAd0AAAAFGJYWVoAAAeIAAAAFHJUUkMA
|
||||
AAecAAAADmNoYWQAAAesAAAALGJUUkMAAAecAAAADmdUUkMAAAecAAAADmRlc2MAAAAAAAAAFEdlbmVy
|
||||
aWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAABRHZW5lcmljIFJHQiBQcm9maWxlAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAB8AAAAMc2tTSwAAACgA
|
||||
AAGEZGFESwAAAC4AAAGsY2FFUwAAACQAAAHadmlWTgAAACQAAAH+cHRCUgAAACYAAAIidWtVQQAAACoA
|
||||
AAJIZnJGVQAAACgAAAJyaHVIVQAAACgAAAKaemhUVwAAABYAAALCbmJOTwAAACYAAALYY3NDWgAAACIA
|
||||
AAL+aGVJTAAAAB4AAAMgaXRJVAAAACgAAAM+cm9STwAAACQAAANmZGVERQAAACwAAAOKa29LUgAAABYA
|
||||
AAO2c3ZTRQAAACYAAALYemhDTgAAABYAAAPMamFKUAAAABoAAAPiZWxHUgAAACIAAAP8cHRQTwAAACYA
|
||||
AAQebmxOTAAAACgAAAREZXNFUwAAACYAAAQedGhUSAAAACQAAARsdHJUUgAAACIAAASQZmlGSQAAACgA
|
||||
AASyaHJIUgAAACgAAATacGxQTAAAACwAAAUCcnVSVQAAACIAAAUuYXJFRwAAACYAAAVQZW5VUwAAACYA
|
||||
AAV2AFYBYQBlAG8AYgBlAGMAbgD9ACAAUgBHAEIAIABwAHIAbwBmAGkAbABHAGUAbgBlAHIAZQBsACAA
|
||||
UgBHAEIALQBiAGUAcwBrAHIAaQB2AGUAbABzAGUAUABlAHIAZgBpAGwAIABSAEcAQgAgAGcAZQBuAOgA
|
||||
cgBpAGMAQx6lAHUAIABoAOwAbgBoACAAUgBHAEIAIABDAGgAdQBuAGcAUABlAHIAZgBpAGwAIABSAEcA
|
||||
QgAgAEcAZQBuAOkAcgBpAGMAbwQXBDAEMwQwBDsETAQ9BDgEOQAgBD8EQAQ+BEQEMAQ5BDsAIABSAEcA
|
||||
QgBQAHIAbwBmAGkAbAAgAGcA6QBuAOkAcgBpAHEAdQBlACAAUgBWAEIAwQBsAHQAYQBsAOEAbgBvAHMA
|
||||
IABSAEcAQgAgAHAAcgBvAGYAaQBskBp1KAAgAFIARwBCACCCcl9pY8+P8ABHAGUAbgBlAHIAaQBzAGsA
|
||||
IABSAEcAQgAtAHAAcgBvAGYAaQBsAE8AYgBlAGMAbgD9ACAAUgBHAEIAIABwAHIAbwBmAGkAbAXkBegF
|
||||
1QXkBdkF3AAgAFIARwBCACAF2wXcBdwF2QBQAHIAbwBmAGkAbABvACAAUgBHAEIAIABnAGUAbgBlAHIA
|
||||
aQBjAG8AUAByAG8AZgBpAGwAIABSAEcAQgAgAGcAZQBuAGUAcgBpAGMAQQBsAGwAZwBlAG0AZQBpAG4A
|
||||
ZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbMd8vBgAIABSAEcAQgAg1QS4XNMMx3xmbpAaACAAUgBHAEIA
|
||||
IGPPj/Blh072TgCCLAAgAFIARwBCACAw1zDtMNUwoTCkMOsDkwO1A70DuQO6A8wAIAPAA8EDvwPGA68D
|
||||
uwAgAFIARwBCAFAAZQByAGYAaQBsACAAUgBHAEIAIABnAGUAbgDpAHIAaQBjAG8AQQBsAGcAZQBtAGUA
|
||||
ZQBuACAAUgBHAEIALQBwAHIAbwBmAGkAZQBsDkIOGw4jDkQOHw4lDkwAIABSAEcAQgAgDhcOMQ5IDicO
|
||||
RA4bAEcAZQBuAGUAbAAgAFIARwBCACAAUAByAG8AZgBpAGwAaQBZAGwAZQBpAG4AZQBuACAAUgBHAEIA
|
||||
LQBwAHIAbwBmAGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABSAEcAQgAgAHAAcgBvAGYAaQBsAFUA
|
||||
bgBpAHcAZQByAHMAYQBsAG4AeQAgAHAAcgBvAGYAaQBsACAAUgBHAEIEHgQxBEkEOAQ5ACAEPwRABD4E
|
||||
RAQ4BDsETAAgAFIARwBCBkUGRAZBACAGKgY5BjEGSgZBACAAUgBHAEIAIAYnBkQGOQYnBkUARwBlAG4A
|
||||
ZQByAGkAYwAgAFIARwBCACAAUAByAG8AZgBpAGwAZXRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUg
|
||||
SW5jLiwgYWxsIHJpZ2h0cyByZXNlcnZlZC4AWFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAAAAAAdE0A
|
||||
AD3uAAAD0FhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAACgaAAAVnwAAuDZjdXJ2AAAAAAAAAAEB
|
||||
zQAAc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeSAAD9kf//+6L///2jAAAD3AAAwGzSJSYnKFokY2xhc3Nu
|
||||
YW1lWCRjbGFzc2VzXxAQTlNCaXRtYXBJbWFnZVJlcKMnKSpaTlNJbWFnZVJlcFhOU09iamVjdNIlJiwt
|
||||
V05TQXJyYXmiLCrSJSYvMF5OU011dGFibGVBcnJheaMvLCrTMjMKNDU2V05TV2hpdGVcTlNDb2xvclNw
|
||||
YWNlRDAgMAAQA4AM0iUmODlXTlNDb2xvcqI4KtIlJjs8V05TSW1hZ2WiOypfEA9OU0tleWVkQXJjaGl2
|
||||
ZXLRP0BUcm9vdIABAAgAEQAaACMALQAyADcARgBMAFcAXgBlAHIAeQCBAIMAhQCKAIwAjgCXAJwApwCp
|
||||
AKsArQCyALUAtwC5ALsAvQDCANkA2wDdEQ8RFBEfESgROxE/EUoRUxFYEWARYxFoEXcRexGCEYoRlxGc
|
||||
EZ4RoBGlEa0RsBG1Eb0RwBHSEdUR2gAAAAAAAAIBAAAAAAAAAEEAAAAAAAAAAAAAAAAAABHcA
|
||||
</mutableData>
|
||||
</image>
|
||||
<image name="selection_tick.png" width="22" height="22"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -40,37 +40,6 @@
|
||||
|
||||
@implementation CallViewController
|
||||
|
||||
#pragma mark - Class methods
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass(self.class)
|
||||
bundle:[NSBundle bundleForClass:self.class]];
|
||||
}
|
||||
|
||||
+ (instancetype)callViewController:(MXCall*)call
|
||||
{
|
||||
CallViewController* instance = [[[self class] alloc] initWithNibName:NSStringFromClass(self.class)
|
||||
bundle:[NSBundle bundleForClass:self.class]];
|
||||
|
||||
// Load the view controller's view now (buttons and views will then be available).
|
||||
if ([instance respondsToSelector:@selector(loadViewIfNeeded)])
|
||||
{
|
||||
// iOS 9 and later
|
||||
[instance loadViewIfNeeded];
|
||||
}
|
||||
else if (instance.view)
|
||||
{
|
||||
// Patch: on iOS < 9.0, we load the view by calling its getter.
|
||||
}
|
||||
|
||||
instance.mxCall = call;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)finalizeInit
|
||||
{
|
||||
[super finalizeInit];
|
||||
|
||||
@@ -230,19 +230,7 @@
|
||||
|
||||
if (roomsAdded)
|
||||
{
|
||||
// Notify the table view there are new items at its tail
|
||||
NSMutableArray<NSIndexPath *> *indexPaths = [NSMutableArray arrayWithCapacity:roomsAdded];
|
||||
|
||||
NSUInteger numberOfRowsBefore = [self->dataSource tableView:self.tableView numberOfRowsInSection:0];
|
||||
numberOfRowsBefore -= roomsAdded;
|
||||
|
||||
for (NSUInteger i = 0; i < roomsAdded; i++)
|
||||
{
|
||||
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(numberOfRowsBefore + i) inSection:0];
|
||||
[indexPaths addObject:indexPath];
|
||||
}
|
||||
|
||||
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
[self removeSpinnerFooterView];
|
||||
|
||||
@@ -240,9 +240,11 @@
|
||||
{
|
||||
if (self.delegate)
|
||||
{
|
||||
id<MXKRecentCellDataStoring> cellData = [recentsDataSource cellDataAtIndexPath:[NSIndexPath indexPathForRow:indexPath.item inSection:collectionView.tag]];
|
||||
RoomCollectionViewCell *roomCollectionViewCell = (RoomCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
|
||||
|
||||
[self.delegate recentListViewController:self didSelectRoom:cellData.roomSummary.roomId inMatrixSession:cellData.roomSummary.room.mxSession];
|
||||
id<MXKRecentCellDataStoring> renderedCellData = (id<MXKRecentCellDataStoring>)roomCollectionViewCell.renderedCellData;
|
||||
|
||||
[self.delegate recentListViewController:self didSelectRoom:renderedCellData.roomSummary.roomId inMatrixSession:renderedCellData.roomSummary.room.mxSession];
|
||||
}
|
||||
|
||||
// Hide the keyboard when user select a room
|
||||
|
||||
24
Riot/ViewController/ReadReceiptsViewController.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright 2017 Aram Sargsyan
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
|
||||
@interface ReadReceiptsViewController : MXKViewController
|
||||
|
||||
+ (void)openInViewController:(UIViewController *)viewController fromContainer:(MXKReceiptSendersContainer *)receiptSendersContainer withSession:(MXSession *)session;
|
||||
|
||||
@end
|
||||
177
Riot/ViewController/ReadReceiptsViewController.m
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright 2017 Aram Sargsyan
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "ReadReceiptsViewController.h"
|
||||
#import <MatrixKit/MatrixKit.h>
|
||||
#import "RiotDesignValues.h"
|
||||
|
||||
@interface ReadReceiptsViewController () <UITableViewDataSource, UITableViewDelegate>
|
||||
|
||||
@property (nonatomic) MXRestClient* restClient;
|
||||
@property (nonatomic) MXSession *session;
|
||||
|
||||
@property (nonatomic) NSArray <MXRoomMember *> *roomMembers;
|
||||
@property (nonatomic) NSArray <UIImage *> *placeholders;
|
||||
@property (nonatomic) NSArray <MXReceiptData *> *receipts;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *overlayView;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIView *containerView;
|
||||
@property (weak, nonatomic) IBOutlet UITableView *receiptsTableView;
|
||||
@property (weak, nonatomic) IBOutlet UIButton *closeButton;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ReadReceiptsViewController
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
+ (void)openInViewController:(UIViewController *)viewController fromContainer:(MXKReceiptSendersContainer *)receiptSendersContainer withSession:(MXSession *)session
|
||||
{
|
||||
ReadReceiptsViewController *receiptsController = [[[self class] alloc] initWithNibName:NSStringFromClass([self class]) bundle:nil];
|
||||
receiptsController.restClient = receiptSendersContainer.restClient;
|
||||
receiptsController.session = session;
|
||||
|
||||
receiptsController.roomMembers = receiptSendersContainer.roomMembers;
|
||||
receiptsController.placeholders = receiptSendersContainer.placeholders;
|
||||
receiptsController.receipts = receiptSendersContainer.readReceipts;
|
||||
|
||||
receiptsController.providesPresentationContextTransitionStyle = YES;
|
||||
receiptsController.definesPresentationContext = YES;
|
||||
receiptsController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||
receiptsController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
|
||||
|
||||
[viewController presentViewController:receiptsController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self configureViews];
|
||||
[self configureReceiptsTableView];
|
||||
[self addOverlayViewGesture];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
#pragma mark - Views
|
||||
|
||||
- (void)configureViews
|
||||
{
|
||||
self.containerView.layer.cornerRadius = 20;
|
||||
self.titleLabel.text = NSLocalizedStringFromTable(@"read_receipts_list", @"Vector", nil);
|
||||
|
||||
[_closeButton setTitle:[NSBundle mxk_localizedStringForKey:@"close"] forState:UIControlStateNormal];
|
||||
[_closeButton setTitle:[NSBundle mxk_localizedStringForKey:@"close"] forState:UIControlStateHighlighted];
|
||||
}
|
||||
|
||||
- (void)configureReceiptsTableView
|
||||
{
|
||||
self.receiptsTableView.dataSource = self;
|
||||
self.receiptsTableView.delegate = self;
|
||||
self.receiptsTableView.showsVerticalScrollIndicator = NO;
|
||||
self.receiptsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
|
||||
[self.receiptsTableView registerNib:[MXKReadReceiptTableViewCell nib] forCellReuseIdentifier:[MXKReadReceiptTableViewCell defaultReuseIdentifier]];
|
||||
}
|
||||
|
||||
- (void)addOverlayViewGesture
|
||||
{
|
||||
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(overlayTap)];
|
||||
[tapRecognizer setNumberOfTapsRequired:1];
|
||||
[tapRecognizer setNumberOfTouchesRequired:1];
|
||||
[self.overlayView addGestureRecognizer:tapRecognizer];
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)overlayTap
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (IBAction)onCloseButtonPress:(id)sender
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.roomMembers.count;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
MXKReadReceiptTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[MXKReadReceiptTableViewCell defaultReuseIdentifier] forIndexPath:indexPath];
|
||||
|
||||
if (indexPath.row < self.roomMembers.count)
|
||||
{
|
||||
NSString *name = self.roomMembers[indexPath.row].displayname;
|
||||
if (name.length == 0) {
|
||||
name = self.roomMembers[indexPath.row].userId;
|
||||
}
|
||||
cell.displayNameLabel.text = name;
|
||||
}
|
||||
if (indexPath.row < self.placeholders.count)
|
||||
{
|
||||
NSString *avatarUrl = self.roomMembers[indexPath.row].avatarUrl;
|
||||
if (self.restClient && avatarUrl)
|
||||
{
|
||||
CGFloat side = CGRectGetWidth(cell.avatarImageView.frame);
|
||||
avatarUrl = [self.restClient urlOfContentThumbnail:avatarUrl toFitViewSize:CGSizeMake(side, side) withMethod:MXThumbnailingMethodCrop];
|
||||
}
|
||||
[cell.avatarImageView setImageURL:avatarUrl withType:nil andImageOrientation:UIImageOrientationUp previewImage:self.placeholders[indexPath.row]];
|
||||
}
|
||||
if (indexPath.row < self.receipts.count)
|
||||
{
|
||||
NSString *receiptReadText = NSLocalizedStringFromTable(@"receipt_status_read", @"Vector", nil);
|
||||
NSString *receiptTimeText = [(MXKEventFormatter*)self.session.roomSummaryUpdateDelegate dateStringFromTimestamp:self.receipts[indexPath.row].ts withTime:YES];
|
||||
|
||||
NSMutableAttributedString *receiptDescription = [[NSMutableAttributedString alloc] initWithString:receiptReadText attributes:@{NSForegroundColorAttributeName : kRiotTextColorGray, NSFontAttributeName : [UIFont boldSystemFontOfSize:15]}];
|
||||
|
||||
[receiptDescription appendAttributedString:[[NSAttributedString alloc] initWithString:receiptTimeText attributes:@{NSForegroundColorAttributeName : kRiotTextColorGray, NSFontAttributeName : [UIFont systemFontOfSize:15]}]];
|
||||
|
||||
cell.receiptDescriptionLabel.attributedText = receiptDescription;
|
||||
}
|
||||
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return 70;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
98
Riot/ViewController/ReadReceiptsViewController.xib
Normal file
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ReadReceiptsViewController">
|
||||
<connections>
|
||||
<outlet property="closeButton" destination="np9-sm-bvz" id="6Na-H8-nmE"/>
|
||||
<outlet property="containerView" destination="kg4-Yk-K6b" id="DNS-mH-6HR"/>
|
||||
<outlet property="overlayView" destination="41Z-5b-umc" id="gpj-Ux-mhK"/>
|
||||
<outlet property="receiptsTableView" destination="9qg-nd-kFU" id="ZWb-Hn-hIe"/>
|
||||
<outlet property="titleLabel" destination="jsl-CT-BFF" id="7co-HF-mWI"/>
|
||||
<outlet property="view" destination="iN0-l3-epB" id="bVY-jN-77v"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="41Z-5b-umc" userLabel="Overlay View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kg4-Yk-K6b" userLabel="Master Container View">
|
||||
<rect key="frame" x="10" y="58.5" width="355" height="550"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YD2-h3-4xX" userLabel="Title Container View">
|
||||
<rect key="frame" x="0.0" y="0.0" width="355" height="40"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jsl-CT-BFF" userLabel="Title Label">
|
||||
<rect key="frame" x="156.5" y="10" width="41.5" height="19.5"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="jsl-CT-BFF" firstAttribute="centerY" secondItem="YD2-h3-4xX" secondAttribute="centerY" id="3nq-G3-rhK"/>
|
||||
<constraint firstItem="jsl-CT-BFF" firstAttribute="centerX" secondItem="YD2-h3-4xX" secondAttribute="centerX" id="YfA-8b-6PG"/>
|
||||
<constraint firstAttribute="height" constant="40" id="vYa-wu-b0l"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="9qg-nd-kFU">
|
||||
<rect key="frame" x="0.0" y="40" width="355" height="460"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</tableView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="np9-sm-bvz">
|
||||
<rect key="frame" x="296" y="510" width="39" height="30"/>
|
||||
<state key="normal" title="Close"/>
|
||||
<connections>
|
||||
<action selector="onCloseButtonPress:" destination="-1" eventType="touchUpInside" id="3LU-e2-3qZ"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="9qg-nd-kFU" secondAttribute="bottom" constant="50" id="9tH-uU-nTl"/>
|
||||
<constraint firstAttribute="trailing" secondItem="9qg-nd-kFU" secondAttribute="trailing" id="MLa-NR-q4z"/>
|
||||
<constraint firstItem="YD2-h3-4xX" firstAttribute="leading" secondItem="kg4-Yk-K6b" secondAttribute="leading" id="X5O-8F-CyO"/>
|
||||
<constraint firstAttribute="trailing" secondItem="YD2-h3-4xX" secondAttribute="trailing" id="aUL-jB-exK"/>
|
||||
<constraint firstItem="YD2-h3-4xX" firstAttribute="top" secondItem="kg4-Yk-K6b" secondAttribute="top" id="aUc-NR-Suw"/>
|
||||
<constraint firstAttribute="bottom" secondItem="np9-sm-bvz" secondAttribute="bottom" constant="10" id="fYr-Lb-UtL"/>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="550" id="j5U-sf-HMF"/>
|
||||
<constraint firstItem="9qg-nd-kFU" firstAttribute="leading" secondItem="kg4-Yk-K6b" secondAttribute="leading" id="p5C-BH-56n"/>
|
||||
<constraint firstAttribute="trailing" secondItem="np9-sm-bvz" secondAttribute="trailing" constant="20" symbolic="YES" id="pEK-YF-c4b"/>
|
||||
<constraint firstItem="9qg-nd-kFU" firstAttribute="top" secondItem="YD2-h3-4xX" secondAttribute="bottom" id="thD-Si-NzK"/>
|
||||
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="550" id="wln-eD-ner"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="41Z-5b-umc" secondAttribute="bottom" id="2qB-lj-z6b"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kg4-Yk-K6b" secondAttribute="trailing" constant="10" id="96x-1M-6KX"/>
|
||||
<constraint firstItem="41Z-5b-umc" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="CoG-Nf-HX8"/>
|
||||
<constraint firstItem="kg4-Yk-K6b" firstAttribute="top" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="top" constant="40" id="ERj-JN-Ljg"/>
|
||||
<constraint firstItem="kg4-Yk-K6b" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="M3i-yJ-w5M"/>
|
||||
<constraint firstAttribute="trailing" secondItem="41Z-5b-umc" secondAttribute="trailing" id="USj-F9-gZi"/>
|
||||
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="kg4-Yk-K6b" secondAttribute="bottom" constant="10" id="Xl6-6H-Rb6"/>
|
||||
<constraint firstItem="kg4-Yk-K6b" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" priority="750" constant="40" id="Zmw-aZ-NHG"/>
|
||||
<constraint firstAttribute="bottom" secondItem="kg4-Yk-K6b" secondAttribute="bottom" priority="750" constant="10" id="hTL-dj-W5I"/>
|
||||
<constraint firstItem="kg4-Yk-K6b" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="hgX-JU-Hm1"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kg4-Yk-K6b" secondAttribute="trailing" priority="750" constant="10" id="lJU-iL-6th"/>
|
||||
<constraint firstItem="kg4-Yk-K6b" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="qYN-Lz-Uvz"/>
|
||||
<constraint firstItem="kg4-Yk-K6b" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" priority="750" constant="10" id="xg1-8A-kJZ"/>
|
||||
<constraint firstItem="41Z-5b-umc" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="z6e-1g-MG7"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -327,10 +327,10 @@
|
||||
[self prepareStickyHeaders];
|
||||
|
||||
// In case of split view controller where the primary and secondary view controllers are displayed side-by-side on screen,
|
||||
// the selected room (if any) is updated and kept visible.
|
||||
// the selected room (if any) is updated.
|
||||
if (!self.splitViewController.isCollapsed)
|
||||
{
|
||||
[self refreshCurrentSelectedCell:YES];
|
||||
[self refreshCurrentSelectedCell:NO];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1662,10 +1662,27 @@
|
||||
|
||||
- (void)scrollToTheTopTheNextRoomWithMissedNotificationsInSection:(NSInteger)section
|
||||
{
|
||||
UITableViewCell *firstVisibleCell = self.recentsTableView.visibleCells.firstObject;
|
||||
UITableViewCell *firstVisibleCell;
|
||||
NSIndexPath *firstVisibleCellIndexPath;
|
||||
|
||||
UIView *firstSectionHeader = displayedSectionHeaders.firstObject;
|
||||
|
||||
if (firstSectionHeader && firstSectionHeader.frame.origin.y <= self.recentsTableView.contentOffset.y)
|
||||
{
|
||||
// Compute the height of the hidden part of the section header.
|
||||
CGFloat hiddenPart = self.recentsTableView.contentOffset.y - firstSectionHeader.frame.origin.y;
|
||||
CGFloat firstVisibleCellPosY = self.recentsTableView.contentOffset.y + (firstSectionHeader.frame.size.height - hiddenPart);
|
||||
firstVisibleCellIndexPath = [self.recentsTableView indexPathForRowAtPoint:CGPointMake(0, firstVisibleCellPosY)];
|
||||
firstVisibleCell = [self.recentsTableView cellForRowAtIndexPath:firstVisibleCellIndexPath];
|
||||
}
|
||||
else
|
||||
{
|
||||
firstVisibleCell = self.recentsTableView.visibleCells.firstObject;
|
||||
firstVisibleCellIndexPath = [self.recentsTableView indexPathForCell:firstVisibleCell];
|
||||
}
|
||||
|
||||
if (firstVisibleCell)
|
||||
{
|
||||
NSIndexPath *firstVisibleCellIndexPath = [self.recentsTableView indexPathForCell:firstVisibleCell];
|
||||
NSInteger nextCellRow = (firstVisibleCellIndexPath.section == section) ? firstVisibleCellIndexPath.row + 1 : 0;
|
||||
|
||||
// Look for the next room with missed notifications.
|
||||
|
||||
@@ -601,7 +601,7 @@
|
||||
// Add a plus icon to the contact cell in the contacts picker, in order to make it more understandable for the end user.
|
||||
contactsDataSource.contactCellAccessoryImage = [UIImage imageNamed:@"plus_icon"];
|
||||
|
||||
// List all the participants by their matrix user id, or a room 3pid invite token to ignore them during the contacts search.
|
||||
// List all the participants matrix user id to ignore them during the contacts search.
|
||||
for (Contact *contact in actualParticipants)
|
||||
{
|
||||
[contactsDataSource.ignoredContactsByMatrixId setObject:contact forKey:contact.mxMember.userId];
|
||||
@@ -612,10 +612,6 @@
|
||||
{
|
||||
[contactsDataSource.ignoredContactsByMatrixId setObject:contact forKey:contact.mxMember.userId];
|
||||
}
|
||||
else if (contact.mxThirdPartyInvite)
|
||||
{
|
||||
[contactsDataSource.ignoredContactsByMatrixId setObject:contact forKey:contact.mxThirdPartyInvite.token];
|
||||
}
|
||||
}
|
||||
if (userParticipant)
|
||||
{
|
||||
@@ -905,7 +901,7 @@
|
||||
- (void)pushViewController:(UIViewController*)viewController
|
||||
{
|
||||
// Check whether the view controller is displayed inside a segmented one.
|
||||
if (self.parentViewController)
|
||||
if (self.parentViewController.navigationController)
|
||||
{
|
||||
// Hide back button title
|
||||
self.parentViewController.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
|
||||
|
||||
@@ -23,9 +23,11 @@
|
||||
|
||||
#import "RoomParticipantsViewController.h"
|
||||
|
||||
#import "ContactsTableViewController.h"
|
||||
|
||||
#import "UIViewController+RiotSearch.h"
|
||||
|
||||
@interface RoomViewController : MXKRoomViewController <UISearchBarDelegate, UIGestureRecognizerDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate>
|
||||
@interface RoomViewController : MXKRoomViewController <UISearchBarDelegate, UIGestureRecognizerDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate>
|
||||
|
||||
// The expanded header
|
||||
@property (weak, nonatomic) IBOutlet UIView *expandedHeaderContainer;
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
|
||||
#import "UsersDevicesViewController.h"
|
||||
|
||||
#import "ReadReceiptsViewController.h"
|
||||
|
||||
#import "RoomEmptyBubbleCell.h"
|
||||
|
||||
#import "RoomIncomingTextMsgBubbleCell.h"
|
||||
@@ -162,6 +164,9 @@
|
||||
|
||||
// Tell whether the view controller is appeared or not.
|
||||
BOOL isAppeared;
|
||||
|
||||
// The search bar buttom item back up.
|
||||
UIBarButtonItem *searchBarButtonItem;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -853,6 +858,14 @@
|
||||
{
|
||||
[self showExpandedHeader:NO];
|
||||
|
||||
// Force a simple title view initialised with the current room before leaving actually the room.
|
||||
[self setRoomTitleViewClass:SimpleRoomTitleView.class];
|
||||
self.titleView.editable = NO;
|
||||
self.titleView.mxRoom = self.roomDataSource.room;
|
||||
|
||||
// Hide the potential read marker banner.
|
||||
self.jumpToLastUnreadBannerContainer.hidden = YES;
|
||||
|
||||
[super leaveRoomOnEvent:event];
|
||||
}
|
||||
|
||||
@@ -906,7 +919,7 @@
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
NSLog(@"[Vector RoomVC] Join roomAlias (%@) failed", roomAlias);
|
||||
NSLog(@"[RoomVC] Join roomAlias (%@) failed", roomAlias);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
@@ -961,15 +974,20 @@
|
||||
{
|
||||
[super setBubbleTableViewDisplayInTransition:bubbleTableViewDisplayInTransition];
|
||||
|
||||
// Refresh additional displays when the table is ready.
|
||||
if (!bubbleTableViewDisplayInTransition && !self.bubblesTableView.isHidden)
|
||||
{
|
||||
[self refreshActivitiesViewDisplay];
|
||||
|
||||
[self checkReadMarkerVisibility];
|
||||
[self refreshJumpToLastUnreadBannerDisplay];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
searchBarButtonItem = nil;
|
||||
self.navigationItem.rightBarButtonItem.enabled = NO;
|
||||
|
||||
if (currentAlert)
|
||||
@@ -1007,7 +1025,7 @@
|
||||
if (previewHeader || (self.expandedHeaderContainer.isHidden == NO))
|
||||
{
|
||||
// Here [destroy] is called before [viewWillDisappear:]
|
||||
NSLog(@"[Vector RoomVC] destroyed whereas it is still visible");
|
||||
NSLog(@"[RoomVC] destroyed whereas it is still visible");
|
||||
|
||||
[previewHeader removeFromSuperview];
|
||||
previewHeader = nil;
|
||||
@@ -1067,6 +1085,12 @@
|
||||
|
||||
- (void)refreshRoomTitle
|
||||
{
|
||||
if (searchBarButtonItem && !self.navigationItem.rightBarButtonItem)
|
||||
{
|
||||
// Restore by default the search bar button.
|
||||
self.navigationItem.rightBarButtonItem = searchBarButtonItem;
|
||||
}
|
||||
|
||||
// Set the right room title view
|
||||
if (self.isRoomPreview)
|
||||
{
|
||||
@@ -1101,7 +1125,8 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hide the search button
|
||||
// Remove the search button temporarily
|
||||
searchBarButtonItem = self.navigationItem.rightBarButtonItem;
|
||||
self.navigationItem.rightBarButtonItem = nil;
|
||||
|
||||
[self setRoomTitleViewClass:SimpleRoomTitleView.class];
|
||||
@@ -1198,7 +1223,7 @@
|
||||
// - if the event details view is displayed
|
||||
if (isVisible && (isSizeTransitionInProgress == YES || !self.roomDataSource || !self.roomDataSource.isLive || (self.roomDataSource.room.state.membership != MXMembershipJoin) || !self.splitViewController || encryptionInfoView.superview || eventDetailsView.superview))
|
||||
{
|
||||
NSLog(@"[Vector RoomVC] Show expanded header ignored");
|
||||
NSLog(@"[RoomVC] Show expanded header ignored");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1279,7 +1304,7 @@
|
||||
// or if the view controller is not embedded inside a split view controller yet.
|
||||
if (isVisible && (isSizeTransitionInProgress == YES || !self.splitViewController))
|
||||
{
|
||||
NSLog(@"[Vector RoomVC] Show preview header ignored");
|
||||
NSLog(@"[RoomVC] Show preview header ignored");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1686,6 +1711,11 @@
|
||||
[self showEncryptionInformation:tappedEvent];
|
||||
}
|
||||
}
|
||||
else if ([actionIdentifier isEqualToString:kMXKRoomBubbleCellTapOnReceiptsContainer])
|
||||
{
|
||||
MXKReceiptSendersContainer *container = userInfo[kMXKRoomBubbleCellReceiptsContainerKey];
|
||||
[ReadReceiptsViewController openInViewController:self fromContainer:container withSession:self.mainSession];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep default implementation for other actions
|
||||
@@ -1984,7 +2014,7 @@
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf stopActivityIndicator];
|
||||
|
||||
NSLog(@"[Vector RoomVC] Redact event (%@) failed", selectedEvent.eventId);
|
||||
NSLog(@"[RoomVC] Redact event (%@) failed", selectedEvent.eventId);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
@@ -2071,7 +2101,7 @@
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf stopActivityIndicator];
|
||||
|
||||
NSLog(@"[Vector RoomVC] Ignore user (%@) failed", selectedEvent.sender);
|
||||
NSLog(@"[RoomVC] Ignore user (%@) failed", selectedEvent.sender);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
@@ -2093,7 +2123,7 @@
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
[strongSelf stopActivityIndicator];
|
||||
|
||||
NSLog(@"[Vector RoomVC] Report event (%@) failed", selectedEvent.eventId);
|
||||
NSLog(@"[RoomVC] Report event (%@) failed", selectedEvent.eventId);
|
||||
//Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
@@ -2351,6 +2381,46 @@
|
||||
unknownDevices = nil;
|
||||
}
|
||||
}
|
||||
else if ([[segue identifier] isEqualToString:@"showContactPicker"])
|
||||
{
|
||||
ContactsTableViewController *contactsPickerViewController = (ContactsTableViewController*)pushedViewController;
|
||||
|
||||
// Set delegate to handle selected contact
|
||||
contactsPickerViewController.contactsTableViewControllerDelegate = self;
|
||||
|
||||
// Prepare its data source
|
||||
ContactsDataSource *contactsDataSource = [[ContactsDataSource alloc] init];
|
||||
contactsDataSource.areSectionsShrinkable = YES;
|
||||
contactsDataSource.displaySearchInputInContactsList = YES;
|
||||
contactsDataSource.forceMatrixIdInDisplayName = YES;
|
||||
// Add a plus icon to the contact cell in the contacts picker, in order to make it more understandable for the end user.
|
||||
contactsDataSource.contactCellAccessoryImage = [UIImage imageNamed:@"plus_icon"];
|
||||
|
||||
// List all the participants matrix user id to ignore them during the contacts search.
|
||||
MXSession* session = self.roomDataSource.mxSession;
|
||||
NSString* roomId = self.roomDataSource.roomId;
|
||||
MXRoom *room = [session roomWithRoomId:roomId];
|
||||
if (room)
|
||||
{
|
||||
NSArray *members = [room.state membersWithoutConferenceUser];
|
||||
|
||||
for (MXRoomMember *mxMember in members)
|
||||
{
|
||||
// Check his status
|
||||
if (mxMember.membership == MXMembershipJoin || mxMember.membership == MXMembershipInvite)
|
||||
{
|
||||
// Create the contact related to this member
|
||||
MXKContact *contact = [[MXKContact alloc] initMatrixContactWithDisplayName:mxMember.displayname andMatrixID:mxMember.userId];
|
||||
[contactsDataSource.ignoredContactsByMatrixId setObject:contact forKey:mxMember.userId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[contactsPickerViewController showSearch:YES];
|
||||
contactsPickerViewController.searchBar.placeholder = NSLocalizedStringFromTable(@"room_participants_invite_another_user", @"Vector", nil);
|
||||
|
||||
[contactsPickerViewController displayList:contactsDataSource];
|
||||
}
|
||||
|
||||
// Hide back button title
|
||||
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
|
||||
@@ -2560,6 +2630,16 @@
|
||||
[super scrollViewDidScroll:scrollView];
|
||||
|
||||
[self checkReadMarkerVisibility];
|
||||
|
||||
// Switch back to the live mode when the user scrolls to the bottom of the non live timeline.
|
||||
if (!self.roomDataSource.isLive && ![self isRoomPreview])
|
||||
{
|
||||
CGFloat contentBottomPosY = self.bubblesTableView.contentOffset.y + self.bubblesTableView.frame.size.height - self.bubblesTableView.contentInset.bottom;
|
||||
if (contentBottomPosY >= self.bubblesTableView.contentSize.height && ![self.roomDataSource.timeline canPaginate:MXTimelineDirectionForwards])
|
||||
{
|
||||
[self goBackToLive];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
|
||||
@@ -2722,6 +2802,11 @@
|
||||
selectedRoomDetailsIndex = 0;
|
||||
[self performSegueWithIdentifier:@"showRoomDetails" sender:self];
|
||||
}
|
||||
else if (tappedView == titleView.addParticipantMask)
|
||||
{
|
||||
// Open contact picker
|
||||
[self performSegueWithIdentifier:@"showContactPicker" sender:self];
|
||||
}
|
||||
else if (tappedView == previewHeader.rightButton)
|
||||
{
|
||||
// 'Join' button has been pressed
|
||||
@@ -2810,7 +2895,7 @@
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
[self stopActivityIndicator];
|
||||
NSLog(@"[Vector RoomVC] Failed to reject an invited room (%@) failed", self.roomDataSource.room.state.roomId);
|
||||
NSLog(@"[RoomVC] Failed to reject an invited room (%@) failed", self.roomDataSource.room.state.roomId);
|
||||
|
||||
}];
|
||||
}
|
||||
@@ -3011,7 +3096,7 @@
|
||||
{
|
||||
[roomActivitiesView displayOngoingConferenceCall:^(BOOL video) {
|
||||
|
||||
NSLog(@"[Vector RoomVC] onOngoingConferenceCallPressed");
|
||||
NSLog(@"[RoomVC] onOngoingConferenceCallPressed");
|
||||
|
||||
// Make sure there is not yet a call
|
||||
if (![customizedRoomDataSource.mxSession.callManager callInRoom:customizedRoomDataSource.roomId])
|
||||
@@ -3025,7 +3110,8 @@
|
||||
{
|
||||
// Show "scroll to bottom" icon when the most recent message is not visible,
|
||||
// or when the timelime is not live (this icon is used to go back to live).
|
||||
if (!self.roomDataSource.isLive || (!self.bubblesTableView.isHidden && [self isBubblesTableScrollViewAtTheBottom] == NO))
|
||||
// Note: we check if `currentEventIdAtTableBottom` is set to know whether the table has been rendered at least once.
|
||||
if (!self.roomDataSource.isLive || (currentEventIdAtTableBottom && [self isBubblesTableScrollViewAtTheBottom] == NO))
|
||||
{
|
||||
// Retrieve the unread messages count
|
||||
NSUInteger unreadCount = self.roomDataSource.room.summary.localUnreadEventCount;
|
||||
@@ -3039,6 +3125,26 @@
|
||||
|
||||
[roomActivitiesView displayScrollToBottomIcon:unreadCount onIconTapGesture:^{
|
||||
|
||||
[self goBackToLive];
|
||||
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self refreshTypingNotification];
|
||||
}
|
||||
}
|
||||
|
||||
// Recognize swipe downward to dismiss keyboard if any
|
||||
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)];
|
||||
[swipe setNumberOfTouchesRequired:1];
|
||||
[swipe setDirection:UISwipeGestureRecognizerDirectionDown];
|
||||
[roomActivitiesView addGestureRecognizer:swipe];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)goBackToLive
|
||||
{
|
||||
if (self.roomDataSource.isLive)
|
||||
{
|
||||
// Enable the read marker display, and disable its update (in order to not mark as read all the new messages by default).
|
||||
@@ -3070,21 +3176,6 @@
|
||||
self.inputToolbarView.textMessage = roomDataSource.partialTextMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self refreshTypingNotification];
|
||||
}
|
||||
}
|
||||
|
||||
// Recognize swipe downward to dismiss keyboard if any
|
||||
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(onSwipeGesture:)];
|
||||
[swipe setNumberOfTouchesRequired:1];
|
||||
[swipe setDirection:UISwipeGestureRecognizerDirectionDown];
|
||||
[roomActivitiesView addGestureRecognizer:swipe];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Missed discussions handling
|
||||
@@ -3606,5 +3697,127 @@
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - ContactsTableViewControllerDelegate
|
||||
|
||||
- (void)contactsTableViewController:(ContactsTableViewController *)contactsTableViewController didSelectContact:(MXKContact*)contact
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
if (currentAlert)
|
||||
{
|
||||
[currentAlert dismiss:NO];
|
||||
currentAlert = nil;
|
||||
}
|
||||
|
||||
// Invite ?
|
||||
NSString *promptMsg = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_participants_invite_prompt_msg", @"Vector", nil), contact.displayName];
|
||||
currentAlert = [[MXKAlert alloc] initWithTitle:NSLocalizedStringFromTable(@"room_participants_invite_prompt_title", @"Vector", nil)
|
||||
message:promptMsg
|
||||
style:MXKAlertStyleAlert];
|
||||
|
||||
currentAlert.cancelButtonIndex = [currentAlert addActionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:MXKAlertActionStyleCancel
|
||||
handler:^(MXKAlert *alert) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
strongSelf->currentAlert = nil;
|
||||
}
|
||||
|
||||
}];
|
||||
|
||||
[currentAlert addActionWithTitle:NSLocalizedStringFromTable(@"invite", @"Vector", nil)
|
||||
style:MXKAlertActionStyleDefault
|
||||
handler:^(MXKAlert *alert) {
|
||||
|
||||
// Sanity check
|
||||
if (!weakSelf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__strong __typeof(weakSelf)strongSelf = weakSelf;
|
||||
strongSelf->currentAlert = nil;
|
||||
|
||||
MXSession* session = strongSelf.roomDataSource.mxSession;
|
||||
NSString* roomId = strongSelf.roomDataSource.roomId;
|
||||
MXRoom *room = [session roomWithRoomId:roomId];
|
||||
|
||||
NSArray *identifiers = contact.matrixIdentifiers;
|
||||
NSString *participantId;
|
||||
|
||||
if (identifiers.count)
|
||||
{
|
||||
participantId = identifiers.firstObject;
|
||||
|
||||
// Invite this user if a room is defined
|
||||
[room inviteUser:participantId success:^{
|
||||
|
||||
// Refresh display by removing the contacts picker
|
||||
[contactsTableViewController withdrawViewControllerAnimated:YES completion:nil];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
NSLog(@"[RoomVC] Invite %@ failed", participantId);
|
||||
// Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (contact.emailAddresses.count)
|
||||
{
|
||||
// This is a local contact, consider the first email by default.
|
||||
// TODO: Prompt the user to select the right email.
|
||||
MXKEmail *email = contact.emailAddresses.firstObject;
|
||||
participantId = email.emailAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is the text filled by the user.
|
||||
participantId = contact.displayName;
|
||||
}
|
||||
|
||||
// Is it an email or a Matrix user ID?
|
||||
if ([MXTools isEmailAddress:participantId])
|
||||
{
|
||||
[room inviteUserByEmail:participantId success:^{
|
||||
|
||||
// Refresh display by removing the contacts picker
|
||||
[contactsTableViewController withdrawViewControllerAnimated:YES completion:nil];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
NSLog(@"[RoomVC] Invite be email %@ failed", participantId);
|
||||
// Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
}
|
||||
else //if ([MXTools isMatrixUserIdentifier:participantId])
|
||||
{
|
||||
[room inviteUser:participantId success:^{
|
||||
|
||||
// Refresh display by removing the contacts picker
|
||||
[contactsTableViewController withdrawViewControllerAnimated:YES completion:nil];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
NSLog(@"[RoomVC] Invite %@ failed", participantId);
|
||||
// Alert user
|
||||
[[AppDelegate theDelegate] showErrorAsAlert:error];
|
||||
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
}];
|
||||
|
||||
currentAlert.mxkAccessibilityIdentifier = @"RoomVCInviteAlert";
|
||||
[currentAlert showInViewController:self];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -209,9 +209,14 @@
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (indexPath.section == recentsDataSource.directorySection)
|
||||
{
|
||||
// Sanity check
|
||||
MXPublicRoom *publicRoom = [recentsDataSource.publicRoomsDirectoryDataSource roomAtIndexPath:indexPath];
|
||||
if (publicRoom)
|
||||
{
|
||||
[self openPublicRoomAtIndexPath:indexPath];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
|
||||
@@ -268,9 +273,12 @@
|
||||
|
||||
- (void)triggerDirectoryPagination
|
||||
{
|
||||
if (recentsDataSource.publicRoomsDirectoryDataSource.hasReachedPaginationEnd || footerSpinnerView)
|
||||
if (!recentsDataSource
|
||||
|| recentsDataSource.state == MXKDataSourceStateUnknown
|
||||
|| recentsDataSource.publicRoomsDirectoryDataSource.hasReachedPaginationEnd
|
||||
|| footerSpinnerView)
|
||||
{
|
||||
// We got all public rooms or we are already paginating
|
||||
// We are not yet ready or being killed or we got all public rooms or we are already paginating
|
||||
// Do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,12 @@ NSString *const kRoomEncryptedDataBubbleCellTapOnEncryptionIcon = @"kRoomEncrypt
|
||||
{
|
||||
component = bubbleComponents[componentIndex];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UIImage *icon = [RoomEncryptedDataBubbleCell encryptionIconForEvent:component.event andSession:bubbleData.mxSession];
|
||||
UIImageView *encryptStatusImageView = [[UIImageView alloc] initWithImage:icon];
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomIncomingEncryptedTextMsgBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomOutgoingEncryptedTextMsgBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#import "RoomEncryptedDataBubbleCell.h"
|
||||
|
||||
#import "RoomBubbleCellData.h"
|
||||
|
||||
@implementation RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell
|
||||
|
||||
- (void)awakeFromNib
|
||||
@@ -64,15 +66,27 @@
|
||||
// Check which bubble component is displayed in front of the tapped line.
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
// Consider by default the first component
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents.firstObject;
|
||||
// Consider by default the first display component
|
||||
NSInteger firstComponentIndex = 0;
|
||||
if ([bubbleData isKindOfClass:RoomBubbleCellData.class])
|
||||
{
|
||||
firstComponentIndex = ((RoomBubbleCellData*)bubbleData).oldestComponentIndex;
|
||||
}
|
||||
MXKRoomBubbleComponent *tappedComponent = bubbleComponents[firstComponentIndex++];
|
||||
|
||||
CGPoint tapPoint = [sender locationInView:self.messageTextView];
|
||||
|
||||
for (NSInteger index = 1; index < bubbleComponents.count; index++)
|
||||
for (NSInteger index = firstComponentIndex; index < bubbleComponents.count; index++)
|
||||
{
|
||||
// Here the bubble is composed by multiple text messages
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tapPoint.y < component.position.y)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
}
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UILabel *roomTitle;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *roomTitle1;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *roomTitle2;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *directRoomBorderView;
|
||||
@property (weak, nonatomic) IBOutlet MXKImageView *roomAvatar;
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#import "MXRoom+Riot.h"
|
||||
|
||||
#import "MXTools.h"
|
||||
|
||||
@implementation RoomCollectionViewCell
|
||||
|
||||
#pragma mark - Class methods
|
||||
@@ -39,6 +41,8 @@
|
||||
_missedNotifAndUnreadBadgeBgViewWidthConstraint.constant = 0;
|
||||
|
||||
self.roomTitle.textColor = kRiotTextColorBlack;
|
||||
self.roomTitle1.textColor = kRiotTextColorBlack;
|
||||
self.roomTitle2.textColor = kRiotTextColorBlack;
|
||||
self.missedNotifAndUnreadBadgeLabel.textColor = [UIColor whiteColor];
|
||||
|
||||
// Prepare direct room border
|
||||
@@ -54,8 +58,6 @@
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)render:(MXKCellData *)cellData
|
||||
@@ -68,7 +70,24 @@
|
||||
if (roomCellData)
|
||||
{
|
||||
// Report computed values as is
|
||||
self.roomTitle.hidden = NO;
|
||||
self.roomTitle.text = roomCellData.roomDisplayname;
|
||||
self.roomTitle1.hidden = YES;
|
||||
self.roomTitle2.hidden = YES;
|
||||
|
||||
// Check whether the room display name is an alias to keep visible the HS.
|
||||
if ([MXTools isMatrixRoomAlias:roomCellData.roomDisplayname])
|
||||
{
|
||||
NSRange range = [roomCellData.roomDisplayname rangeOfString:@":" options:NSBackwardsSearch];
|
||||
if (range.location != NSNotFound)
|
||||
{
|
||||
self.roomTitle.hidden = YES;
|
||||
self.roomTitle1.hidden = NO;
|
||||
self.roomTitle1.text = [roomCellData.roomDisplayname substringToIndex:range.location + 1];
|
||||
self.roomTitle2.hidden = NO;
|
||||
self.roomTitle2.text = [roomCellData.roomDisplayname substringFromIndex:range.location + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// Notify unreads and bing
|
||||
if (roomCellData.hasUnread)
|
||||
@@ -87,11 +106,11 @@
|
||||
// Use bold font for the room title
|
||||
if ([UIFont respondsToSelector:@selector(systemFontOfSize:weight:)])
|
||||
{
|
||||
self.roomTitle.font = [UIFont systemFontOfSize:15 weight:UIFontWeightBold];
|
||||
self.roomTitle.font = self.roomTitle1.font = self.roomTitle2.font = [UIFont systemFontOfSize:13 weight:UIFontWeightBold];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.roomTitle.font = [UIFont boldSystemFontOfSize:15];
|
||||
self.roomTitle.font = self.roomTitle1.font = self.roomTitle2.font = [UIFont boldSystemFontOfSize:13];
|
||||
}
|
||||
}
|
||||
else if (roomCellData.roomSummary.room.state.membership == MXMembershipInvite)
|
||||
@@ -107,11 +126,11 @@
|
||||
// Use bold font for the room title
|
||||
if ([UIFont respondsToSelector:@selector(systemFontOfSize:weight:)])
|
||||
{
|
||||
self.roomTitle.font = [UIFont systemFontOfSize:15 weight:UIFontWeightBold];
|
||||
self.roomTitle.font = self.roomTitle1.font = self.roomTitle2.font = [UIFont systemFontOfSize:13 weight:UIFontWeightBold];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.roomTitle.font = [UIFont boldSystemFontOfSize:15];
|
||||
self.roomTitle.font = self.roomTitle1.font = self.roomTitle2.font = [UIFont boldSystemFontOfSize:13];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -119,11 +138,11 @@
|
||||
// The room title is not bold anymore
|
||||
if ([UIFont respondsToSelector:@selector(systemFontOfSize:weight:)])
|
||||
{
|
||||
self.roomTitle.font = [UIFont systemFontOfSize:15 weight:UIFontWeightMedium];
|
||||
self.roomTitle.font = self.roomTitle1.font = self.roomTitle2.font = [UIFont systemFontOfSize:13 weight:UIFontWeightMedium];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.roomTitle.font = [UIFont systemFontOfSize:15];
|
||||
self.roomTitle.font = self.roomTitle1.font = self.roomTitle2.font = [UIFont systemFontOfSize:13];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,15 +156,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (MXKCellData*)renderedCellData
|
||||
{
|
||||
return roomCellData;
|
||||
}
|
||||
|
||||
+ (CGFloat)heightForCellData:(MXKCellData *)cellData withMaximumWidth:(CGFloat)maxWidth
|
||||
{
|
||||
// The height is fixed
|
||||
return 100;
|
||||
return 115;
|
||||
}
|
||||
|
||||
+ (CGSize)defaultCellSize
|
||||
{
|
||||
return CGSizeMake(80, 100);
|
||||
return CGSizeMake(80, 115);
|
||||
}
|
||||
|
||||
- (void)prepareForReuse
|
||||
@@ -158,6 +182,8 @@
|
||||
[self removeGestureRecognizer:self.gestureRecognizers[0]];
|
||||
}
|
||||
self.tag = -1;
|
||||
|
||||
roomCellData = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@@ -13,10 +13,10 @@
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="eCk-zY-LXq" customClass="RoomCollectionViewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="100"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="115"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="100"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="115"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="T1Q-RS-8o6" customClass="MXKImageView">
|
||||
@@ -61,13 +61,24 @@
|
||||
<constraint firstAttribute="width" constant="15" id="bbS-D2-SZi"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="RoomTitle" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oxX-IL-dG4">
|
||||
<rect key="frame" x="4" y="74" width="72" height="21"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="RoomTitle" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oxX-IL-dG4">
|
||||
<rect key="frame" x="4" y="74" width="72" height="16"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="TitleLabel"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="21" id="WA1-mL-sFU"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="13"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="RoomTitle" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X8H-1U-wc3">
|
||||
<rect key="frame" x="7" y="74" width="66" height="16"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="TitleLabel"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="13"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="RoomTitle" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jkz-Zp-aaG">
|
||||
<rect key="frame" x="7" y="90" width="66" height="16"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="TitleLabel"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="13"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
@@ -75,16 +86,25 @@
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="5Yd-df-HbB" secondAttribute="trailing" constant="12" id="0gr-xn-dfD"/>
|
||||
<constraint firstAttribute="bottom" secondItem="oxX-IL-dG4" secondAttribute="bottom" constant="5" id="1JB-d1-zb9"/>
|
||||
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="oxX-IL-dG4" secondAttribute="bottom" constant="5" id="1JB-d1-zb9"/>
|
||||
<constraint firstItem="oxX-IL-dG4" firstAttribute="top" secondItem="T1Q-RS-8o6" secondAttribute="bottom" constant="4" id="2DB-H2-E2v"/>
|
||||
<constraint firstItem="oxX-IL-dG4" firstAttribute="leading" secondItem="eCk-zY-LXq" secondAttribute="leading" constant="4" id="6gu-JD-Gb1"/>
|
||||
<constraint firstItem="X8H-1U-wc3" firstAttribute="centerX" secondItem="oxX-IL-dG4" secondAttribute="centerX" id="K9T-eO-WNb"/>
|
||||
<constraint firstItem="xws-BR-H47" firstAttribute="centerX" secondItem="T1Q-RS-8o6" secondAttribute="centerX" id="Lo3-Ov-Bw8"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Q6g-b0-3sZ" secondAttribute="trailing" id="Mf1-H6-oH4"/>
|
||||
<constraint firstItem="Jkz-Zp-aaG" firstAttribute="centerX" secondItem="oxX-IL-dG4" secondAttribute="centerX" id="OQy-tF-e3Z"/>
|
||||
<constraint firstItem="Jkz-Zp-aaG" firstAttribute="top" secondItem="X8H-1U-wc3" secondAttribute="bottom" id="XDO-yX-Zs5"/>
|
||||
<constraint firstItem="X8H-1U-wc3" firstAttribute="leading" secondItem="eCk-zY-LXq" secondAttribute="leading" constant="7" id="XU5-Lv-9Xn"/>
|
||||
<constraint firstItem="T1Q-RS-8o6" firstAttribute="top" secondItem="eCk-zY-LXq" secondAttribute="top" constant="10" id="cc7-bg-15Z"/>
|
||||
<constraint firstItem="Jkz-Zp-aaG" firstAttribute="leading" secondItem="eCk-zY-LXq" secondAttribute="leading" constant="7" id="fPh-Lb-Bv9"/>
|
||||
<constraint firstItem="xws-BR-H47" firstAttribute="centerY" secondItem="T1Q-RS-8o6" secondAttribute="centerY" id="faX-hg-WfP"/>
|
||||
<constraint firstItem="5Yd-df-HbB" firstAttribute="top" secondItem="eCk-zY-LXq" secondAttribute="top" constant="55" id="h4R-2d-Xxn"/>
|
||||
<constraint firstAttribute="trailing" secondItem="oxX-IL-dG4" secondAttribute="trailing" constant="4" id="hDl-X9-M4n"/>
|
||||
<constraint firstItem="T1Q-RS-8o6" firstAttribute="centerX" secondItem="eCk-zY-LXq" secondAttribute="centerX" id="hmB-fl-oN2"/>
|
||||
<constraint firstItem="Q6g-b0-3sZ" firstAttribute="top" secondItem="eCk-zY-LXq" secondAttribute="top" constant="5" id="jST-Ic-lsn"/>
|
||||
<constraint firstAttribute="trailing" secondItem="X8H-1U-wc3" secondAttribute="trailing" constant="7" id="o5i-7H-n0G"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Jkz-Zp-aaG" secondAttribute="trailing" constant="7" id="uQe-FG-3lb"/>
|
||||
<constraint firstItem="X8H-1U-wc3" firstAttribute="top" secondItem="oxX-IL-dG4" secondAttribute="top" id="uTm-3W-QoM"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="directRoomBorderView" destination="xws-BR-H47" id="34A-hu-DXq"/>
|
||||
@@ -94,6 +114,8 @@
|
||||
<outlet property="missedNotifAndUnreadBadgeLabel" destination="ZUZ-tv-dVV" id="6IV-rz-s4I"/>
|
||||
<outlet property="roomAvatar" destination="T1Q-RS-8o6" id="4sR-Wm-jwz"/>
|
||||
<outlet property="roomTitle" destination="oxX-IL-dG4" id="vff-Fw-AOf"/>
|
||||
<outlet property="roomTitle1" destination="X8H-1U-wc3" id="nnS-Hp-1qV"/>
|
||||
<outlet property="roomTitle2" destination="Jkz-Zp-aaG" id="xO1-Av-NID"/>
|
||||
</connections>
|
||||
</collectionViewCell>
|
||||
</objects>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1108" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -47,12 +48,12 @@
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="details_icon" translatesAutoresizingMaskIntoConstraints="NO" id="S3Y-wJ-HOe">
|
||||
<rect key="frame" x="325" y="187" width="6" height="12"/>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="members_list_icon.png" translatesAutoresizingMaskIntoConstraints="NO" id="S3Y-wJ-HOe">
|
||||
<rect key="frame" x="260" y="185.5" width="15" height="15"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="RoomMembersDetailsIcon"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="6" id="XTx-6p-2wB"/>
|
||||
<constraint firstAttribute="height" constant="12" id="tXh-eB-ave"/>
|
||||
<constraint firstAttribute="width" constant="15" id="XTx-6p-2wB"/>
|
||||
<constraint firstAttribute="height" constant="15" id="tXh-eB-ave"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ckb-7c-sTg">
|
||||
@@ -67,9 +68,28 @@
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MFb-0F-eO8">
|
||||
<rect key="frame" x="0.0" y="177" width="600" height="38"/>
|
||||
<rect key="frame" x="0.0" y="177" width="322" height="38"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tsg-nl-P3k">
|
||||
<rect key="frame" x="322" y="173.5" width="38" height="38"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="add_participant.png" translatesAutoresizingMaskIntoConstraints="NO" id="i40-fd-AlH">
|
||||
<rect key="frame" x="10" y="10" width="18" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="18" id="Jxs-fk-U04"/>
|
||||
<constraint firstAttribute="width" secondItem="i40-fd-AlH" secondAttribute="height" multiplier="1:1" id="cuB-Hn-Dl3"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="38" id="E23-7d-llG"/>
|
||||
<constraint firstItem="i40-fd-AlH" firstAttribute="centerX" secondItem="tsg-nl-P3k" secondAttribute="centerX" id="gK0-hw-x7R"/>
|
||||
<constraint firstItem="i40-fd-AlH" firstAttribute="centerY" secondItem="tsg-nl-P3k" secondAttribute="centerY" id="tyV-XH-iOk"/>
|
||||
<constraint firstAttribute="width" secondItem="tsg-nl-P3k" secondAttribute="height" multiplier="1:1" id="xH6-0P-TLQ"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="RoomTitle"/>
|
||||
@@ -77,15 +97,18 @@
|
||||
<constraint firstAttribute="trailing" secondItem="uSp-YH-L18" secondAttribute="trailing" id="0UG-aH-hVB"/>
|
||||
<constraint firstItem="qD3-kA-DSI" firstAttribute="centerX" secondItem="BkF-x3-7fX" secondAttribute="centerX" id="1MA-VE-nEM"/>
|
||||
<constraint firstAttribute="bottom" secondItem="MFb-0F-eO8" secondAttribute="bottom" id="1W0-oZ-AQb"/>
|
||||
<constraint firstItem="tsg-nl-P3k" firstAttribute="centerY" secondItem="ou0-3Z-weL" secondAttribute="centerY" id="3Pa-cx-AsC"/>
|
||||
<constraint firstItem="6uH-I3-RQg" firstAttribute="centerX" secondItem="BkF-x3-7fX" secondAttribute="centerX" id="3uN-6W-rVZ"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="S3Y-wJ-HOe" secondAttribute="trailing" id="3z3-Ye-wh3"/>
|
||||
<constraint firstItem="8HH-9b-1yH" firstAttribute="leading" secondItem="BkF-x3-7fX" secondAttribute="leading" id="49B-Gu-i1k"/>
|
||||
<constraint firstItem="8HH-9b-1yH" firstAttribute="top" secondItem="BkF-x3-7fX" secondAttribute="top" id="4IU-hf-3R1"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="tsg-nl-P3k" secondAttribute="trailing" id="4Y7-tV-Spc"/>
|
||||
<constraint firstItem="ou0-3Z-weL" firstAttribute="centerX" secondItem="BkF-x3-7fX" secondAttribute="centerX" id="9kY-pQ-khO"/>
|
||||
<constraint firstItem="S3Y-wJ-HOe" firstAttribute="centerY" secondItem="ou0-3Z-weL" secondAttribute="centerY" id="C0N-Rf-ncJ"/>
|
||||
<constraint firstItem="S3Y-wJ-HOe" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="BkF-x3-7fX" secondAttribute="leading" id="Dib-vF-l0D"/>
|
||||
<constraint firstItem="qD3-kA-DSI" firstAttribute="top" secondItem="6uH-I3-RQg" secondAttribute="bottom" constant="5" id="IRZ-hl-lUU"/>
|
||||
<constraint firstItem="S3Y-wJ-HOe" firstAttribute="leading" secondItem="ou0-3Z-weL" secondAttribute="trailing" constant="7" id="JrS-kW-PJv"/>
|
||||
<constraint firstItem="MFb-0F-eO8" firstAttribute="leading" secondItem="BkF-x3-7fX" secondAttribute="leading" id="LTB-3D-soR"/>
|
||||
<constraint firstItem="tsg-nl-P3k" firstAttribute="leading" secondItem="MFb-0F-eO8" secondAttribute="trailing" id="QOq-Cv-1pw"/>
|
||||
<constraint firstItem="tsg-nl-P3k" firstAttribute="leading" secondItem="ou0-3Z-weL" secondAttribute="trailing" constant="4" id="RNc-DE-a8O"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="qD3-kA-DSI" secondAttribute="trailing" constant="31" id="RSk-Fd-oq0"/>
|
||||
<constraint firstAttribute="trailing" secondItem="8HH-9b-1yH" secondAttribute="trailing" id="SrK-30-YET"/>
|
||||
<constraint firstItem="MFb-0F-eO8" firstAttribute="top" secondItem="8HH-9b-1yH" secondAttribute="bottom" id="ULI-RY-Ase"/>
|
||||
@@ -97,16 +120,17 @@
|
||||
<constraint firstItem="uSp-YH-L18" firstAttribute="top" secondItem="BkF-x3-7fX" secondAttribute="top" id="dn3-Hv-OyX"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Ckb-7c-sTg" secondAttribute="trailing" id="erV-R4-LXD"/>
|
||||
<constraint firstItem="6uH-I3-RQg" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="BkF-x3-7fX" secondAttribute="leading" constant="31" id="gnq-cO-l4Y"/>
|
||||
<constraint firstItem="ou0-3Z-weL" firstAttribute="leading" secondItem="S3Y-wJ-HOe" secondAttribute="trailing" constant="7" id="iAL-UV-5nu"/>
|
||||
<constraint firstItem="qD3-kA-DSI" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="BkF-x3-7fX" secondAttribute="leading" constant="31" id="jjG-gN-eIv"/>
|
||||
<constraint firstItem="6uH-I3-RQg" firstAttribute="top" secondItem="uSp-YH-L18" secondAttribute="bottom" constant="8" id="rAh-mV-nb5"/>
|
||||
<constraint firstItem="ou0-3Z-weL" firstAttribute="top" secondItem="qD3-kA-DSI" secondAttribute="bottom" constant="14" id="sJB-Wr-gFl"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ou0-3Z-weL" secondAttribute="trailing" constant="31" id="sPZ-Hp-JeH"/>
|
||||
<constraint firstAttribute="trailing" secondItem="MFb-0F-eO8" secondAttribute="trailing" id="vjK-vS-uzY"/>
|
||||
<constraint firstItem="8HH-9b-1yH" firstAttribute="bottom" secondItem="qD3-kA-DSI" secondAttribute="bottom" constant="7" id="wzH-3D-S6C"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ou0-3Z-weL" secondAttribute="bottom" constant="14" id="yXn-jl-DeG"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="addParticipantMask" destination="tsg-nl-P3k" id="ADj-t1-9wf"/>
|
||||
<outlet property="bottomBorderView" destination="Ckb-7c-sTg" id="2Ky-GN-bO0"/>
|
||||
<outlet property="displayNameTextField" destination="6uH-I3-RQg" id="MfX-LQ-C2K"/>
|
||||
<outlet property="roomAvatarHeaderBackground" destination="uSp-YH-L18" id="sfW-ED-5bD"/>
|
||||
@@ -119,6 +143,7 @@
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="details_icon" width="31" height="31"/>
|
||||
<image name="add_participant.png" width="58" height="58"/>
|
||||
<image name="members_list_icon.png" width="12" height="12"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *titleMask;
|
||||
@property (weak, nonatomic) IBOutlet UIView *roomDetailsMask;
|
||||
@property (weak, nonatomic) IBOutlet UIView *addParticipantMask;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *displayNameCenterXConstraint;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *roomDetailsIconImageView;
|
||||
|
||||
|
||||
@@ -59,6 +59,16 @@
|
||||
[self.roomDetailsMask addGestureRecognizer:tap];
|
||||
self.roomDetailsMask.userInteractionEnabled = YES;
|
||||
}
|
||||
|
||||
if (_addParticipantMask)
|
||||
{
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reportTapGesture:)];
|
||||
[tap setNumberOfTouchesRequired:1];
|
||||
[tap setNumberOfTapsRequired:1];
|
||||
[tap setDelegate:self];
|
||||
[self.addParticipantMask addGestureRecognizer:tap];
|
||||
self.addParticipantMask.userInteractionEnabled = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
|
||||