Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Weblate 2017-09-21 13:09:02 +00:00
commit 0854424921
132 changed files with 5973 additions and 691 deletions

View file

@ -1,3 +1,20 @@
Changes in 0.5.3 (2017-08-25)
===============================================
Improvements:
* Upgrade MatrixKit version (v0.6.2).
* Support dark theme (vector-im/riot-meta#22).
* Set the application group identifier to be able to share userDefaults object.
Bug Fixes:
* SettingsViewController: Release correctly the pushed view controller.
* App have crashed whilst uploading photos (#1445).
* Register for remote notifications only if user provides access to notification feature, thanks to @aramsargsyan (#1467).
* Improvements in notification registration flow, thanks to @aramsargsyan (#1472).
Translations:
* Enable Russian.
Changes in 0.5.2 (2017-08-01)
===============================================

37
Podfile
View file

@ -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.6.1'
pod 'MatrixKit', '0.6.2'
# The lastest release available on the CocoaPods repository
#pod 'MatrixKit'
@ -38,6 +38,41 @@ pod 'Realm', '~> 2.8.1'
pod 'OLMKit', :inhibit_warnings => true
pod 'cmark', :inhibit_warnings => true
pod 'DTCoreText', :inhibit_warnings => true
end
target "RiotShareExtension" do
pod 'GoogleAnalytics'
# The Google WebRTC stack
pod 'WebRTC', '58.17.16937'
# OLMKit for crypto
pod 'OLMKit'
#pod 'OLMKit', :path => '../olm/OLMKit.podspec'
pod 'Realm', '~> 2.8.1'
# The tagged version on which this version of Riot share extension has been built
pod 'MatrixKit/AppExtension', '0.6.2'
# The lastest release available on the CocoaPods repository
#pod 'MatrixKit/AppExtension'
# The develop branch version
#pod 'MatrixSDK', :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'
# The one used for developing both MatrixSDK and MatrixKit
# Note that MatrixSDK must be cloned into a folder called matrix-ios-sdk next to the MatrixKit folder
#pod 'MatrixSDK', :path => '../matrix-ios-sdk/MatrixSDK.podspec'
#pod 'MatrixKit/AppExtension', :path => '../matrix-ios-kit/MatrixKit.podspec'
# Remove warnings from "bad" pods
pod 'OLMKit', :inhibit_warnings => true
pod 'cmark', :inhibit_warnings => true
end

View file

@ -26,6 +26,11 @@ PODS:
- DTFoundation/DTAnimatedGIF (~> 1.7.5)
- DTFoundation/DTHTMLParser (~> 1.7.5)
- DTFoundation/UIKit (~> 1.7.5)
- DTCoreText/Extension (1.6.20):
- DTFoundation/Core (~> 1.7.5)
- DTFoundation/DTAnimatedGIF (~> 1.7.5)
- DTFoundation/DTHTMLParser (~> 1.7.5)
- DTFoundation/UIKit (~> 1.7.5)
- DTFoundation/Core (1.7.12)
- DTFoundation/DTAnimatedGIF (1.7.12)
- DTFoundation/DTHTMLParser (1.7.12):
@ -39,13 +44,27 @@ PODS:
- GZIP (1.1.1)
- HPGrowingTextView (1.1)
- libPhoneNumber-iOS (0.9.10)
- MatrixKit (0.6.1):
- MatrixKit (0.6.2):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.17)
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.10)
- MatrixSDK (= 0.9.1)
- MatrixSDK (0.9.1):
- MatrixKit/Core (= 0.6.2)
- MatrixSDK (= 0.9.2)
- MatrixKit/AppExtension (0.6.2):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.17)
- DTCoreText/Extension
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.10)
- MatrixSDK (= 0.9.2)
- MatrixKit/Core (0.6.2):
- cmark (~> 0.24.1)
- DTCoreText (~> 1.6.17)
- HPGrowingTextView (~> 1.1)
- libPhoneNumber-iOS (~> 0.9.10)
- MatrixSDK (= 0.9.2)
- MatrixSDK (0.9.2):
- AFNetworking (~> 3.1.0)
- GZIP (~> 1.1.1)
- OLMKit (2.2.2):
@ -63,7 +82,8 @@ DEPENDENCIES:
- DTCoreText
- GBDeviceInfo (~> 4.3.0)
- GoogleAnalytics
- MatrixKit (= 0.6.1)
- MatrixKit (= 0.6.2)
- MatrixKit/AppExtension (= 0.6.2)
- OLMKit
- Realm (~> 2.8.1)
- WebRTC (= 58.17.16937)
@ -78,12 +98,12 @@ SPEC CHECKSUMS:
GZIP: f8beb59597f651e6970a45b816508a9c6d700b77
HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19
libPhoneNumber-iOS: f721ae4d5854bce60934f9fb9b0b28e8e68913cb
MatrixKit: fbf30823fb64604b5f8bb8ef8cbb8d949189525b
MatrixSDK: c5d9b84da5e32b305c5def410f239a7d94c72105
MatrixKit: 8552ee8abf935b08ae08fc0000f53ab3218ea5a0
MatrixSDK: 0499dd3dbe293ce1e743a7cda181dcf50eda7f10
OLMKit: b9d8c0ffee9ea8c45bc0aaa9afb47f93fba7efbd
Realm: 3601ef091c8c499a31101d8563b991e75546cdce
WebRTC: 1e9a85bf75509eec44be6478c64e9de65ac82332
PODFILE CHECKSUM: 76ecd40dee0ff2c3007141b353b385be7e863d6c
PODFILE CHECKSUM: db0ae7d6037f7768feb2adf17119ba69d9e1a77b
COCOAPODS: 1.2.1
COCOAPODS: 1.3.1

View file

@ -7,8 +7,33 @@
objects = {
/* Begin PBXBuildFile section */
05D592A32FF1D1877B89F73C /* libPods-Riot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD9D0BDE9232898950554DD5 /* libPods-Riot.a */; };
2435179C1F375B9400D0683E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 2466B7551F2F80B800AE27B0 /* Info.plist */; };
2435179F1F375C0F00D0683E /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382C01F276AED00356143 /* Vector.strings */; };
245FC3ED1F3D079A00603C6A /* ShareExtensionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 245FC3EB1F3CAF9800603C6A /* ShareExtensionManager.m */; };
245FC3EF1F3DD30800603C6A /* RecentCellData.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BC071E7009EC00A9B29C /* RecentCellData.m */; };
2466B73E1F2DFAC100AE27B0 /* animatedLogo-4.png in Resources */ = {isa = PBXBuildFile; fileRef = F083BB201E7009EC00A9B29C /* animatedLogo-4.png */; };
24B5103E1EFA7083004C6AD2 /* ReadReceiptsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24B5103D1EFA7083004C6AD2 /* ReadReceiptsViewController.m */; };
24B510401EFA88CC004C6AD2 /* ReadReceiptsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 24B5103F1EFA88CC004C6AD2 /* ReadReceiptsViewController.xib */; };
24CBEC591F0EAD310093EABB /* RiotShareExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
24D6B3581F3C90D300FC7A71 /* ShareRecentsDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D6B3571F3C90D300FC7A71 /* ShareRecentsDataSource.m */; };
24D6B3591F3CA02900FC7A71 /* SharePresentingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D6B34B1F3C8F8A00FC7A71 /* SharePresentingViewController.m */; };
24D6B35A1F3CA02C00FC7A71 /* ShareViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D6B34D1F3C8F8A00FC7A71 /* ShareViewController.m */; };
24D6B35B1F3CA03300FC7A71 /* ShareViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 24D6B34E1F3C8F8A00FC7A71 /* ShareViewController.xib */; };
24D6B35C1F3CA03600FC7A71 /* RoomsListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D6B3491F3C8F8A00FC7A71 /* RoomsListViewController.m */; };
24D6B35D1F3CA03A00FC7A71 /* FallbackViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24D6B3461F3C8F8A00FC7A71 /* FallbackViewController.m */; };
24D6B35E1F3CA03E00FC7A71 /* FallbackViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 24D6B3471F3C8F8A00FC7A71 /* FallbackViewController.xib */; };
24EEE5A01F23A08900B3C705 /* RoomTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BCED1E7009EC00A9B29C /* RoomTableViewCell.m */; };
24EEE5A11F23A09A00B3C705 /* RiotDesignValues.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BC171E7009EC00A9B29C /* RiotDesignValues.m */; };
24EEE5A21F23A8B400B3C705 /* MXRoom+Riot.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BBE81E7009EC00A9B29C /* MXRoom+Riot.m */; };
24EEE5A31F23A8C300B3C705 /* AvatarGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BC111E7009EC00A9B29C /* AvatarGenerator.m */; };
24EEE5A41F24C06E00B3C705 /* (null) in Resources */ = {isa = PBXBuildFile; };
24EEE5A81F25529600B3C705 /* cancel@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0614A121EDEE65000F5DC9A /* cancel@3x.png */; };
24EEE5A91F25529900B3C705 /* cancel@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0614A111EDEE65000F5DC9A /* cancel@2x.png */; };
24EEE5AA1F25529C00B3C705 /* cancel.png in Resources */ = {isa = PBXBuildFile; fileRef = F0614A101EDEE65000F5DC9A /* cancel.png */; };
24EEE5AF1F25F0F500B3C705 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F083BBEF1E7009EC00A9B29C /* Images.xcassets */; };
24EEE5B41F2607C000B3C705 /* SegmentedViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F083BC4E1E7009EC00A9B29C /* SegmentedViewController.m */; };
24EEE5B51F2607C500B3C705 /* SegmentedViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F083BC4F1E7009EC00A9B29C /* SegmentedViewController.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 */; };
@ -27,7 +52,6 @@
32471CDD1F1373A100BDF50A /* RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32471CDB1F1373A100BDF50A /* RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib */; };
32471CE11F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 32471CDF1F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.m */; };
32471CE21F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32471CE01F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.xib */; };
325072141E8C0AC900A084B6 /* LaunchScreenLogo.png in Resources */ = {isa = PBXBuildFile; fileRef = 325072131E8C0AC900A084B6 /* LaunchScreenLogo.png */; };
325E1C151E8D03950018D91E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 325E1C131E8D03950018D91E /* LaunchScreen.storyboard */; };
327382B51F276AD200356143 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382A81F276AD200356143 /* InfoPlist.strings */; };
327382B61F276AD200356143 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382AA1F276AD200356143 /* Localizable.strings */; };
@ -38,6 +62,10 @@
327382C21F276AED00356143 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382BC1F276AED00356143 /* InfoPlist.strings */; };
327382C31F276AED00356143 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382BE1F276AED00356143 /* Localizable.strings */; };
327382C41F276AED00356143 /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382C01F276AED00356143 /* Vector.strings */; };
32918EA91F473BDB0076CA16 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 32918EA51F473BDB0076CA16 /* Localizable.strings */; };
32918EAA1F473BDB0076CA16 /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = 32918EA71F473BDB0076CA16 /* Vector.strings */; };
32935CB11F6056FD006888C8 /* IntegrationManagerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32935CB01F6056FD006888C8 /* IntegrationManagerViewController.m */; };
32935CB41F628BCE006888C8 /* IntegrationManager.js in Resources */ = {isa = PBXBuildFile; fileRef = 32935CB31F628BCE006888C8 /* IntegrationManager.js */; };
32AE61E41F0A971B007255F4 /* RoomMembershipBubbleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 32AE61E21F0A971B007255F4 /* RoomMembershipBubbleCell.m */; };
32AE61E51F0A971B007255F4 /* RoomMembershipBubbleCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32AE61E31F0A971B007255F4 /* RoomMembershipBubbleCell.xib */; };
32AE61E91F0CE099007255F4 /* RoomMembershipWithPaginationTitleBubbleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 32AE61E71F0CE099007255F4 /* RoomMembershipWithPaginationTitleBubbleCell.m */; };
@ -47,9 +75,15 @@
32AE61F41F0D2183007255F4 /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = 32AE61F01F0D2183007255F4 /* Vector.strings */; };
32D392181EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 32D392161EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.m */; };
32D392191EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32D392171EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib */; };
32E84FA11F6BD32700CA0B89 /* apps-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E84F9E1F6BD32700CA0B89 /* apps-icon.png */; };
32E84FA21F6BD32700CA0B89 /* apps-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E84F9F1F6BD32700CA0B89 /* apps-icon@2x.png */; };
32E84FA31F6BD32700CA0B89 /* apps-icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 32E84FA01F6BD32700CA0B89 /* apps-icon@3x.png */; };
32F3AE1A1F6FF4E600F0F004 /* WidgetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32F3AE191F6FF4E600F0F004 /* WidgetViewController.m */; };
32FD0A3D1EB0CD9B0072B066 /* BugReportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32FD0A3B1EB0CD9B0072B066 /* BugReportViewController.m */; };
32FD0A3E1EB0CD9B0072B066 /* BugReportViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32FD0A3C1EB0CD9B0072B066 /* BugReportViewController.xib */; };
E2EAC1A4FBD6FE5228584591 /* libPods-Riot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D8737F782E108CFD6908691 /* libPods-Riot.a */; };
92324BE31F4F66D3009DE194 /* IncomingCallView.m in Sources */ = {isa = PBXBuildFile; fileRef = 92324BE21F4F66D3009DE194 /* IncomingCallView.m */; };
92324BE61F4F6A60009DE194 /* CircleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 92324BE51F4F6A60009DE194 /* CircleButton.m */; };
A27ECCE3FC4971745D2CB78D /* libPods-RiotShareExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7246451C668D6782166E22EC /* libPods-RiotShareExtension.a */; };
F0131DE51F2200D600CBF707 /* RiotSplitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0131DE41F2200D600CBF707 /* RiotSplitViewController.m */; };
F02C1A861E8EB04C0045A404 /* PeopleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F02C1A841E8EB04C0045A404 /* PeopleViewController.m */; };
F05BD79E1E7AEBF800C69941 /* UnifiedSearchViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F05BD79D1E7AEBF800C69941 /* UnifiedSearchViewController.m */; };
@ -462,9 +496,13 @@
F0B4CBAC1F41F090008E99C5 /* EncryptionInfoView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0B4CBAB1F41F090008E99C5 /* EncryptionInfoView.xib */; };
F0B4CBB11F4215E3008E99C5 /* EventDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = F0B4CBAF1F4215E3008E99C5 /* EventDetailsView.m */; };
F0B4CBB21F4215E3008E99C5 /* EventDetailsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0B4CBB01F4215E3008E99C5 /* EventDetailsView.xib */; };
F0B5430A1F70FF8F00D29293 /* back_icon@4x.png in Resources */ = {isa = PBXBuildFile; fileRef = F0B543091F70FF8F00D29293 /* back_icon@4x.png */; };
F0B7A8B11F475783006E27D2 /* RoomsListViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F0B7A8AF1F4756A5006E27D2 /* RoomsListViewController.xib */; };
F0D2ADA11F6AA5FD00A7097D /* MXRoomSummary+Riot.m in Sources */ = {isa = PBXBuildFile; fileRef = F0D2ADA01F6AA5FD00A7097D /* MXRoomSummary+Riot.m */; };
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 */; };
F0DD05D01F615ECF00CB5292 /* LaunchScreenRiot.png in Resources */ = {isa = PBXBuildFile; fileRef = F0DD05CF1F615ECF00CB5292 /* LaunchScreenRiot.png */; };
F0E059FD1E9545BB004B83FB /* UnifiedSearchRecentsDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = F0E059FC1E9545BB004B83FB /* UnifiedSearchRecentsDataSource.m */; };
F0E05A021E963103004B83FB /* FavouritesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0E059FF1E963103004B83FB /* FavouritesViewController.m */; };
F0E05A031E963103004B83FB /* RoomsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F0E05A011E963103004B83FB /* RoomsViewController.m */; };
@ -497,6 +535,13 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
242661F51F12B1BA00D3FC08 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
proxyType = 1;
remoteGlobalIDString = 24CBEC4D1F0EAD310093EABB;
remoteInfo = "Riot Share Extension";
};
F094A9BF1B78D8F000B1FBBF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
@ -507,6 +552,17 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
24CBEC5D1F0EAD310093EABB /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
24CBEC591F0EAD310093EABB /* RiotShareExtension.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
3233F7481F3497E2006ACA81 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -521,10 +577,27 @@
/* End PBXCopyFilesBuildPhase section */
/* 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>"; };
12AA0005C8B3D8D8162584C5 /* Pods-RiotShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotShareExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RiotShareExtension/Pods-RiotShareExtension.debug.xcconfig"; sourceTree = "<group>"; };
245FC3EA1F3CAF9800603C6A /* ShareExtensionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareExtensionManager.h; sourceTree = "<group>"; };
245FC3EB1F3CAF9800603C6A /* ShareExtensionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareExtensionManager.m; sourceTree = "<group>"; };
2466B7551F2F80B800AE27B0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RiotShareExtension/Info.plist; sourceTree = SOURCE_ROOT; };
2466B7561F2F80B800AE27B0 /* RiotShareExtension.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = RiotShareExtension.entitlements; path = RiotShareExtension/RiotShareExtension.entitlements; sourceTree = SOURCE_ROOT; };
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>"; };
24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = RiotShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
24D6B3451F3C8F8A00FC7A71 /* FallbackViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FallbackViewController.h; sourceTree = "<group>"; };
24D6B3461F3C8F8A00FC7A71 /* FallbackViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FallbackViewController.m; sourceTree = "<group>"; };
24D6B3471F3C8F8A00FC7A71 /* FallbackViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = FallbackViewController.xib; sourceTree = "<group>"; };
24D6B3481F3C8F8A00FC7A71 /* RoomsListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomsListViewController.h; sourceTree = "<group>"; };
24D6B3491F3C8F8A00FC7A71 /* RoomsListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomsListViewController.m; sourceTree = "<group>"; };
24D6B34A1F3C8F8A00FC7A71 /* SharePresentingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharePresentingViewController.h; sourceTree = "<group>"; };
24D6B34B1F3C8F8A00FC7A71 /* SharePresentingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SharePresentingViewController.m; sourceTree = "<group>"; };
24D6B34C1F3C8F8A00FC7A71 /* ShareViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareViewController.h; sourceTree = "<group>"; };
24D6B34D1F3C8F8A00FC7A71 /* ShareViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareViewController.m; sourceTree = "<group>"; };
24D6B34E1F3C8F8A00FC7A71 /* ShareViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ShareViewController.xib; sourceTree = "<group>"; };
24D6B3561F3C90D300FC7A71 /* ShareRecentsDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareRecentsDataSource.h; sourceTree = "<group>"; };
24D6B3571F3C90D300FC7A71 /* ShareRecentsDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareRecentsDataSource.m; 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>"; };
@ -552,7 +625,6 @@
32471CDE1F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomMembershipExpandedWithPaginationTitleBubbleCell.h; sourceTree = "<group>"; };
32471CDF1F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomMembershipExpandedWithPaginationTitleBubbleCell.m; sourceTree = "<group>"; };
32471CE01F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomMembershipExpandedWithPaginationTitleBubbleCell.xib; sourceTree = "<group>"; };
325072131E8C0AC900A084B6 /* LaunchScreenLogo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LaunchScreenLogo.png; path = Assets/Images/LaunchScreenLogo.png; sourceTree = "<group>"; };
325E1C141E8D03950018D91E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
327382A91F276AD200356143 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = InfoPlist.strings; sourceTree = "<group>"; };
327382AB1F276AD200356143 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Localizable.strings; sourceTree = "<group>"; };
@ -563,6 +635,11 @@
327382BD1F276AED00356143 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = "<group>"; };
327382BF1F276AED00356143 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = "<group>"; };
327382C11F276AED00356143 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Vector.strings; sourceTree = "<group>"; };
32918EA61F473BDB0076CA16 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Localizable.strings; sourceTree = "<group>"; };
32918EA81F473BDB0076CA16 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Vector.strings; sourceTree = "<group>"; };
32935CAF1F6056FD006888C8 /* IntegrationManagerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IntegrationManagerViewController.h; sourceTree = "<group>"; };
32935CB01F6056FD006888C8 /* IntegrationManagerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IntegrationManagerViewController.m; sourceTree = "<group>"; };
32935CB31F628BCE006888C8 /* IntegrationManager.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = IntegrationManager.js; sourceTree = "<group>"; };
32AE61E11F0A971B007255F4 /* RoomMembershipBubbleCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomMembershipBubbleCell.h; sourceTree = "<group>"; };
32AE61E21F0A971B007255F4 /* RoomMembershipBubbleCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomMembershipBubbleCell.m; sourceTree = "<group>"; };
32AE61E31F0A971B007255F4 /* RoomMembershipBubbleCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomMembershipBubbleCell.xib; sourceTree = "<group>"; };
@ -575,10 +652,22 @@
32D392151EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectoryServerDetailTableViewCell.h; sourceTree = "<group>"; };
32D392161EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectoryServerDetailTableViewCell.m; sourceTree = "<group>"; };
32D392171EB9B7AB009A2BAF /* DirectoryServerDetailTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DirectoryServerDetailTableViewCell.xib; sourceTree = "<group>"; };
32E84F9E1F6BD32700CA0B89 /* apps-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apps-icon.png"; sourceTree = "<group>"; };
32E84F9F1F6BD32700CA0B89 /* apps-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apps-icon@2x.png"; sourceTree = "<group>"; };
32E84FA01F6BD32700CA0B89 /* apps-icon@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "apps-icon@3x.png"; sourceTree = "<group>"; };
32F3AE181F6FF4E600F0F004 /* WidgetViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WidgetViewController.h; sourceTree = "<group>"; };
32F3AE191F6FF4E600F0F004 /* WidgetViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WidgetViewController.m; sourceTree = "<group>"; };
32FD0A3A1EB0CD9B0072B066 /* BugReportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugReportViewController.h; sourceTree = "<group>"; };
32FD0A3B1EB0CD9B0072B066 /* BugReportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugReportViewController.m; sourceTree = "<group>"; };
32FD0A3C1EB0CD9B0072B066 /* BugReportViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = BugReportViewController.xib; sourceTree = "<group>"; };
7D8737F782E108CFD6908691 /* libPods-Riot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Riot.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7246451C668D6782166E22EC /* libPods-RiotShareExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RiotShareExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; };
765F5104DB3EC39713DEB3A4 /* Pods-RiotShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RiotShareExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-RiotShareExtension/Pods-RiotShareExtension.release.xcconfig"; sourceTree = "<group>"; };
839BB91240D350D5607D55BA /* 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>"; };
92324BE11F4F66D3009DE194 /* IncomingCallView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncomingCallView.h; sourceTree = "<group>"; };
92324BE21F4F66D3009DE194 /* IncomingCallView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IncomingCallView.m; sourceTree = "<group>"; };
92324BE41F4F6A60009DE194 /* CircleButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CircleButton.h; sourceTree = "<group>"; };
92324BE51F4F6A60009DE194 /* CircleButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CircleButton.m; sourceTree = "<group>"; };
C195C53961EA28E6900AEB68 /* Pods-Riot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Riot.release.xcconfig"; path = "Pods/Target Support Files/Pods-Riot/Pods-Riot.release.xcconfig"; sourceTree = "<group>"; };
F0131DE31F2200D600CBF707 /* RiotSplitViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RiotSplitViewController.h; sourceTree = "<group>"; };
F0131DE41F2200D600CBF707 /* RiotSplitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RiotSplitViewController.m; sourceTree = "<group>"; };
F02C1A831E8EB04C0045A404 /* PeopleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeopleViewController.h; sourceTree = "<group>"; };
@ -1114,9 +1203,14 @@
F0B4CBAE1F4215E3008E99C5 /* EventDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventDetailsView.h; sourceTree = "<group>"; };
F0B4CBAF1F4215E3008E99C5 /* EventDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventDetailsView.m; sourceTree = "<group>"; };
F0B4CBB01F4215E3008E99C5 /* EventDetailsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = EventDetailsView.xib; sourceTree = "<group>"; };
F0B543091F70FF8F00D29293 /* back_icon@4x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_icon@4x.png"; sourceTree = "<group>"; };
F0B7A8AF1F4756A5006E27D2 /* RoomsListViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RoomsListViewController.xib; sourceTree = "<group>"; };
F0D2AD9F1F6AA5FD00A7097D /* MXRoomSummary+Riot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXRoomSummary+Riot.h"; sourceTree = "<group>"; };
F0D2ADA01F6AA5FD00A7097D /* MXRoomSummary+Riot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MXRoomSummary+Riot.m"; 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>"; };
F0DD05CF1F615ECF00CB5292 /* LaunchScreenRiot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = LaunchScreenRiot.png; path = Assets/Images/LaunchScreenRiot.png; sourceTree = "<group>"; };
F0E059FB1E9545BB004B83FB /* UnifiedSearchRecentsDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnifiedSearchRecentsDataSource.h; sourceTree = "<group>"; };
F0E059FC1E9545BB004B83FB /* UnifiedSearchRecentsDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UnifiedSearchRecentsDataSource.m; sourceTree = "<group>"; };
F0E059FE1E963103004B83FB /* FavouritesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FavouritesViewController.h; sourceTree = "<group>"; };
@ -1150,15 +1244,23 @@
F0E05A2D1EA0F9EB004B83FB /* tab_rooms.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = tab_rooms.png; sourceTree = "<group>"; };
F0E05A2E1EA0F9EB004B83FB /* tab_rooms@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_rooms@2x.png"; sourceTree = "<group>"; };
F0E05A2F1EA0F9EB004B83FB /* tab_rooms@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_rooms@3x.png"; sourceTree = "<group>"; };
F9D678EF54918C036FDEDBF9 /* Pods-Riot.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Riot.release.xcconfig"; path = "Pods/Target Support Files/Pods-Riot/Pods-Riot.release.xcconfig"; sourceTree = "<group>"; };
FD9D0BDE9232898950554DD5 /* libPods-Riot.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Riot.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
24CBEC4B1F0EAD310093EABB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A27ECCE3FC4971745D2CB78D /* libPods-RiotShareExtension.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F094A99F1B78D8F000B1FBBF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E2EAC1A4FBD6FE5228584591 /* libPods-Riot.a in Frameworks */,
05D592A32FF1D1877B89F73C /* libPods-Riot.a in Frameworks */,
3233F7461F3497E2006ACA81 /* JitsiMeet.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1173,6 +1275,49 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
24CBEC4F1F0EAD310093EABB /* RiotShareExtension */ = {
isa = PBXGroup;
children = (
2466B7551F2F80B800AE27B0 /* Info.plist */,
2466B7561F2F80B800AE27B0 /* RiotShareExtension.entitlements */,
24D6B3441F3C8F8A00FC7A71 /* ViewController */,
24D6B3551F3C8FCC00FC7A71 /* Model */,
);
name = RiotShareExtension;
path = "Riot Share Extension";
sourceTree = "<group>";
};
24D6B3441F3C8F8A00FC7A71 /* ViewController */ = {
isa = PBXGroup;
children = (
24D6B34A1F3C8F8A00FC7A71 /* SharePresentingViewController.h */,
24D6B34B1F3C8F8A00FC7A71 /* SharePresentingViewController.m */,
24D6B34C1F3C8F8A00FC7A71 /* ShareViewController.h */,
24D6B34D1F3C8F8A00FC7A71 /* ShareViewController.m */,
24D6B34E1F3C8F8A00FC7A71 /* ShareViewController.xib */,
24D6B3481F3C8F8A00FC7A71 /* RoomsListViewController.h */,
24D6B3491F3C8F8A00FC7A71 /* RoomsListViewController.m */,
F0B7A8AF1F4756A5006E27D2 /* RoomsListViewController.xib */,
24D6B3451F3C8F8A00FC7A71 /* FallbackViewController.h */,
24D6B3461F3C8F8A00FC7A71 /* FallbackViewController.m */,
24D6B3471F3C8F8A00FC7A71 /* FallbackViewController.xib */,
);
name = ViewController;
path = RiotShareExtension/ViewController;
sourceTree = SOURCE_ROOT;
};
24D6B3551F3C8FCC00FC7A71 /* Model */ = {
isa = PBXGroup;
children = (
245FC3EA1F3CAF9800603C6A /* ShareExtensionManager.h */,
245FC3EB1F3CAF9800603C6A /* ShareExtensionManager.m */,
24D6B3561F3C90D300FC7A71 /* ShareRecentsDataSource.h */,
24D6B3571F3C90D300FC7A71 /* ShareRecentsDataSource.m */,
);
name = Model;
path = RiotShareExtension/Model;
sourceTree = SOURCE_ROOT;
};
3205ED801E97725E003D65FA /* Directory */ = {
isa = PBXGroup;
children = (
@ -1197,6 +1342,10 @@
3233F72D1F31F47E006ACA81 /* Widgets */ = {
isa = PBXGroup;
children = (
32F3AE181F6FF4E600F0F004 /* WidgetViewController.h */,
32F3AE191F6FF4E600F0F004 /* WidgetViewController.m */,
32935CAF1F6056FD006888C8 /* IntegrationManagerViewController.h */,
32935CB01F6056FD006888C8 /* IntegrationManagerViewController.m */,
3233F72E1F31F4BF006ACA81 /* JitsiViewController.h */,
3233F72F1F31F4BF006ACA81 /* JitsiViewController.m */,
3233F7301F31F4BF006ACA81 /* JitsiViewController.xib */,
@ -1253,6 +1402,23 @@
path = en.lproj;
sourceTree = "<group>";
};
32918EA41F473BDB0076CA16 /* ru.lproj */ = {
isa = PBXGroup;
children = (
32918EA51F473BDB0076CA16 /* Localizable.strings */,
32918EA71F473BDB0076CA16 /* Vector.strings */,
);
path = ru.lproj;
sourceTree = "<group>";
};
32935CB21F628B98006888C8 /* js */ = {
isa = PBXGroup;
children = (
32935CB31F628BCE006888C8 /* IntegrationManager.js */,
);
path = js;
sourceTree = "<group>";
};
32AE61EB1F0D2183007255F4 /* nl.lproj */ = {
isa = PBXGroup;
children = (
@ -1263,23 +1429,37 @@
path = nl.lproj;
sourceTree = "<group>";
};
6567B0BBF3C05D7F7A7F79CC /* Frameworks */ = {
5FC42FA41F5186AFFB6A2404 /* Frameworks */ = {
isa = PBXGroup;
children = (
7D8737F782E108CFD6908691 /* libPods-Riot.a */,
FD9D0BDE9232898950554DD5 /* libPods-Riot.a */,
7246451C668D6782166E22EC /* libPods-RiotShareExtension.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
E1451F540F8BC02A7FB7AA31 /* Pods */ = {
7471DF3720D498384A068DA7 /* Pods */ = {
isa = PBXGroup;
children = (
1129C74A281B080432B1A1A1 /* Pods-Riot.debug.xcconfig */,
F9D678EF54918C036FDEDBF9 /* Pods-Riot.release.xcconfig */,
839BB91240D350D5607D55BA /* Pods-Riot.debug.xcconfig */,
C195C53961EA28E6900AEB68 /* Pods-Riot.release.xcconfig */,
12AA0005C8B3D8D8162584C5 /* Pods-RiotShareExtension.debug.xcconfig */,
765F5104DB3EC39713DEB3A4 /* Pods-RiotShareExtension.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
92324BE01F4F668F009DE194 /* Calls */ = {
isa = PBXGroup;
children = (
92324BE11F4F66D3009DE194 /* IncomingCallView.h */,
92324BE21F4F66D3009DE194 /* IncomingCallView.m */,
92324BE41F4F6A60009DE194 /* CircleButton.h */,
92324BE51F4F6A60009DE194 /* CircleButton.m */,
);
path = Calls;
sourceTree = "<group>";
};
F083BB021E7005FD00A9B29C /* RiotTests */ = {
isa = PBXGroup;
children = (
@ -1331,12 +1511,14 @@
F083BB0E1E7009EC00A9B29C /* Assets */ = {
isa = PBXGroup;
children = (
32918EA41F473BDB0076CA16 /* ru.lproj */,
327382A71F276AD200356143 /* de.lproj */,
327382BB1F276AED00356143 /* en.lproj */,
327382AE1F276AD200356143 /* fr.lproj */,
32AE61EB1F0D2183007255F4 /* nl.lproj */,
F083BB151E7009EC00A9B29C /* Images */,
F083BBDA1E7009EC00A9B29C /* Sounds */,
F083BB151E7009EC00A9B29C /* Images */,
32935CB21F628B98006888C8 /* js */,
);
path = Assets;
sourceTree = "<group>";
@ -1344,6 +1526,9 @@
F083BB151E7009EC00A9B29C /* Images */ = {
isa = PBXGroup;
children = (
32E84F9E1F6BD32700CA0B89 /* apps-icon.png */,
32E84F9F1F6BD32700CA0B89 /* apps-icon@2x.png */,
32E84FA01F6BD32700CA0B89 /* apps-icon@3x.png */,
F0A4A1641EF7CB66003630DB /* members_list_icon.png */,
F0A4A1651EF7CB66003630DB /* members_list_icon@2x.png */,
F0A4A1661EF7CB66003630DB /* members_list_icon@3x.png */,
@ -1394,6 +1579,7 @@
F083BB211E7009EC00A9B29C /* back_icon.png */,
F083BB221E7009EC00A9B29C /* back_icon@2x.png */,
F083BB231E7009EC00A9B29C /* back_icon@3x.png */,
F0B543091F70FF8F00D29293 /* back_icon@4x.png */,
F083BB241E7009EC00A9B29C /* bubbles_bg_landscape.png */,
F083BB251E7009EC00A9B29C /* bubbles_bg_landscape@2x.png */,
F083BB261E7009EC00A9B29C /* bubbles_bg_landscape@3x.png */,
@ -1599,6 +1785,8 @@
F083BBE61E7009EC00A9B29C /* MXKRoomBubbleTableViewCell+Riot.m */,
F083BBE71E7009EC00A9B29C /* MXRoom+Riot.h */,
F083BBE81E7009EC00A9B29C /* MXRoom+Riot.m */,
F0D2AD9F1F6AA5FD00A7097D /* MXRoomSummary+Riot.h */,
F0D2ADA01F6AA5FD00A7097D /* MXRoomSummary+Riot.m */,
F083BBE91E7009EC00A9B29C /* UINavigationController+Riot.h */,
F083BBEA1E7009EC00A9B29C /* UINavigationController+Riot.m */,
F083BBEB1E7009EC00A9B29C /* UIViewController+RiotSearch.h */,
@ -1787,6 +1975,7 @@
F083BC571E7009EC00A9B29C /* Views */ = {
isa = PBXGroup;
children = (
92324BE01F4F668F009DE194 /* Calls */,
F0B4CBAD1F4215E3008E99C5 /* Event */,
F083BC581E7009EC00A9B29C /* Authentication */,
F083BC5F1E7009EC00A9B29C /* Contact */,
@ -2120,7 +2309,7 @@
F083BEA41E700B2800A9B29C /* Supporting Files */ = {
isa = PBXGroup;
children = (
325072131E8C0AC900A084B6 /* LaunchScreenLogo.png */,
F0DD05CF1F615ECF00CB5292 /* LaunchScreenRiot.png */,
F083BBED1E7009EC00A9B29C /* empty.mm */,
F083BBEE1E7009EC00A9B29C /* GoogleService-Info.plist */,
F083BBF01E7009EC00A9B29C /* Info.plist */,
@ -2136,9 +2325,10 @@
children = (
F083BB081E7009EC00A9B29C /* Riot */,
F083BB021E7005FD00A9B29C /* RiotTests */,
24CBEC4F1F0EAD310093EABB /* RiotShareExtension */,
F094A9A31B78D8F000B1FBBF /* Products */,
E1451F540F8BC02A7FB7AA31 /* Pods */,
6567B0BBF3C05D7F7A7F79CC /* Frameworks */,
7471DF3720D498384A068DA7 /* Pods */,
5FC42FA41F5186AFFB6A2404 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -2147,6 +2337,7 @@
children = (
F094A9A21B78D8F000B1FBBF /* Riot.app */,
F094A9BE1B78D8F000B1FBBF /* RiotTests.xctest */,
24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */,
);
name = Products;
sourceTree = "<group>";
@ -2164,21 +2355,42 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
24CBEC4D1F0EAD310093EABB /* RiotShareExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 24CBEC5C1F0EAD310093EABB /* Build configuration list for PBXNativeTarget "RiotShareExtension" */;
buildPhases = (
3051A9ED306E05F8AE91C906 /* [CP] Check Pods Manifest.lock */,
24CBEC4A1F0EAD310093EABB /* Sources */,
24CBEC4B1F0EAD310093EABB /* Frameworks */,
24CBEC4C1F0EAD310093EABB /* Resources */,
8EA19F5011654D3BD5EDAC33 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = RiotShareExtension;
productName = "Riot Share Extension";
productReference = 24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
F094A9A11B78D8F000B1FBBF /* Riot */ = {
isa = PBXNativeTarget;
buildConfigurationList = F094A9C81B78D8F000B1FBBF /* Build configuration list for PBXNativeTarget "Riot" */;
buildPhases = (
9131C24971B46D743282FCF6 /* [CP] Check Pods Manifest.lock */,
2372F8E1A49557FE0072BC56 /* [CP] Check Pods Manifest.lock */,
F094A99E1B78D8F000B1FBBF /* Sources */,
F094A99F1B78D8F000B1FBBF /* Frameworks */,
F094A9A01B78D8F000B1FBBF /* Resources */,
44C35695CFA4F9799C449367 /* [CP] Copy Pods Resources */,
381DA4CC07D2104BFA23E45A /* [CP] Embed Pods Frameworks */,
24CBEC5D1F0EAD310093EABB /* Embed App Extensions */,
7FFD40AA75DB32D83350D225 /* [CP] Embed Pods Frameworks */,
68D6013FA64A4507DC9DB95B /* [CP] Copy Pods Resources */,
3233F7481F3497E2006ACA81 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
242661F61F12B1BA00D3FC08 /* PBXTargetDependency */,
);
name = Riot;
productName = Vector;
@ -2212,6 +2424,16 @@
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = matrix.org;
TargetAttributes = {
24CBEC4D1F0EAD310093EABB = {
CreatedOnToolsVersion = 8.3.2;
DevelopmentTeam = 7J4U792NQT;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.ApplicationGroups.iOS = {
enabled = 1;
};
};
};
F094A9A11B78D8F000B1FBBF = {
CreatedOnToolsVersion = 6.2;
DevelopmentTeam = 7J4U792NQT;
@ -2242,6 +2464,7 @@
nl,
de,
fr,
ru,
);
mainGroup = F094A9991B78D8F000B1FBBF;
productRefGroup = F094A9A31B78D8F000B1FBBF /* Products */;
@ -2250,11 +2473,31 @@
targets = (
F094A9A11B78D8F000B1FBBF /* Riot */,
F094A9BD1B78D8F000B1FBBF /* RiotTests */,
24CBEC4D1F0EAD310093EABB /* RiotShareExtension */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
24CBEC4C1F0EAD310093EABB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
24D6B35B1F3CA03300FC7A71 /* ShareViewController.xib in Resources */,
24EEE5B51F2607C500B3C705 /* SegmentedViewController.xib in Resources */,
24EEE5A91F25529900B3C705 /* cancel@2x.png in Resources */,
F0B7A8B11F475783006E27D2 /* RoomsListViewController.xib in Resources */,
2435179C1F375B9400D0683E /* Info.plist in Resources */,
24EEE5A81F25529600B3C705 /* cancel@3x.png in Resources */,
2466B73E1F2DFAC100AE27B0 /* animatedLogo-4.png in Resources */,
2435179F1F375C0F00D0683E /* Vector.strings in Resources */,
24EEE5AF1F25F0F500B3C705 /* Images.xcassets in Resources */,
24EEE5AA1F25529C00B3C705 /* cancel.png in Resources */,
24D6B35E1F3CA03E00FC7A71 /* FallbackViewController.xib in Resources */,
24EEE5A41F24C06E00B3C705 /* (null) in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F094A9A01B78D8F000B1FBBF /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -2265,6 +2508,7 @@
F083BE1D1E7009ED00A9B29C /* RoomMemberDetailsViewController.xib in Resources */,
F083BD5B1E7009ED00A9B29C /* chevron@3x.png in Resources */,
F083BD8A1E7009ED00A9B29C /* file_music_icon@2x.png in Resources */,
32E84FA31F6BD32700CA0B89 /* apps-icon@3x.png in Resources */,
F083BE451E7009ED00A9B29C /* RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.xib in Resources */,
F083BD611E7009ED00A9B29C /* details_icon@3x.png in Resources */,
F083BD9D1E7009ED00A9B29C /* main_alias_icon@3x.png in Resources */,
@ -2284,6 +2528,7 @@
F083BD441E7009ED00A9B29C /* call_speaker_on_icon@3x.png in Resources */,
F0614A0F1EDDCCE700F5DC9A /* jump_to_unread@3x.png in Resources */,
F083BE511E7009ED00A9B29C /* RoomOutgoingEncryptedTextMsgBubbleCell.xib in Resources */,
32918EA91F473BDB0076CA16 /* Localizable.strings in Resources */,
F083BDAE1E7009ED00A9B29C /* plus_icon@2x.png in Resources */,
F0E05A401EA0F9EB004B83FB /* tab_people@2x.png in Resources */,
F083BD5A1E7009ED00A9B29C /* chevron@2x.png in Resources */,
@ -2310,6 +2555,7 @@
F083BDA51E7009ED00A9B29C /* notifications@2x.png in Resources */,
F0E05A3F1EA0F9EB004B83FB /* tab_people.png in Resources */,
F0E05A351EA0F9EB004B83FB /* tab_favourites@3x.png in Resources */,
F0DD05D01F615ECF00CB5292 /* LaunchScreenRiot.png in Resources */,
F083BE611E7009ED00A9B29C /* RoomIncomingTextMsgBubbleCell.xib in Resources */,
F083BE9D1E7009ED00A9B29C /* TableViewCellWithCheckBoxAndLabel.xib in Resources */,
F083BDC41E7009ED00A9B29C /* scrollup@3x.png in Resources */,
@ -2354,7 +2600,6 @@
F0E05A451EA0F9EB004B83FB /* tab_rooms.png in Resources */,
F083BE751E7009ED00A9B29C /* RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib in Resources */,
F083BD261E7009ED00A9B29C /* admin_icon@2x.png in Resources */,
325072141E8C0AC900A084B6 /* LaunchScreenLogo.png in Resources */,
3205ED851E97725E003D65FA /* DirectoryServerTableViewCell.xib in Resources */,
F083BD761E7009ED00A9B29C /* e2e_verified@3x.png in Resources */,
F083BE181E7009ED00A9B29C /* MediaPickerViewController.xib in Resources */,
@ -2381,6 +2626,7 @@
F083BD811E7009ED00A9B29C /* favourite@2x.png in Resources */,
F0A4A1681EF7CB66003630DB /* members_list_icon@2x.png in Resources */,
F083BD9F1E7009ED00A9B29C /* mod_icon@2x.png in Resources */,
32918EAA1F473BDB0076CA16 /* Vector.strings in Resources */,
F083BD801E7009ED00A9B29C /* favourite.png in Resources */,
F083BD4B1E7009ED00A9B29C /* camera_capture.png in Resources */,
F083BD841E7009ED00A9B29C /* favouriteOff@2x.png in Resources */,
@ -2486,7 +2732,9 @@
F083BD591E7009ED00A9B29C /* chevron.png in Resources */,
F0D869EC1EC455A100BB0A2B /* create_direct_chat@2x.png in Resources */,
F083BDE11E7009ED00A9B29C /* video_icon@2x.png in Resources */,
32E84FA21F6BD32700CA0B89 /* apps-icon@2x.png in Resources */,
F083BDB51E7009ED00A9B29C /* priorityLow@3x.png in Resources */,
32E84FA11F6BD32700CA0B89 /* apps-icon.png in Resources */,
F083BE891E7009ED00A9B29C /* RoomMemberTitleView.xib in Resources */,
F083BE3D1E7009ED00A9B29C /* RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib in Resources */,
F0E05A431EA0F9EB004B83FB /* tab_rooms_selected@2x.png in Resources */,
@ -2547,6 +2795,7 @@
F083BE771E7009ED00A9B29C /* RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib in Resources */,
F083BDA71E7009ED00A9B29C /* notificationsOff.png in Resources */,
F06CDD6A1EF01E3900870B75 /* RoomEmptyBubbleCell.xib in Resources */,
F0B5430A1F70FF8F00D29293 /* back_icon@4x.png in Resources */,
F083BDBD1E7009ED00A9B29C /* riot_icon@2x.png in Resources */,
F083BDDE1E7009ED00A9B29C /* upload_icon@2x.png in Resources */,
F083BE8B1E7009ED00A9B29C /* ExpandedRoomTitleView.xib in Resources */,
@ -2561,6 +2810,7 @@
F083BD961E7009ED00A9B29C /* leave@2x.png in Resources */,
F0E05A461EA0F9EB004B83FB /* tab_rooms@2x.png in Resources */,
32AE61F41F0D2183007255F4 /* Vector.strings in Resources */,
32935CB41F628BCE006888C8 /* IntegrationManager.js in Resources */,
F083BD851E7009ED00A9B29C /* favouriteOff@3x.png in Resources */,
F083BD541E7009ED00A9B29C /* camera_switch@2x.png in Resources */,
F083BD6A1E7009ED00A9B29C /* directChatOn@3x.png in Resources */,
@ -2616,54 +2866,179 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
381DA4CC07D2104BFA23E45A /* [CP] Embed Pods Frameworks */ = {
2372F8E1A49557FE0072BC56 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Embed Pods Frameworks";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Riot-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Riot/Pods-Riot-frameworks.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
44C35695CFA4F9799C449367 /* [CP] Copy Pods Resources */ = {
3051A9ED306E05F8AE91C906 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RiotShareExtension-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
68D6013FA64A4507DC9DB95B /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Riot/Pods-Riot-resources.sh",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKAccountDetailsViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKAttachmentsViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKAuthenticationViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKCallViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKContactDetailsViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKContactListViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKCountryPickerViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKLanguagePickerViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKRecentListViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKRoomMemberDetailsViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKRoomMemberListViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKRoomSettingsViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKRoomViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Controllers/MXKSearchViewController.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/Account/MXKAccountTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/Authentication/MXKAuthInputsEmailCodeBasedView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/Authentication/MXKAuthInputsPasswordBasedView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/Contact/MXKContactTableCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/DeviceView/MXKDeviceView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/EncryptionInfoView/MXKEncryptionInfoView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKCollectionViewCell/MXKMediaCollectionViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKEventDetailsView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKPieChartHUD.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKRoomCreationView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithButton.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndButton.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndImageView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndMXKImageView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndSlider.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndSubLabel.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndSwitch.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelAndTextField.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithLabelTextFieldAndButton.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithPicker.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithSearchBar.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithTextFieldAndButton.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/MXKTableViewCell/MXKTableViewCellWithTextView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/PushRule/MXKPushRuleCreationTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/PushRule/MXKPushRuleTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/ReadReceipts/MXKReadReceiptTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomEmptyBubbleTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomIOSOutgoingBubbleTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarViewWithHPGrowingText.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomInputToolbar/MXKRoomInputToolbarViewWithSimpleTextView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomList/MXKInterleavedRecentTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomList/MXKPublicRoomTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomList/MXKRecentTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomMemberList/MXKRoomMemberTableViewCell.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomTitle/MXKRoomTitleView.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/RoomTitle/MXKRoomTitleViewWithTopic.xib",
"${PODS_ROOT}/MatrixKit/MatrixKit/Views/Search/MXKSearchTableViewCell.xib",
"$PODS_CONFIGURATION_BUILD_DIR/MatrixKit/MatrixKit.bundle",
"${PODS_ROOT}/MatrixSDK/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.xcdatamodeld",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Riot/Pods-Riot-resources.sh\"\n";
showEnvVarsInLog = 0;
};
9131C24971B46D743282FCF6 /* [CP] Check Pods Manifest.lock */ = {
7FFD40AA75DB32D83350D225 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Riot/Pods-Riot-frameworks.sh",
"${PODS_ROOT}/WebRTC/WebRTC.framework",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WebRTC.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Riot/Pods-Riot-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
8EA19F5011654D3BD5EDAC33 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-RiotShareExtension/Pods-RiotShareExtension-resources.sh",
"${PODS_ROOT}/MatrixSDK/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.xcdatamodeld",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RiotShareExtension/Pods-RiotShareExtension-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
24CBEC4A1F0EAD310093EABB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
24EEE5A01F23A08900B3C705 /* RoomTableViewCell.m in Sources */,
24D6B3581F3C90D300FC7A71 /* ShareRecentsDataSource.m in Sources */,
245FC3EF1F3DD30800603C6A /* RecentCellData.m in Sources */,
24D6B35C1F3CA03600FC7A71 /* RoomsListViewController.m in Sources */,
24D6B35A1F3CA02C00FC7A71 /* ShareViewController.m in Sources */,
24D6B3591F3CA02900FC7A71 /* SharePresentingViewController.m in Sources */,
24EEE5A31F23A8C300B3C705 /* AvatarGenerator.m in Sources */,
24D6B35D1F3CA03A00FC7A71 /* FallbackViewController.m in Sources */,
24EEE5A11F23A09A00B3C705 /* RiotDesignValues.m in Sources */,
24EEE5A21F23A8B400B3C705 /* MXRoom+Riot.m in Sources */,
245FC3ED1F3D079A00603C6A /* ShareExtensionManager.m in Sources */,
24EEE5B41F2607C000B3C705 /* SegmentedViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F094A99E1B78D8F000B1FBBF /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -2679,6 +3054,7 @@
F083BE9C1E7009ED00A9B29C /* TableViewCellWithCheckBoxAndLabel.m in Sources */,
32471CE11F13AC1500BDF50A /* RoomMembershipExpandedWithPaginationTitleBubbleCell.m in Sources */,
F083BDFE1E7009ED00A9B29C /* RecentCellData.m in Sources */,
92324BE61F4F6A60009DE194 /* CircleButton.m in Sources */,
F083BE3A1E7009ED00A9B29C /* RoomIncomingEncryptedAttachmentBubbleCell.m in Sources */,
3205ED841E97725E003D65FA /* DirectoryServerTableViewCell.m in Sources */,
F083BEA21E7009ED00A9B29C /* TableViewCellWithPhoneNumberTextField.m in Sources */,
@ -2712,6 +3088,7 @@
F083BE481E7009ED00A9B29C /* RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m in Sources */,
F06CDD691EF01E3900870B75 /* RoomEmptyBubbleCell.m in Sources */,
F083BE041E7009ED00A9B29C /* Tools.m in Sources */,
92324BE31F4F66D3009DE194 /* IncomingCallView.m in Sources */,
F083BE6A1E7009ED00A9B29C /* RoomOutgoingAttachmentBubbleCell.m in Sources */,
F083BDEF1E7009ED00A9B29C /* UINavigationController+Riot.m in Sources */,
F083BE761E7009ED00A9B29C /* RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m in Sources */,
@ -2734,6 +3111,8 @@
F083BE6E1E7009ED00A9B29C /* RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m in Sources */,
3233F7311F31F4BF006ACA81 /* JitsiViewController.m in Sources */,
F083BE2A1E7009ED00A9B29C /* UsersDevicesViewController.m in Sources */,
32F3AE1A1F6FF4E600F0F004 /* WidgetViewController.m in Sources */,
F0D2ADA11F6AA5FD00A7097D /* MXRoomSummary+Riot.m in Sources */,
F083BE2D1E7009ED00A9B29C /* ForgotPasswordInputsView.m in Sources */,
F083BE7E1E7009ED00A9B29C /* InviteRecentTableViewCell.m in Sources */,
F083BE3C1E7009ED00A9B29C /* RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
@ -2800,6 +3179,7 @@
F083BE391E7009ED00A9B29C /* RoomEncryptedDataBubbleCell.m in Sources */,
F083BDF01E7009ED00A9B29C /* UIViewController+RiotSearch.m in Sources */,
F083BDF91E7009ED00A9B29C /* RoomEmailInvitation.m in Sources */,
32935CB11F6056FD006888C8 /* IntegrationManagerViewController.m in Sources */,
F083BE341E7009ED00A9B29C /* EncryptionInfoView.m in Sources */,
F083BE641E7009ED00A9B29C /* RoomIncomingTextMsgWithoutSenderNameBubbleCell.m in Sources */,
F075BED61EBB169C00A7B68A /* RoomCollectionViewCell.m in Sources */,
@ -2821,6 +3201,11 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
242661F61F12B1BA00D3FC08 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 24CBEC4D1F0EAD310093EABB /* RiotShareExtension */;
targetProxy = 242661F51F12B1BA00D3FC08 /* PBXContainerItemProxy */;
};
F094A9C01B78D8F000B1FBBF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F094A9A11B78D8F000B1FBBF /* Riot */;
@ -2909,6 +3294,22 @@
name = Vector.strings;
sourceTree = "<group>";
};
32918EA51F473BDB0076CA16 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (
32918EA61F473BDB0076CA16 /* ru */,
);
name = Localizable.strings;
sourceTree = "<group>";
};
32918EA71F473BDB0076CA16 /* Vector.strings */ = {
isa = PBXVariantGroup;
children = (
32918EA81F473BDB0076CA16 /* ru */,
);
name = Vector.strings;
sourceTree = "<group>";
};
32AE61EC1F0D2183007255F4 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
@ -2944,6 +3345,51 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
24CBEC5A1F0EAD310093EABB /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 12AA0005C8B3D8D8162584C5 /* Pods-RiotShareExtension.debug.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CODE_SIGN_ENTITLEMENTS = RiotShareExtension/RiotShareExtension.entitlements;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = RiotShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.shareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
24CBEC5B1F0EAD310093EABB /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 765F5104DB3EC39713DEB3A4 /* Pods-RiotShareExtension.release.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CODE_SIGN_ENTITLEMENTS = RiotShareExtension/RiotShareExtension.entitlements;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 7J4U792NQT;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = RiotShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.shareExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
F094A9C61B78D8F000B1FBBF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -3031,7 +3477,7 @@
};
F094A9C91B78D8F000B1FBBF /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1129C74A281B080432B1A1A1 /* Pods-Riot.debug.xcconfig */;
baseConfigurationReference = 839BB91240D350D5607D55BA /* Pods-Riot.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Riot/Riot.entitlements;
@ -3054,7 +3500,7 @@
};
F094A9CA1B78D8F000B1FBBF /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = F9D678EF54918C036FDEDBF9 /* Pods-Riot.release.xcconfig */;
baseConfigurationReference = C195C53961EA28E6900AEB68 /* Pods-Riot.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = Riot/Riot.entitlements;
@ -3115,6 +3561,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
24CBEC5C1F0EAD310093EABB /* Build configuration list for PBXNativeTarget "RiotShareExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
24CBEC5A1F0EAD310093EABB /* Debug */,
24CBEC5B1F0EAD310093EABB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
F094A99D1B78D8F000B1FBBF /* Build configuration list for PBXProject "Riot" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View file

@ -116,6 +116,13 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification;
- (void)registerUserNotificationSettings;
/**
Perform registration for remote notifications.
@param completion the block to be executed when registration finished.
*/
- (void)registerForRemoteNotificationsWithCompletion:(void (^)(NSError *))completion;
#pragma mark - Matrix Room handling
- (void)showRoom:(NSString*)roomId andEventId:(NSString*)eventId withMatrixSession:(MXSession*)mxSession;

View file

@ -34,7 +34,6 @@
#import "MatrixSDK/MatrixSDK.h"
#import "Tools.h"
#import "MXRoom+Riot.h"
#import "WidgetManager.h"
#import "AFNetworkReachabilityManager.h"
@ -166,7 +165,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
}
@property (strong, nonatomic) UIAlertController *mxInAppNotification;
@property (strong, nonatomic) UIAlertController *incomingCallNotification;
@property (nonatomic, nullable, copy) void (^registrationForRemoteNotificationsCompletion)(NSError *);
@end
@ -563,13 +563,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
// Enable error notifications
isErrorNotificationSuspended = NO;
// Restore call alert if any
if (_incomingCallNotification)
{
NSLog(@"[AppDelegate] restoreInitialDisplay: keep visible incoming call alert");
[self showNotificationAlert:_incomingCallNotification];
}
else if (noCallSupportAlert)
if (noCallSupportAlert)
{
NSLog(@"[AppDelegate] restoreInitialDisplay: keep visible noCall support alert");
[self showNotificationAlert:noCallSupportAlert];
@ -897,9 +891,25 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
}
}
- (void)registerForRemoteNotificationsWithCompletion:(nullable void (^)(NSError *))completion
{
self.registrationForRemoteNotificationsCompletion = completion;
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[application registerForRemoteNotifications];
// Register for remote notifications only if user provide access to notification feature
if (notificationSettings.types != UIUserNotificationTypeNone)
{
[self registerForRemoteNotificationsWithCompletion:nil];
}
else
{
// Clear existing token
MXKAccountManager* accountManager = [MXKAccountManager sharedManager];
[accountManager setApnsDeviceToken:nil];
}
}
- (void)application:(UIApplication*)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
@ -911,11 +921,23 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
[accountManager setApnsDeviceToken:deviceToken];
isAPNSRegistered = YES;
if (self.registrationForRemoteNotificationsCompletion)
{
self.registrationForRemoteNotificationsCompletion(nil);
self.registrationForRemoteNotificationsCompletion = nil;
}
}
- (void)application:(UIApplication*)app didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"[AppDelegate] Failed to register for APNS: %@", error);
if (self.registrationForRemoteNotificationsCompletion)
{
self.registrationForRemoteNotificationsCompletion(error);
self.registrationForRemoteNotificationsCompletion = nil;
}
}
- (void)cancelBackgroundSync
@ -1442,6 +1464,9 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
MXSDKOptions *sdkOptions = [MXSDKOptions sharedInstance];
// Set the App Group identifier.
sdkOptions.applicationGroupIdentifier = @"group.im.vector";
// Define the media cache version
sdkOptions.mediaCacheAppVersion = 0;
@ -1456,6 +1481,9 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
// Use UIKit BackgroundTask for handling background tasks in the SDK
sdkOptions.backgroundModeHandler = [[MXUIKitBackgroundModeHandler alloc] init];
// Get modular widget events in rooms histories
[[MXKAppSettings standardAppSettings] addSupportedEventTypes:@[kWidgetEventTypeString]];
// Disable long press on event in bubble cells
[MXKRoomBubbleTableViewCell disableLongPressGestureOnEvent:YES];
@ -1504,6 +1532,11 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
// Each room member will be considered as a potential contact.
[MXKContactManager sharedManager].contactManagerMXRoomSource = MXKContactManagerMXRoomSourceAll;
// Send read receipts for modular widgets events too
NSMutableArray<MXEventTypeString> *acknowledgableEventTypes = [NSMutableArray arrayWithArray:mxSession.acknowledgableEventTypes];
[acknowledgableEventTypes addObject:kWidgetEventTypeString];
mxSession.acknowledgableEventTypes = acknowledgableEventTypes;
}
else if (mxSession.state == MXSessionStateStoreDataReady)
{
@ -1591,6 +1624,9 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
// Remove inApp notifications toggle change
MXKAccount *account = notif.object;
[account removeObserver:self forKeyPath:@"enableInAppNotifications"];
// Clear Modular data
[[WidgetManager sharedManager] deleteDataForUser:account.mxCredentials.userId];
// Logout the app when there is no available account
if (![MXKAccountManager sharedManager].accounts.count)
@ -1617,8 +1653,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
}];
// Apply the application group name, and add observer on settings changes.
[MXKAppSettings standardAppSettings].applicationGroup = @"group.im.vector";
// Add observer on settings changes.
[[MXKAppSettings standardAppSettings] addObserver:self forKeyPath:@"showAllEventsInRoomHistory" options:0 context:nil];
// Prepare account manager
@ -1808,81 +1843,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
currentCallViewController = [CallViewController callViewController:mxCall];
currentCallViewController.delegate = self;
if (mxCall.isIncoming)
{
// Prompt user before presenting the call view controller
NSString *callPromptFormat = mxCall.isVideoCall ? NSLocalizedStringFromTable(@"call_incoming_video_prompt", @"Vector", nil) : NSLocalizedStringFromTable(@"call_incoming_voice_prompt", @"Vector", nil);
NSString *callerName = currentCallViewController.peer.displayname;
if (!callerName.length)
{
callerName = currentCallViewController.peer.userId;
}
NSString *callPrompt = [NSString stringWithFormat:callPromptFormat, callerName];
__weak typeof(self) weakSelf = self;
// Removing existing notification (if any)
[_incomingCallNotification dismissViewControllerAnimated:NO completion:nil];
_incomingCallNotification = [UIAlertController alertControllerWithTitle:callPrompt
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[_incomingCallNotification addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"decline", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
// Reject the call.
// Note: Do not reset the incoming call notification before this operation, because it is used to release properly the dismissed call view controller.
if (self->currentCallViewController)
{
[self->currentCallViewController onButtonPressed:self->currentCallViewController.rejectCallButton];
currentCallViewController = nil;
}
self.incomingCallNotification = nil;
mxCall.delegate = nil;
}
}]];
[_incomingCallNotification addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"accept", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self.incomingCallNotification = nil;
if (self->currentCallViewController)
{
[self->currentCallViewController onButtonPressed:self->currentCallViewController.answerCallButton];
[self presentCallViewController:nil];
}
}
}]];
[_incomingCallNotification mxk_setAccessibilityIdentifier:@"AppDelegateIncomingCallAlert"];
[self showNotificationAlert:_incomingCallNotification];
}
else
{
[self presentCallViewController:nil];
}
[self presentCallViewController:nil];
}
}];
}
@ -1962,60 +1924,6 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
[NSLayoutConstraint activateConstraints:@[widthConstraint, heightConstraint, centerXConstraint, centerYConstraint]];
// In addition, show a spinner under this giffy animation
UIActivityIndicatorView* activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityIndicator.backgroundColor = [UIColor colorWithRed:0.8 green:0.8 blue:0.8 alpha:1.0];
activityIndicator.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
activityIndicator.hidesWhenStopped = YES;
CGRect frame = activityIndicator.frame;
frame.size.width += 30;
frame.size.height += 30;
activityIndicator.bounds = frame;
[activityIndicator.layer setCornerRadius:5];
activityIndicator.center = CGPointMake(launchAnimationContainerView.center.x, 6 * launchAnimationContainerView.center.y / 4);
[launchAnimationContainerView addSubview:activityIndicator];
activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint* widthConstraint2 = [NSLayoutConstraint constraintWithItem:activityIndicator
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:frame.size.width];
NSLayoutConstraint* heightConstraint2 = [NSLayoutConstraint constraintWithItem:activityIndicator
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:frame.size.height];
NSLayoutConstraint* centerXConstraint2 = [NSLayoutConstraint constraintWithItem:activityIndicator
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:launchAnimationContainerView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0];
NSLayoutConstraint* centerYConstraint2 = [NSLayoutConstraint constraintWithItem:activityIndicator
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:launchAnimationContainerView
attribute:NSLayoutAttributeCenterY
multiplier:6.0/4.0
constant:0];
[NSLayoutConstraint activateConstraints:@[widthConstraint2, heightConstraint2, centerXConstraint2, centerYConstraint2]];
[activityIndicator startAnimating];
launchAnimationStart = [NSDate date];
}
@ -2428,22 +2336,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
{
if (currentCallViewController && callViewController == currentCallViewController)
{
if (_incomingCallNotification)
{
// The user was prompted for an incoming call which ended
// The call view controller was not presented yet.
[_incomingCallNotification dismissViewControllerAnimated:NO completion:nil];
_incomingCallNotification = nil;
// Release properly
[currentCallViewController destroy];
if (completion)
{
completion();
}
}
else if (callViewController.isBeingPresented)
if (callViewController.isBeingPresented)
{
// Here the presentation of the call view controller is in progress
// Postpone the dismiss
@ -2568,7 +2461,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
[_jitsiViewController dismissViewControllerAnimated:YES completion:^{
MXRoom *room = [_jitsiViewController.widget.mxSession roomWithRoomId:_jitsiViewController.widget.roomId];
NSString *btnTitle = [NSString stringWithFormat:NSLocalizedStringFromTable(@"active_call_details", @"Vector", nil), room.riotDisplayname];
NSString *btnTitle = [NSString stringWithFormat:NSLocalizedStringFromTable(@"active_call_details", @"Vector", nil), room.summary.displayname];
[self addCallStatusBar:btnTitle];
if (completion)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
Riot/Assets/Images/e2e_unencrypted.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

After

Width:  |  Height:  |  Size: 286 B

BIN
Riot/Assets/Images/e2e_unencrypted@2x.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 441 B

BIN
Riot/Assets/Images/e2e_unencrypted@3x.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 565 B

View file

@ -11,9 +11,9 @@
/* New action message from a specific person in a named room. */
"ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@";
/* New action message from a specific person, not referencing a room. */
"IMAGE_FROM_USER" = "%@ sandte dir ein Bild";
"IMAGE_FROM_USER" = "%@ sandte dir ein Bild %@";
/* New action message from a specific person in a named room. */
"IMAGE_FROM_USER_IN_ROOM" = "%@ sandte ein Bild in %@";
"IMAGE_FROM_USER_IN_ROOM" = "%@ sandte ein Bild %@ in %@";
/* Multiple unread messages in a room */
"UNREAD_IN_ROOM" = "%@ neue Nachrichten in %@";
/* Multiple unread messages from a specific person, not referencing a room */

View file

@ -39,10 +39,10 @@
/** Image Messages **/
/* New action message from a specific person, not referencing a room. */
"IMAGE_FROM_USER" = "%@ sent you a picture";
"IMAGE_FROM_USER" = "%@ sent you a picture %@";
/* New action message from a specific person in a named room. */
"IMAGE_FROM_USER_IN_ROOM" = "%@ posted a picture in %@";
"IMAGE_FROM_USER_IN_ROOM" = "%@ posted a picture %@ in %@";
/** Coalesced messages **/

View file

@ -49,6 +49,8 @@
"later" = "Later";
"rename" = "Rename";
"collapse" = "collapse";
"send_to" = "Send to %@";
"sending" = "Sending";
// Authentication
"auth_login" = "Log in";
@ -104,6 +106,7 @@
"auth_reset_password_error_not_found" = "Your email address does not appear to be associated with a Matrix ID on this Homeserver.";
"auth_reset_password_success_message" = "Your password has been reset.\n\nYou have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, re-log in on each device.";
"auth_add_email_and_phone_warning" = "Registration with email and phone number at once is not supported yet until the api exists. Only the phone number will be taken into account. You may add your email to your profile in settings.";
"auth_share_extension_prompt" = "Login in the main app to share content";
// Chat creation
"room_creation_title" = "New Chat";
@ -255,6 +258,7 @@
"room_event_action_cancel_download" = "Cancel Download";
"room_event_action_view_encryption" = "Encryption Information";
"room_warning_about_encryption" = "End-to-end encryption is in beta and may not be reliable.\n\nYou should not yet trust it to secure data.\n\nDevices will not yet be able to decrypt history from before they joined the room.\n\nEncrypted messages will not be visible on clients that do not yet implement encryption.";
"room_event_failed_to_send" = "Failed to send";
// Unknown devices
"unknown_devices_alert_title" = "Room contains unknown devices";
@ -346,6 +350,7 @@
"settings_labs_e2e_encryption" = "End-to-End Encryption";
"settings_labs_e2e_encryption_prompt_message" = "To finish setting up encryption you must log in again.";
"settings_labs_matrix_apps" = "Matrix Apps";
"settings_labs_create_conference_with_jitsi" = "Create conference calls with jitsi";
"settings_version" = "Version %@";
@ -384,6 +389,7 @@
"room_details_favourite_tag" = "Favourite";
"room_details_low_priority_tag" = "Low priority";
"room_details_mute_notifs" = "Mute notifications";
"room_details_direct_chat" = "Direct Chat";
"room_details_access_section"="Who can access this room?";
"room_details_access_section_invited_only"="Only people who have been invited";
"room_details_access_section_anyone_apart_from_guest"="Anyone who knows the room's link, apart from guests";
@ -423,6 +429,7 @@
"room_details_fail_to_add_room_aliases" = "Fail to add the new room addresses";
"room_details_fail_to_remove_room_aliases" = "Fail to remove the room addresses";
"room_details_fail_to_update_room_canonical_alias" = "Fail to update the main address";
"room_details_fail_to_update_room_direct" = "Fail to update the direct flag of this room";
"room_details_fail_to_enable_encryption" = "Fail to enable encryption in this room";
"room_details_save_changes_prompt" = "Do you want to save changes?";
"room_details_set_main_address" = "Set as Main Address";
@ -449,6 +456,8 @@
// Events formatter
"event_formatter_member_updates" = "%tu membership changes";
"event_formatter_jitsi_widget_added" = "VoIP conference added by %@";
"event_formatter_jitsi_widget_removed" = "VoIP conference removed by %@";
// Others
"or" = "or";
@ -472,6 +481,8 @@
// Call
"call_incoming_voice_prompt" = "Incoming voice call from %@";
"call_incoming_video_prompt" = "Incoming video call from %@";
"call_incoming_voice" = "Incoming call...";
"call_incoming_video" = "Incoming video call...";
"call_already_displayed" = "There is already a call in progress.";
"call_jitsi_error" = "Failed to join the conference call.";
@ -502,3 +513,15 @@
"widget_no_power_to_manage" = "You need permission to manage widgets in this room";
"widget_creation_failure" = "Widget creation has failed";
// Widget Integration Manager
"widget_integration_need_to_be_able_to_invite" = "You need to be able to invite users to do that.";
"widget_integration_unable_to_create" = "Unable to create widget.";
"widget_integration_failed_to_send_request" = "Failed to send request.";
"widget_integration_room_not_recognised" = "This room is not recognised.";
"widget_integration_positive_power_level" = "Power level must be positive integer.";
"widget_integration_must_be_in_room" = "You are not in this room.";
"widget_integration_no_permission_in_room" = "You do not have permission to do that in this room.";
"widget_integration_missing_room_id" = "Missing room_id in request.";
"widget_integration_missing_user_id" = "Missing user_id in request.";
"widget_integration_room_not_visible" = "Room %@ is not visible.";

View file

@ -11,9 +11,9 @@
/* New action message from a specific person in a named room. */
"ACTION_FROM_USER_IN_ROOM" = "%@ : * %@ %@";
/* New action message from a specific person, not referencing a room. */
"IMAGE_FROM_USER" = "%@ vous a envoyé une image";
"IMAGE_FROM_USER" = "%@ vous a envoyé une image %@";
/* New action message from a specific person in a named room. */
"IMAGE_FROM_USER_IN_ROOM" = "%@ a posté une image dans %@";
"IMAGE_FROM_USER_IN_ROOM" = "%@ a posté une image %@ dans %@";
/* Multiple unread messages in a room */
"UNREAD_IN_ROOM" = "%@ nouveaux messages dans %@";
/* Multiple unread messages from a specific person, not referencing a room */

View file

@ -313,6 +313,7 @@
"room_details_favourite_tag" = "Favoris";
"room_details_low_priority_tag" = "Priorité basse";
"room_details_mute_notifs" = "Désactiver les notifications";
"room_details_direct_chat" = "Discussion directe";
"room_details_access_section" = "Qui peut accéder à ce salon ?";
"room_details_access_section_invited_only" = "Seulement les personnes qui ont été invitées";
"room_details_access_section_anyone_apart_from_guest" = "N'importe qui ayant un lien vers le salon, hormis les visiteurs";
@ -352,6 +353,7 @@
"room_details_fail_to_add_room_aliases" = "Impossible d'ajouter les nouvelles adresses au salon";
"room_details_fail_to_remove_room_aliases" = "Impossible de supprimer les adresses du salon";
"room_details_fail_to_update_room_canonical_alias" = "Impossible de modifier l'adresse principale";
"room_details_fail_to_update_room_direct" = "Impossible de modifier l'état de discussion directe";
"room_details_fail_to_enable_encryption" = "Impossible d'activer le chiffrement sur ce salon";
"room_details_save_changes_prompt" = "Voulez-vous enregistrer les changements ?";
"room_details_set_main_address" = "Configurer comme adresse principale";

View file

@ -0,0 +1,67 @@
/*
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.
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.
*/
window.riotIOS = {};
// Generic JS -> ObjC bridge
window.riotIOS.sendObjectMessageToObjC = function(parameters) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', 'js:' + JSON.stringify(parameters));
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
};
window.riotIOS.events = {};
// Listen to messages posted by Modular
window.riotIOS.onMessage = function(event) {
// Do not SPAM ObjC with event already managed
if (riotIOS.events[event.data._id]) {
return;
}
if (!event.origin) { // stupid chrome
event.origin = event.originalEvent.origin;
}
// Keep this event for future usage
riotIOS.events[event.data._id] = event;
riotIOS.sendObjectMessageToObjC({
'event.data': event.data,
});
};
window.addEventListener('message', riotIOS.onMessage, false);
// ObjC -> Modular JS bridge
window.riotIOS.sendResponse = function(eventId, res) {
// Retrieve the correspong JS event
var event = riotIOS.events[eventId];
console.log("sendResponse to " + event.data.action + " for "+ eventId + ": " + JSON.stringify(res));
var data = JSON.parse(JSON.stringify(event.data));
data.response = res;
event.source.postMessage(data, event.origin);
// Mark this event as handled
riotIOS.events[eventId] = true;
}

View file

@ -39,10 +39,10 @@
/** Image Messages **/
/* New action message from a specific person, not referencing a room. */
"IMAGE_FROM_USER" = "%@ heeft je een afbeelding gestuurd";
"IMAGE_FROM_USER" = "%@ heeft je een afbeelding %@ gestuurd";
/* New action message from a specific person in a named room. */
"IMAGE_FROM_USER_IN_ROOM" = "%@ plaatste een afbeelding in %@";
"IMAGE_FROM_USER_IN_ROOM" = "%@ plaatste een afbeelding %@ in %@";
/** Coalesced messages **/

View file

@ -11,9 +11,9 @@
/* New action message from a specific person in a named room. */
"ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@";
/* New action message from a specific person, not referencing a room. */
"IMAGE_FROM_USER" = "%@ отправил(а) вам фото";
"IMAGE_FROM_USER" = "%@ отправил(а) вам фото %@";
/* New action message from a specific person in a named room. */
"IMAGE_FROM_USER_IN_ROOM" = "%@ отправил(а) фото в %@";
"IMAGE_FROM_USER_IN_ROOM" = "%@ отправил(а) фото %@ в %@";
/* Multiple unread messages in a room */
"UNREAD_IN_ROOM" = "%@ новых сообщений в %@";
/* Multiple unread messages from a specific person, not referencing a room */

View file

@ -22,7 +22,7 @@
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LaunchScreenLogo.png" translatesAutoresizingMaskIntoConstraints="NO" id="IcW-17-3Qq">
<imageView clearsContextBeforeDrawing="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LaunchScreenRiot.png" translatesAutoresizingMaskIntoConstraints="NO" id="IcW-17-3Qq">
<rect key="frame" x="122" y="192" width="170" height="170"/>
<constraints>
<constraint firstAttribute="height" constant="170" id="Lbo-ar-PiJ"/>
@ -43,6 +43,6 @@
</scene>
</scenes>
<resources>
<image name="LaunchScreenLogo.png" width="300" height="300"/>
<image name="LaunchScreenRiot.png" width="480" height="480"/>
</resources>
</document>

View file

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="H1p-Uh-vWS">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="H1p-Uh-vWS">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="Navigation items with more than one left or right bar item" minToolsVersion="7.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@ -36,7 +37,14 @@
<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="wyR-qv-IxC" userLabel="Menu Bar Button Item"/>
<rightBarButtonItems>
<barButtonItem image="search_icon.png" id="wyR-qv-IxC" userLabel="Menu Bar Button Item">
<inset key="imageInsets" minX="-5" minY="0.0" maxX="5" maxY="0.0"/>
</barButtonItem>
<barButtonItem image="apps-icon.png" id="cal-D0-6Fw">
<inset key="imageInsets" minX="10" minY="0.0" maxX="-10" maxY="0.0"/>
</barButtonItem>
</rightBarButtonItems>
</navigationItem>
<connections>
<outlet property="roomTitleViewContainer" destination="aas-th-FW1" id="SFz-1s-ywg"/>
@ -564,6 +572,7 @@
</scene>
</scenes>
<resources>
<image name="apps-icon.png" width="24" height="24"/>
<image name="logo.png" width="120" height="101"/>
<image name="search_icon.png" width="22" height="22"/>
<image name="settings_icon.png" width="24" height="24"/>
@ -577,10 +586,10 @@
<image name="tab_rooms_selected.png" width="25" height="25"/>
</resources>
<inferredMetricsTieBreakers>
<segue reference="fNQ-S3-DbZ"/>
<segue reference="ziz-Xl-QVg"/>
<segue reference="mFs-HA-7Oo"/>
<segue reference="0ws-cL-0tk"/>
<segue reference="f5u-Y1-7nt"/>
<segue reference="vCz-dl-6xQ"/>
<segue reference="cUw-vU-gJq"/>
<segue reference="tk8-vF-K4T"/>
<segue reference="Tfl-tq-LQp"/>
</inferredMetricsTieBreakers>
</document>

View file

@ -22,11 +22,6 @@
*/
@interface MXRoom (Riot)
/**
The Riot displayname of the room
*/
@property(nonatomic, readonly) NSString* riotDisplayname;
/**
Tell whether all the notifications are disabled for the room.
*/
@ -47,17 +42,6 @@
*/
@property (nonatomic) id notificationCenterDidUpdateObserver;
/**
Set the room avatar in the dedicated MXKImageView.
The vector style implies to use in order :
1 - the default avatar if there is one
2 - the member avatar for < 3 members rooms
3 - the first later of the room name.
@param mxkImageView the destinated MXKImageView.
*/
- (void)setRoomAvatarImageIn:(MXKImageView*)mxkImageView;
/**
Update the room tag.

View file

@ -23,182 +23,6 @@
@implementation MXRoom (Riot)
#pragma mark - Room avatar
- (void)setRoomAvatarImageIn:(MXKImageView*)mxkImageView
{
NSString* roomAvatarUrl = self.state.avatar;
if (!roomAvatarUrl)
{
// If the room has only two members, use the avatar of the second member.
NSArray* members = self.state.members;
if (members.count == 2)
{
NSString* myUserId = self.mxSession.myUser.userId;
for (MXRoomMember *roomMember in members)
{
if (![roomMember.userId isEqualToString:myUserId])
{
// Use the avatar of this member only if he joined or he is invited.
if (MXMembershipJoin == roomMember.membership || MXMembershipInvite == roomMember.membership)
{
roomAvatarUrl = roomMember.avatarUrl;
}
break;
}
}
}
}
// Retrieve the Riot room display name to prepare the default avatar image.
// Note: this display name is nil for an "empty room" without display name (We name "empty room" a room in which the current user is the only active member).
NSString *avatarDisplayName = self.riotDisplayname;
UIImage* avatarImage = [AvatarGenerator generateAvatarForMatrixItem:self.state.roomId withDisplayName:avatarDisplayName];
if (roomAvatarUrl)
{
mxkImageView.enableInMemoryCache = YES;
[mxkImageView setImageURL:[self.mxSession.matrixRestClient urlOfContentThumbnail:roomAvatarUrl toFitViewSize:mxkImageView.frame.size withMethod:MXThumbnailingMethodCrop] withType:nil andImageOrientation:UIImageOrientationUp previewImage:avatarImage];
}
else
{
mxkImageView.image = avatarImage;
}
mxkImageView.contentMode = UIViewContentModeScaleAspectFill;
}
#pragma mark - Room display name
// @TODO: May worth to refactor to use MXRoomSummary
- (NSString *)riotDisplayname
{
// this algo is the one defined in
// https://github.com/matrix-org/matrix-js-sdk/blob/develop/lib/models/room.js#L617
// calculateRoomName(room, userId)
MXRoomState* roomState = self.state;
if (roomState.name.length > 0)
{
return roomState.name;
}
NSString *alias = roomState.canonicalAlias;
if (!alias)
{
// For rooms where canonical alias is not defined, we use the 1st alias as a workaround
NSArray *aliases = roomState.aliases;
if (aliases.count)
{
alias = [aliases[0] copy];
}
}
// check if there is non empty alias.
if ([alias length] > 0)
{
return alias;
}
NSString* myUserId = self.mxSession.myUser.userId;
NSArray* members = roomState.members;
NSMutableArray* othersActiveMembers = [[NSMutableArray alloc] init];
NSMutableArray* activeMembers = [[NSMutableArray alloc] init];
for(MXRoomMember* member in members)
{
if (member.membership != MXMembershipLeave)
{
if (![member.userId isEqualToString:myUserId])
{
[othersActiveMembers addObject:member];
}
[activeMembers addObject:member];
}
}
// sort the members by their creation (oldest first)
othersActiveMembers = [[othersActiveMembers sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
uint64_t originServerTs1 = 0;
uint64_t originServerTs2 = 0;
MXRoomMember* member1 = (MXRoomMember*)obj1;
MXRoomMember* member2 = (MXRoomMember*)obj2;
if (member1.originalEvent)
{
originServerTs1 = member1.originalEvent.originServerTs;
}
if (member2.originalEvent)
{
originServerTs2 = member2.originalEvent.originServerTs;
}
if (originServerTs1 == originServerTs2)
{
return NSOrderedSame;
}
else
{
return originServerTs1 > originServerTs2 ? NSOrderedDescending : NSOrderedAscending;
}
}] mutableCopy];
NSString* displayName = @"";
if (othersActiveMembers.count == 0)
{
if (activeMembers.count == 1)
{
MXRoomMember* member = [activeMembers objectAtIndex:0];
if (member.membership == MXMembershipInvite)
{
if (member.originalEvent.sender)
{
// extract who invited us to the room
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_invite_from", @"Vector", nil), [roomState memberName:member.originalEvent.sender]];
}
else
{
displayName = NSLocalizedStringFromTable(@"room_displayname_room_invite", @"Vector", nil);
}
}
}
}
else if (othersActiveMembers.count == 1)
{
MXRoomMember* member = [othersActiveMembers objectAtIndex:0];
displayName = [roomState memberName:member.userId];
}
else if (othersActiveMembers.count == 2)
{
MXRoomMember* member1 = [othersActiveMembers objectAtIndex:0];
MXRoomMember* member2 = [othersActiveMembers objectAtIndex:1];
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_two_members", @"Vector", nil), [roomState memberName:member1.userId], [roomState memberName:member2.userId]];
}
else
{
MXRoomMember* member = [othersActiveMembers objectAtIndex:0];
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_more_than_two_members", @"Vector", nil), [roomState memberName:member.userId], othersActiveMembers.count - 1];
}
return displayName;
}
#pragma mark - Room tags
- (void)setRoomTag:(NSString*)tag completion:(void (^)())completion

View file

@ -0,0 +1,35 @@
/*
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.
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 <MatrixKit/MatrixKit.h>
/**
Define a `MXRoomSummary` category at Riot level.
*/
@interface MXRoomSummary (Riot)
/**
Set the room avatar in the dedicated MXKImageView.
The riot style implies to use in order :
1 - the default avatar if there is one
2 - the member avatar for < 3 members rooms
3 - the first letter of the room name.
@param mxkImageView the destinated MXKImageView.
*/
- (void)setRoomAvatarImageIn:(MXKImageView*)mxkImageView;
@end

View file

@ -0,0 +1,43 @@
/*
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.
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 "MXRoomSummary+Riot.h"
#import "AvatarGenerator.h"
@implementation MXRoomSummary (Riot)
- (void)setRoomAvatarImageIn:(MXKImageView*)mxkImageView
{
// Use the room display name to prepare the default avatar image.
NSString *avatarDisplayName = self.displayname;
UIImage* avatarImage = [AvatarGenerator generateAvatarForMatrixItem:self.roomId withDisplayName:avatarDisplayName];
if (self.avatar)
{
mxkImageView.enableInMemoryCache = YES;
[mxkImageView setImageURL:[self.mxSession.matrixRestClient urlOfContentThumbnail:self.avatar toFitViewSize:mxkImageView.frame.size withMethod:MXThumbnailingMethodCrop] withType:nil andImageOrientation:UIImageOrientationUp previewImage:avatarImage];
}
else
{
mxkImageView.image = avatarImage;
}
mxkImageView.contentMode = UIViewContentModeScaleAspectFill;
}
@end

View file

@ -19,6 +19,8 @@
#import <objc/runtime.h>
#import "RiotDesignValues.h"
/**
`UIViewControllerRiotSearchInternals` is the internal single point storage for the search feature.
@ -91,6 +93,10 @@
// Reset searches
self.searchBar.text = @"";
// Customize search bar
self.searchBar.barStyle = kRiotDesignSearchBarStyle;
self.searchBar.tintColor = kRiotDesignSearchBarTintColor;
// Remove navigation buttons
self.navigationItem.hidesBackButton = YES;
self.navigationItem.rightBarButtonItem = nil;
@ -128,7 +134,8 @@
- (void)addBackgroundImageViewToView:(UIView*)view
{
UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"search_bg"]];
UIImage *searchBgImage = [MXKTools paintImage:[UIImage imageNamed:@"search_bg"] withColor:kRiotKeyboardColor];
UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:searchBgImage];
backgroundImageView.translatesAutoresizingMaskIntoConstraints = NO;
[view addSubview:backgroundImageView];

View file

@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.5.2</string>
<string>0.5.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.5.2</string>
<string>0.5.3</string>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<key>ITSEncryptionExportComplianceCode</key>

View file

@ -746,7 +746,7 @@
attributes:@{NSForegroundColorAttributeName : kRiotPrimaryTextColor,
NSFontAttributeName: [UIFont boldSystemFontOfSize:15.0]}];
[mutableSectionTitle appendAttributedString:[[NSMutableAttributedString alloc] initWithString:roomCount
attributes:@{NSForegroundColorAttributeName : kRiotColorSilver,
attributes:@{NSForegroundColorAttributeName : kRiotAuxiliaryColor,
NSFontAttributeName: [UIFont boldSystemFontOfSize:15.0]}]];
sectionTitle = mutableSectionTitle;

View file

@ -17,8 +17,6 @@
#import "RoomPreviewData.h"
#import "MXRoom+Riot.h"
@implementation RoomPreviewData
- (instancetype)initWithRoomId:(NSString *)roomId andSession:(MXSession *)mxSession
@ -88,8 +86,8 @@
[_roomDataSource finalizeInitialization];
_roomDataSource.markTimelineInitialEvent = YES;
_roomName = peekingRoom.riotDisplayname;
_roomAvatarUrl = peekingRoom.state.avatar;
_roomName = peekingRoom.summary.displayname;
_roomAvatarUrl = peekingRoom.summary.avatar;
_roomTopic = [MXTools stripNewlineCharacters:peekingRoom.state.topic];;
_roomAliases = peekingRoom.state.aliases;

View file

@ -57,7 +57,7 @@
- (void)update
{
[super update];
roomDisplayname = self.roomSummary.room.riotDisplayname;
roomDisplayname = self.roomSummary.displayname;
if (!roomDisplayname.length)
{
roomDisplayname = NSLocalizedStringFromTable(@"room_displayname_no_title", @"Vector", nil);

View file

@ -398,7 +398,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
attributes:@{NSForegroundColorAttributeName : kRiotPrimaryTextColor,
NSFontAttributeName: [UIFont boldSystemFontOfSize:15.0]}];
[mutableSectionTitle appendAttributedString:[[NSMutableAttributedString alloc] initWithString:roomCount
attributes:@{NSForegroundColorAttributeName : kRiotColorSilver,
attributes:@{NSForegroundColorAttributeName : kRiotAuxiliaryColor,
NSFontAttributeName: [UIFont boldSystemFontOfSize:15.0]}]];
sectionTitle = mutableSectionTitle;
@ -463,7 +463,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
missedNotifAndUnreadBadgeBgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bgViewWidth, 20)];
[missedNotifAndUnreadBadgeBgView.layer setCornerRadius:10];
missedNotifAndUnreadBadgeBgView.backgroundColor = kRiotColorSilver;
missedNotifAndUnreadBadgeBgView.backgroundColor = kRiotAuxiliaryColor;
[missedNotifAndUnreadBadgeBgView addSubview:missedNotifAndUnreadBadgeLabel];
missedNotifAndUnreadBadgeLabel.center = missedNotifAndUnreadBadgeBgView.center;
@ -1487,7 +1487,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou
NSString* tagOrder = [room.mxSession tagOrderToBeAtIndex:newPath.row from:oldPos withTag:dstRoomTag];
NSLog(@"[RecentsDataSource] Update the room %@ [%@] tag from %@ to %@ with tag order %@", room.state.roomId, room.riotDisplayname, oldRoomTag, dstRoomTag, tagOrder);
NSLog(@"[RecentsDataSource] Update the room %@ [%@] tag from %@ to %@ with tag order %@", room.state.roomId, room.summary.displayname, oldRoomTag, dstRoomTag, tagOrder);
[room replaceTag:oldRoomTag
byTag:dstRoomTag

View file

@ -17,8 +17,6 @@
#import "FilesSearchCellData.h"
#import "MXRoom+Riot.h"
@implementation FilesSearchCellData
@synthesize roomId, senderDisplayName;
@synthesize searchResult, title, message, date, shouldShowRoomDisplayName, roomDisplayName, attachment, isAttachmentWithThumbnail, attachmentIcon;
@ -82,7 +80,7 @@
MXRoom *room = [searchDataSource.mxSession roomWithRoomId:roomId];
if (room)
{
roomDisplayName = room.riotDisplayname;
roomDisplayName = room.summary.displayname;
if (!roomDisplayName.length)
{
roomDisplayName = NSLocalizedStringFromTable(@"room_displayname_no_title", @"Vector", nil);

View file

@ -24,6 +24,10 @@
<string>https://riot.im/beta</string>
<key>webAppUrl</key>
<string>https://riot.im/app</string>
<key>integrationsUiUrl</key>
<string>https://scalar-staging.riot.im/scalar-web/</string>
<key>integrationsRestUrl</key>
<string>https://scalar-staging.riot.im/scalar/api</string>
<key>apnsDeviceToken</key>
<string></string>
<key>showAllEventsInRoomHistory</key>

View file

@ -19,6 +19,8 @@
#import "RiotDesignValues.h"
#import "WidgetManager.h"
@interface EventFormatter ()
{
/**
@ -35,6 +37,53 @@
@implementation EventFormatter
- (NSAttributedString *)attributedStringFromEvent:(MXEvent *)event withRoomState:(MXRoomState *)roomState error:(MXKEventFormatterError *)error
{
// Build strings for modular widget events
// TODO: At the moment, we support only jitsi widgets
if (event.eventType == MXEventTypeCustom
&& [event.type isEqualToString:kWidgetEventTypeString])
{
NSString *displayText;
// Prepare the display name of the sender
NSString *senderDisplayName = roomState ? [self senderDisplayNameForEvent:event withRoomState:roomState] : event.sender;
if ([event.content[@"type"] isEqualToString:kWidgetTypeJitsi])
{
// This is an alive jitsi widget
displayText = [NSString stringWithFormat:NSLocalizedStringFromTable(@"event_formatter_jitsi_widget_added", @"Vector", nil), senderDisplayName];
}
else if (event.content.count == 0)
{
// This is a closed widget
// Check if it corresponds to a jitsi widget by looking at other state events for
// this jitsi widget (widget id = event.stateKey).
for (MXEvent *widgetStateEvent in [roomState stateEventsWithType:kWidgetEventTypeString])
{
if ([widgetStateEvent.stateKey isEqualToString:event.stateKey] && [widgetStateEvent.content[@"type"] isEqualToString:kWidgetTypeJitsi])
{
displayText = [NSString stringWithFormat:NSLocalizedStringFromTable(@"event_formatter_jitsi_widget_removed", @"Vector", nil), senderDisplayName];
break;
}
}
}
if (displayText)
{
if (error)
{
*error = MXKEventFormatterErrorNone;
}
// Build the attributed string with the right font and color for the events
return [self renderString:displayText forEvent:event];
}
}
return [super attributedStringFromEvent:event withRoomState:roomState error:error];
}
- (NSAttributedString*)attributedStringFromEvents:(NSArray<MXEvent*>*)events withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error
{
NSString *displayText;
@ -79,7 +128,7 @@
white-space: pre; \
-coretext-fontname: Menlo-Regular; \
font-size: small; \
}", bgColor];
}", (unsigned long)bgColor];
self.defaultTextColor = kRiotPrimaryTextColor;
self.subTitleTextColor = kRiotSecondaryTextColor;
@ -141,6 +190,225 @@
return senderAvatarUrl;
}
#pragma mark - MXRoomSummaryUpdating
- (BOOL)session:(MXSession *)session updateRoomSummary:(MXRoomSummary *)summary withStateEvents:(NSArray<MXEvent *> *)stateEvents
{
BOOL ret = [super session:session updateRoomSummary:summary withStateEvents:stateEvents];
// Check whether the room display name and/or the room avatar url should be updated at Riot level.
NSString *riotRoomDisplayName;
NSString *riotRoomAvatarURL;
for (MXEvent *event in stateEvents)
{
switch (event.eventType)
{
case MXEventTypeRoomName:
case MXEventTypeRoomAliases:
case MXEventTypeRoomCanonicalAlias:
{
if (!riotRoomDisplayName.length)
{
riotRoomDisplayName = [self riotRoomDisplayNameFromRoomState:summary.room.state];
}
break;
}
case MXEventTypeRoomMember:
{
if (!riotRoomDisplayName.length)
{
riotRoomDisplayName = [self riotRoomDisplayNameFromRoomState:summary.room.state];
}
// Do not break here to check avatar url too.
}
case MXEventTypeRoomAvatar:
{
if (!riotRoomAvatarURL.length)
{
riotRoomAvatarURL = [self riotRoomAvatarURLFromRoomState:summary.room.state];
}
break;
}
default:
break;
}
}
if (riotRoomDisplayName.length && ![summary.displayname isEqualToString:riotRoomDisplayName])
{
summary.displayname = riotRoomDisplayName;
ret = YES;
}
if (riotRoomAvatarURL.length && ![summary.avatar isEqualToString:riotRoomAvatarURL])
{
summary.avatar = riotRoomAvatarURL;
ret = YES;
}
return ret;
}
#pragma mark - Riot room display name
- (NSString *)riotRoomDisplayNameFromRoomState:(MXRoomState *)roomState
{
// this algo is the one defined in
// https://github.com/matrix-org/matrix-js-sdk/blob/develop/lib/models/room.js#L617
// calculateRoomName(room, userId)
// This display name is @"" for an "empty room" without display name (We name "empty room" a room in which the current user is the only active member).
if (roomState.name.length > 0)
{
return roomState.name;
}
NSString *alias = roomState.canonicalAlias;
if (!alias)
{
// For rooms where canonical alias is not defined, we use the 1st alias as a workaround
NSArray *aliases = roomState.aliases;
if (aliases.count)
{
alias = [aliases[0] copy];
}
}
// check if there is non empty alias.
if ([alias length] > 0)
{
return alias;
}
NSString* myUserId = mxSession.myUser.userId;
NSArray* members = roomState.members;
NSMutableArray* othersActiveMembers = [[NSMutableArray alloc] init];
NSMutableArray* activeMembers = [[NSMutableArray alloc] init];
for(MXRoomMember* member in members)
{
if (member.membership != MXMembershipLeave)
{
if (![member.userId isEqualToString:myUserId])
{
[othersActiveMembers addObject:member];
}
[activeMembers addObject:member];
}
}
// sort the members by their creation (oldest first)
othersActiveMembers = [[othersActiveMembers sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
uint64_t originServerTs1 = 0;
uint64_t originServerTs2 = 0;
MXRoomMember* member1 = (MXRoomMember*)obj1;
MXRoomMember* member2 = (MXRoomMember*)obj2;
if (member1.originalEvent)
{
originServerTs1 = member1.originalEvent.originServerTs;
}
if (member2.originalEvent)
{
originServerTs2 = member2.originalEvent.originServerTs;
}
if (originServerTs1 == originServerTs2)
{
return NSOrderedSame;
}
else
{
return originServerTs1 > originServerTs2 ? NSOrderedDescending : NSOrderedAscending;
}
}] mutableCopy];
NSString* displayName = @"";
if (othersActiveMembers.count == 0)
{
if (activeMembers.count == 1)
{
MXRoomMember* member = [activeMembers objectAtIndex:0];
if (member.membership == MXMembershipInvite)
{
if (member.originalEvent.sender)
{
// extract who invited us to the room
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_invite_from", @"Vector", nil), [roomState memberName:member.originalEvent.sender]];
}
else
{
displayName = NSLocalizedStringFromTable(@"room_displayname_room_invite", @"Vector", nil);
}
}
}
}
else if (othersActiveMembers.count == 1)
{
MXRoomMember* member = [othersActiveMembers objectAtIndex:0];
displayName = [roomState memberName:member.userId];
}
else if (othersActiveMembers.count == 2)
{
MXRoomMember* member1 = [othersActiveMembers objectAtIndex:0];
MXRoomMember* member2 = [othersActiveMembers objectAtIndex:1];
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_two_members", @"Vector", nil), [roomState memberName:member1.userId], [roomState memberName:member2.userId]];
}
else
{
MXRoomMember* member = [othersActiveMembers objectAtIndex:0];
displayName = [NSString stringWithFormat:NSLocalizedStringFromTable(@"room_displayname_more_than_two_members", @"Vector", nil), [roomState memberName:member.userId], othersActiveMembers.count - 1];
}
return displayName;
}
#pragma mark - Riot room avatar url
- (NSString *)riotRoomAvatarURLFromRoomState:(MXRoomState *)roomState
{
NSString* roomAvatarUrl = roomState.avatar;
if (!roomAvatarUrl)
{
// If the room has only two members, use the avatar of the second member.
NSArray* members = roomState.members;
if (members.count == 2)
{
NSString* myUserId = mxSession.myUser.userId;
for (MXRoomMember *roomMember in members)
{
if (![roomMember.userId isEqualToString:myUserId])
{
// Use the avatar of this member only if he joined or he is invited.
if (MXMembershipJoin == roomMember.membership || MXMembershipInvite == roomMember.membership)
{
roomAvatarUrl = roomMember.avatarUrl;
}
break;
}
}
}
}
return roomAvatarUrl;
}
#pragma mark - Timestamp formatting

View file

@ -39,6 +39,9 @@ extern UIColor *kRiotSecondaryTextColor; //subtitle, sending messages color.
extern UIColor *kRiotPlaceholderTextColor; // nil is used to keep the default color.
extern UIColor *kRiotTopicTextColor;
extern UIColor *kRiotSelectedBgColor; // nil is used to keep the default color.
extern UIColor *kRiotAuxiliaryColor; // kRiotColorSilver by default.
extern UIColor *kRiotOverlayColor; // fading behind dialog modals. This color includes the transparency value.
extern UIColor *kRiotKeyboardColor;
#pragma mark - Riot Colors
extern UIColor *kRiotColorGreen;

View file

@ -26,6 +26,9 @@ UIColor *kRiotSecondaryTextColor;
UIColor *kRiotPlaceholderTextColor;
UIColor *kRiotTopicTextColor;
UIColor *kRiotSelectedBgColor;
UIColor *kRiotAuxiliaryColor;
UIColor *kRiotOverlayColor;
UIColor *kRiotKeyboardColor;
// Riot Colors
UIColor *kRiotColorGreen;
@ -42,6 +45,8 @@ UIColor *kRiotBgColorWhite;
UIColor *kRiotBgColorBlack;
UIColor *kRiotColorLightGrey;
UIColor *kRiotColorLightBlack;
UIColor *kRiotColorLightKeyboard;
UIColor *kRiotColorDarkKeyboard;
// Riot Text Colors
UIColor *kRiotTextColorBlack;
@ -90,6 +95,9 @@ UIColor *kRiotDesignSearchBarTintColor = nil;
kRiotColorLightGrey = UIColorFromRGB(0xF2F2F2);
kRiotColorLightBlack = UIColorFromRGB(0x353535);
kRiotColorLightKeyboard = UIColorFromRGB(0xE7E7E7);
kRiotColorDarkKeyboard = UIColorFromRGB(0x7E7E7E);
kRiotTextColorBlack = UIColorFromRGB(0x3C3C3C);
kRiotTextColorDarkGray = UIColorFromRGB(0x4A4A4A);
@ -135,6 +143,10 @@ UIColor *kRiotDesignSearchBarTintColor = nil;
kRiotDesignStatusBarStyle = UIStatusBarStyleLightContent;
kRiotDesignSearchBarStyle = UIBarStyleBlack;
kRiotDesignSearchBarTintColor = kRiotColorGreen;
kRiotAuxiliaryColor = kRiotTextColorGray;
kRiotOverlayColor = [UIColor colorWithWhite:0.3 alpha:0.5];
kRiotKeyboardColor = kRiotColorDarkKeyboard;
}
else
{
@ -150,6 +162,10 @@ UIColor *kRiotDesignSearchBarTintColor = nil;
kRiotDesignStatusBarStyle = UIStatusBarStyleDefault;
kRiotDesignSearchBarStyle = UIBarStyleDefault;
kRiotDesignSearchBarTintColor = nil; // Default tint color.
kRiotAuxiliaryColor = kRiotColorSilver;
kRiotOverlayColor = [UIColor colorWithWhite:0.7 alpha:0.5];
kRiotKeyboardColor = kRiotColorLightKeyboard;
}
[[NSNotificationCenter defaultCenter] postNotificationName:kRiotDesignValuesDidChangeThemeNotification object:nil];

View file

@ -19,7 +19,7 @@
#import <MatrixSDK/MatrixSDK.h>
/**
The `Widget` class represents scalar widget information.
The `Widget` class represents modular widget information.
*/
@interface Widget : NSObject

View file

@ -24,7 +24,7 @@
{
if (![widgetEvent.type isEqualToString:kWidgetEventTypeString])
{
// The Widget class works only with scalar, aka "im.vector.modular.widgets", widgets
// The Widget class works only with modular, aka "im.vector.modular.widgets", widgets
return nil;
}
@ -46,6 +46,18 @@
withString:mxSession.myUser.displayname ? mxSession.myUser.displayname : mxSession.myUser.userId];
_url = [_url stringByReplacingOccurrencesOfString:@"$matrix_avatar_url"
withString:mxSession.myUser.avatarUrl ? mxSession.myUser.avatarUrl : @""];
// And their scalar token
NSString *scalarToken = [[WidgetManager sharedManager] scalarTokenForMXSession:mxSession];
if (scalarToken)
{
_url = [_url stringByAppendingString:[NSString stringWithFormat:@"&scalar_token=%@", scalarToken]];
}
else
{
// Some widget can live without scalar token (ex: Jitsi widget)
NSLog(@"[Widget] Note: There is no scalar token for %@", self);
}
}
return self;

View file

@ -21,7 +21,7 @@
#import "Widget.h"
/**
The type of matrix event used for scalar widgets.
The type of matrix event used for modular widgets.
*/
FOUNDATION_EXPORT NSString *const kWidgetEventTypeString;
@ -50,7 +50,7 @@ WidgetManagerErrorCode;
/**
The `WidgetManager` helps to handle scalar widgets.
The `WidgetManager` helps to handle modular widgets.
*/
@interface WidgetManager : NSObject
@ -80,7 +80,7 @@ WidgetManagerErrorCode;
/**
Add a scalar widget to a room.
Add a modular widget to a room.
@param widgetId the id of the widget.
@param widgetContent the widget content.
@ -139,4 +139,38 @@ WidgetManagerErrorCode;
- (void)addMatrixSession:(MXSession*)mxSession;
- (void)removeMatrixSession:(MXSession*)mxSession;
/**
Delete the data associated with an user.
@param userId the id of the user.
*/
- (void)deleteDataForUser:(NSString*)userId;
#pragma mark - Modular interface
/**
Make sure there is a scalar token for the given Matrix session.
If no token was gotten and stored before, the operation will make http requests
to get one.
@param mxSession the session to check.
@param success A block object called when the operation succeeds.
@param failure A block object called when the operation fails.
*/
- (MXHTTPOperation *)getScalarTokenForMXSession:(MXSession*)mxSession
success:(void (^)(NSString *scalarToken))success
failure:(void (^)(NSError *error))failure;
/**
The current scalar token for the given Matrix session.
It may be nil if `getScalarTokenForMXSession` was never called before.
@param mxSession the session to check.
@return the current scalar token .
*/
- (NSString *)scalarTokenForMXSession:(MXSession*)mxSession;
@end

View file

@ -16,6 +16,8 @@
#import "WidgetManager.h"
#import "MXKAppSettings.h"
#pragma mark - Contants
NSString *const kWidgetEventTypeString = @"im.vector.modular.widgets";
@ -40,6 +42,9 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain";
// MXSession kind of hash -> (Widget id -> `createWidget:` failure block).
NSMutableDictionary<NSString*,
NSMutableDictionary<NSString*, void (^)(NSError *error)>*> *failureBlockForWidgetCreation;
// User id -> scalar token
NSMutableDictionary<NSString*, NSString*> *scalarTokens;
}
@end
@ -66,6 +71,13 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain";
widgetEventListener = [NSMutableDictionary dictionary];
successBlockForWidgetCreation = [NSMutableDictionary dictionary];
failureBlockForWidgetCreation = [NSMutableDictionary dictionary];
[self load];
if (!scalarTokens)
{
scalarTokens = [NSMutableDictionary dictionary];
}
}
return self;
}
@ -157,8 +169,12 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain";
return nil;
}
NSString *hash = [NSString stringWithFormat:@"%p", room.mxSession];
successBlockForWidgetCreation[hash][widgetId] = success;
failureBlockForWidgetCreation[hash][widgetId] = failure;
// Send a state event with the widget data
// TODO: This API will be shortly replaced by a pure scalar API
// TODO: This API will be shortly replaced by a pure modular API
return [room sendStateEventOfType:kWidgetEventTypeString
content:widgetContent
stateKey:widgetId
@ -181,14 +197,11 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain";
NSString *confId = [room.roomId substringWithRange:NSMakeRange(1, [room.roomId rangeOfString:@":"].location - 1)];
confId = [confId stringByAppendingString:widgetSessionId];
// TODO: This url may come from scalar API
// TODO: This url should come from modular API
// Note: this url can be used as is inside a web container (like iframe for Riot-web)
// Riot-iOS does not directly use it but extracts params from it (see `[JitsiViewController openWidget:withVideo:]`)
NSString *url = [NSString stringWithFormat:@"https://scalar-staging.riot.im/scalar/api/widgets/jitsi.html?confId=%@&isAudioConf=%@&displayName=$matrix_display_name&avatarUrl=$matrix_avatar_url&email=$matrix_user_id@", confId, video ? @"false" : @"true"];
NSString *hash = [NSString stringWithFormat:@"%p", room.mxSession];
successBlockForWidgetCreation[hash][widgetId] = success;
failureBlockForWidgetCreation[hash][widgetId] = failure;
NSString *modularRestUrl = [[NSUserDefaults standardUserDefaults] objectForKey:@"integrationsRestUrl"];
NSString *url = [NSString stringWithFormat:@"%@/widgets/jitsi.html?confId=%@&isAudioConf=%@&displayName=$matrix_display_name&avatarUrl=$matrix_avatar_url&email=$matrix_user_id@", modularRestUrl, confId, video ? @"false" : @"true"];
return [self createWidget:widgetId
withContent:@{
@ -216,7 +229,7 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain";
}
// Send a state event with an empty content to disable the widget
// TODO: This API will be shortly replaced by a pure scalar API
// TODO: This API will be shortly replaced by a pure modular API
return [room sendStateEventOfType:kWidgetEventTypeString
content:@{}
stateKey:widgetId
@ -326,4 +339,100 @@ NSString *const WidgetManagerErrorDomain = @"WidgetManagerErrorDomain";
[failureBlockForWidgetCreation removeObjectForKey:hash];
}
- (void)deleteDataForUser:(NSString *)userId
{
[scalarTokens removeObjectForKey:userId];
[self save];
}
#pragma mark - Modular interface
- (NSString *)scalarTokenForMXSession:(MXSession *)mxSession
{
return scalarTokens[mxSession.myUser.userId];
}
- (MXHTTPOperation *)getScalarTokenForMXSession:(MXSession*)mxSession
success:(void (^)(NSString *scalarToken))success
failure:(void (^)(NSError *error))failure;
{
MXHTTPOperation *operation;
__block NSString *scalarToken = [self scalarTokenForMXSession:mxSession];
if (scalarToken)
{
success(scalarToken);
}
else
{
__weak __typeof__(self) weakSelf = self;
operation = [mxSession.matrixRestClient openIdToken:^(MXOpenIdToken *tokenObject) {
typeof(self) self = weakSelf;
if (self)
{
// Exchange the token for a scalar token
NSString *modularRestUrl = [[NSUserDefaults standardUserDefaults] objectForKey:@"integrationsRestUrl"];
MXHTTPClient *httpClient = [[MXHTTPClient alloc] initWithBaseURL:modularRestUrl andOnUnrecognizedCertificateBlock:nil];
MXHTTPOperation *operation2 = [httpClient requestWithMethod:@"POST"
path:@"register"
parameters:tokenObject.JSONDictionary
success:^(NSDictionary *JSONResponse) {
MXJSONModelSetString(scalarToken, JSONResponse[@"scalar_token"])
self->scalarTokens[mxSession.myUser.userId] = scalarToken;
[self save];
if (success)
{
success(scalarToken);
}
} failure:^(NSError *error) {
NSLog(@"[WidgetManager] getScalarTokenForMXSession. Error in modular/register request");
if (failure)
{
failure(error);
}
}];
[operation mutateTo:operation2];
}
} failure:^(NSError *error) {
NSLog(@"[WidgetManager] getScalarTokenForMXSession. Error in openIdToken request");
if (failure)
{
failure(error);
}
}];
}
return operation;
}
#pragma mark - Private methods
- (void)load
{
NSUserDefaults *userDefaults = [MXKAppSettings standardAppSettings].sharedUserDefaults;
scalarTokens = [NSMutableDictionary dictionaryWithDictionary:[userDefaults objectForKey:@"scalarTokens"]];
}
- (void)save
{
NSUserDefaults *userDefaults = [MXKAppSettings standardAppSettings].sharedUserDefaults;
[userDefaults setObject:scalarTokens forKey:@"scalarTokens"];
[userDefaults synchronize];
}
@end

View file

@ -61,6 +61,11 @@
self.view.backgroundColor = kRiotPrimaryBgColor;
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.navigationBar.tintColor = kRiotSecondaryBgColor;
self.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: kRiotPrimaryTextColor};
self.backButton.tintColor = kRiotColorGreen;
}
- (void)viewWillAppear:(BOOL)animated

View file

@ -176,6 +176,7 @@
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
[self.authInputsView customizeViewRendering];
@ -722,6 +723,27 @@
// Hide the custom server details in order to save customized inputs
[self hideCustomServers:YES];
// Create DM with Riot-bot on new account creation.
if (self.authType == MXKAuthenticationTypeRegister)
{
MXKAccount *account = [[MXKAccountManager sharedManager] accountForUserId:userId];
[account.mxSession createRoom:nil
visibility:kMXRoomDirectoryVisibilityPrivate
roomAlias:nil
topic:nil
invite:@[@"@riot-bot:matrix.org"]
invite3PID:nil
isDirect:YES
preset:kMXRoomPresetTrustedPrivateChat
success:nil
failure:^(NSError *error) {
NSLog(@"[AuthenticationVC] Create chat with riot-bot failed");
}];
}
// Remove auth view controller on successful login
if (self.navigationController)
{

View file

@ -34,6 +34,8 @@
@property (nonatomic) BOOL sendLogs;
@property (nonatomic) BOOL sendScreenshot;
@property (weak, nonatomic) IBOutlet UIView *overlayView;
@end
@implementation BugReportViewController
@ -87,9 +89,6 @@
{
_titleLabel.text = NSLocalizedStringFromTable(@"bug_report_title", @"Vector", nil);
_descriptionLabel.text = NSLocalizedStringFromTable(@"bug_report_description", @"Vector", nil);
// Allow to send empty description for crash report but not for bug report
_sendButton.enabled = NO;
}
[_cancelButton setTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] forState:UIControlStateNormal];
@ -137,6 +136,10 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.overlayView.backgroundColor = kRiotOverlayColor;
self.overlayView.alpha = 1.0;
self.containerView.backgroundColor = kRiotPrimaryBgColor;
self.sendingContainer.backgroundColor = kRiotPrimaryBgColor;

View file

@ -1,5 +1,5 @@
<?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">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina5_5" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
@ -17,6 +17,7 @@
<outlet property="containerView" destination="7U4-br-xRl" id="kJI-mL-pkw"/>
<outlet property="descriptionLabel" destination="Q2l-Yi-SlQ" id="VPO-0N-huQ"/>
<outlet property="logsDescriptionLabel" destination="ggt-kq-Zy9" id="3Nl-m3-1EE"/>
<outlet property="overlayView" destination="CXZ-fI-kPd" id="ZJb-0n-Tmf"/>
<outlet property="scrollView" destination="4fS-3N-tbW" id="Dsn-gw-VuW"/>
<outlet property="scrollViewBottomConstraint" destination="fnt-1e-ZW4" id="W1B-1m-h13"/>
<outlet property="sendButton" destination="z8A-7B-jAi" id="VSX-a9-yfs"/>

View file

@ -21,12 +21,12 @@
#import "AvatarGenerator.h"
#import "MXRoom+Riot.h"
#import "UsersDevicesViewController.h"
#import "RiotNavigationController.h"
#import "IncomingCallView.h"
@interface CallViewController ()
{
// Display a gradient view above the screen
@ -99,6 +99,7 @@
self.view.backgroundColor = kRiotPrimaryBgColor;
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.callerNameLabel.textColor = kRiotPrimaryTextColor;
self.callStatusLabel.textColor = kRiotTopicTextColor;
@ -196,6 +197,37 @@
gradientMaskLayer = nil;
}
- (UIView *)createIncomingCallView
{
NSString *avatarThumbURL = [self.mainSession.matrixRestClient urlOfContentThumbnail:self.peer.avatarUrl
toFitViewSize:IncomingCallView.callerAvatarSize
withMethod:MXThumbnailingMethodCrop];
NSString *callInfo;
if (self.mxCall.isVideoCall)
callInfo = NSLocalizedStringFromTable(@"call_incoming_video", @"Vector", nil);
else
callInfo = NSLocalizedStringFromTable(@"call_incoming_voice", @"Vector", nil);
IncomingCallView *incomingCallView = [[IncomingCallView alloc] initWithCallerAvatarURL:avatarThumbURL
placeholderImage:self.picturePlaceholder
callerName:self.peer.displayname
callInfo:callInfo];
// Incoming call is retained by call vc so use weak to avoid retain cycle
__weak typeof(self) weakSelf = self;
incomingCallView.onAnswer = ^{
[weakSelf onButtonPressed:weakSelf.answerCallButton];
};
incomingCallView.onReject = ^{
[weakSelf onButtonPressed:weakSelf.rejectCallButton];
};
return incomingCallView;
}
#pragma mark - MXCallDelegate
- (void)call:(MXCall *)call didEncounterError:(NSError *)error
@ -325,7 +357,7 @@
}
else if (self.mxCall.room)
{
return [AvatarGenerator generateAvatarForMatrixItem:self.mxCall.room.roomId withDisplayName:self.mxCall.room.riotDisplayname size:self.callerImageViewWidthConstraint.constant andFontSize:fontSize];
return [AvatarGenerator generateAvatarForMatrixItem:self.mxCall.room.roomId withDisplayName:self.mxCall.room.summary.displayname size:self.callerImageViewWidthConstraint.constant andFontSize:fontSize];
}
return [UIImage imageNamed:@"placeholder"];
@ -354,7 +386,7 @@
}
else if (self.mxCall.isConferenceCall)
{
peerDisplayName = self.mxCall.room.riotDisplayname;
peerDisplayName = self.mxCall.room.summary.displayname;
peerAvatarURL = self.mxCall.room.state.avatar;
}

View file

@ -224,6 +224,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.headerView.backgroundColor = kRiotSecondaryBgColor;
self.contactNameLabel.textColor = kRiotPrimaryTextColor;

View file

@ -105,6 +105,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.contactsTableView.backgroundColor = ((self.contactsTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -73,6 +73,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.searchBar.barStyle = kRiotDesignSearchBarStyle;
self.searchBar.tintColor = kRiotDesignSearchBarTintColor;

View file

@ -121,6 +121,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -72,6 +72,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -72,6 +72,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.searchTableView.backgroundColor = ((self.searchTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -79,6 +79,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.searchTableView.backgroundColor = ((self.searchTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -70,6 +70,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.searchBar.barStyle = kRiotDesignSearchBarStyle;
self.searchBar.tintColor = kRiotDesignSearchBarTintColor;

View file

@ -114,6 +114,7 @@
self.assetsCollectionView.backgroundColor = kRiotPrimaryBgColor;
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
}
- (UIStatusBarStyle)preferredStatusBarStyle

View file

@ -183,6 +183,7 @@ static void *RecordingContext = &RecordingContext;
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.cameraVideoCaptureProgressView.progressColor = kRiotPrimaryBgColor;
self.cameraVideoCaptureProgressView.unprogressColor = [UIColor clearColor];

View file

@ -96,6 +96,10 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.overlayView.backgroundColor = kRiotOverlayColor;
self.overlayView.alpha = 1.0;
self.titleLabel.textColor = kRiotPrimaryTextColor;
self.containerView.backgroundColor = kRiotPrimaryBgColor;

View file

@ -159,6 +159,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Use the primary bg color for the recents table view in plain style.
self.recentsTableView.backgroundColor = kRiotPrimaryBgColor;

View file

@ -73,6 +73,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.searchTableView.backgroundColor = ((self.searchTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -111,6 +111,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.bubblesTableView.backgroundColor = ((self.bubblesTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -209,6 +209,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.memberHeaderView.backgroundColor = kRiotSecondaryBgColor;
self.roomMemberNameLabel.textColor = kRiotPrimaryTextColor;

View file

@ -74,6 +74,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.searchTableView.backgroundColor = ((self.searchTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -158,10 +158,11 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
[self refreshSearchBarItemsColor:_searchBarView];
_searchBarHeaderBorder.backgroundColor = kRiotColorSilver;
_searchBarHeaderBorder.backgroundColor = kRiotAuxiliaryColor;
// Check the table view style to select its bg color.
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -63,7 +63,7 @@
[super viewDidLoad];
// Add the Vector background image when search bar is empty
// Add the Riot background image when search bar is empty
[self addBackgroundImageViewToView:self.view];
// Initialize here the data sources if a matrix session has been already set.
@ -72,6 +72,18 @@
self.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
}
- (void)userInterfaceThemeDidChange
{
[super userInterfaceThemeDidChange];
UIImageView *backgroundImageView = self.backgroundImageView;
if (backgroundImageView)
{
UIImage *image = [MXKTools paintImage:backgroundImageView.image withColor:kRiotKeyboardColor];
backgroundImageView.image = image;
}
}
- (void)destroy
{
[super destroy];

View file

@ -26,6 +26,7 @@
#import "Tools.h"
#import "MXRoom+Riot.h"
#import "MXRoomSummary+Riot.h"
#import "AppDelegate.h"
@ -45,9 +46,10 @@
#define ROOM_SETTINGS_MAIN_SECTION_ROW_NAME 1
#define ROOM_SETTINGS_MAIN_SECTION_ROW_TOPIC 2
#define ROOM_SETTINGS_MAIN_SECTION_ROW_TAG 3
#define ROOM_SETTINGS_MAIN_SECTION_ROW_MUTE_NOTIFICATIONS 4
#define ROOM_SETTINGS_MAIN_SECTION_ROW_LEAVE 5
#define ROOM_SETTINGS_MAIN_SECTION_ROW_COUNT 6
#define ROOM_SETTINGS_MAIN_SECTION_ROW_DIRECT_CHAT 4
#define ROOM_SETTINGS_MAIN_SECTION_ROW_MUTE_NOTIFICATIONS 5
#define ROOM_SETTINGS_MAIN_SECTION_ROW_LEAVE 6
#define ROOM_SETTINGS_MAIN_SECTION_ROW_COUNT 7
#define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_INVITED_ONLY 0
#define ROOM_SETTINGS_ROOM_ACCESS_SECTION_ROW_ANYONE_APART_FROM_GUEST 1
@ -70,6 +72,7 @@ NSString *const kRoomSettingsNameKey = @"kRoomSettingsNameKey";
NSString *const kRoomSettingsTopicKey = @"kRoomSettingsTopicKey";
NSString *const kRoomSettingsTagKey = @"kRoomSettingsTagKey";
NSString *const kRoomSettingsMuteNotifKey = @"kRoomSettingsMuteNotifKey";
NSString *const kRoomSettingsDirectChatKey = @"kRoomSettingsDirectChatKey";
NSString *const kRoomSettingsJoinRuleKey = @"kRoomSettingsJoinRuleKey";
NSString *const kRoomSettingsGuestAccessKey = @"kRoomSettingsGuestAccessKey";
NSString *const kRoomSettingsDirectoryKey = @"kRoomSettingsDirectoryKey";
@ -137,11 +140,6 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
// picker
MediaPickerViewController* mediaPicker;
// switches
UISwitch *roomNotifSwitch;
UISwitch *roomEncryptionSwitch;
UISwitch *roomEncryptionBlacklistUnverifiedDevicesSwitch;
// Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar.
id appDelegateDidTapStatusBarNotificationObserver;
@ -246,6 +244,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);
@ -1596,7 +1595,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
if ([updatedItemsDict objectForKey:kRoomSettingsMuteNotifKey])
{
if (roomNotifSwitch.on)
if (((NSNumber*)[updatedItemsDict objectForKey:kRoomSettingsMuteNotifKey]).boolValue)
{
[mxRoom mentionsOnly:^{
@ -1627,6 +1626,45 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
return;
}
if ([updatedItemsDict objectForKey:kRoomSettingsDirectChatKey])
{
pendingOperation = [mxRoom setIsDirect:((NSNumber*)[updatedItemsDict objectForKey:kRoomSettingsDirectChatKey]).boolValue withUserId:nil success:^{
if (weakSelf)
{
typeof(self) self = weakSelf;
self->pendingOperation = nil;
[self->updatedItemsDict removeObjectForKey:kRoomSettingsDirectChatKey];
[self onSave:nil];
}
} failure:^(NSError *error) {
NSLog(@"[RoomSettingsViewController] Altering DMness failed");
if (weakSelf)
{
typeof(self) self = weakSelf;
self->pendingOperation = nil;
dispatch_async(dispatch_get_main_queue(), ^{
NSString* message = error.localizedDescription;
if (!message.length)
{
message = NSLocalizedStringFromTable(@"room_details_fail_to_update_room_direct", @"Vector", nil);
}
[self onSaveFailed:message withKey:kRoomSettingsDirectChatKey];
});
}
}];
return;
}
// Room directory visibility
MXRoomDirectoryVisibility directoryVisibility = [updatedItemsDict objectForKey:kRoomSettingsDirectoryKey];
if (directoryVisibility)
@ -1942,29 +1980,42 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
{
if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_MUTE_NOTIFICATIONS)
{
MXKTableViewCellWithLabelAndSwitch *roomNotifCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath];
roomNotifCell.mxkLabelLeadingConstraint.constant = roomNotifCell.separatorInset.left;
roomNotifCell.mxkSwitchTrailingConstraint.constant = 15;
[roomNotifCell.mxkSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged];
roomNotifCell.mxkSwitch.onTintColor = kRiotColorGreen;
MXKTableViewCellWithLabelAndSwitch *roomNotifCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
[roomNotifCell.mxkSwitch addTarget:self action:@selector(toggleRoomNotification:) forControlEvents:UIControlEventValueChanged];
roomNotifCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_mute_notifs", @"Vector", nil);
roomNotifCell.mxkLabel.textColor = kRiotPrimaryTextColor;
roomNotifSwitch = roomNotifCell.mxkSwitch;
if ([updatedItemsDict objectForKey:kRoomSettingsMuteNotifKey])
{
roomNotifSwitch.on = ((NSNumber*)[updatedItemsDict objectForKey:kRoomSettingsMuteNotifKey]).boolValue;
roomNotifCell.mxkSwitch.on = ((NSNumber*)[updatedItemsDict objectForKey:kRoomSettingsMuteNotifKey]).boolValue;
}
else
{
roomNotifSwitch.on = mxRoom.isMute || mxRoom.isMentionsOnly;
roomNotifCell.mxkSwitch.on = mxRoom.isMute || mxRoom.isMentionsOnly;
}
cell = roomNotifCell;
}
else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_DIRECT_CHAT)
{
MXKTableViewCellWithLabelAndSwitch *roomDirectChat = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
[roomDirectChat.mxkSwitch addTarget:self action:@selector(toggleDirectChat:) forControlEvents:UIControlEventValueChanged];
roomDirectChat.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_direct_chat", @"Vector", nil);
if ([updatedItemsDict objectForKey:kRoomSettingsDirectChatKey])
{
roomDirectChat.mxkSwitch.on = ((NSNumber*)[updatedItemsDict objectForKey:kRoomSettingsDirectChatKey]).boolValue;
}
else
{
roomDirectChat.mxkSwitch.on = mxRoom.isDirect;
}
cell = roomDirectChat;
}
else if (row == ROOM_SETTINGS_MAIN_SECTION_ROW_PHOTO)
{
MXKTableViewCellWithLabelAndMXKImageView *roomPhotoCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndMXKImageView defaultReuseIdentifier] forIndexPath:indexPath];
@ -1994,7 +2045,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
}
else
{
[mxRoom setRoomAvatarImageIn:roomPhotoCell.mxkImageView];
[mxRoom.summary setRoomAvatarImageIn:roomPhotoCell.mxkImageView];
roomPhotoCell.userInteractionEnabled = (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomAvatar]);
roomPhotoCell.mxkImageView.alpha = roomPhotoCell.userInteractionEnabled ? 1.0f : 0.5f;
@ -2139,46 +2190,27 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
{
if (indexPath.row == directoryVisibilityIndex)
{
MXKTableViewCellWithLabelAndSwitch *directoryToggleCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath];
directoryToggleCell.mxkLabelLeadingConstraint.constant = directoryToggleCell.separatorInset.left;
directoryToggleCell.mxkSwitchTrailingConstraint.constant = 15;
MXKTableViewCellWithLabelAndSwitch *directoryToggleCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
directoryToggleCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_access_section_directory_toggle", @"Vector", nil);
directoryToggleCell.mxkLabel.textColor = kRiotPrimaryTextColor;
directoryVisibilitySwitch = directoryToggleCell.mxkSwitch;
// Workaround to avoid mixing between switches
// TODO: this is a design issue with switch within UITableViewCell that must fix everywhere
if (roomEncryptionSwitch == directoryVisibilitySwitch)
{
roomEncryptionSwitch = nil;
}
else if (roomNotifSwitch == directoryVisibilitySwitch)
{
roomNotifSwitch = nil;
}
else if (roomEncryptionBlacklistUnverifiedDevicesSwitch == directoryVisibilitySwitch)
{
roomEncryptionBlacklistUnverifiedDevicesSwitch = nil;
}
[directoryVisibilitySwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged];
directoryVisibilitySwitch.onTintColor = kRiotColorGreen;
[directoryToggleCell.mxkSwitch addTarget:self action:@selector(toggleDirectoryVisibility:) forControlEvents:UIControlEventValueChanged];
if ([updatedItemsDict objectForKey:kRoomSettingsDirectoryKey])
{
directoryVisibilitySwitch.on = ((NSNumber*)[updatedItemsDict objectForKey:kRoomSettingsDirectoryKey]).boolValue;
directoryToggleCell.mxkSwitch.on = ((NSNumber*)[updatedItemsDict objectForKey:kRoomSettingsDirectoryKey]).boolValue;
}
else
{
// Use the last retrieved value if any
directoryVisibilitySwitch.on = actualDirectoryVisibility ? [actualDirectoryVisibility isEqualToString:kMXRoomDirectoryVisibilityPublic] : NO;
directoryToggleCell.mxkSwitch.on = actualDirectoryVisibility ? [actualDirectoryVisibility isEqualToString:kMXRoomDirectoryVisibilityPublic] : NO;
}
// Check whether the user can change this option
directoryVisibilitySwitch.enabled = (oneSelfPowerLevel >= powerLevels.stateDefault);
directoryToggleCell.mxkSwitch.enabled = (oneSelfPowerLevel >= powerLevels.stateDefault);
// Store the switch to be able to update it
directoryVisibilitySwitch = directoryToggleCell.mxkSwitch;
cell = directoryToggleCell;
}
@ -2435,33 +2467,12 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
{
if (indexPath.row == 1)
{
MXKTableViewCellWithLabelAndSwitch *roomBlacklistUnverifiedDevicesCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath];
MXKTableViewCellWithLabelAndSwitch *roomBlacklistUnverifiedDevicesCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
roomBlacklistUnverifiedDevicesCell.mxkLabelLeadingConstraint.constant = roomBlacklistUnverifiedDevicesCell.separatorInset.left;
roomBlacklistUnverifiedDevicesCell.mxkSwitchTrailingConstraint.constant = 15;
[roomBlacklistUnverifiedDevicesCell.mxkSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged];
[roomBlacklistUnverifiedDevicesCell.mxkSwitch addTarget:self action:@selector(toggleBlacklistUnverifiedDevice:) forControlEvents:UIControlEventValueChanged];
roomBlacklistUnverifiedDevicesCell.mxkSwitch.onTintColor = kRiotColorGreen;
roomBlacklistUnverifiedDevicesCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_advanced_e2e_encryption_blacklist_unverified_devices", @"Vector", nil);
roomBlacklistUnverifiedDevicesCell.mxkLabel.textColor = kRiotPrimaryTextColor;
roomEncryptionBlacklistUnverifiedDevicesSwitch = roomBlacklistUnverifiedDevicesCell.mxkSwitch;
// Workaround to avoid mixing between switches
// TODO: this is a design issue with switch within UITableViewCell that must fix everywhere
if (directoryVisibilitySwitch == roomEncryptionBlacklistUnverifiedDevicesSwitch)
{
directoryVisibilitySwitch = nil;
}
else if (roomNotifSwitch == roomEncryptionBlacklistUnverifiedDevicesSwitch)
{
roomNotifSwitch = nil;
}
else if (roomEncryptionSwitch == roomEncryptionBlacklistUnverifiedDevicesSwitch)
{
roomEncryptionSwitch = nil;
}
// For the switch value, use by order:
// - the MXCrypto.globalBlacklistUnverifiedDevices if its value is YES
@ -2472,11 +2483,11 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
if (mxRoom.mxSession.crypto.globalBlacklistUnverifiedDevices)
{
blacklistUnverifiedDevices = YES;
roomEncryptionBlacklistUnverifiedDevicesSwitch.enabled = NO;
roomBlacklistUnverifiedDevicesCell.mxkSwitch.enabled = NO;
}
else
{
roomEncryptionBlacklistUnverifiedDevicesSwitch.enabled = YES;
roomBlacklistUnverifiedDevicesCell.mxkSwitch.enabled = YES;
if ([updatedItemsDict objectForKey:kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey])
{
@ -2488,9 +2499,12 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
}
}
roomEncryptionBlacklistUnverifiedDevicesSwitch.on = blacklistUnverifiedDevices;
roomBlacklistUnverifiedDevicesCell.mxkSwitch.on = blacklistUnverifiedDevices;
cell = roomBlacklistUnverifiedDevicesCell;
// Force layout before reusing a cell (fix switch displayed outside the screen)
[cell layoutIfNeeded];
}
else if (indexPath.row == 2)
{
@ -2516,35 +2530,13 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
if (oneSelfPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:kMXEventTypeStringRoomEncryption])
{
MXKTableViewCellWithLabelAndSwitch *roomEncryptionCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath];
MXKTableViewCellWithLabelAndSwitch *roomEncryptionCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
roomEncryptionCell.mxkLabelLeadingConstraint.constant = roomEncryptionCell.separatorInset.left;
roomEncryptionCell.mxkSwitchTrailingConstraint.constant = 15;
[roomEncryptionCell.mxkSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged];
roomEncryptionCell.mxkSwitch.onTintColor = kRiotColorGreen;
[roomEncryptionCell.mxkSwitch addTarget:self action:@selector(toggleEncryption:) forControlEvents:UIControlEventValueChanged];
roomEncryptionCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_advanced_enable_e2e_encryption", @"Vector", nil);
roomEncryptionCell.mxkLabel.textColor = kRiotPrimaryTextColor;
roomEncryptionSwitch = roomEncryptionCell.mxkSwitch;
// Workaround to avoid mixing between switches
// TODO: this is a design issue with switch within UITableViewCell that must fix everywhere
if (directoryVisibilitySwitch == roomEncryptionSwitch)
{
directoryVisibilitySwitch = nil;
}
else if (roomNotifSwitch == roomEncryptionSwitch)
{
roomNotifSwitch = nil;
}
else if (roomEncryptionBlacklistUnverifiedDevicesSwitch == roomEncryptionSwitch)
{
roomEncryptionBlacklistUnverifiedDevicesSwitch = nil;
}
roomEncryptionSwitch.on = ([updatedItemsDict objectForKey:kRoomSettingsEncryptionKey] != nil);
roomEncryptionCell.mxkSwitch.on = ([updatedItemsDict objectForKey:kRoomSettingsEncryptionKey] != nil);
cell = roomEncryptionCell;
}
@ -2594,6 +2586,30 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
// iOS8 requires this method to enable editing (see editActionsForRowAtIndexPath).
}
- (MXKTableViewCellWithLabelAndSwitch*)getLabelAndSwitchCell:(UITableView*)tableview forIndexPath:(NSIndexPath *)indexPath
{
MXKTableViewCellWithLabelAndSwitch *cell = [tableview dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath];
cell.mxkLabelLeadingConstraint.constant = cell.separatorInset.left;
cell.mxkSwitchTrailingConstraint.constant = 15;
cell.mxkLabel.textColor = kRiotPrimaryTextColor;
cell.mxkSwitch.onTintColor = kRiotColorGreen;
[cell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventValueChanged];
// Reset the stored `directoryVisibilitySwitch` if the corresponding cell is reused.
if (cell.mxkSwitch == directoryVisibilitySwitch)
{
directoryVisibilitySwitch = nil;
}
// Force layout before reusing a cell (fix switch displayed outside the screen)
[cell layoutIfNeeded];
return cell;
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
@ -3122,102 +3138,123 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
[self presentViewController:navigationController animated:YES completion:nil];
}
- (void)onSwitchUpdate:(UISwitch*)theSwitch
- (void)toggleRoomNotification:(UISwitch*)theSwitch
{
if (theSwitch == roomNotifSwitch)
if (theSwitch.on == (mxRoom.isMute || mxRoom.isMentionsOnly))
{
if (roomNotifSwitch.on == (mxRoom.isMute || mxRoom.isMentionsOnly))
{
[updatedItemsDict removeObjectForKey:kRoomSettingsMuteNotifKey];
}
else
{
[updatedItemsDict setObject:[NSNumber numberWithBool:roomNotifSwitch.on] forKey:kRoomSettingsMuteNotifKey];
}
[updatedItemsDict removeObjectForKey:kRoomSettingsMuteNotifKey];
}
else if (theSwitch == directoryVisibilitySwitch)
else
{
MXRoomDirectoryVisibility visibility = directoryVisibilitySwitch.on ? kMXRoomDirectoryVisibilityPublic : kMXRoomDirectoryVisibilityPrivate;
[updatedItemsDict setObject:[NSNumber numberWithBool:theSwitch.on] forKey:kRoomSettingsMuteNotifKey];
}
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
}
- (void)toggleDirectChat:(UISwitch*)theSwitch
{
if (theSwitch.on == mxRoom.isDirect)
{
[updatedItemsDict removeObjectForKey:kRoomSettingsDirectChatKey];
}
else
{
[updatedItemsDict setObject:[NSNumber numberWithBool:theSwitch.on] forKey:kRoomSettingsDirectChatKey];
}
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
}
- (void)toggleEncryption:(UISwitch*)theSwitch
{
if (theSwitch.on)
{
// Prompt here user before turning on the data encryption
__weak typeof(self) weakSelf = self;
// Check whether the actual settings has been retrieved
if (actualDirectoryVisibility)
[currentAlert dismissViewControllerAnimated:NO completion:nil];
currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"warning", @"Vector", nil)
message:NSLocalizedStringFromTable(@"room_details_advanced_e2e_encryption_prompt_message", @"Vector", nil)
preferredStyle:UIAlertControllerStyleAlert];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
// Reset switch change
theSwitch.on = NO;
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
[self->updatedItemsDict setObject:@(YES) forKey:kRoomSettingsEncryptionKey];
[self getNavigationItem].rightBarButtonItem.enabled = self->updatedItemsDict.count;
}
}]];
[currentAlert mxk_setAccessibilityIdentifier:@"RoomSettingsVCEnableEncryptionAlert"];
[self presentViewController:currentAlert animated:YES completion:nil];
}
else
{
[updatedItemsDict removeObjectForKey:kRoomSettingsEncryptionKey];
}
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
}
- (void)toggleBlacklistUnverifiedDevice:(UISwitch*)theSwitch
{
if ([mxRoom.mxSession.crypto isBlacklistUnverifiedDevicesInRoom:mxRoom.roomId] != theSwitch.on)
{
updatedItemsDict[kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey] = @(theSwitch.on);
}
else
{
[updatedItemsDict removeObjectForKey:kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey];
}
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);
}
- (void)toggleDirectoryVisibility:(UISwitch*)theSwitch
{
MXRoomDirectoryVisibility visibility = theSwitch.on ? kMXRoomDirectoryVisibilityPublic : kMXRoomDirectoryVisibilityPrivate;
// Check whether the actual settings has been retrieved
if (actualDirectoryVisibility)
{
if ([visibility isEqualToString:actualDirectoryVisibility])
{
if ([visibility isEqualToString:actualDirectoryVisibility])
{
[updatedItemsDict removeObjectForKey:kRoomSettingsDirectoryKey];
}
else
{
[updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey];
}
[updatedItemsDict removeObjectForKey:kRoomSettingsDirectoryKey];
}
else
{
[updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey];
}
}
else if (theSwitch == roomEncryptionSwitch)
else
{
if (roomEncryptionSwitch.on)
{
// Prompt here user before turning on the data encryption
__weak typeof(self) weakSelf = self;
[currentAlert dismissViewControllerAnimated:NO completion:nil];
currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"warning", @"Vector", nil)
message:NSLocalizedStringFromTable(@"room_details_advanced_e2e_encryption_prompt_message", @"Vector", nil)
preferredStyle:UIAlertControllerStyleAlert];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
}
// Reset switch change
theSwitch.on = NO;
}]];
[currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (weakSelf)
{
typeof(self) self = weakSelf;
self->currentAlert = nil;
[self->updatedItemsDict setObject:@(YES) forKey:kRoomSettingsEncryptionKey];
[self getNavigationItem].rightBarButtonItem.enabled = self->updatedItemsDict.count;
}
}]];
[currentAlert mxk_setAccessibilityIdentifier:@"RoomSettingsVCEnableEncryptionAlert"];
[self presentViewController:currentAlert animated:YES completion:nil];
}
else
{
[updatedItemsDict removeObjectForKey:kRoomSettingsEncryptionKey];
}
}
else if (theSwitch == roomEncryptionBlacklistUnverifiedDevicesSwitch)
{
if ([mxRoom.mxSession.crypto isBlacklistUnverifiedDevicesInRoom:mxRoom.roomId] != roomEncryptionBlacklistUnverifiedDevicesSwitch.on)
{
updatedItemsDict[kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey] = @(roomEncryptionBlacklistUnverifiedDevicesSwitch.on);
}
else
{
[updatedItemsDict removeObjectForKey:kRoomSettingsEncryptionBlacklistUnverifiedDevicesKey];
}
[updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey];
}
[self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0);

View file

@ -109,6 +109,9 @@
#import "MXRoom+Riot.h"
#import "IntegrationManagerViewController.h"
#import "WidgetViewController.h"
@interface RoomViewController ()
{
// The expanded header
@ -180,9 +183,9 @@
// Tell whether the view controller is appeared or not.
BOOL isAppeared;
// The search bar buttom item back up.
UIBarButtonItem *searchBarButtonItem;
// The right bar button items back up.
NSArray<UIBarButtonItem *> *rightBarButtonItems;
// Observe kRiotDesignValuesDidChangeThemeNotification to handle user interface theme change.
id kRiotDesignValuesDidChangeThemeNotificationObserver;
}
@ -360,9 +363,12 @@
[self setEventDetailsViewClass:EventDetailsView.class];
// Update navigation bar items
self.navigationItem.rightBarButtonItem.target = self;
self.navigationItem.rightBarButtonItem.action = @selector(onButtonPressed:);
for (UIBarButtonItem *barButtonItem in self.navigationItem.rightBarButtonItems)
{
barButtonItem.target = self;
barButtonItem.action = @selector(onButtonPressed:);
}
// Prepare missed dicussion badge
missedDiscussionsBarButtonCustomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 21)];
missedDiscussionsBarButtonCustomView.backgroundColor = [UIColor clearColor];
@ -417,6 +423,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Prepare jump to last unread banner
self.jumpToLastUnreadBannerContainer.backgroundColor = kRiotPrimaryBgColor;
@ -1046,8 +1053,11 @@
- (void)destroy
{
searchBarButtonItem = nil;
self.navigationItem.rightBarButtonItem.enabled = NO;
rightBarButtonItems = nil;
for (UIBarButtonItem *barButtonItem in self.navigationItem.rightBarButtonItems)
{
barButtonItem.enabled = NO;
}
if (currentAlert)
{
@ -1150,17 +1160,20 @@
- (void)refreshRoomTitle
{
if (searchBarButtonItem && !self.navigationItem.rightBarButtonItem)
if (rightBarButtonItems && !self.navigationItem.rightBarButtonItems)
{
// Restore by default the search bar button.
self.navigationItem.rightBarButtonItem = searchBarButtonItem;
self.navigationItem.rightBarButtonItems = rightBarButtonItems;
}
// Set the right room title view
if (self.isRoomPreview)
{
// Disable the search button
self.navigationItem.rightBarButtonItem.enabled = NO;
// Disable the right buttons
for (UIBarButtonItem *barButtonItem in self.navigationItem.rightBarButtonItems)
{
barButtonItem.enabled = NO;
}
[self showPreviewHeader:YES];
}
@ -1170,8 +1183,18 @@
if (self.roomDataSource.isLive)
{
// Enable the search button
self.navigationItem.rightBarButtonItem.enabled = YES;
// Enable the right buttons (Search and Integrations)
for (UIBarButtonItem *barButtonItem in self.navigationItem.rightBarButtonItems)
{
barButtonItem.enabled = YES;
}
BOOL matrixAppsEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"matrixApps"];
if (!matrixAppsEnabled && self.navigationItem.rightBarButtonItems.count == 2)
{
// If the setting is disabled, do not show the icon
self.navigationItem.rightBarButtonItems = @[self.navigationItem.rightBarButtonItem];
}
// Do not change title view class here if the expanded header is visible.
if (self.expandedHeaderContainer.hidden)
@ -1191,8 +1214,8 @@
else
{
// Remove the search button temporarily
searchBarButtonItem = self.navigationItem.rightBarButtonItem;
self.navigationItem.rightBarButtonItem = nil;
rightBarButtonItems = self.navigationItem.rightBarButtonItems;
self.navigationItem.rightBarButtonItems = nil;
[self setRoomTitleViewClass:SimpleRoomTitleView.class];
self.titleView.editable = NO;
@ -2850,10 +2873,35 @@
- (IBAction)onButtonPressed:(id)sender
{
// Search button
if (sender == self.navigationItem.rightBarButtonItem)
{
[self performSegueWithIdentifier:@"showRoomSearch" sender:self];
}
// Matrix Apps button
else if (self.navigationItem.rightBarButtonItems.count == 2 && sender == self.navigationItem.rightBarButtonItems[1])
{
// Temporary code to test `WidgetViewController`
// TODO: remove it
// NSArray<Widget *> *widgets = [[WidgetManager sharedManager] widgetsInRoom:self.roomDataSource.room];
// if (widgets.count)
// {
// // Hide back button title
// self.navigationItem.backBarButtonItem =[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
//
// WidgetViewController *widgetVC = [[WidgetViewController alloc] initForWidget:widgets[0]];
// [self.navigationController pushViewController:widgetVC animated:YES];
// }
// else
{
IntegrationManagerViewController *modularVC = [[IntegrationManagerViewController alloc] initForMXSession:self.roomDataSource.mxSession
inRoom:self.roomDataSource.roomId
screen:kIntegrationManagerMainScreen
widgetId:nil];
[self presentViewController:modularVC animated:NO completion:nil];
}
}
else if (sender == self.jumpToLastUnreadButton)
{
// Hide expanded header to restore navigation bar settings.

View file

@ -20,7 +20,7 @@ limitations under the License.
#import "UIViewController+RiotSearch.h"
/**
This view controller manages several uiviewcontrollers like UISegmentedControlled manages uiTableView
This view controller manages several uiviewcontrollers like UISegmentedController manages uiTableView
except that the managed items are custom UIViewControllers.
It uses a Vector design.
*/
@ -77,6 +77,11 @@ limitations under the License.
@param viewControllers the list of viewControllers to display.
@param defaultSelected index of the default selected UIViewController in the list.
*/
- (void)initWithTitles:(NSArray*)titles viewControllers:(NSArray*)viewControllers defaultSelected:(NSUInteger)index;
- (void)initWithTitles:(NSArray*)titles viewControllers:(NSArray*)viewControllers defaultSelected:(NSUInteger)defaultSelected;
/**
Callback used to take into account the change of the user interface theme.
*/
- (void)userInterfaceThemeDidChange;
@end

View file

@ -17,7 +17,7 @@
#import "SegmentedViewController.h"
#import "AppDelegate.h"
#import "RiotDesignValues.h"
@interface SegmentedViewController ()
{
@ -71,11 +71,11 @@
@param viewControllers the list of viewControllers to display.
@param defaultSelected index of the default selected UIViewController in the list.
*/
- (void)initWithTitles:(NSArray*)titles viewControllers:(NSArray*)someViewControllers defaultSelected:(NSUInteger)index
- (void)initWithTitles:(NSArray*)titles viewControllers:(NSArray*)someViewControllers defaultSelected:(NSUInteger)defaultSelected
{
viewControllers = someViewControllers;
sectionTitles = titles;
_selectedIndex = index;
_selectedIndex = defaultSelected;
}
- (void)destroy
@ -129,7 +129,6 @@
// Setup `MXKViewControllerHandling` properties
self.enableBarTintColorStatusChange = NO;
self.rageShakeManager = [RageShakeManager sharedManager];
}
- (void)viewDidLoad
@ -173,6 +172,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
self.view.backgroundColor = kRiotPrimaryBgColor;
}

View file

@ -98,8 +98,9 @@ enum
enum
{
#ifdef USE_JITSI_WIDGET
LABS_MATRIX_APPS_INDEX = 0,
#ifdef USE_JITSI_WIDGET
LABS_USE_JITSI_WIDGET_INDEX,
#endif
LABS_CRYPTO_INDEX,
LABS_COUNT
@ -307,6 +308,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);
@ -1255,6 +1257,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
cell.alpha = 1.0f;
cell.userInteractionEnabled = YES;
[cell layoutIfNeeded];
return cell;
}
@ -1267,6 +1271,9 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
cell.mxkLabel.textColor = kRiotPrimaryTextColor;
// Force layout before reusing a cell (fix switch displayed outside the screen)
[cell layoutIfNeeded];
return cell;
}
@ -1317,6 +1324,12 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
signOutCell = [[MXKTableViewCellWithButton alloc] init];
}
else
{
// Fix https://github.com/vector-im/riot-ios/issues/1354
// Do not move this line in prepareForReuse because of https://github.com/vector-im/riot-ios/issues/1323
signOutCell.mxkButton.titleLabel.text = nil;
}
NSString* title = NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil);
@ -1860,6 +1873,11 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
markAllBtnCell = [[MXKTableViewCellWithButton alloc] init];
}
else
{
// Fix https://github.com/vector-im/riot-ios/issues/1354
markAllBtnCell.mxkButton.titleLabel.text = nil;
}
NSString *btnTitle = NSLocalizedStringFromTable(@"settings_mark_all_as_read", @"Vector", nil);
[markAllBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
@ -1880,6 +1898,11 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
clearCacheBtnCell = [[MXKTableViewCellWithButton alloc] init];
}
else
{
// Fix https://github.com/vector-im/riot-ios/issues/1354
clearCacheBtnCell.mxkButton.titleLabel.text = nil;
}
NSString *btnTitle = NSLocalizedStringFromTable(@"settings_clear_cache", @"Vector", nil);
[clearCacheBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
@ -1900,6 +1923,11 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
reportBugBtnCell = [[MXKTableViewCellWithButton alloc] init];
}
else
{
// Fix https://github.com/vector-im/riot-ios/issues/1354
reportBugBtnCell.mxkButton.titleLabel.text = nil;
}
NSString *btnTitle = NSLocalizedStringFromTable(@"settings_report_bug", @"Vector", nil);
[reportBugBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
@ -1916,11 +1944,23 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
}
else if (section == SETTINGS_SECTION_LABS_INDEX)
{
#ifdef USE_JITSI_WIDGET
if (row == LABS_MATRIX_APPS_INDEX)
{
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_labs_matrix_apps", @"Vector", nil);
labelAndSwitchCell.mxkSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:@"matrixApps"];
[labelAndSwitchCell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleLabsMatrixApps:) forControlEvents:UIControlEventTouchUpInside];
cell = labelAndSwitchCell;
}
#ifdef USE_JITSI_WIDGET
else if (row == LABS_USE_JITSI_WIDGET_INDEX)
{
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_labs_create_conference_with_jitsi", @"Vector", nil);
labelAndSwitchCell.mxkSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:@"createConferenceCallsWithJitsi"];
@ -2003,6 +2043,11 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
exportKeysBtnCell = [[MXKTableViewCellWithButton alloc] init];
}
else
{
// Fix https://github.com/vector-im/riot-ios/issues/1354
exportKeysBtnCell.mxkButton.titleLabel.text = nil;
}
NSString *btnTitle = NSLocalizedStringFromTable(@"settings_crypto_export", @"Vector", nil);
[exportKeysBtnCell.mxkButton setTitle:btnTitle forState:UIControlStateNormal];
@ -2562,7 +2607,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
- (void)togglePushNotifications:(id)sender
{
// Check first whether the user allow notification from device settings
if ([[MXKAccountManager sharedManager] isAPNSAvailable] == NO)
UIUserNotificationType currentUserNotificationTypes = UIApplication.sharedApplication.currentUserNotificationSettings.types;
if (currentUserNotificationTypes == UIUserNotificationTypeNone)
{
[currentAlert dismissViewControllerAnimated:NO completion:nil];
@ -2594,10 +2640,28 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
{
[self startActivityIndicator];
MXKAccount* account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
MXKAccountManager *accountManager = [MXKAccountManager sharedManager];
MXKAccount* account = accountManager.activeAccounts.firstObject;
// toggle the pushes
[account setEnablePushNotifications:!account.pushNotificationServiceIsActive];
if (accountManager.apnsDeviceToken)
{
[account setEnablePushNotifications:!account.pushNotificationServiceIsActive];
}
else
{
// Obtain device token when user has just enabled access to notifications from system settings
[[AppDelegate theDelegate] registerForRemoteNotificationsWithCompletion:^(NSError * error) {
if (error)
{
[(UISwitch *)sender setOn:NO animated:YES];
[self stopActivityIndicator];
}
else
{
[account setEnablePushNotifications:YES];
}
}];
}
}
}
@ -2646,6 +2710,19 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
}
}
- (void)toggleLabsMatrixApps:(id)sender
{
if (sender && [sender isKindOfClass:UISwitch.class])
{
UISwitch *switchButton = (UISwitch*)sender;
[[NSUserDefaults standardUserDefaults] setBool:switchButton.isOn forKey:@"matrixApps"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.tableView reloadData];
}
}
- (void)toggleJitsiForConference:(id)sender
{
if (sender && [sender isKindOfClass:UISwitch.class])

View file

@ -148,7 +148,7 @@
[self refreshSearchBarItemsColor:_searchBarView];
_searchBarHeaderBorder.backgroundColor = kRiotColorSilver;
_searchBarHeaderBorder.backgroundColor = kRiotAuxiliaryColor;
// Check the table view style to select its bg color.
self.contactsTableView.backgroundColor = ((self.contactsTableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -95,7 +95,7 @@
[super viewDidLoad];
// Add the Vector background image when search bar is empty
// Add the Riot background image when search bar is empty
[self addBackgroundImageViewToView:self.view];
// Initialize here the data sources if a matrix session has been already set.
@ -107,6 +107,18 @@
[super showSearch:NO];
}
- (void)userInterfaceThemeDidChange
{
[super userInterfaceThemeDidChange];
UIImageView *backgroundImageView = self.backgroundImageView;
if (backgroundImageView)
{
UIImage *image = [MXKTools paintImage:backgroundImageView.image withColor:kRiotKeyboardColor];
backgroundImageView.image = image;
}
}
- (void)destroy
{
[super destroy];

View file

@ -83,6 +83,7 @@
{
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
// Check the table view style to select its bg color.
self.tableView.backgroundColor = ((self.tableView.style == UITableViewStylePlain) ? kRiotPrimaryBgColor : kRiotSecondaryBgColor);

View file

@ -54,6 +54,7 @@
self.view.backgroundColor = kRiotPrimaryBgColor;
self.defaultBarTintColor = kRiotSecondaryBgColor;
self.barTitleColor = kRiotPrimaryTextColor;
self.activityIndicator.backgroundColor = kRiotOverlayColor;
webView.backgroundColor = kRiotPrimaryBgColor;
}

View file

@ -0,0 +1,40 @@
/*
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.
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 "WebViewViewController.h"
#import <MatrixSDK/MatrixSDK.h>
FOUNDATION_EXPORT NSString *const kIntegrationManagerMainScreen;
FOUNDATION_EXPORT NSString *const kIntegrationManagerAddIntegrationScreen;
/**
`IntegrationManagerViewController` displays the Modular integration manager webapp
into a webview.
*/
@interface IntegrationManagerViewController : WebViewViewController <UIWebViewDelegate>
/**
Initialise with params for the Modular interface webapp.
@param mxSession the session to use.
@param roomId the room where to set up widgets.
@param screen the screen to display in the Modular interface webapp. Can be nil.
@param widgetId the id of the widget in case of widget configuration edition. Can be nil.
*/
- (instancetype)initForMXSession:(MXSession*)mxSession inRoom:(NSString*)roomId screen:(NSString*)screen widgetId:(NSString*)widgetId;
@end

View file

@ -0,0 +1,822 @@
/*
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.
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 "IntegrationManagerViewController.h"
#import "WidgetManager.h"
#import "AppDelegate.h"
#import <JavaScriptCore/JavaScriptCore.h>
NSString *const kIntegrationManagerMainScreen = nil;
NSString *const kIntegrationManagerAddIntegrationScreen = @"add_integ";
NSString *const kJavascriptSendResponseToModular = @"riotIOS.sendResponse('%@', %@);";
@interface IntegrationManagerViewController ()
{
MXSession *mxSession;
NSString *roomId;
NSString *screen;
NSString *widgetId;
NSString *scalarToken;
MXHTTPOperation *operation;
}
@end
@implementation IntegrationManagerViewController
- (instancetype)initForMXSession:(MXSession *)theMXSession inRoom:(NSString *)theRoomId screen:(NSString *)theScreen widgetId:(NSString *)theWidgetId
{
self = [super init];
if (self)
{
mxSession = theMXSession;
roomId = theRoomId;
screen = theScreen;
widgetId = theWidgetId;
}
return self;
}
- (void)destroy
{
[super destroy];
[operation cancel];
operation = nil;
}
- (void)viewDidLoad
{
[super viewDidLoad];
webView.scalesPageToFit = NO;
webView.scrollView.bounces = NO;
// Disable opacity so that the webview background uses the current interface theme
webView.opaque = NO;
webView.delegate = self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (!self.URL && !operation)
{
__weak __typeof__(self) weakSelf = self;
[self startActivityIndicator];
// Make sure we a scalar token
operation = [[WidgetManager sharedManager] getScalarTokenForMXSession:mxSession success:^(NSString *theScalarToken) {
typeof(self) self = weakSelf;
if (self)
{
self->operation = nil;
scalarToken = theScalarToken;
// Launch the webview on the right modular webapp page
self.URL = [self interfaceUrl];
}
} failure:^(NSError *error) {
typeof(self) self = weakSelf;
if (self)
{
self->operation = nil;
[self stopActivityIndicator];
}
}];
}
}
#pragma mark - Private methods
/**
Build the URL to use in the Modular interface webapp.
*/
- (NSString *)interfaceUrl
{
NSMutableString *url;
if (scalarToken)
{
url = [NSMutableString stringWithFormat:@"%@?scalar_token=%@&room_id=%@",
[[NSUserDefaults standardUserDefaults] objectForKey:@"integrationsUiUrl"],
[scalarToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[roomId stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]
];
if (screen)
{
[url appendString:@"&screen="];
[url appendString:[screen stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
if (widgetId)
{
[url appendString:@"&integ_id="];
[url appendString:[widgetId stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
}
return url;
}
- (void)enableDebug
{
// Setup console.log() -> NSLog() route
JSContext *ctx = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
ctx[@"console"][@"log"] = ^(JSValue * msg) {
NSLog(@"-- JavaScript: %@", msg);
};
// Redirect all console.* logging methods to console.log
[webView stringByEvaluatingJavaScriptFromString:@"console.debug = console.log; console.info = console.log; console.warn = console.log; console.error = console.log;"];
}
- (void)showErrorAsAlert:(NSError*)error
{
NSString *title = [error.userInfo valueForKey:NSLocalizedFailureReasonErrorKey];
NSString *msg = [error.userInfo valueForKey:NSLocalizedDescriptionKey];
if (!title)
{
if (msg)
{
title = msg;
msg = nil;
}
else
{
title = [NSBundle mxk_localizedStringForKey:@"error"];
}
}
__weak __typeof__(self) weakSelf = self;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"]
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
typeof(self) self = weakSelf;
if (self)
{
// Leave this Intergrations Manager VC
[self withdrawViewControllerAnimated:YES completion:nil];
}
}]];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark - UIWebViewDelegate
-(void)webViewDidFinishLoad:(UIWebView *)theWebView
{
[self enableDebug];
// Setup js code
NSString *path = [[NSBundle mainBundle] pathForResource:@"IntegrationManager" ofType:@"js"];
NSString *js = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[webView stringByEvaluatingJavaScriptFromString:js];
[self stopActivityIndicator];
// Check connectivity
if ([AppDelegate theDelegate].isOffline)
{
// The web page may be in the cache, so its loading will be successful
// but we cannot go further, it often leads to a blank screen.
// So, display an error so that the user can escape.
NSError *error = [NSError errorWithDomain:NSURLErrorDomain
code:NSURLErrorNotConnectedToInternet
userInfo:@{
NSLocalizedDescriptionKey : NSLocalizedStringFromTable(@"network_offline_prompt", @"Vector", nil)
}];
[self showErrorAsAlert:error];
}
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *urlString = [[request URL] absoluteString];
if ([urlString hasPrefix:@"js:"])
{
// Listen only to scheme of the JS-UIWebView bridge
NSString *jsonString = [[[urlString componentsSeparatedByString:@"js:"] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *parameters = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers
error:&error];
if (!error)
{
[self onMessage:parameters];
}
return NO;
}
if (navigationType == UIWebViewNavigationTypeLinkClicked )
{
// Open links outside the app
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// Filter out the users's scalar token
NSString *errorDescription = error.description;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"scalar_token=\\w*"
options:NSRegularExpressionCaseInsensitive error:nil];
errorDescription = [regex stringByReplacingMatchesInString:errorDescription
options:0
range:NSMakeRange(0, errorDescription.length)
withTemplate:@"scalar_token=..."];
NSLog(@"[IntegrationManagerVC] didFailLoadWithError: %@", errorDescription);
[self stopActivityIndicator];
[self showErrorAsAlert:error];
}
#pragma mark - Modular postMessage API
- (void)onMessage:(NSDictionary*)JSData
{
NSDictionary *eventData;
MXJSONModelSetDictionary(eventData, JSData[@"event.data"]);
NSString *roomIdInEvent, *userId, *action;
MXJSONModelSetString(roomIdInEvent, eventData[@"room_id"]);
MXJSONModelSetString(userId, eventData[@"user_id"]);
MXJSONModelSetString(action, eventData[@"action"]);
if ([action isEqualToString:@"close_scalar"])
{
[self withdrawViewControllerAnimated:YES completion:nil];
return;
}
if (!roomIdInEvent)
{
[self sendLocalisedError:@"widget_integration_missing_room_id" toEvent:eventData];
return;
}
if (![roomIdInEvent isEqualToString:roomId])
{
[self sendError:[NSString stringWithFormat:NSLocalizedStringFromTable(@"widget_integration_room_not_visible", @"Vector", nil), roomIdInEvent] toEvent:eventData];
return;
}
// These APIs don't require userId
if ([@"join_rules_state" isEqualToString:action])
{
[self getJoinRules:eventData];
return;
}
else if ([@"set_plumbing_state" isEqualToString:action])
{
[self setPlumbingState:eventData];
return;
}
else if ([@"get_membership_count" isEqualToString:action])
{
[self getMembershipCount:eventData];
return;
}
else if ([@"set_widget" isEqualToString:action])
{
[self setWidget:eventData];
return;
}
else if ([@"get_widgets" isEqualToString:action])
{
[self getWidgets:eventData];
return;
}
else if ([@"can_send_event" isEqualToString:action])
{
[self canSendEvent:eventData];
return;
}
if (!userId)
{
[self sendLocalisedError:@"widget_integration_missing_user_id" toEvent:eventData];
return;
}
if ([@"membership_state" isEqualToString:action])
{
[self getMembershipState:userId eventData:eventData];
}
else if ([@"invite" isEqualToString:action])
{
[self inviteUser:userId eventData:eventData];
}
else if ([@"bot_options" isEqualToString:action])
{
[self getBotOptions:userId eventData:eventData];
}
else if ([@"set_bot_options" isEqualToString:action])
{
[self setBotOptions:userId eventData:eventData];
}
else if ([@"set_bot_power" isEqualToString:action])
{
[self setBotPower:userId eventData:eventData];
}
else
{
NSLog(@"[IntegrationManagerViewControllerVC] Unhandled postMessage event with action %@: %@", action, JSData);
}
}
- (void)sendBoolResponse:(BOOL)response toEvent:(NSDictionary*)eventData
{
// Convert BOOL to "true" or "false"
NSString *js = [NSString stringWithFormat:kJavascriptSendResponseToModular,
eventData[@"_id"],
response ? @"true" : @"false"];
[webView stringByEvaluatingJavaScriptFromString:js];
}
- (void)sendIntegerResponse:(NSUInteger)response toEvent:(NSDictionary*)eventData
{
NSString *js = [NSString stringWithFormat:kJavascriptSendResponseToModular,
eventData[@"_id"],
@(response)];
[webView stringByEvaluatingJavaScriptFromString:js];
}
- (void)sendNSObjectResponse:(NSObject*)response toEvent:(NSDictionary*)eventData
{
NSString *jsString;
if (response)
{
// Convert response into a JS object through a JSON string
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:response
options:0
error:0];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
jsString = [NSString stringWithFormat:@"JSON.parse('%@')", jsonString];
}
else
{
jsString = @"null";
}
NSString *js = [NSString stringWithFormat:kJavascriptSendResponseToModular,
eventData[@"_id"],
jsString];
[webView stringByEvaluatingJavaScriptFromString:js];
}
- (void)sendError:(NSString*)message toEvent:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] sendError: Action %@ failed with message: %@", eventData[@"action"], message);
// TODO: JS has an additional optional parameter: nestedError
[self sendNSObjectResponse:@{
@"error": @{
@"message": message
}
}
toEvent:eventData];
}
- (void)sendLocalisedError:(NSString*)errorKey toEvent:(NSDictionary*)eventData
{
[self sendError:NSLocalizedStringFromTable(errorKey, @"Vector", nil) toEvent:eventData];
}
#pragma mark - Modular postMessage Implementation
- (MXRoom *)roomCheckWithEvent:(NSDictionary*)eventData
{
MXRoom *room = [mxSession roomWithRoomId:roomId];
if (!room)
{
[self sendLocalisedError:@"widget_integration_room_not_recognised" toEvent:eventData];
}
return room;
}
- (void)inviteUser:(NSString*)userId eventData:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] Received request to invite %@ into room %@.", userId, roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
MXRoomMember *member = [room.state memberWithUserId:userId];
if (member && member.membership == MXMembershipJoin)
{
[self sendNSObjectResponse:@{
@"success": @(YES)
}
toEvent:eventData];
}
else
{
__weak __typeof__(self) weakSelf = self;
[room inviteUser:userId success:^{
typeof(self) self = weakSelf;
if (self)
{
[self sendNSObjectResponse:@{
@"success": @(YES)
}
toEvent:eventData];
}
} failure:^(NSError *error) {
typeof(self) self = weakSelf;
if (self)
{
[self sendLocalisedError:@"widget_integration_need_to_be_able_to_invite" toEvent:eventData];
}
}];
}
}
}
- (void)setWidget:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] Received request to set widget in room %@.", roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
NSString *widget_id, *widgetType, *widgetUrl;
NSString *widgetName; // optional
NSDictionary *widgetData ; // optional
MXJSONModelSetString(widget_id, eventData[@"widget_id"]);
MXJSONModelSetString(widgetType, eventData[@"type"]);
MXJSONModelSetString(widgetUrl, eventData[@"url"]);
MXJSONModelSetString(widgetName, eventData[@"name"]);
MXJSONModelSetDictionary(widgetData, eventData[@"data"]);
if (!widget_id)
{
[self sendLocalisedError:@"widget_integration_unable_to_create" toEvent:eventData]; // new Error("Missing required widget fields."));
return;
}
NSMutableDictionary *widgetEventContent = [NSMutableDictionary dictionary];
if (widgetUrl)
{
if (!widgetType)
{
[self sendLocalisedError:@"widget_integration_unable_to_create" toEvent:eventData];
return;
}
widgetEventContent[@"type"] = widgetType;
widgetEventContent[@"url"] = widgetUrl;
if (widgetName)
{
widgetEventContent[@"name"] = widgetName;
}
if (widgetData)
{
widgetEventContent[@"data"] = widgetData;
}
}
__weak __typeof__(self) weakSelf = self;
[room sendStateEventOfType:kWidgetEventTypeString
content:widgetEventContent
stateKey:widget_id
success:^(NSString *eventId) {
typeof(self) self = weakSelf;
if (self)
{
[self sendNSObjectResponse:@{
@"success": @(YES)
}
toEvent:eventData];
}
}
failure:^(NSError *error) {
typeof(self) self = weakSelf;
if (self)
{
[self sendLocalisedError:@"widget_integration_failed_to_send_request" toEvent:eventData];
}
}];
}
}
- (void)getWidgets:(NSDictionary*)eventData
{
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
NSArray<Widget*> *widgets = [[WidgetManager sharedManager] widgetsInRoom:room];
NSMutableArray<NSDictionary*> *widgetStateEvents = [NSMutableArray arrayWithCapacity:widgets.count];
for (Widget *widget in widgets)
{
[widgetStateEvents addObject:widget.widgetEvent.JSONDictionary];
}
[self sendNSObjectResponse:widgetStateEvents toEvent:eventData];
}
}
- (void)canSendEvent:(NSDictionary*)eventData
{
NSString *eventType;
BOOL isState = NO;
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
if (room.state.membership != MXMembershipJoin)
{
[self sendLocalisedError:@"widget_integration_must_be_in_room" toEvent:eventData];
return;
}
MXJSONModelSetString(eventType, eventData[@"event_type"]);
MXJSONModelSetBoolean(isState, eventData[@"is_state"]);
MXRoomPowerLevels *powerLevels = room.state.powerLevels;
NSInteger userPowerLevel = [powerLevels powerLevelOfUserWithUserID:mxSession.myUser.userId];
BOOL canSend = NO;
if (isState)
{
canSend = (userPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsStateEvent:eventType]);
}
else
{
canSend = (userPowerLevel >= [powerLevels minimumPowerLevelForSendingEventAsMessage:eventType]);
}
if (canSend)
{
[self sendBoolResponse:YES toEvent:eventData];
}
else
{
[self sendLocalisedError:@"widget_integration_no_permission_in_room" toEvent:eventData];
}
}
}
- (void)getMembershipState:(NSString*)userId eventData:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] membership_state of %@ in room %@ requested.", userId, roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
MXRoomMember *member = [room.state memberWithUserId:userId];
[self sendNSObjectResponse:member.originalEvent.content toEvent:eventData];
}
}
- (void)getJoinRules:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] join_rules of %@ requested.", roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
MXEvent *event = [room.state stateEventsWithType:kMXEventTypeStringRoomJoinRules].lastObject;
[self sendNSObjectResponse:event.JSONDictionary toEvent:eventData];
}
}
- (void)setPlumbingState:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] Received request to set plumbing state to status %@ in room %@.", eventData[@"status"], roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
NSString *status;
MXJSONModelSetString(status, eventData[@"status"]);
if (status)
{
__weak __typeof__(self) weakSelf = self;
[room sendStateEventOfType:kMXEventTypeStringRoomPlumbing
content:@{
@"status": status
}
stateKey:nil
success:^(NSString *eventId) {
typeof(self) self = weakSelf;
if (self)
{
[self sendNSObjectResponse:@{
@"success": @(YES)
}
toEvent:eventData];
}
}
failure:^(NSError *error) {
typeof(self) self = weakSelf;
if (self)
{
[self sendLocalisedError:@"widget_integration_failed_to_send_request" toEvent:eventData];
}
}];
}
else
{
NSLog(@"[IntegrationManagerVC] setPlumbingState. Error: Plumbing state status should be a string.");
}
}
}
- (void)getBotOptions:(NSString*)userId eventData:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] Received request to get options for bot %@ in room %@", userId, roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
NSString *stateKey = [NSString stringWithFormat:@"_%@", userId];
NSArray<MXEvent*> *stateEvents = [room.state stateEventsWithType:kMXEventTypeStringRoomBotOptions];
MXEvent *botOptionsEvent;
for (MXEvent *stateEvent in stateEvents)
{
if ([stateEvent.stateKey isEqualToString:stateKey])
{
if (!botOptionsEvent || stateEvent.ageLocalTs > botOptionsEvent.ageLocalTs)
{
botOptionsEvent = stateEvent;
}
}
}
[self sendNSObjectResponse:botOptionsEvent.JSONDictionary toEvent:eventData];
}
}
- (void)setBotOptions:(NSString*)userId eventData:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] Received request to set options for bot %@ in room %@", userId, roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
NSDictionary *content;
MXJSONModelSetDictionary(content, eventData[@"content"]);
if (content)
{
__weak __typeof__(self) weakSelf = self;
NSString *stateKey = [NSString stringWithFormat:@"_%@", userId];
[room sendStateEventOfType:kMXEventTypeStringRoomBotOptions
content:content
stateKey:stateKey
success:^(NSString *eventId) {
typeof(self) self = weakSelf;
if (self)
{
[self sendNSObjectResponse:@{
@"success": @(YES)
}
toEvent:eventData];
}
}
failure:^(NSError *error) {
typeof(self) self = weakSelf;
if (self)
{
[self sendLocalisedError:@"widget_integration_failed_to_send_request" toEvent:eventData];
}
}];
}
else
{
NSLog(@"[IntegrationManagerVC] setBotOptions. Error: options should be a dict.");
}
}
}
- (void)setBotPower:(NSString*)userId eventData:(NSDictionary*)eventData
{
NSLog(@"[IntegrationManagerVC] Received request to set power level to %@ for bot %@ in room %@.", eventData[@"level"], userId, roomId);
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
NSInteger level = -1;
MXJSONModelSetInteger(level, eventData[@"level"]);
if (level >= 0)
{
__weak __typeof__(self) weakSelf = self;
[room setPowerLevelOfUserWithUserID:userId powerLevel:level success:^{
typeof(self) self = weakSelf;
if (self)
{
[self sendNSObjectResponse:@{
@"success": @(YES)
}
toEvent:eventData];
}
} failure:^(NSError *error) {
typeof(self) self = weakSelf;
if (self)
{
[self sendLocalisedError:@"widget_integration_failed_to_send_request" toEvent:eventData];
}
}];
}
else
{
NSLog(@"[IntegrationManagerVC] setBotPower. Power level must be positive integer.");
[self sendLocalisedError:@"widget_integration_positive_power_level" toEvent:eventData];
}
}
}
- (void)getMembershipCount:(NSDictionary*)eventData
{
MXRoom *room = [self roomCheckWithEvent:eventData];
if (room)
{
NSUInteger membershipCount = room.state.joinedMembers.count;
[self sendIntegerResponse:membershipCount toEvent:eventData];
}
}
@end

View file

@ -24,7 +24,7 @@
/**
The `JitsiViewController` is a VC for specifically handling a jitsi widget using the
jitsi-meet iOS SDK instead of displaying it in a webview like other scalar widgets.
jitsi-meet iOS SDK instead of displaying it in a webview like other modular widgets.
https://github.com/jitsi/jitsi-meet/tree/master/ios
*/

View file

@ -0,0 +1,33 @@
/*
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.
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 "WebViewViewController.h"
#import "WidgetManager.h"
/**
`WidgetViewController` displays widget within a webview.
*/
@interface WidgetViewController : WebViewViewController
/**
Init 'WidgetViewController' instance with a widget.
@param widget the widget to open.
*/
- (instancetype)initForWidget:(Widget*)widget;
@end

View file

@ -0,0 +1,48 @@
/*
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.
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 "WidgetViewController.h"
@interface WidgetViewController ()
{
Widget *widget;
}
@end
@implementation WidgetViewController
- (instancetype)initForWidget:(Widget*)theWidget
{
self = [super initWithURL:theWidget.url];
if (self)
{
widget = theWidget;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
webView.scalesPageToFit = NO;
webView.scrollView.bounces = NO;
self.navigationItem.title = widget.name;
}
@end

View file

@ -0,0 +1,55 @@
/*
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.
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>
NS_ASSUME_NONNULL_BEGIN
@interface CircleButton : UIButton
/**
Background color that is used for highlighted state
By default the same as borderColor
*/
@property (nonatomic) UIColor *highlightBackgroundColor;
/**
Background color that is used for normal state
By default white
*/
@property (nonatomic) UIColor *defaultBackgroundColor;
/**
Tint color that is used for highlighted state
By default is white
*/
@property (nonatomic) UIColor *highlightTintColor;
/**
Tint color that is used for normal state
By default is the same as borderColor
*/
@property (nonatomic) UIColor *defaultTintColor;
- (instancetype)initWithImage:(UIImage *)image borderColor:(UIColor *)borderColor;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,86 @@
/*
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.
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 "CircleButton.h"
@implementation CircleButton
- (instancetype)initWithImage:(UIImage *)image borderColor:(UIColor *)borderColor
{
self = [[super class] buttonWithType:UIButtonTypeCustom];
self.adjustsImageWhenDisabled = NO;
self.adjustsImageWhenHighlighted = NO;
self.layer.borderWidth = 1.0;
self.layer.borderColor = borderColor.CGColor;
self.defaultBackgroundColor = [UIColor whiteColor];
self.highlightTintColor = [UIColor whiteColor];
self.highlightBackgroundColor = borderColor;
self.defaultTintColor = borderColor;
self.tintColor = borderColor;
[self setImage:[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
return self;
}
- (void)setDefaultBackgroundColor:(UIColor *)defaultBackgroundColor
{
_defaultBackgroundColor = defaultBackgroundColor;
self.backgroundColor = defaultBackgroundColor;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.layer.cornerRadius = CGRectGetWidth(self.bounds) / 2.0;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[self animateBackgroundColor:self.highlightBackgroundColor tintColor:self.highlightTintColor];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
[self animateBackgroundColor:self.defaultBackgroundColor tintColor:self.defaultTintColor];
}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
[self animateBackgroundColor:self.defaultBackgroundColor tintColor:self.defaultTintColor];
}
- (void)animateBackgroundColor:(UIColor *)color tintColor:(UIColor *)tintColor
{
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.backgroundColor = color;
self.tintColor = tintColor;
}
completion:nil];
}
@end

View file

@ -0,0 +1,47 @@
/*
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.
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>
NS_ASSUME_NONNULL_BEGIN
typedef void (^IncomingCallViewAction)();
@interface IncomingCallView : UIView
/**
Size that is applied to displayed user avatar
*/
@property (class, readonly) CGSize callerAvatarSize;
/**
Block which is performed on call answer action
*/
@property (nonatomic, nullable, copy) IncomingCallViewAction onAnswer;
/**
Block which is performed on call reject
*/
@property (nonatomic, nullable, copy) IncomingCallViewAction onReject;
- (instancetype)initWithCallerAvatarURL:(NSString *)callerAvatarURL
placeholderImage:(UIImage *)placeholderImage
callerName:(NSString *)callerName
callInfo:(NSString *)callInfo;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,326 @@
/*
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.
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 "IncomingCallView.h"
#import <MatrixKit/MXKImageView.h>
#import <MatrixSDK/MXMediaManager.h>
#import "CircleButton.h"
#import "RiotDesignValues.h"
static const CGFloat kAvatarSize = 100.0;
static const CGFloat kButtonSize = 80.0;
@interface IncomingCallView ()
@property (nonatomic) MXKImageView *callerImageView;
@property (nonatomic) UILabel *callerNameLabel;
@property (nonatomic) UILabel *callInfoLabel;
@property (nonatomic) CircleButton *answerButton;
@property (nonatomic) UILabel *answerTitleLabel;
@property (nonatomic) CircleButton *rejectButton;
@property (nonatomic) UILabel *rejectTitleLabel;
@end
@implementation IncomingCallView
+ (CGSize)callerAvatarSize
{
return CGSizeMake(kAvatarSize, kAvatarSize);
}
- (instancetype)initWithCallerAvatarURL:(NSString *)callerAvatarURL placeholderImage:(UIImage *)placeholderImage callerName:(NSString *)callerName callInfo:(NSString *)callInfo
{
self = [super initWithFrame:CGRectZero];
if (self)
{
self.backgroundColor = kRiotPrimaryBgColor;
self.opaque = YES;
self.callerImageView = [[MXKImageView alloc] init];
self.callerImageView.backgroundColor = kRiotPrimaryBgColor;
self.callerImageView.clipsToBounds = YES;
self.callerImageView.mediaFolder = kMXMediaManagerAvatarThumbnailFolder;
self.callerImageView.enableInMemoryCache = YES;
[self.callerImageView setImageURL:callerAvatarURL
withType:nil
andImageOrientation:UIImageOrientationUp
previewImage:placeholderImage];
self.callerNameLabel = [[UILabel alloc] init];
self.callerNameLabel.backgroundColor = kRiotPrimaryBgColor;
self.callerNameLabel.textColor = kRiotPrimaryTextColor;
self.callerNameLabel.font = [UIFont systemFontOfSize:24.0 weight:UIFontWeightMedium];
self.callerNameLabel.text = callerName;
self.callerNameLabel.textAlignment = NSTextAlignmentCenter;
self.callInfoLabel = [[UILabel alloc] init];
self.callInfoLabel.backgroundColor = kRiotPrimaryBgColor;
self.callInfoLabel.textColor = kRiotSecondaryTextColor;
self.callInfoLabel.font = [UIFont systemFontOfSize:18.0 weight:UIFontWeightRegular];
self.callInfoLabel.text = callInfo;
self.callInfoLabel.textAlignment = NSTextAlignmentCenter;
UIColor *answerButtonBorderColor = kRiotColorGreen;
self.answerButton = [[CircleButton alloc] initWithImage:[UIImage imageNamed:@"voice_call_icon"]
borderColor:answerButtonBorderColor];
self.answerButton.defaultBackgroundColor = kRiotPrimaryBgColor;
[self.answerButton addTarget:self action:@selector(didTapAnswerButton) forControlEvents:UIControlEventTouchUpInside];
self.answerTitleLabel = [[UILabel alloc] init];
self.answerTitleLabel.backgroundColor = kRiotPrimaryBgColor;
self.answerTitleLabel.textColor = answerButtonBorderColor;
self.answerTitleLabel.font = [UIFont systemFontOfSize:18.0 weight:UIFontWeightRegular];
self.answerTitleLabel.text = NSLocalizedStringFromTable(@"accept", @"Vector", nil);
UIColor *rejectButtonBorderColor = kRiotColorPinkRed;
self.rejectButton = [[CircleButton alloc] initWithImage:[UIImage imageNamed:@"call_hangup_icon"]
borderColor:rejectButtonBorderColor];
self.rejectButton.defaultBackgroundColor = kRiotPrimaryBgColor;
[self.rejectButton addTarget:self action:@selector(didTapRejectButton) forControlEvents:UIControlEventTouchUpInside];
self.rejectTitleLabel = [[UILabel alloc] init];
self.rejectTitleLabel.backgroundColor = kRiotPrimaryBgColor;
self.rejectTitleLabel.textColor = rejectButtonBorderColor;
self.rejectTitleLabel.font = [UIFont systemFontOfSize:18.0 weight:UIFontWeightRegular];
self.rejectTitleLabel.text = NSLocalizedStringFromTable(@"decline", @"Vector", nil);
[self setupLayout];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.callerImageView.layer.cornerRadius = CGRectGetWidth(self.callerImageView.bounds) / 2.0;
}
- (void)setupLayout
{
NSArray *views = @[self.callerImageView, self.callerNameLabel, self.callInfoLabel, self.answerButton, self.answerTitleLabel, self.rejectButton, self.rejectTitleLabel];
for (UIView *view in views)
{
view.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:view];
}
[NSLayoutConstraint activateConstraints:@[
[NSLayoutConstraint constraintWithItem:self.callerImageView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:62.0],
[NSLayoutConstraint constraintWithItem:self.callerImageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.callerImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:kAvatarSize],
[NSLayoutConstraint constraintWithItem:self.callerImageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.callerImageView
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.callerNameLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.callerImageView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:18.0],
[NSLayoutConstraint constraintWithItem:self.callerNameLabel
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeLeading
multiplier:1.0
constant:15.0],
[NSLayoutConstraint constraintWithItem:self.callerNameLabel
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:-15.0],
[NSLayoutConstraint constraintWithItem:self.callInfoLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.callerNameLabel
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:7.0],
[NSLayoutConstraint constraintWithItem:self.callInfoLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.callInfoLabel
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.callerNameLabel
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.rejectButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:kButtonSize],
[NSLayoutConstraint constraintWithItem:self.rejectButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.rejectButton
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.rejectButton
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:-22.5],
[NSLayoutConstraint constraintWithItem:self.rejectTitleLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.rejectButton
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:8.0],
[NSLayoutConstraint constraintWithItem:self.rejectTitleLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.rejectButton
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.rejectTitleLabel
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-16.0],
[NSLayoutConstraint constraintWithItem:self.answerButton
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:kButtonSize],
[NSLayoutConstraint constraintWithItem:self.answerButton
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.answerButton
attribute:NSLayoutAttributeWidth
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.answerButton
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:22.5],
[NSLayoutConstraint constraintWithItem:self.answerTitleLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.answerButton
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:8.0],
[NSLayoutConstraint constraintWithItem:self.answerTitleLabel
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.answerButton
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0],
[NSLayoutConstraint constraintWithItem:self.answerTitleLabel
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-16.0]
]];
}
// MARK: - Actions
- (void)didTapAnswerButton
{
if (self.onAnswer)
{
self.onAnswer();
}
}
- (void)didTapRejectButton
{
if (self.onReject)
{
self.onReject();
}
}
@end

View file

@ -82,7 +82,7 @@
// Remove default toolbar background color
self.backgroundColor = [UIColor clearColor];
self.separatorView.backgroundColor = kRiotColorSilver;
self.separatorView.backgroundColor = kRiotAuxiliaryColor;
// Custom the growingTextView display
growingTextView.layer.cornerRadius = 0;

View file

@ -23,7 +23,7 @@
#import "RiotDesignValues.h"
#import "MXRoom+Riot.h"
#import "MXRoomSummary+Riot.h"
@implementation RecentTableViewCell
@ -111,7 +111,7 @@
}
else
{
self.missedNotifAndUnreadIndicator.backgroundColor = kRiotColorSilver;
self.missedNotifAndUnreadIndicator.backgroundColor = kRiotAuxiliaryColor;
}
// Use bold font for the room title
@ -143,7 +143,7 @@
self.encryptedRoomIcon.hidden = !roomCellData.roomSummary.isEncrypted;
[roomCellData.roomSummary.room setRoomAvatarImageIn:self.roomAvatar];
[roomCellData.roomSummary setRoomAvatarImageIn:self.roomAvatar];
}
else
{

View file

@ -20,7 +20,7 @@
#import "RiotDesignValues.h"
#import "MXRoom+Riot.h"
#import "MXRoomSummary+Riot.h"
#import "MXTools.h"
@ -171,7 +171,7 @@
self.encryptedRoomIcon.hidden = !roomCellData.roomSummary.isEncrypted;
[roomCellData.roomSummary.room setRoomAvatarImageIn:self.roomAvatar];
[roomCellData.roomSummary setRoomAvatarImageIn:self.roomAvatar];
}
}

View file

@ -29,7 +29,7 @@
/**
Update the information displayed by the cell.
@param rooom the room to render.
@param room the room to render.
*/
- (void)render:(MXRoom *)room;

View file

@ -18,7 +18,7 @@
#import "RoomTableViewCell.h"
#import "RiotDesignValues.h"
#import "MXRoom+Riot.h"
#import "MXRoomSummary+Riot.h"
@implementation RoomTableViewCell
@ -50,9 +50,9 @@
- (void)render:(MXRoom *)room
{
[room setRoomAvatarImageIn:self.avatarImageView];
[room.summary setRoomAvatarImageIn:self.avatarImageView];
self.titleLabel.text = room.riotDisplayname;
self.titleLabel.text = room.summary.displayname;
self.directRoomBorderView.hidden = !room.isDirect;

View file

@ -19,8 +19,6 @@
#import "RiotDesignValues.h"
#import "MXRoom+Riot.h"
@implementation ExpandedRoomTitleView
+ (UINib *)nib
@ -38,7 +36,7 @@
{
[super customizeViewRendering];
self.displayNameTextField.textColor = (self.mxRoom.riotDisplayname.length ? kRiotPrimaryTextColor : kRiotSecondaryTextColor);
self.displayNameTextField.textColor = (self.mxRoom.summary.displayname.length ? kRiotPrimaryTextColor : kRiotSecondaryTextColor);
self.roomTopic.textColor = kRiotTopicTextColor;
self.roomMembers.textColor = kRiotColorGreen;
}
@ -49,7 +47,7 @@
if (self.mxRoom)
{
self.displayNameTextField.text = self.mxRoom.riotDisplayname;
self.displayNameTextField.text = self.mxRoom.summary.displayname;
if (!self.displayNameTextField.text.length)
{
self.displayNameTextField.text = NSLocalizedStringFromTable(@"room_displayname_no_title", @"Vector", nil);

View file

@ -19,8 +19,6 @@
#import "RiotDesignValues.h"
#import "MXRoom+Riot.h"
@implementation PreviewRoomTitleView
+ (UINib *)nib
@ -64,7 +62,7 @@
self.backgroundColor = kRiotPrimaryBgColor;
self.mainHeaderBackground.backgroundColor = kRiotSecondaryBgColor;
self.displayNameTextField.textColor = (self.mxRoom.riotDisplayname.length ? kRiotPrimaryTextColor : kRiotSecondaryTextColor);
self.displayNameTextField.textColor = (self.mxRoom.summary.displayname.length ? kRiotPrimaryTextColor : kRiotSecondaryTextColor);
self.roomTopic.textColor = kRiotTopicTextColor;
self.roomTopic.numberOfLines = 0;
@ -145,7 +143,7 @@
else if (self.mxRoom)
{
// The user is here invited to join a room (This invitation has been received from server sync)
self.displayNameTextField.text = self.mxRoom.riotDisplayname;
self.displayNameTextField.text = self.mxRoom.summary.displayname;
if (!self.displayNameTextField.text.length)
{
self.displayNameTextField.text = NSLocalizedStringFromTable(@"room_displayname_no_title", @"Vector", nil);

Some files were not shown because too many files have changed in this diff Show more