diff --git a/CHANGES.rst b/CHANGES.rst index 6df19eb2a..90b2745c4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,23 +1,45 @@ -Changes in 0.7.0 () +Changes in 0.7.2 (2018-08-) =============================================== Improvements: -* RoomVC: Add "view decrypted source" option on the selected event (#1642). -* RoomVC: Implement replies sending (#1911). -* Support room versioning (#1938). -* Add support of lazy-loading of room members (#1931) (disabled for now). -* i18n: Add Traditional Chinese (zh_Hant). -* i18n: Add Albanian (sq). -* Update project structure. Organize UI related files by feature (PR#1932). -* Move image files to xcassets (PR#1932). -* Replies: Implement sending (#1911). -* Support room versioning (#1938). -* Add support of lazy-loading of room members (#1931). -* Chat screen: Add "view decrypted source" option on the selected event (#1642). -* Improve GDPR consent webview management (#1952). + * Upgrade MatrixKit version (v0.8.1). + * Server Quota Notices in Riot (#1937). + + Bug fix: + * User defaults: the preset application language (if any) is ignored. + +Changes in 0.7.1 (2018-08-17) +=============================================== + +Improvements: + * Upgrade MatrixKit version (v0.8.1). + +Bug fix: + * Empty app if initial /sync fails (#1975). + * Direct rooms can be lost on an initial /sync (vector-im/riot-ios/issues/1983). + * Fix possible race conditions in direct rooms management. + +Changes in 0.7.0 (2018-08-10) +=============================================== + +Improvements: + * Upgrade MatrixKit version (v0.8.0). + * RoomVC: Add "view decrypted source" option on the selected event (#1642). + * RoomVC: Implement replies sending (#1911). + * Support room versioning (#1938). + * Add support of lazy-loading of room members (#1931) (disabled for now). + * i18n: Add Traditional Chinese (zh_Hant). + * i18n: Add Albanian (sq). + * Update project structure. Organize UI related files by feature (PR#1932). + * Move image files to xcassets (PR#1932). + * Replies: Implement sending (#1911). + * Support room versioning (#1938). + * Add support of lazy-loading of room members (#1931). + * Chat screen: Add "view decrypted source" option on the selected event (#1642). + * Improve GDPR consent webview management (#1952). Bug fix: -* Multiple rooms can be opened (#1967). + * Multiple rooms can be opened (#1967). Changes in 0.6.20 (2018-07-13) =============================================== @@ -37,7 +59,6 @@ Changes in 0.6.18 (2018-07-03) =============================================== Improvements: - * Upgrade MatrixKit version (v0.7.15). * RoomVC: Add a re-request keys button on message unable to decrypt (#1879). * Analytics: Move code from AppDelegate to a dedicated class: Analytics. * Analytics: Track Matrix SDK stats (time to startup the app). diff --git a/Podfile b/Podfile index 90d6bd801..736793f20 100644 --- a/Podfile +++ b/Podfile @@ -9,7 +9,7 @@ source 'https://github.com/CocoaPods/Specs.git' # Different flavours of pods to MatrixKit # The current MatrixKit pod version -$matrixKitVersion = '0.7.15' +$matrixKitVersion = '0.8.1' # The develop branch version #$matrixKitVersion = 'develop' @@ -23,18 +23,18 @@ $matrixKitVersion = '0.7.15' def import_MatrixKit if $matrixKitVersion == 'local' pod 'MatrixSDK', :path => '../matrix-ios-sdk/MatrixSDK.podspec' - pod 'MatrixSDK/SwiftSupport', :path => '../matrix-ios-sdk/MatrixSDK.podspec' + #pod 'MatrixSDK/SwiftSupport', :path => '../matrix-ios-sdk/MatrixSDK.podspec' pod 'MatrixSDK/JingleCallStack', :path => '../matrix-ios-sdk/MatrixSDK.podspec' pod 'MatrixKit', :path => '../matrix-ios-kit/MatrixKit.podspec' else if $matrixKitVersion == 'develop' pod 'MatrixSDK', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' - pod 'MatrixSDK/SwiftSupport', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' + #pod 'MatrixSDK/SwiftSupport', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' pod 'MatrixSDK/JingleCallStack', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' pod 'MatrixKit', :git => 'https://github.com/matrix-org/matrix-ios-kit.git', :branch => 'develop' else pod 'MatrixKit', $matrixKitVersion - pod 'MatrixSDK/SwiftSupport' + #pod 'MatrixSDK/SwiftSupport' pod 'MatrixSDK/JingleCallStack' end end @@ -44,18 +44,18 @@ end def import_MatrixKitAppExtension if $matrixKitVersion == 'local' pod 'MatrixSDK', :path => '../matrix-ios-sdk/MatrixSDK.podspec' - pod 'MatrixSDK/SwiftSupport', :path => '../matrix-ios-sdk/MatrixSDK.podspec' + #pod 'MatrixSDK/SwiftSupport', :path => '../matrix-ios-sdk/MatrixSDK.podspec' pod 'MatrixSDK/JingleCallStack', :path => '../matrix-ios-sdk/MatrixSDK.podspec' pod 'MatrixKit/AppExtension', :path => '../matrix-ios-kit/MatrixKit.podspec' else if $matrixKitVersion == 'develop' pod 'MatrixSDK', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' - pod 'MatrixSDK/SwiftSupport', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' + #pod 'MatrixSDK/SwiftSupport', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' pod 'MatrixSDK/JingleCallStack', :git => 'https://github.com/matrix-org/matrix-ios-sdk.git', :branch => 'develop' pod 'MatrixKit/AppExtension', :git => 'https://github.com/matrix-org/matrix-ios-kit.git', :branch => 'develop' else pod 'MatrixKit/AppExtension', $matrixKitVersion - pod 'MatrixSDK/SwiftSupport' + #pod 'MatrixSDK/SwiftSupport' pod 'MatrixSDK/JingleCallStack' end end diff --git a/Podfile.lock b/Podfile.lock index bbcc75a9a..68496c18c 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -43,55 +43,55 @@ PODS: - GZIP (1.2.1) - HPGrowingTextView (1.1) - libPhoneNumber-iOS (0.9.13) - - MatrixKit (0.7.15): + - MatrixKit (0.8.1): - cmark (~> 0.24.1) - DTCoreText (~> 1.6.21) - HPGrowingTextView (~> 1.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixKit/Core (= 0.7.15) - - MatrixSDK (= 0.10.12) - - MatrixKit/AppExtension (0.7.15): + - MatrixKit/Core (= 0.8.1) + - MatrixSDK (= 0.11.1) + - MatrixKit/AppExtension (0.8.1): - cmark (~> 0.24.1) - DTCoreText (~> 1.6.21) - DTCoreText/Extension - HPGrowingTextView (~> 1.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.10.12) - - MatrixKit/Core (0.7.15): + - MatrixSDK (= 0.11.1) + - MatrixKit/Core (0.8.1): - cmark (~> 0.24.1) - DTCoreText (~> 1.6.21) - HPGrowingTextView (~> 1.1) - libPhoneNumber-iOS (~> 0.9.13) - - MatrixSDK (= 0.10.12) - - MatrixSDK (0.10.12): - - MatrixSDK/Core (= 0.10.12) - - MatrixSDK/Core (0.10.12): + - MatrixSDK (= 0.11.1) + - MatrixSDK (0.11.1): + - MatrixSDK/Core (= 0.11.1) + - MatrixSDK/Core (0.11.1): - AFNetworking (~> 3.2.0) - GZIP (~> 1.2.1) - - OLMKit (~> 2.2.2) - - Realm (~> 3.6.0) - - MatrixSDK/JingleCallStack (0.10.12): + - OLMKit (~> 2.3.0) + - Realm (~> 3.7.4) + - MatrixSDK/JingleCallStack (0.11.1): - MatrixSDK/Core - WebRTC (= 63.11.20455) - - OLMKit (2.2.2): - - OLMKit/olmc (= 2.2.2) - - OLMKit/olmcpp (= 2.2.2) - - OLMKit/olmc (2.2.2) - - OLMKit/olmcpp (2.2.2) + - OLMKit (2.3.0): + - OLMKit/olmc (= 2.3.0) + - OLMKit/olmcpp (= 2.3.0) + - OLMKit/olmc (2.3.0) + - OLMKit/olmcpp (2.3.0) - PiwikTracker (4.4.2): - PiwikTracker/Core (= 4.4.2) - PiwikTracker/Core (4.4.2) - - Realm (3.6.0): - - Realm/Headers (= 3.6.0) - - Realm/Headers (3.6.0) + - Realm (3.7.6): + - Realm/Headers (= 3.7.6) + - Realm/Headers (3.7.6) - WebRTC (63.11.20455) DEPENDENCIES: - cmark - DTCoreText - GBDeviceInfo (~> 5.2.0) - - MatrixKit (= 0.7.15) - - MatrixKit/AppExtension (= 0.7.15) + - MatrixKit (= 0.8.1) + - MatrixKit/AppExtension (= 0.8.1) - MatrixSDK/JingleCallStack - OLMKit - PiwikTracker (from `https://github.com/manuroe/matomo-sdk-ios.git`, branch `feature/CustomVariables`) @@ -131,13 +131,13 @@ SPEC CHECKSUMS: GZIP: 7ee835f989fb3c6ea79005fc90b8fa6af710a70d HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19 libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa - MatrixKit: 5668775ddcb36939f22cb5e76dcf617980c52c75 - MatrixSDK: 5d5eae9a9a098ec130022da4a4925332df8df1d9 - OLMKit: b9d8c0ffee9ea8c45bc0aaa9afb47f93fba7efbd + MatrixKit: 8b0d82633286ba9be7b17adfeca003bed644cffe + MatrixSDK: 5562f0116b2b08f74b81e9df365a07151ca76584 + OLMKit: dd79cdc5fab9ec04c940a901e025195b7801f306 PiwikTracker: 42862c7b13028065c3dfd36b4dc38db8a5765acf - Realm: 08b464b462d4f31bbd4ba5f5a1c8722ef0a700b7 + Realm: 9eaecad54712d6246d08ba34c10f354e4715d7d3 WebRTC: f2a6203584745fe53532633397557876b5d71640 -PODFILE CHECKSUM: 948cd5479b6467245ee83ba82304e73d83c7e4e2 +PODFILE CHECKSUM: c1a7c995727b5697ab109e65cbfe947f5d5cda55 COCOAPODS: 1.5.3 diff --git a/Riot.xcodeproj/project.pbxproj b/Riot.xcodeproj/project.pbxproj index c13b8c2bd..f57a97e9c 100644 --- a/Riot.xcodeproj/project.pbxproj +++ b/Riot.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 3233F7461F3497E2006ACA81 /* JitsiMeet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3233F7441F3497DA006ACA81 /* JitsiMeet.framework */; }; 3233F7471F3497E2006ACA81 /* JitsiMeet.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3233F7441F3497DA006ACA81 /* JitsiMeet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 3284A35120A07C210044F922 /* postMessageAPI.js in Resources */ = {isa = PBXBuildFile; fileRef = 3284A35020A07C210044F922 /* postMessageAPI.js */; }; + 32C10340211DD1A100DFFB5D /* MatrixSDK+Swift.m in Sources */ = {isa = PBXBuildFile; fileRef = 32C1033F211DD1A100DFFB5D /* MatrixSDK+Swift.m */; }; 68A2327678CA647A9A7739C7 /* Pods_RiotPods_Riot.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0FAA1A49F76B0CE15C5CBD8 /* Pods_RiotPods_Riot.framework */; }; 926FA53F1F4C132000F826C2 /* MXSession+Riot.m in Sources */ = {isa = PBXBuildFile; fileRef = 926FA53E1F4C132000F826C2 /* MXSession+Riot.m */; }; 92726A471F58737A004AD26F /* IntentHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 92726A461F58737A004AD26F /* IntentHandler.m */; }; @@ -383,7 +384,7 @@ 24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = RiotShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 3233F7441F3497DA006ACA81 /* JitsiMeet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JitsiMeet.framework; sourceTree = ""; }; 3267EFB320E379FD00FF1CAA /* CHANGES.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CHANGES.rst; sourceTree = ""; }; - 3267EFB420E379FD00FF1CAA /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = Podfile; sourceTree = ""; }; + 3267EFB420E379FD00FF1CAA /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = Podfile; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 3267EFB520E379FD00FF1CAA /* AUTHORS.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS.rst; sourceTree = ""; }; 3267EFB620E379FD00FF1CAA /* README.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.rst; sourceTree = ""; }; 3284A35020A07C210044F922 /* postMessageAPI.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = postMessageAPI.js; sourceTree = ""; }; @@ -393,6 +394,8 @@ 32BDC9A4211C34C90064AF51 /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = sq.lproj/InfoPlist.strings; sourceTree = ""; }; 32BDC9A5211C34C90064AF51 /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = sq.lproj/Localizable.strings; sourceTree = ""; }; 32BDC9A6211C34C90064AF51 /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = sq.lproj/Vector.strings; sourceTree = ""; }; + 32C1033E211DD1A100DFFB5D /* MatrixSDK+Swift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MatrixSDK+Swift.h"; sourceTree = ""; }; + 32C1033F211DD1A100DFFB5D /* MatrixSDK+Swift.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MatrixSDK+Swift.m"; sourceTree = ""; }; 33F966BE1A83B32A2DFE24CA /* Pods-RiotPods-SiriIntents.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotPods-SiriIntents.release.xcconfig"; path = "Pods/Target Support Files/Pods-RiotPods-SiriIntents/Pods-RiotPods-SiriIntents.release.xcconfig"; sourceTree = ""; }; 397BCA987893439918EBF330 /* Pods-SiriIntents.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SiriIntents.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents.debug.xcconfig"; sourceTree = ""; }; 4D1164C2F07EF74950DCDA7A /* Pods-SiriIntents.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SiriIntents.release.xcconfig"; path = "Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents.release.xcconfig"; sourceTree = ""; }; @@ -2463,6 +2466,8 @@ F083BBEC1E7009EC00A9B29C /* UIViewController+RiotSearch.m */, 926FA53D1F4C132000F826C2 /* MXSession+Riot.h */, 926FA53E1F4C132000F826C2 /* MXSession+Riot.m */, + 32C1033E211DD1A100DFFB5D /* MatrixSDK+Swift.h */, + 32C1033F211DD1A100DFFB5D /* MatrixSDK+Swift.m */, ); path = Categories; sourceTree = ""; @@ -3123,6 +3128,7 @@ B1B5590920EF768F00210D55 /* RoomEmptyBubbleCell.m in Sources */, B1B5574720EE6C4D00210D55 /* UsersDevicesViewController.m in Sources */, B1B558D220EF768F00210D55 /* RoomEncryptedDataBubbleCell.m in Sources */, + 32C10340211DD1A100DFFB5D /* MatrixSDK+Swift.m in Sources */, B1B558FA20EF768F00210D55 /* RoomMembershipBubbleCell.m in Sources */, B1B557BF20EF5B4500210D55 /* DisabledRoomInputToolbarView.m in Sources */, B1B5578620EF564900210D55 /* GroupTableViewCellWithSwitch.m in Sources */, diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index 8047f6841..b31e9c60d 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -400,6 +400,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN NSLog(@"MatrixSDK version: %@", MatrixSDKVersion); NSLog(@"Build: %@\n", build); NSLog(@"------------------------------\n"); + + [self setupUserDefaults]; // Set up runtime language and fallback by considering the userDefaults object shared within the application group. NSUserDefaults *sharedUserDefaults = [MXKAppSettings standardAppSettings].sharedUserDefaults; @@ -462,8 +464,6 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN _isAppForeground = NO; - [self setupUserDefaults]; - // Configure our analytics. It will indeed start if the option is enabled [MXSDKOptions sharedInstance].analyticsDelegate = [Analytics sharedInstance]; [DecryptionFailureTracker sharedInstance].delegate = [Analytics sharedInstance]; @@ -599,6 +599,18 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN } // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + + // Check if an initial sync failure occured while the app was in background + MXSession *mainSession = self.mxSessions.firstObject; + if (mainSession.state == MXSessionStateInitialSyncFailed) + { + // Inform the end user why the app appears blank + NSError *error = [NSError errorWithDomain:NSURLErrorDomain + code:NSURLErrorCannotConnectToHost + userInfo:@{NSLocalizedDescriptionKey : NSLocalizedStringFromTable(@"homeserver_connection_lost", @"Vector", nil)}]; + + [self showErrorAsAlert:error]; + } // Register to GDPR consent not given notification [self registerUserConsentNotGivenNotification]; diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 08b8d3258..8d7ec630b 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -133,6 +133,7 @@ "room_recents_conversations_section" = "ROOMS"; "room_recents_no_conversation" = "No rooms"; "room_recents_low_priority_section" = "LOW PRIORITY"; +"room_recents_server_notice_section" = "SYSTEM ALERTS"; "room_recents_invites_section" = "INVITES"; "room_recents_start_chat_with" = "Start chat"; "room_recents_create_empty_room" = "Create room"; @@ -277,6 +278,9 @@ "room_replacement_link" = "The conversation continues here."; "room_predecessor_information" = "This room is a continuation of another conversation."; "room_predecessor_link" = "Click here to see older messages."; +"room_resource_limit_exceeded_message_contact_1" = " Please "; +"room_resource_limit_exceeded_message_contact_2_link" = "contact your service administrator"; +"room_resource_limit_exceeded_message_contact_3" = " to continue using this service."; // Unknown devices "unknown_devices_alert_title" = "Room contains unknown devices"; @@ -537,6 +541,7 @@ "today" = "Today"; "yesterday" = "Yesterday"; "network_offline_prompt" = "The Internet connection appears to be offline."; +"homeserver_connection_lost" = "Could not connect to the homeserver."; "public_room_section_title" = "Public Rooms (at %@):"; "bug_report_prompt" = "The application has crashed last time. Would you like to submit a crash report?"; "rage_shake_prompt" = "You seem to be shaking the phone in frustration. Would you like to submit a bug report?"; diff --git a/Riot/Categories/MatrixSDK+Swift.h b/Riot/Categories/MatrixSDK+Swift.h new file mode 100644 index 000000000..f87280d89 --- /dev/null +++ b/Riot/Categories/MatrixSDK+Swift.h @@ -0,0 +1,47 @@ +/* + Copyright 2018 New Vector Ltd + + 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 + +/** + IMPORTANT: This file must be removed once the pod 'MatrixSDK/SwiftSupport' can + be pushed. + + Methods are redefined here to skip NS_REFINED_FOR_SWIFT defined in their declaration. + */ + +@interface MXSession (Swift) + +- (MXHTTPOperation*)createRoomFromSwift:(NSString*)name + visibility:(MXRoomDirectoryVisibility)visibility + roomAlias:(NSString*)roomAlias + topic:(NSString*)topic + invite:(NSArray*)inviteArray + invite3PID:(NSArray*)invite3PIDArray + isDirect:(BOOL)isDirect + preset:(MXRoomPreset)preset + success:(void (^)(void))success + failure:(void (^)(NSError *error))failure; + +@end + + +@interface MXRoomSummary (Swift) + +@property (nonatomic, readonly) MXMembership membershipFromSwift; + +@end + diff --git a/Riot/Categories/MatrixSDK+Swift.m b/Riot/Categories/MatrixSDK+Swift.m new file mode 100644 index 000000000..b0b03c828 --- /dev/null +++ b/Riot/Categories/MatrixSDK+Swift.m @@ -0,0 +1,52 @@ +/* + Copyright 2018 New Vector Ltd + + 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 + +#import "MatrixSDK+Swift.h" + +@implementation MXSession (Swift) + +- (MXHTTPOperation*)createRoomFromSwift:(NSString*)name + visibility:(MXRoomDirectoryVisibility)visibility + roomAlias:(NSString*)roomAlias + topic:(NSString*)topic + invite:(NSArray*)inviteArray + invite3PID:(NSArray*)invite3PIDArray + isDirect:(BOOL)isDirect + preset:(MXRoomPreset)preset + success:(void (^)(void))success + failure:(void (^)(NSError *error))failure +{ + return [self createRoom:name visibility:visibility roomAlias:roomAlias topic:topic invite:inviteArray invite3PID:invite3PIDArray isDirect:isDirect preset:preset success:^(MXRoom *room) { + + if (success) + { + success(); + } + } failure:failure]; +} + +@end + +@implementation MXRoomSummary (Swift) + +- (MXMembership)membershipFromSwift +{ + return self.membership; +} + +@end diff --git a/Riot/Managers/OnBoarding/OnBoardingManager.swift b/Riot/Managers/OnBoarding/OnBoardingManager.swift index fd17d0028..f16f70076 100644 --- a/Riot/Managers/OnBoarding/OnBoardingManager.swift +++ b/Riot/Managers/OnBoarding/OnBoardingManager.swift @@ -49,21 +49,30 @@ final public class OnBoardingManager: NSObject { return } +// // Create DM room with Riot-bot +// +// let httpOperation = self.session.createRoom(name: nil, visibility: .private, alias: nil, topic: nil, invite: [Constants.riotBotMatrixId], invite3PID: nil, isDirect: true, preset: .trustedPrivateChat) { (response) in +// +// switch response { +// case .success(_): +// success?() +// case .failure(let error): +// NSLog("[OnBoardingManager] Create chat with riot-bot failed"); +// failure?(error) +// } +// } +// +// // Make multipe tries, until we get a response +// httpOperation.maxNumberOfTries = Constants.createRiotBotDMRequestMaxNumberOfTries + + // Create DM room with Riot-bot - - let httpOperation = self.session.createRoom(name: nil, visibility: .private, alias: nil, topic: nil, invite: [Constants.riotBotMatrixId], invite3PID: nil, isDirect: true, preset: .trustedPrivateChat) { (response) in - - switch response { - case .success(_): - success?() - case .failure(let error): - NSLog("[OnBoardingManager] Create chat with riot-bot failed"); - failure?(error) - } - } - + + let httpOperation = self.session.createRoom(fromSwift: nil, visibility: kMXRoomDirectoryVisibilityPrivate, roomAlias: nil, topic: nil, invite: [Constants.riotBotMatrixId], invite3PID: nil, isDirect: true, preset: kMXRoomPresetTrustedPrivateChat, success: success, failure: nil) + + // Make multipe tries, until we get a response - httpOperation.maxNumberOfTries = Constants.createRiotBotDMRequestMaxNumberOfTries + httpOperation?.maxNumberOfTries = Constants.createRiotBotDMRequestMaxNumberOfTries } // MARK: - Private @@ -76,12 +85,13 @@ final public class OnBoardingManager: NSObject { var isUSerJoinedARoom = false for roomSummary in roomSummaries { - if case .join = roomSummary.membership { + // if case .join = roomSummary.membership { + if case __MXMembershipJoin = roomSummary.membershipFromSwift { isUSerJoinedARoom = true break } } - + return isUSerJoinedARoom } } diff --git a/Riot/Modules/Authentication/AuthenticationViewController.m b/Riot/Modules/Authentication/AuthenticationViewController.m index 47d6ffd64..7b7f83947 100644 --- a/Riot/Modules/Authentication/AuthenticationViewController.m +++ b/Riot/Modules/Authentication/AuthenticationViewController.m @@ -427,20 +427,26 @@ } else { - [self isUserNameInUse:^(BOOL isUserNameInUse) { - - if (isUserNameInUse) + [self testUserRegistration:^(MXError *mxError) { + // We consider that a user can be registered if: + // - the username is not already in use + if ([mxError.errcode isEqualToString:kMXErrCodeStringUserInUse]) { NSLog(@"[AuthenticationVC] User name is already use"); [self onFailureDuringAuthRequest:[NSError errorWithDomain:MXKAuthErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey:[NSBundle mxk_localizedStringForKey:@"auth_username_in_use"]}]]; } + // - the server quota limits is not reached + else if ([mxError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded]) + { + [self showResourceLimitExceededError:mxError.userInfo]; + } else { [self.authenticationActivityIndicator stopAnimating]; - + // Show the supported 3rd party ids which may be added to the account authInputsview.thirdPartyIdentifiersHidden = NO; - + [self updateRegistrationScreenWithThirdPartyIdentifiersHidden:NO]; } }]; @@ -534,7 +540,15 @@ } else { - [super onFailureDuringAuthRequest:error]; + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if ([mxError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded]) + { + [self showResourceLimitExceededError:mxError.userInfo]; + } + else + { + [super onFailureDuringAuthRequest:error]; + } } } @@ -708,6 +722,23 @@ } } +- (void)showResourceLimitExceededError:(NSDictionary *)errorDict +{ + NSLog(@"[AuthenticationVC] showResourceLimitExceededError"); + + [self showResourceLimitExceededError:errorDict onAdminContactTapped:^(NSURL *adminContact) { + + if ([[UIApplication sharedApplication] canOpenURL:adminContact]) + { + [[UIApplication sharedApplication] openURL:adminContact]; + } + else + { + NSLog(@"[AuthenticationVC] adminContact(%@) cannot be opened", adminContact); + } + }]; +} + #pragma mark - KVO - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h index 81ca32c18..bfb3833b4 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h @@ -52,12 +52,14 @@ extern NSString *const kRecentsDataSourceTapOnDirectoryServerChange; @property (nonatomic) NSInteger peopleSection; @property (nonatomic) NSInteger conversationSection; @property (nonatomic) NSInteger lowPrioritySection; +@property (nonatomic) NSInteger serverNoticeSection; @property (nonatomic, readonly) NSArray* invitesCellDataArray; @property (nonatomic, readonly) NSArray* favoriteCellDataArray; @property (nonatomic, readonly) NSArray* peopleCellDataArray; @property (nonatomic, readonly) NSArray* conversationCellDataArray; @property (nonatomic, readonly) NSArray* lowPriorityCellDataArray; +@property (nonatomic, readonly) NSArray* serverNoticeCellDataArray; /** Set the delegate by specifying the selected display mode. diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m index ad27b3746..03d6c7e0b 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m @@ -32,7 +32,8 @@ #define RECENTSDATASOURCE_SECTION_FAVORITES 0x04 #define RECENTSDATASOURCE_SECTION_CONVERSATIONS 0x08 #define RECENTSDATASOURCE_SECTION_LOWPRIORITY 0x10 -#define RECENTSDATASOURCE_SECTION_PEOPLE 0x20 +#define RECENTSDATASOURCE_SECTION_SERVERNOTICE 0x20 +#define RECENTSDATASOURCE_SECTION_PEOPLE 0x40 #define RECENTSDATASOURCE_DEFAULT_SECTION_HEADER_HEIGHT 30.0 #define RECENTSDATASOURCE_DIRECTORY_SECTION_HEADER_HEIGHT 65.0 @@ -46,6 +47,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou NSMutableArray* peopleCellDataArray; NSMutableArray* conversationCellDataArray; NSMutableArray* lowPriorityCellDataArray; + NSMutableArray* serverNoticeCellDataArray; NSInteger shrinkedSectionsBitMask; @@ -61,9 +63,9 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou @end @implementation RecentsDataSource -@synthesize directorySection, invitesSection, favoritesSection, peopleSection, conversationSection, lowPrioritySection; +@synthesize directorySection, invitesSection, favoritesSection, peopleSection, conversationSection, lowPrioritySection, serverNoticeSection; @synthesize hiddenCellIndexPath, droppingCellIndexPath, droppingCellBackGroundView; -@synthesize invitesCellDataArray, favoriteCellDataArray, peopleCellDataArray, conversationCellDataArray, lowPriorityCellDataArray; +@synthesize invitesCellDataArray, favoriteCellDataArray, peopleCellDataArray, conversationCellDataArray, lowPriorityCellDataArray, serverNoticeCellDataArray; - (instancetype)init { @@ -74,6 +76,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou favoriteCellDataArray = [[NSMutableArray alloc] init]; peopleCellDataArray = [[NSMutableArray alloc] init]; lowPriorityCellDataArray = [[NSMutableArray alloc] init]; + serverNoticeCellDataArray = [[NSMutableArray alloc] init]; conversationCellDataArray = [[NSMutableArray alloc] init]; directorySection = -1; @@ -82,6 +85,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou peopleSection = -1; conversationSection = -1; lowPrioritySection = -1; + serverNoticeSection = -1; _areSectionsShrinkable = NO; shrinkedSectionsBitMask = 0; @@ -242,7 +246,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou // Check whether all data sources are ready before rendering recents if (self.state == MXKDataSourceStateReady) { - directorySection = favoritesSection = peopleSection = conversationSection = lowPrioritySection = invitesSection = -1; + directorySection = favoritesSection = peopleSection = conversationSection = lowPrioritySection = invitesSection = serverNoticeSection = -1; if (invitesCellDataArray.count > 0) { @@ -275,6 +279,11 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou { lowPrioritySection = sectionsCount++; } + + if (serverNoticeCellDataArray.count > 0) + { + serverNoticeSection = sectionsCount++; + } } return sectionsCount; @@ -311,6 +320,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou { count = lowPriorityCellDataArray.count; } + else if (section == serverNoticeSection && !(shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_SERVERNOTICE)) + { + count = serverNoticeCellDataArray.count; + } else if (section == invitesSection && !(shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_INVITES)) { count = invitesCellDataArray.count; @@ -378,6 +391,11 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou count = lowPriorityCellDataArray.count; title = NSLocalizedStringFromTable(@"room_recents_low_priority_section", @"Vector", nil); } + else if (section == serverNoticeSection) + { + count = serverNoticeCellDataArray.count; + title = NSLocalizedStringFromTable(@"room_recents_server_notice_section", @"Vector", nil); + } else if (section == invitesSection) { count = invitesCellDataArray.count; @@ -438,6 +456,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou { sectionArray = lowPriorityCellDataArray; } + else if (section == serverNoticeSection) + { + sectionArray = serverNoticeCellDataArray; + } for (id cellData in sectionArray) { @@ -521,6 +543,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou { sectionBitwise = RECENTSDATASOURCE_SECTION_LOWPRIORITY; } + else if (section == serverNoticeSection) + { + sectionBitwise = RECENTSDATASOURCE_SECTION_SERVERNOTICE; + } else if (section == invitesSection) { sectionBitwise = RECENTSDATASOURCE_SECTION_INVITES; @@ -889,6 +915,13 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou cellData = [lowPriorityCellDataArray objectAtIndex:cellDataIndex]; } } + else if (tableSection == serverNoticeSection) + { + if (cellDataIndex < serverNoticeCellDataArray.count) + { + cellData = [serverNoticeCellDataArray objectAtIndex:cellDataIndex]; + } + } else if (tableSection == invitesSection) { if (cellDataIndex < invitesCellDataArray.count) @@ -1041,6 +1074,21 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou indexPath = [NSIndexPath indexPathForRow:index inSection:lowPrioritySection]; } } + + if (!indexPath && (serverNoticeSection >= 0)) + { + index = [self cellIndexPosWithRoomId:roomId andMatrixSession:matrixSession within:serverNoticeCellDataArray]; + + if (index != NSNotFound) + { + // Check whether the low priority rooms are shrinked + if (shrinkedSectionsBitMask & RECENTSDATASOURCE_SECTION_SERVERNOTICE) + { + return nil; + } + indexPath = [NSIndexPath indexPathForRow:index inSection:serverNoticeSection]; + } + } return indexPath; } @@ -1055,12 +1103,13 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou [peopleCellDataArray removeAllObjects]; [conversationCellDataArray removeAllObjects]; [lowPriorityCellDataArray removeAllObjects]; + [serverNoticeCellDataArray removeAllObjects]; _missedFavouriteDiscussionsCount = _missedHighlightFavouriteDiscussionsCount = 0; _missedDirectDiscussionsCount = _missedHighlightDirectDiscussionsCount = 0; _missedGroupDiscussionsCount = _missedHighlightGroupDiscussionsCount = 0; - directorySection = favoritesSection = peopleSection = conversationSection = lowPrioritySection = invitesSection = -1; + directorySection = favoritesSection = peopleSection = conversationSection = lowPrioritySection = serverNoticeSection = invitesSection = -1; if (displayedRecentsDataSourceArray.count > 0) { @@ -1077,7 +1126,11 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou if (_recentsDataSourceMode == RecentsDataSourceModeHome) { - if (room.accountData.tags[kMXRoomTagFavourite]) + if (room.accountData.tags[kMXRoomTagServerNotice]) + { + [serverNoticeCellDataArray addObject:recentCellDataStoring]; + } + else if (room.accountData.tags[kMXRoomTagFavourite]) { [favoriteCellDataArray addObject:recentCellDataStoring]; } @@ -1288,6 +1341,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou [peopleCellDataArray sortUsingComparator:comparator]; [conversationCellDataArray sortUsingComparator:comparator]; [lowPriorityCellDataArray sortUsingComparator:comparator]; + [serverNoticeCellDataArray sortUsingComparator:comparator]; } } else if (favoriteCellDataArray.count > 0 && _recentsDataSourceMode == RecentsDataSourceModeFavourites) @@ -1421,8 +1475,8 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou { return NO; } - - return (path && ((path.section == favoritesSection) || (path.section == peopleSection) || (path.section == lowPrioritySection) || (path.section == conversationSection))); + + return (path && ((path.section == favoritesSection) || (path.section == peopleSection) || (path.section == lowPrioritySection) || (path.section == serverNoticeSection) || (path.section == conversationSection))); } - (BOOL)canCellMoveFrom:(NSIndexPath*)oldPath to:(NSIndexPath*)newPath @@ -1451,6 +1505,10 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou { return kMXRoomTagLowPriority; } + else if (path.section == serverNoticeSection) + { + return kMXRoomTagServerNotice; + } return nil; } diff --git a/Riot/Modules/GlobalSearch/DataSources/UnifiedSearchRecentsDataSource.m b/Riot/Modules/GlobalSearch/DataSources/UnifiedSearchRecentsDataSource.m index 547972da0..4c87b10a5 100644 --- a/Riot/Modules/GlobalSearch/DataSources/UnifiedSearchRecentsDataSource.m +++ b/Riot/Modules/GlobalSearch/DataSources/UnifiedSearchRecentsDataSource.m @@ -89,7 +89,7 @@ if (_hideRecents) { - self.invitesSection = self.favoritesSection = self.peopleSection = self.conversationSection = self.lowPrioritySection = -1; + self.invitesSection = self.favoritesSection = self.peopleSection = self.conversationSection = self.lowPrioritySection = self.serverNoticeSection = -1; sectionsCount = sectionsOffset; } else @@ -114,6 +114,10 @@ { self.lowPrioritySection += sectionsOffset; } + if (self.serverNoticeSection != -1) + { + self.serverNoticeSection += sectionsOffset; + } sectionsCount += sectionsOffset; } } diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index d4d31dde3..44620d9ee 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -176,7 +176,10 @@ // Observe kAppDelegateNetworkStatusDidChangeNotification to handle network status change. id kAppDelegateNetworkStatusDidChangeNotificationObserver; - + + // Observers to manage MXSession state (and sync errors) + id kMXSessionStateDidChangeObserver; + // Observers to manage ongoing conference call banner id kMXCallStateDidChangeObserver; id kMXCallManagerConferenceStartedObserver; @@ -470,6 +473,7 @@ [self listenCallNotifications]; [self listenWidgetNotifications]; [self listenTombstoneEventNotifications]; + [self listenMXSessionStateChangeNotifications]; if (self.showExpandedHeader) { @@ -519,6 +523,7 @@ [self removeCallNotificationsListeners]; [self removeWidgetNotificationsListeners]; [self removeTombstoneEventNotificationsListener]; + [self removeMXSessionStateChangeNotificationsListener]; // Re-enable the read marker display, and disable its update. self.roomDataSource.showReadMarker = YES; @@ -941,8 +946,9 @@ BOOL canSend = (userPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsMessage:kMXEventTypeStringRoomMessage]); BOOL isRoomObsolete = self.roomDataSource.roomState.isObsolete; + BOOL isResourceLimitExceeded = [self.roomDataSource.mxSession.syncError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded]; - if (isRoomObsolete) + if (isRoomObsolete || isResourceLimitExceeded) { roomInputToolbarViewClass = nil; } @@ -1156,6 +1162,7 @@ [self removeCallNotificationsListeners]; [self removeWidgetNotificationsListeners]; [self removeTombstoneEventNotificationsListener]; + [self removeMXSessionStateChangeNotificationsListener]; if (previewHeader || (self.expandedHeaderContainer.isHidden == NO)) { @@ -3872,8 +3879,21 @@ } Widget *jitsiWidget = [customizedRoomDataSource jitsiWidget]; - - if ([AppDelegate theDelegate].isOffline) + + if ([self.roomDataSource.mxSession.syncError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded]) + { + [roomActivitiesView showResourceLimitExceededError:self.roomDataSource.mxSession.syncError.userInfo onAdminContactTapped:^(NSURL *adminContact) { + if ([[UIApplication sharedApplication] canOpenURL:adminContact]) + { + [[UIApplication sharedApplication] openURL:adminContact]; + } + else + { + NSLog(@"[RoomVC] refreshActivitiesViewDisplay: adminContact(%@) cannot be opened", adminContact); + } + }]; + } + else if ([AppDelegate theDelegate].isOffline) { [roomActivitiesView displayNetworkErrorNotification:NSLocalizedStringFromTable(@"room_offline_notification", @"Vector", nil)]; } @@ -4810,5 +4830,32 @@ } } +#pragma mark MXSession state change + +- (void)listenMXSessionStateChangeNotifications +{ + kMXSessionStateDidChangeObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:self.roomDataSource.mxSession queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + + if (self.roomDataSource.mxSession.state == MXSessionStateSyncError + || self.roomDataSource.mxSession.state == MXSessionStateRunning) + { + [self refreshActivitiesViewDisplay]; + + // update inputToolbarView + [self setRoomInputToolbarViewClass]; + [self updateInputToolBarViewHeight]; + } + }]; +} + +- (void)removeMXSessionStateChangeNotificationsListener +{ + if (kMXSessionStateDidChangeObserver) + { + [[NSNotificationCenter defaultCenter] removeObserver:kMXSessionStateDidChangeObserver]; + kMXSessionStateDidChangeObserver = nil; + } +} + @end diff --git a/Riot/Modules/Room/Views/Activities/RoomActivitiesView.h b/Riot/Modules/Room/Views/Activities/RoomActivitiesView.h index fc695bea6..df8b66581 100644 --- a/Riot/Modules/Room/Views/Activities/RoomActivitiesView.h +++ b/Riot/Modules/Room/Views/Activities/RoomActivitiesView.h @@ -85,6 +85,14 @@ */ - (void)displayRoomReplacementWithRoomLinkTappedHandler:(void (^)(void))onRoomReplacementLinkTapped; +/** + Display a kMXErrCodeStringResourceLimitExceeded error received during a /sync request. + + @param errorDict the error data. + @param onAdminContactTapped a callback indicating if the user wants to contact their admin. + */ +- (void)showResourceLimitExceededError:(NSDictionary *)errorDict onAdminContactTapped:(void (^)(NSURL *adminContact))onAdminContactTapped; + /** Remove any displayed information. */ diff --git a/Riot/Modules/Room/Views/Activities/RoomActivitiesView.m b/Riot/Modules/Room/Views/Activities/RoomActivitiesView.m index 56dc9b1b7..2634ed57a 100644 --- a/Riot/Modules/Room/Views/Activities/RoomActivitiesView.m +++ b/Riot/Modules/Room/Views/Activities/RoomActivitiesView.m @@ -374,6 +374,78 @@ [self checkHeight:YES]; } +- (void)showResourceLimitExceededError:(NSDictionary *)errorDict onAdminContactTapped:(void (^)(NSURL *adminContact))onAdminContactTapped +{ + [self reset]; + + CGFloat fontSize = 15; + + // Parse error data + NSString *limitType, *adminContactString; + NSURL *adminContact; + + MXJSONModelSetString(limitType, errorDict[kMXErrorResourceLimitExceededLimitTypeKey]); + MXJSONModelSetString(adminContactString, errorDict[kMXErrorResourceLimitExceededAdminContactKey]); + + if (adminContactString) + { + adminContact = [NSURL URLWithString:adminContactString]; + } + + // Build the message content + // Reuse MatrixKit as is for the beginning + NSMutableString *message = [NSMutableString new]; + if ([limitType isEqualToString:kMXErrorResourceLimitExceededLimitTypeMonthlyActiveUserValue]) + { + [message appendString:[NSBundle mxk_localizedStringForKey:@"login_error_resource_limit_exceeded_message_monthly_active_user"]]; + } + else + { + [message appendString:[NSBundle mxk_localizedStringForKey:@"login_error_resource_limit_exceeded_message_default"]]; + } + + NSDictionary *messageContact2LinkAttributes; + if (adminContact && onAdminContactTapped) + { + void (^onAdminContactTappedLink)(void) = ^() { + onAdminContactTapped(adminContact); + }; + + objc_setAssociatedObject(self.messageTextView, "onAdminContactTappedLink", [onAdminContactTappedLink copy], OBJC_ASSOCIATION_RETAIN_NONATOMIC); + messageContact2LinkAttributes = @{ + NSFontAttributeName : [UIFont systemFontOfSize:fontSize], + NSUnderlineStyleAttributeName : @(NSUnderlineStyleSingle), + NSLinkAttributeName : @"onAdminContactTappedLink", + }; + } + + NSDictionary *attributes = @{ + NSFontAttributeName: [UIFont systemFontOfSize:fontSize], + NSForegroundColorAttributeName: kRiotPrimaryBgColor + }; + + NSAttributedString *messageContact1 = [[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"room_resource_limit_exceeded_message_contact_1", @"Vector", nil) attributes:attributes]; + NSAttributedString *messageContact2Link = [[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"room_resource_limit_exceeded_message_contact_2_link", @"Vector", nil) attributes:messageContact2LinkAttributes]; + NSAttributedString *messageContact3 = [[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"room_resource_limit_exceeded_message_contact_3", @"Vector", nil) attributes:attributes]; + + NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:message attributes:attributes]; + [attributedText appendAttributedString:messageContact1]; + [attributedText appendAttributedString:messageContact2Link]; + [attributedText appendAttributedString:messageContact3]; + + self.messageTextView.attributedText = attributedText; + self.messageTextView.tintColor = kRiotPrimaryBgColor; + self.messageTextView.hidden = NO; + + self.backgroundColor = kRiotColorPinkRed; + self.messageTextView.backgroundColor = kRiotColorPinkRed; + + // Hide the separator to display correctly the banner + self.separatorView.hidden = YES; + + [self checkHeight:YES]; +} + - (void)reset { self.separatorView.hidden = NO; @@ -476,6 +548,16 @@ return NO; } + else if ([[URL absoluteString] isEqualToString:@"onAdminContactTappedLink"]) + { + void (^onAdminContactTappedLink)(void) = objc_getAssociatedObject(self.messageTextView, "onAdminContactTappedLink"); + if (onAdminContactTappedLink) + { + onAdminContactTappedLink(); + } + + return NO; + } return YES; } diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 7dfadf331..d7f340f00 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -117,7 +117,7 @@ enum enum { - //LABS_USE_ROOM_MEMBERS_LAZY_LOADING_INDEX = 0, + LABS_USE_ROOM_MEMBERS_LAZY_LOADING_INDEX = 0, LABS_USE_JITSI_WIDGET_INDEX = 0, LABS_CRYPTO_INDEX, LABS_COUNT @@ -2041,7 +2041,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); } else if (section == SETTINGS_SECTION_LABS_INDEX) { - /*if (row == LABS_USE_ROOM_MEMBERS_LAZY_LOADING_INDEX) + if (row == LABS_USE_ROOM_MEMBERS_LAZY_LOADING_INDEX) { MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; @@ -2052,7 +2052,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); cell = labelAndSwitchCell; } - else*/ if (row == LABS_USE_JITSI_WIDGET_INDEX) + else if (row == LABS_USE_JITSI_WIDGET_INDEX) { MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; @@ -2904,6 +2904,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); if (!switchButton.isOn) { + // Disable LL and reload [MXKAppSettings standardAppSettings].syncWithLazyLoadOfRoomMembers = NO; [self launchClearCache]; } @@ -2916,13 +2917,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); MXSession* session = [AppDelegate theDelegate].mxSessions.firstObject; MXWeakify(self); - [session setFilter:[MXFilterJSONModel syncFilterForLazyLoading] success:^(NSString *filterId) { - - // Lazy-loading is supported, enable it - [MXKAppSettings standardAppSettings].syncWithLazyLoadOfRoomMembers = YES; - [self launchClearCache]; - - } failure:^(NSError *error) { + void(^onFailure)(NSError *) = ^(NSError *error) { MXStrongifyAndReturnIfNil(self); [switchButton setOn:NO animated:YES]; @@ -2946,7 +2941,27 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); [self->currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCNoHSSupportOfLazyLoading"]; [self presentViewController:self->currentAlert animated:YES completion:nil]; - }]; + }; + + // Check first the home server supports m.lazy_load_members + [session supportedMatrixVersions:^(MXMatrixVersions *matrixVersions) { + + if (matrixVersions.supportLazyLoadMembers) + { + // Check then, we can create a LL filter on it + [session setFilter:[MXFilterJSONModel syncFilterForLazyLoading] success:^(NSString *filterId) { + + // Lazy-loading is fully supported, enable it + [MXKAppSettings standardAppSettings].syncWithLazyLoadOfRoomMembers = YES; + [self launchClearCache]; + + } failure:onFailure]; + } + else + { + onFailure(nil); + } + } failure:onFailure]; } } } diff --git a/Riot/SupportingFiles/Info.plist b/Riot/SupportingFiles/Info.plist index f017f4c89..446dd004c 100644 --- a/Riot/SupportingFiles/Info.plist +++ b/Riot/SupportingFiles/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.6.20 + 0.7.1 CFBundleSignature ???? CFBundleVersion - 0.6.20 + 0.7.1 ITSAppUsesNonExemptEncryption ITSEncryptionExportComplianceCode diff --git a/Riot/SupportingFiles/Riot-Bridging-Header.h b/Riot/SupportingFiles/Riot-Bridging-Header.h index 59026bb56..02b3ba165 100644 --- a/Riot/SupportingFiles/Riot-Bridging-Header.h +++ b/Riot/SupportingFiles/Riot-Bridging-Header.h @@ -4,3 +4,4 @@ @import MatrixSDK; #import "WebViewViewController.h" +#import "MatrixSDK+Swift.h" diff --git a/RiotShareExtension/SupportingFiles/Info.plist b/RiotShareExtension/SupportingFiles/Info.plist index 71d2af70e..a5061299f 100644 --- a/RiotShareExtension/SupportingFiles/Info.plist +++ b/RiotShareExtension/SupportingFiles/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 0.6.20 + 0.7.1 CFBundleVersion - 0.6.20 + 0.7.1 NSExtension NSExtensionAttributes diff --git a/SiriIntents/Info.plist b/SiriIntents/Info.plist index 429d4d1cd..2d9b1c51d 100644 --- a/SiriIntents/Info.plist +++ b/SiriIntents/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 0.6.20 + 0.7.1 CFBundleVersion - 0.6.20 + 0.7.1 NSExtension NSExtensionAttributes