mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
54ebef8c53
36 changed files with 1703 additions and 335 deletions
54
CHANGES.rst
54
CHANGES.rst
|
@ -1,3 +1,57 @@
|
|||
Changes in 0.5.6 (2017-10-05)
|
||||
===============================================
|
||||
|
||||
Improvements:
|
||||
* Settings: Pin rooms with missed notifs and unread msg by default (PR #1556).
|
||||
|
||||
Bug Fix:
|
||||
* Fix RAM peak usage when doing an initial sync with large rooms (PR #1553).
|
||||
|
||||
Changes in 0.5.5 (2017-10-04)
|
||||
===============================================
|
||||
|
||||
Improvements:
|
||||
* Rageshake: Add a setting to enable (disable) it (PR #1552).
|
||||
|
||||
Bug Fix:
|
||||
* Some rooms have gone nameless after upgrade (PR #1551).
|
||||
|
||||
Changes in 0.5.4 (2017-10-03)
|
||||
===============================================
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version (v0.6.3).
|
||||
* Show the "Integrations Manager" into a webview (PR #1511).
|
||||
* Widgets: list active widgets in a room (#1535).
|
||||
* Jitsi widget: Add notices for jitsi widget in rooms histories (PR #1488).
|
||||
* Add screen for incoming calls, thanks to @morozkin (PR #1477).
|
||||
* Update strings for push notifications, thanks to @morozkin (PR #1486).
|
||||
* Handle the room display name and its avatar at the room summary level (PR #1510).
|
||||
* Create DM with Riot-bot on new account creation (vector-im/riot-meta#94).
|
||||
* Add WidgetViewController (PR #1514).
|
||||
* BugReportVC: Force users to add a description in crash reports (PR #1520).
|
||||
* Jitsi: Enable the "Create conference calls with jitsi" settings by default (PR #1549).
|
||||
|
||||
Bug Fixes:
|
||||
* Fix inbound video calls don't have speakerphone turned on by default (#933).
|
||||
* Room settings: the displayed room access settings is wrong (#1494).
|
||||
* When receiving an invite tagged as DM it's filed in rooms (#1308).
|
||||
* Altering DMness of rooms is broken (#1370).
|
||||
* Alert about incoming call isn't displayed (#1480), thanks to @morozkin (#1481).
|
||||
* Dark theme - Improvements (#1444).
|
||||
* Settings: some of the labels push the switch controls off screen (#1506).
|
||||
* Settings: The "Sign out" button and other buttons of this page sometimes blinks (#1354).
|
||||
* [iOS11] "Smart [colors] Invert" renders badly in the app (#1524).
|
||||
* [iOS11] Room member details: the member's avatar is cropped in the header (#1531).
|
||||
* [iOS11] Fix layout disruptions (PR #1537).
|
||||
* Return key on hardware keyboards now sends messages, thanks to @vivlim (PR #1513).
|
||||
* MediaPickerViewController: Add sanity checks to avoid crashes (#1532).
|
||||
* RoomsViewController: Crash in [RoomsViewController prepareForSegue:… (#1533).
|
||||
|
||||
Translations:
|
||||
* Enable Basque, thanks to @osoitz.
|
||||
* Enable Simplified Chinese, thanks to @tonghuix (Note: the push notifications are not translated yet).
|
||||
|
||||
Changes in 0.5.3 (2017-08-25)
|
||||
===============================================
|
||||
|
||||
|
|
34
Podfile
34
Podfile
|
@ -5,10 +5,9 @@ source 'https://github.com/CocoaPods/Specs.git'
|
|||
|
||||
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.2'
|
||||
pod 'MatrixKit', '0.6.3'
|
||||
|
||||
# The lastest release available on the CocoaPods repository
|
||||
#pod 'MatrixKit'
|
||||
|
@ -53,7 +52,7 @@ pod 'OLMKit'
|
|||
pod 'Realm', '~> 2.10.2'
|
||||
|
||||
# The tagged version on which this version of Riot share extension has been built
|
||||
pod 'MatrixKit/AppExtension', '0.6.2'
|
||||
pod 'MatrixKit/AppExtension', '0.6.3'
|
||||
|
||||
# The lastest release available on the CocoaPods repository
|
||||
#pod 'MatrixKit/AppExtension'
|
||||
|
@ -74,5 +73,34 @@ pod 'cmark', :inhibit_warnings => true
|
|||
end
|
||||
|
||||
|
||||
target "SiriIntents" 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.10.2'
|
||||
|
||||
# The tagged version on which this version of Riot share extension has been built
|
||||
pod 'MatrixKit/AppExtension', '0.6.3'
|
||||
|
||||
# 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
|
||||
|
||||
|
|
46
Podfile.lock
46
Podfile.lock
|
@ -37,34 +37,34 @@ PODS:
|
|||
- DTFoundation/Core
|
||||
- DTFoundation/UIKit (1.7.12):
|
||||
- DTFoundation/Core
|
||||
- GBDeviceInfo (4.3.0):
|
||||
- GBDeviceInfo/Core (= 4.3.0)
|
||||
- GBDeviceInfo/Core (4.3.0)
|
||||
- GBDeviceInfo (4.4.0):
|
||||
- GBDeviceInfo/Core (= 4.4.0)
|
||||
- GBDeviceInfo/Core (4.4.0)
|
||||
- GoogleAnalytics (3.17.0)
|
||||
- GZIP (1.1.1)
|
||||
- HPGrowingTextView (1.1)
|
||||
- libPhoneNumber-iOS (0.9.10)
|
||||
- MatrixKit (0.6.2):
|
||||
- MatrixKit (0.6.3):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.17)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.10)
|
||||
- MatrixKit/Core (= 0.6.2)
|
||||
- MatrixSDK (= 0.9.2)
|
||||
- MatrixKit/AppExtension (0.6.2):
|
||||
- MatrixKit/Core (= 0.6.3)
|
||||
- MatrixSDK (= 0.9.3)
|
||||
- MatrixKit/AppExtension (0.6.3):
|
||||
- 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):
|
||||
- MatrixSDK (= 0.9.3)
|
||||
- MatrixKit/Core (0.6.3):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.17)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.10)
|
||||
- MatrixSDK (= 0.9.2)
|
||||
- MatrixSDK (0.9.2):
|
||||
- MatrixSDK (= 0.9.3)
|
||||
- MatrixSDK (0.9.3):
|
||||
- AFNetworking (~> 3.1.0)
|
||||
- GZIP (~> 1.1.1)
|
||||
- OLMKit (2.2.2):
|
||||
|
@ -72,20 +72,20 @@ PODS:
|
|||
- OLMKit/olmcpp (= 2.2.2)
|
||||
- OLMKit/olmc (2.2.2)
|
||||
- OLMKit/olmcpp (2.2.2)
|
||||
- Realm (2.8.3):
|
||||
- Realm/Headers (= 2.8.3)
|
||||
- Realm/Headers (2.8.3)
|
||||
- Realm (2.10.2):
|
||||
- Realm/Headers (= 2.10.2)
|
||||
- Realm/Headers (2.10.2)
|
||||
- WebRTC (58.17.16937)
|
||||
|
||||
DEPENDENCIES:
|
||||
- cmark
|
||||
- DTCoreText
|
||||
- GBDeviceInfo (~> 4.3.0)
|
||||
- GBDeviceInfo (~> 4.4.0)
|
||||
- GoogleAnalytics
|
||||
- MatrixKit (= 0.6.2)
|
||||
- MatrixKit/AppExtension (= 0.6.2)
|
||||
- MatrixKit (= 0.6.3)
|
||||
- MatrixKit/AppExtension (= 0.6.3)
|
||||
- OLMKit
|
||||
- Realm (~> 2.8.1)
|
||||
- Realm (~> 2.10.2)
|
||||
- WebRTC (= 58.17.16937)
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
|
@ -93,17 +93,17 @@ SPEC CHECKSUMS:
|
|||
cmark: ec0275215b504780287b6fca360224e384368af8
|
||||
DTCoreText: e5d688cffc9f6a61eddd1a4f94e2046851230de3
|
||||
DTFoundation: 26a164ef510877387906fb92bff524a792db4bf8
|
||||
GBDeviceInfo: caae36532afcc209b51ac62bba547aadab9e88f2
|
||||
GBDeviceInfo: 2ec90c6808d063061b16773ec8e857257058dc5d
|
||||
GoogleAnalytics: f42cc53a87a51fe94334821868d9c8481ff47a7b
|
||||
GZIP: f8beb59597f651e6970a45b816508a9c6d700b77
|
||||
HPGrowingTextView: 88a716d97fb853bcb08a4a08e4727da17efc9b19
|
||||
libPhoneNumber-iOS: f721ae4d5854bce60934f9fb9b0b28e8e68913cb
|
||||
MatrixKit: 8552ee8abf935b08ae08fc0000f53ab3218ea5a0
|
||||
MatrixSDK: 0499dd3dbe293ce1e743a7cda181dcf50eda7f10
|
||||
MatrixKit: 98a10c8127edb32e0e402d4b9535aea3397e2caa
|
||||
MatrixSDK: 834a8a059de81a967404b04086a4abe28456f49a
|
||||
OLMKit: b9d8c0ffee9ea8c45bc0aaa9afb47f93fba7efbd
|
||||
Realm: 3601ef091c8c499a31101d8563b991e75546cdce
|
||||
Realm: 0ef72b837fb67e9f4b098bac771ddd72c7fdbb69
|
||||
WebRTC: 1e9a85bf75509eec44be6478c64e9de65ac82332
|
||||
|
||||
PODFILE CHECKSUM: db0ae7d6037f7768feb2adf17119ba69d9e1a77b
|
||||
PODFILE CHECKSUM: f14b066c880bcf6d8d97d536d8e70df07eb72cc1
|
||||
|
||||
COCOAPODS: 1.3.1
|
||||
|
|
276
Riot.xcodeproj/project.pbxproj
Normal file → Executable file
276
Riot.xcodeproj/project.pbxproj
Normal file → Executable file
|
@ -29,7 +29,7 @@
|
|||
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 /* BuildFile in Resources */ = {isa = PBXBuildFile; };
|
||||
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 */; };
|
||||
|
@ -84,12 +84,22 @@
|
|||
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 */; };
|
||||
714F6391AC0AA86C0AEB3F43 /* libPods-SiriIntents.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5666C1236223F54D4C635C54 /* libPods-SiriIntents.a */; };
|
||||
83711A7C1F6F8E7D008F0D4D /* KeyboardGrowingTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83711A7B1F6F8E7D008F0D4D /* KeyboardGrowingTextView.m */; };
|
||||
92324BE31F4F66D3009DE194 /* IncomingCallView.m in Sources */ = {isa = PBXBuildFile; fileRef = 92324BE21F4F66D3009DE194 /* IncomingCallView.m */; };
|
||||
92324BE61F4F6A60009DE194 /* CircleButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 92324BE51F4F6A60009DE194 /* CircleButton.m */; };
|
||||
926FA53F1F4C132000F826C2 /* MXSession+Riot.m in Sources */ = {isa = PBXBuildFile; fileRef = 926FA53E1F4C132000F826C2 /* MXSession+Riot.m */; };
|
||||
92726A471F58737A004AD26F /* IntentHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 92726A461F58737A004AD26F /* IntentHandler.m */; };
|
||||
92726A4B1F58737A004AD26F /* SiriIntents.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 92726A431F58737A004AD26F /* SiriIntents.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
92726A511F587410004AD26F /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 92726A501F587410004AD26F /* Intents.framework */; };
|
||||
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 */; };
|
||||
F04AF26A1F83A4C100D20F4D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F04AF25F1F83A4C000D20F4D /* InfoPlist.strings */; };
|
||||
F04AF26B1F83A4C100D20F4D /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = F04AF2611F83A4C000D20F4D /* Vector.strings */; };
|
||||
F04AF26C1F83A4C100D20F4D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = F04AF2641F83A4C000D20F4D /* InfoPlist.strings */; };
|
||||
F04AF26D1F83A4C100D20F4D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F04AF2661F83A4C000D20F4D /* Localizable.strings */; };
|
||||
F04AF26E1F83A4C100D20F4D /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = F04AF2681F83A4C000D20F4D /* Vector.strings */; };
|
||||
F05BD79E1E7AEBF800C69941 /* UnifiedSearchViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F05BD79D1E7AEBF800C69941 /* UnifiedSearchViewController.m */; };
|
||||
F05BD7A11E7C0E4500C69941 /* MasterTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = F05BD7A01E7C0E4500C69941 /* MasterTabBarController.m */; };
|
||||
F0614A0D1EDDCCE700F5DC9A /* jump_to_unread.png in Resources */ = {isa = PBXBuildFile; fileRef = F0614A0A1EDDCCE700F5DC9A /* jump_to_unread.png */; };
|
||||
|
@ -550,6 +560,13 @@
|
|||
remoteGlobalIDString = 24CBEC4D1F0EAD310093EABB;
|
||||
remoteInfo = "Riot Share Extension";
|
||||
};
|
||||
92726A491F58737A004AD26F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 92726A421F58737A004AD26F;
|
||||
remoteInfo = SiriIntents;
|
||||
};
|
||||
F094A9BF1B78D8F000B1FBBF /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = F094A99A1B78D8F000B1FBBF /* Project object */;
|
||||
|
@ -567,6 +584,7 @@
|
|||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
24CBEC591F0EAD310093EABB /* RiotShareExtension.appex in Embed App Extensions */,
|
||||
92726A4B1F58737A004AD26F /* SiriIntents.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -673,6 +691,9 @@
|
|||
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>"; };
|
||||
397BCA987893439918EBF330 /* Pods-SiriIntents.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SiriIntents.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
4D1164C2F07EF74950DCDA7A /* Pods-SiriIntents.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SiriIntents.release.xcconfig"; path = "Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents.release.xcconfig"; sourceTree = "<group>"; };
|
||||
5666C1236223F54D4C635C54 /* libPods-SiriIntents.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SiriIntents.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>"; };
|
||||
83711A7B1F6F8E7D008F0D4D /* KeyboardGrowingTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeyboardGrowingTextView.m; sourceTree = "<group>"; };
|
||||
|
@ -681,11 +702,24 @@
|
|||
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>"; };
|
||||
926FA53D1F4C132000F826C2 /* MXSession+Riot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXSession+Riot.h"; sourceTree = "<group>"; };
|
||||
926FA53E1F4C132000F826C2 /* MXSession+Riot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MXSession+Riot.m"; sourceTree = "<group>"; };
|
||||
92726A431F58737A004AD26F /* SiriIntents.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = SiriIntents.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
92726A451F58737A004AD26F /* IntentHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IntentHandler.h; sourceTree = "<group>"; };
|
||||
92726A461F58737A004AD26F /* IntentHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IntentHandler.m; sourceTree = "<group>"; };
|
||||
92726A481F58737A004AD26F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
92726A4F1F587393004AD26F /* SiriIntents.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = SiriIntents.entitlements; sourceTree = "<group>"; };
|
||||
92726A501F587410004AD26F /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
|
||||
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>"; };
|
||||
F02C1A841E8EB04C0045A404 /* PeopleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PeopleViewController.m; sourceTree = "<group>"; };
|
||||
F04AF2601F83A4C000D20F4D /* zh_Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_Hans; path = InfoPlist.strings; sourceTree = "<group>"; };
|
||||
F04AF2621F83A4C000D20F4D /* zh_Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh_Hans; path = Vector.strings; sourceTree = "<group>"; };
|
||||
F04AF2651F83A4C000D20F4D /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = InfoPlist.strings; sourceTree = "<group>"; };
|
||||
F04AF2671F83A4C000D20F4D /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = Localizable.strings; sourceTree = "<group>"; };
|
||||
F04AF2691F83A4C000D20F4D /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = Vector.strings; sourceTree = "<group>"; };
|
||||
F05BD79C1E7AEBF800C69941 /* UnifiedSearchViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnifiedSearchViewController.h; sourceTree = "<group>"; };
|
||||
F05BD79D1E7AEBF800C69941 /* UnifiedSearchViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UnifiedSearchViewController.m; sourceTree = "<group>"; };
|
||||
F05BD79F1E7C0E4500C69941 /* MasterTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MasterTabBarController.h; sourceTree = "<group>"; };
|
||||
|
@ -1270,6 +1304,15 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
92726A401F58737A004AD26F /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
92726A511F587410004AD26F /* Intents.framework in Frameworks */,
|
||||
714F6391AC0AA86C0AEB3F43 /* libPods-SiriIntents.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F094A99F1B78D8F000B1FBBF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -1460,8 +1503,10 @@
|
|||
5FC42FA41F5186AFFB6A2404 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
92726A501F587410004AD26F /* Intents.framework */,
|
||||
FD9D0BDE9232898950554DD5 /* libPods-Riot.a */,
|
||||
7246451C668D6782166E22EC /* libPods-RiotShareExtension.a */,
|
||||
5666C1236223F54D4C635C54 /* libPods-SiriIntents.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1473,6 +1518,8 @@
|
|||
C195C53961EA28E6900AEB68 /* Pods-Riot.release.xcconfig */,
|
||||
12AA0005C8B3D8D8162584C5 /* Pods-RiotShareExtension.debug.xcconfig */,
|
||||
765F5104DB3EC39713DEB3A4 /* Pods-RiotShareExtension.release.xcconfig */,
|
||||
397BCA987893439918EBF330 /* Pods-SiriIntents.debug.xcconfig */,
|
||||
4D1164C2F07EF74950DCDA7A /* Pods-SiriIntents.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1488,6 +1535,36 @@
|
|||
path = Calls;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
92726A441F58737A004AD26F /* SiriIntents */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
92726A4F1F587393004AD26F /* SiriIntents.entitlements */,
|
||||
92726A451F58737A004AD26F /* IntentHandler.h */,
|
||||
92726A461F58737A004AD26F /* IntentHandler.m */,
|
||||
92726A481F58737A004AD26F /* Info.plist */,
|
||||
);
|
||||
path = SiriIntents;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F04AF25E1F83A4C000D20F4D /* zh_Hans.lproj */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F04AF25F1F83A4C000D20F4D /* InfoPlist.strings */,
|
||||
F04AF2611F83A4C000D20F4D /* Vector.strings */,
|
||||
);
|
||||
path = zh_Hans.lproj;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F04AF2631F83A4C000D20F4D /* eu.lproj */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F04AF2641F83A4C000D20F4D /* InfoPlist.strings */,
|
||||
F04AF2661F83A4C000D20F4D /* Localizable.strings */,
|
||||
F04AF2681F83A4C000D20F4D /* Vector.strings */,
|
||||
);
|
||||
path = eu.lproj;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F083BB021E7005FD00A9B29C /* RiotTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1539,6 +1616,8 @@
|
|||
F083BB0E1E7009EC00A9B29C /* Assets */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F04AF2631F83A4C000D20F4D /* eu.lproj */,
|
||||
F04AF25E1F83A4C000D20F4D /* zh_Hans.lproj */,
|
||||
32918EA41F473BDB0076CA16 /* ru.lproj */,
|
||||
327382A71F276AD200356143 /* de.lproj */,
|
||||
327382BB1F276AED00356143 /* en.lproj */,
|
||||
|
@ -1819,6 +1898,8 @@
|
|||
F083BBEA1E7009EC00A9B29C /* UINavigationController+Riot.m */,
|
||||
F083BBEB1E7009EC00A9B29C /* UIViewController+RiotSearch.h */,
|
||||
F083BBEC1E7009EC00A9B29C /* UIViewController+RiotSearch.m */,
|
||||
926FA53D1F4C132000F826C2 /* MXSession+Riot.h */,
|
||||
926FA53E1F4C132000F826C2 /* MXSession+Riot.m */,
|
||||
);
|
||||
path = Categories;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2355,6 +2436,7 @@
|
|||
F083BB081E7009EC00A9B29C /* Riot */,
|
||||
F083BB021E7005FD00A9B29C /* RiotTests */,
|
||||
24CBEC4F1F0EAD310093EABB /* RiotShareExtension */,
|
||||
92726A441F58737A004AD26F /* SiriIntents */,
|
||||
F094A9A31B78D8F000B1FBBF /* Products */,
|
||||
7471DF3720D498384A068DA7 /* Pods */,
|
||||
5FC42FA41F5186AFFB6A2404 /* Frameworks */,
|
||||
|
@ -2367,6 +2449,7 @@
|
|||
F094A9A21B78D8F000B1FBBF /* Riot.app */,
|
||||
F094A9BE1B78D8F000B1FBBF /* RiotTests.xctest */,
|
||||
24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */,
|
||||
92726A431F58737A004AD26F /* SiriIntents.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2403,6 +2486,25 @@
|
|||
productReference = 24CBEC4E1F0EAD310093EABB /* RiotShareExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
92726A421F58737A004AD26F /* SiriIntents */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 92726A4E1F58737A004AD26F /* Build configuration list for PBXNativeTarget "SiriIntents" */;
|
||||
buildPhases = (
|
||||
6AA0024D4D5FAE30C2E1F311 /* [CP] Check Pods Manifest.lock */,
|
||||
92726A3F1F58737A004AD26F /* Sources */,
|
||||
92726A401F58737A004AD26F /* Frameworks */,
|
||||
92726A411F58737A004AD26F /* Resources */,
|
||||
807A0ABF153A23C2FC22F977 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SiriIntents;
|
||||
productName = SiriIntents;
|
||||
productReference = 92726A431F58737A004AD26F /* SiriIntents.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
F094A9A11B78D8F000B1FBBF /* Riot */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F094A9C81B78D8F000B1FBBF /* Build configuration list for PBXNativeTarget "Riot" */;
|
||||
|
@ -2420,6 +2522,7 @@
|
|||
);
|
||||
dependencies = (
|
||||
242661F61F12B1BA00D3FC08 /* PBXTargetDependency */,
|
||||
92726A4A1F58737A004AD26F /* PBXTargetDependency */,
|
||||
);
|
||||
name = Riot;
|
||||
productName = Vector;
|
||||
|
@ -2463,6 +2566,16 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
92726A421F58737A004AD26F = {
|
||||
CreatedOnToolsVersion = 8.3.3;
|
||||
DevelopmentTeam = 7J4U792NQT;
|
||||
ProvisioningStyle = Automatic;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplicationGroups.iOS = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
F094A9A11B78D8F000B1FBBF = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
DevelopmentTeam = 7J4U792NQT;
|
||||
|
@ -2494,6 +2607,8 @@
|
|||
de,
|
||||
fr,
|
||||
ru,
|
||||
zh_Hans,
|
||||
eu,
|
||||
);
|
||||
mainGroup = F094A9991B78D8F000B1FBBF;
|
||||
productRefGroup = F094A9A31B78D8F000B1FBBF /* Products */;
|
||||
|
@ -2503,6 +2618,7 @@
|
|||
F094A9A11B78D8F000B1FBBF /* Riot */,
|
||||
F094A9BD1B78D8F000B1FBBF /* RiotTests */,
|
||||
24CBEC4D1F0EAD310093EABB /* RiotShareExtension */,
|
||||
92726A421F58737A004AD26F /* SiriIntents */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
@ -2526,9 +2642,16 @@
|
|||
24EEE5AA1F25529C00B3C705 /* cancel.png in Resources */,
|
||||
F0A895601F7D404B00BD6C2A /* e2e_verified.png in Resources */,
|
||||
24D6B35E1F3CA03E00FC7A71 /* FallbackViewController.xib in Resources */,
|
||||
24EEE5A41F24C06E00B3C705 /* BuildFile in Resources */,
|
||||
24EEE5A41F24C06E00B3C705 /* (null) in Resources */,
|
||||
2439DD641F6BBEA50090F42D /* RecentRoomTableViewCell.xib in Resources */,
|
||||
24EEE5A41F24C06E00B3C705 /* BuildFile in Resources */,
|
||||
24EEE5A41F24C06E00B3C705 /* (null) in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
92726A411F58737A004AD26F /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -2601,6 +2724,7 @@
|
|||
F083BD991E7009ED00A9B29C /* logo@2x.png in Resources */,
|
||||
F083BD331E7009ED00A9B29C /* call_audio_mute_off_icon.png in Resources */,
|
||||
F083BD691E7009ED00A9B29C /* directChatOn@2x.png in Resources */,
|
||||
F04AF26E1F83A4C100D20F4D /* Vector.strings in Resources */,
|
||||
F083BD3E1E7009ED00A9B29C /* call_hangup_icon@3x.png in Resources */,
|
||||
32AE61F21F0D2183007255F4 /* InfoPlist.strings in Resources */,
|
||||
F083BDB91E7009ED00A9B29C /* remove_icon_pink.png in Resources */,
|
||||
|
@ -2633,6 +2757,7 @@
|
|||
F0E05A3D1EA0F9EB004B83FB /* tab_people_selected@2x.png in Resources */,
|
||||
F0E05A451EA0F9EB004B83FB /* tab_rooms.png in Resources */,
|
||||
F083BE751E7009ED00A9B29C /* RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib in Resources */,
|
||||
F04AF26A1F83A4C100D20F4D /* InfoPlist.strings in Resources */,
|
||||
F083BD261E7009ED00A9B29C /* admin_icon@2x.png in Resources */,
|
||||
3205ED851E97725E003D65FA /* DirectoryServerTableViewCell.xib in Resources */,
|
||||
F083BD761E7009ED00A9B29C /* e2e_verified@3x.png in Resources */,
|
||||
|
@ -2722,6 +2847,7 @@
|
|||
F083BDB41E7009ED00A9B29C /* priorityLow@2x.png in Resources */,
|
||||
F083BD671E7009ED00A9B29C /* directChatOff@3x.png in Resources */,
|
||||
F083BE791E7009ED00A9B29C /* RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib in Resources */,
|
||||
F04AF26C1F83A4C100D20F4D /* InfoPlist.strings in Resources */,
|
||||
F0E05A321EA0F9EB004B83FB /* tab_favourites_selected@3x.png in Resources */,
|
||||
F083BD4D1E7009ED00A9B29C /* camera_capture@3x.png in Resources */,
|
||||
F083BDB11E7009ED00A9B29C /* priorityHigh@2x.png in Resources */,
|
||||
|
@ -2735,6 +2861,7 @@
|
|||
F083BE831E7009ED00A9B29C /* RecentTableViewCell.xib in Resources */,
|
||||
F083BDB71E7009ED00A9B29C /* remove_icon@2x.png in Resources */,
|
||||
F083BDD31E7009ED00A9B29C /* settings_icon@3x.png in Resources */,
|
||||
F04AF26B1F83A4C100D20F4D /* Vector.strings in Resources */,
|
||||
F083BDBA1E7009ED00A9B29C /* remove_icon_pink@2x.png in Resources */,
|
||||
F083BDC91E7009ED00A9B29C /* search_icon@2x.png in Resources */,
|
||||
F083BE381E7009ED00A9B29C /* RoomActivitiesView.xib in Resources */,
|
||||
|
@ -2858,6 +2985,7 @@
|
|||
F083BD221E7009ED00A9B29C /* add_participant.png in Resources */,
|
||||
F083BDC61E7009ED00A9B29C /* search_bg@2x.png in Resources */,
|
||||
F083BD421E7009ED00A9B29C /* call_speaker_on_icon.png in Resources */,
|
||||
F04AF26D1F83A4C100D20F4D /* Localizable.strings in Resources */,
|
||||
F083BD9A1E7009ED00A9B29C /* logo@3x.png in Resources */,
|
||||
327382BA1F276AD200356143 /* Vector.strings in Resources */,
|
||||
327382C41F276AED00356143 /* Vector.strings in Resources */,
|
||||
|
@ -3003,7 +3131,7 @@
|
|||
"${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_CONFIGURATION_BUILD_DIR/MatrixKit/MatrixKit.bundle,
|
||||
"${PODS_ROOT}/MatrixSDK/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.xcdatamodeld",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
|
@ -3015,6 +3143,24 @@
|
|||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Riot/Pods-Riot-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
6AA0024D4D5FAE30C2E1F311 /* [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-SiriIntents-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;
|
||||
};
|
||||
7FFD40AA75DB32D83350D225 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -3033,6 +3179,24 @@
|
|||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Riot/Pods-Riot-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
807A0ABF153A23C2FC22F977 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-SiriIntents/Pods-SiriIntents-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-SiriIntents/Pods-SiriIntents-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
8EA19F5011654D3BD5EDAC33 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -3075,6 +3239,14 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
92726A3F1F58737A004AD26F /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
92726A471F58737A004AD26F /* IntentHandler.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F094A99E1B78D8F000B1FBBF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -3200,6 +3372,7 @@
|
|||
F083BDF81E7009ED00A9B29C /* RoomDataSource.m in Sources */,
|
||||
F083BE371E7009ED00A9B29C /* RoomActivitiesView.m in Sources */,
|
||||
F083BE131E7009ED00A9B29C /* HomeMessagesSearchViewController.m in Sources */,
|
||||
926FA53F1F4C132000F826C2 /* MXSession+Riot.m in Sources */,
|
||||
F083BE8C1E7009ED00A9B29C /* PreviewRoomTitleView.m in Sources */,
|
||||
F083BE271E7009ED00A9B29C /* SettingsViewController.m in Sources */,
|
||||
F083BE9A1E7009ED00A9B29C /* TableViewCellWithButton.m in Sources */,
|
||||
|
@ -3244,6 +3417,11 @@
|
|||
target = 24CBEC4D1F0EAD310093EABB /* RiotShareExtension */;
|
||||
targetProxy = 242661F51F12B1BA00D3FC08 /* PBXContainerItemProxy */;
|
||||
};
|
||||
92726A4A1F58737A004AD26F /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 92726A421F58737A004AD26F /* SiriIntents */;
|
||||
targetProxy = 92726A491F58737A004AD26F /* PBXContainerItemProxy */;
|
||||
};
|
||||
F094A9C01B78D8F000B1FBBF /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = F094A9A11B78D8F000B1FBBF /* Riot */;
|
||||
|
@ -3372,6 +3550,46 @@
|
|||
name = Vector.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F04AF25F1F83A4C000D20F4D /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F04AF2601F83A4C000D20F4D /* zh_Hans */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F04AF2611F83A4C000D20F4D /* Vector.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F04AF2621F83A4C000D20F4D /* zh_Hans */,
|
||||
);
|
||||
name = Vector.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F04AF2641F83A4C000D20F4D /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F04AF2651F83A4C000D20F4D /* eu */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F04AF2661F83A4C000D20F4D /* Localizable.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F04AF2671F83A4C000D20F4D /* eu */,
|
||||
);
|
||||
name = Localizable.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F04AF2681F83A4C000D20F4D /* Vector.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
F04AF2691F83A4C000D20F4D /* eu */,
|
||||
);
|
||||
name = Vector.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F083BBE21E7009EC00A9B29C /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
|
@ -3428,6 +3646,47 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
92726A4C1F58737A004AD26F /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 397BCA987893439918EBF330 /* Pods-SiriIntents.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = SiriIntents/SiriIntents.entitlements;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 7J4U792NQT;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = SiriIntents/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.SiriIntents;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
92726A4D1F58737A004AD26F /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 4D1164C2F07EF74950DCDA7A /* Pods-SiriIntents.release.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = SiriIntents/SiriIntents.entitlements;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = 7J4U792NQT;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = SiriIntents/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = im.vector.app.SiriIntents;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F094A9C61B78D8F000B1FBBF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -3608,6 +3867,15 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
92726A4E1F58737A004AD26F /* Build configuration list for PBXNativeTarget "SiriIntents" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
92726A4C1F58737A004AD26F /* Debug */,
|
||||
92726A4D1F58737A004AD26F /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F094A99D1B78D8F000B1FBBF /* Build configuration list for PBXProject "Riot" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
|
@ -109,7 +109,11 @@ static RageShakeManager* sharedInstance = nil;
|
|||
- (void)startShaking:(UIResponder*)responder {
|
||||
|
||||
// Start only if the application is in foreground
|
||||
if ([AppDelegate theDelegate].isAppForeground && !confirmationAlert) {
|
||||
// And if the rageshake user setting is enabled
|
||||
if ([AppDelegate theDelegate].isAppForeground
|
||||
&& [[NSUserDefaults standardUserDefaults] boolForKey:@"enableRageShake"]
|
||||
&& !confirmationAlert)
|
||||
{
|
||||
NSLog(@"[RageShakeManager] Start shaking with [%@]", [responder class]);
|
||||
|
||||
startShakingTimeStamp = [[NSDate date] timeIntervalSince1970];
|
||||
|
@ -129,18 +133,6 @@ static RageShakeManager* sharedInstance = nil;
|
|||
confirmationAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"rage_shake_prompt", @"Vector", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->confirmationAlert = nil;
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
@ -160,6 +152,34 @@ static RageShakeManager* sharedInstance = nil;
|
|||
}
|
||||
|
||||
}]];
|
||||
|
||||
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"do_not_ask_again"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->confirmationAlert = nil;
|
||||
|
||||
// Disable rageshake user setting
|
||||
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"enableRageShake"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[confirmationAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"]
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
self->confirmationAlert = nil;
|
||||
}
|
||||
|
||||
}]];
|
||||
|
||||
[(UIViewController*)responder presentViewController:confirmationAlert animated:YES completion:nil];
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification;
|
|||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, MXKCallViewControllerDelegate, UISplitViewControllerDelegate, UINavigationControllerDelegate, JitsiViewControllerDelegate>
|
||||
{
|
||||
BOOL isAPNSRegistered;
|
||||
BOOL isPushRegistered;
|
||||
|
||||
// background sync management
|
||||
void (^_completionHandler)(UIBackgroundFetchResult);
|
||||
|
@ -112,7 +112,7 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification;
|
|||
- (void)startGoogleAnalytics;
|
||||
- (void)stopGoogleAnalytics;
|
||||
|
||||
#pragma mark - APNS methods
|
||||
#pragma mark - Push notifications
|
||||
|
||||
- (void)registerUserNotificationSettings;
|
||||
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <Intents/Intents.h>
|
||||
#import <PushKit/PushKit.h>
|
||||
|
||||
#import "RecentsDataSource.h"
|
||||
#import "RoomDataSource.h"
|
||||
|
||||
|
@ -40,8 +43,17 @@
|
|||
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#include <MatrixSDK/MXUIKitBackgroundModeHandler.h>
|
||||
|
||||
// Calls
|
||||
#import "CallViewController.h"
|
||||
|
||||
#import <MatrixSDK/MXCallKitAdapter.h>
|
||||
#import <MatrixSDK/MXCallKitConfiguration.h>
|
||||
|
||||
#import "MXSession+Riot.h"
|
||||
#import "MXRoom+Riot.h"
|
||||
|
||||
//#define MX_CALL_STACK_OPENWEBRTC
|
||||
#ifdef MX_CALL_STACK_OPENWEBRTC
|
||||
#import <MatrixOpenWebRTCWrapper/MatrixOpenWebRTCWrapper.h>
|
||||
|
@ -51,9 +63,10 @@
|
|||
#import <MatrixEndpointWrapper/MatrixEndpointWrapper.h>
|
||||
#endif
|
||||
|
||||
#include <MatrixSDK/MXJingleCallStack.h>
|
||||
|
||||
#include <MatrixSDK/MXUIKitBackgroundModeHandler.h>
|
||||
#ifdef MX_CALL_STACK_JINGLE
|
||||
#import <MatrixSDK/MXJingleCallStack.h>
|
||||
#import <MatrixSDK/MXJingleCallAudioSessionConfigurator.h>
|
||||
#endif
|
||||
|
||||
#define CALL_STATUS_BAR_HEIGHT 44
|
||||
|
||||
|
@ -63,7 +76,7 @@
|
|||
NSString *const kAppDelegateDidTapStatusBarNotification = @"kAppDelegateDidTapStatusBarNotification";
|
||||
NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateNetworkStatusDidChangeNotification";
|
||||
|
||||
@interface AppDelegate ()
|
||||
@interface AppDelegate () <PKPushRegistryDelegate>
|
||||
{
|
||||
/**
|
||||
Reachability observer
|
||||
|
@ -106,11 +119,6 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
*/
|
||||
NSMutableArray *mxSessionArray;
|
||||
|
||||
/**
|
||||
The room id of the current handled remote notification (if any)
|
||||
*/
|
||||
NSString *remoteNotificationRoomId;
|
||||
|
||||
/**
|
||||
The fragment of the universal link being processing.
|
||||
Only one fragment is handled at a time.
|
||||
|
@ -147,6 +155,13 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
*/
|
||||
NSMutableDictionary *callEventsListeners;
|
||||
|
||||
/**
|
||||
The notification listener blocks.
|
||||
There is one block per MXSession.
|
||||
The key is an identifier of the MXSession. The value, the listener block.
|
||||
*/
|
||||
NSMutableDictionary <NSNumber *, MXOnNotification> *notificationListenerBlocks;
|
||||
|
||||
/**
|
||||
Currently displayed "Call not supported" alert.
|
||||
*/
|
||||
|
@ -165,9 +180,14 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
}
|
||||
|
||||
@property (strong, nonatomic) UIAlertController *mxInAppNotification;
|
||||
@property (strong, nonatomic) UIAlertController *incomingCallNotification;
|
||||
|
||||
@property (nonatomic, nullable, copy) void (^registrationForRemoteNotificationsCompletion)(NSError *);
|
||||
|
||||
|
||||
@property (nonatomic, strong) PKPushRegistry *pushRegistry;
|
||||
@property (nonatomic) BOOL hasPendingLocalNotifications;
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
@ -307,6 +327,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
|
||||
mxSessionArray = [NSMutableArray array];
|
||||
callEventsListeners = [NSMutableDictionary dictionary];
|
||||
notificationListenerBlocks = [NSMutableDictionary dictionary];
|
||||
|
||||
// To simplify navigation into the app, we retrieve here the main navigation controller and the tab bar controller.
|
||||
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
|
||||
|
@ -443,13 +464,6 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
|
||||
// cancel any background sync before resuming
|
||||
// i.e. warn IOS that there is no new data with any received push.
|
||||
[self cancelBackgroundSync];
|
||||
|
||||
// Open account session(s) if this is not already done (see [initMatrixSessions] in case of background launch).
|
||||
[[MXKAccountManager sharedManager] prepareSessionForActiveAccounts];
|
||||
|
||||
_isAppForeground = YES;
|
||||
|
||||
// GA: Start a new session. The next hit from this tracker will be the first in a new session.
|
||||
|
@ -460,7 +474,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
{
|
||||
NSLog(@"[AppDelegate] applicationDidBecomeActive");
|
||||
|
||||
remoteNotificationRoomId = nil;
|
||||
_hasPendingLocalNotifications = NO;
|
||||
|
||||
// Check if there is crash log to send
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"enableCrashReport"])
|
||||
|
@ -534,6 +548,11 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
[self stopGoogleAnalytics];
|
||||
}
|
||||
|
||||
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
|
||||
{
|
||||
NSLog(@"[AppDelegate] applicationDidReceiveMemoryWarning");
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
|
||||
{
|
||||
BOOL continueUserActivity = NO;
|
||||
|
@ -542,6 +561,67 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
{
|
||||
continueUserActivity = [self handleUniversalLink:userActivity];
|
||||
}
|
||||
else if ([userActivity.activityType isEqualToString:INStartAudioCallIntentIdentifier] ||
|
||||
[userActivity.activityType isEqualToString:INStartVideoCallIntentIdentifier])
|
||||
{
|
||||
INInteraction *interaction = userActivity.interaction;
|
||||
|
||||
// roomID provided by Siri intent
|
||||
NSString *roomID = userActivity.userInfo[@"roomID"];
|
||||
|
||||
// We've launched from calls history list
|
||||
if (!roomID)
|
||||
{
|
||||
INPerson *person;
|
||||
|
||||
if ([interaction.intent isKindOfClass:INStartAudioCallIntent.class])
|
||||
{
|
||||
person = [[(INStartAudioCallIntent *)(interaction.intent) contacts] firstObject];
|
||||
}
|
||||
else if ([interaction.intent isKindOfClass:INStartVideoCallIntent.class])
|
||||
{
|
||||
person = [[(INStartVideoCallIntent *)(interaction.intent) contacts] firstObject];
|
||||
}
|
||||
|
||||
roomID = person.personHandle.value;
|
||||
}
|
||||
|
||||
BOOL isVideoCall = [userActivity.activityType isEqualToString:INStartVideoCallIntentIdentifier];
|
||||
|
||||
UIApplication *application = UIApplication.sharedApplication;
|
||||
NSNumber *backgroundTaskIdentifier;
|
||||
|
||||
// Start background task since we need time for MXSession preparasion because our app can be launched in the background
|
||||
if (application.applicationState == UIApplicationStateBackground)
|
||||
backgroundTaskIdentifier = @([application beginBackgroundTaskWithExpirationHandler:^{}]);
|
||||
|
||||
MXSession *session = mxSessionArray.firstObject;
|
||||
[session.callManager placeCallInRoom:roomID
|
||||
withVideo:isVideoCall
|
||||
success:^(MXCall *call) {
|
||||
if (application.applicationState == UIApplicationStateBackground)
|
||||
{
|
||||
__weak NSNotificationCenter *center = NSNotificationCenter.defaultCenter;
|
||||
__block id token =
|
||||
[center addObserverForName:kMXCallStateDidChange
|
||||
object:call
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification * _Nonnull note) {
|
||||
if (call.state == MXCallStateEnded)
|
||||
{
|
||||
[application endBackgroundTask:backgroundTaskIdentifier.unsignedIntegerValue];
|
||||
[center removeObserver:token];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
failure:^(NSError *error) {
|
||||
if (backgroundTaskIdentifier)
|
||||
[application endBackgroundTask:backgroundTaskIdentifier.unsignedIntegerValue];
|
||||
}];
|
||||
|
||||
continueUserActivity = YES;
|
||||
}
|
||||
|
||||
return continueUserActivity;
|
||||
}
|
||||
|
@ -885,11 +965,11 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark - APNS methods
|
||||
#pragma mark - Push notifications
|
||||
|
||||
- (void)registerUserNotificationSettings
|
||||
{
|
||||
if (!isAPNSRegistered)
|
||||
if (!isPushRegistered)
|
||||
{
|
||||
// Registration on iOS 8 and later
|
||||
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound |UIUserNotificationTypeAlert) categories:nil];
|
||||
|
@ -900,7 +980,10 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
- (void)registerForRemoteNotificationsWithCompletion:(nullable void (^)(NSError *))completion
|
||||
{
|
||||
self.registrationForRemoteNotificationsCompletion = completion;
|
||||
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
||||
|
||||
self.pushRegistry = [[PKPushRegistry alloc] initWithQueue:nil];
|
||||
self.pushRegistry.delegate = self;
|
||||
self.pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
|
||||
|
@ -914,58 +997,15 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
{
|
||||
// Clear existing token
|
||||
MXKAccountManager* accountManager = [MXKAccountManager sharedManager];
|
||||
[accountManager setApnsDeviceToken:nil];
|
||||
[accountManager setPushDeviceToken:nil withPushOptions:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication*)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
|
||||
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
|
||||
{
|
||||
NSUInteger len = ((deviceToken.length > 8) ? 8 : deviceToken.length / 2);
|
||||
NSLog(@"[AppDelegate] Got APNS token! (%@ ...)", [deviceToken subdataWithRange:NSMakeRange(0, len)]);
|
||||
NSLog(@"[AppDelegate] didReceiveLocalNotification: applicationState: %@", @([UIApplication sharedApplication].applicationState));
|
||||
|
||||
MXKAccountManager* accountManager = [MXKAccountManager sharedManager];
|
||||
[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
|
||||
{
|
||||
if (_completionHandler)
|
||||
{
|
||||
_completionHandler(UIBackgroundFetchResultNoData);
|
||||
_completionHandler = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// log the full userInfo only in DEBUG
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification: %@", userInfo);
|
||||
#else
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification");
|
||||
#endif
|
||||
|
||||
// Look for the room id
|
||||
NSString* roomId = [userInfo objectForKey:@"room_id"];
|
||||
NSString* roomId = notification.userInfo[@"room_id"];
|
||||
if (roomId.length)
|
||||
{
|
||||
// TODO retrieve the right matrix session
|
||||
|
@ -995,71 +1035,186 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
// sanity checks
|
||||
if (dedicatedAccount && dedicatedAccount.mxSession)
|
||||
{
|
||||
UIApplicationState state = [UIApplication sharedApplication].applicationState;
|
||||
NSLog(@"[AppDelegate] didReceiveLocalNotification: open the roomViewController %@", roomId);
|
||||
|
||||
// Jump to the concerned room only if the app is transitioning from the background
|
||||
if (state == UIApplicationStateInactive)
|
||||
{
|
||||
// Check whether another remote notification is not already processed
|
||||
if (!remoteNotificationRoomId)
|
||||
{
|
||||
remoteNotificationRoomId = roomId;
|
||||
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification: open the roomViewController %@", roomId);
|
||||
|
||||
[self showRoom:roomId andEventId:nil withMatrixSession:dedicatedAccount.mxSession];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification: busy");
|
||||
}
|
||||
}
|
||||
else if (!_completionHandler && (state == UIApplicationStateBackground))
|
||||
{
|
||||
_completionHandler = completionHandler;
|
||||
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification: starts a background sync");
|
||||
|
||||
[dedicatedAccount backgroundSync:20000 success:^{
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification: the background sync succeeds");
|
||||
|
||||
if (_completionHandler)
|
||||
{
|
||||
_completionHandler(UIBackgroundFetchResultNewData);
|
||||
_completionHandler = nil;
|
||||
}
|
||||
} failure:^(NSError *error) {
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification: the background sync fails");
|
||||
|
||||
if (_completionHandler)
|
||||
{
|
||||
_completionHandler(UIBackgroundFetchResultNoData);
|
||||
_completionHandler = nil;
|
||||
}
|
||||
}];
|
||||
|
||||
// wait that the background sync is done
|
||||
return;
|
||||
}
|
||||
[self showRoom:roomId andEventId:nil withMatrixSession:dedicatedAccount.mxSession];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification : no linked session / account has been found.");
|
||||
NSLog(@"[AppDelegate] didReceiveLocalNotification : no linked session / account has been found.");
|
||||
}
|
||||
}
|
||||
completionHandler(UIBackgroundFetchResultNoData);
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
|
||||
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(PKPushType)type
|
||||
{
|
||||
// iOS 10 (at least up to GM beta release) does not call application:didReceiveRemoteNotification:fetchCompletionHandler:
|
||||
// when the user clicks on a notification but it calls this deprecated version
|
||||
// of didReceiveRemoteNotification.
|
||||
// Use this method as a workaround as adviced at http://stackoverflow.com/a/39419245
|
||||
NSLog(@"[AppDelegate] didReceiveRemoteNotification (deprecated version)");
|
||||
NSData *token = credentials.token;
|
||||
|
||||
[self application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:^(UIBackgroundFetchResult result) {
|
||||
}];
|
||||
NSUInteger len = ((token.length > 8) ? 8 : token.length / 2);
|
||||
NSLog(@"[AppDelegate] Got Push token! (%@ ...)", [token subdataWithRange:NSMakeRange(0, len)]);
|
||||
|
||||
MXKAccountManager* accountManager = [MXKAccountManager sharedManager];
|
||||
[accountManager setPushDeviceToken:token withPushOptions:@{@"format": @"event_id_only"}];
|
||||
|
||||
isPushRegistered = YES;
|
||||
|
||||
if (self.registrationForRemoteNotificationsCompletion)
|
||||
{
|
||||
self.registrationForRemoteNotificationsCompletion(nil);
|
||||
self.registrationForRemoteNotificationsCompletion = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(PKPushType)type
|
||||
{
|
||||
MXKAccountManager* accountManager = [MXKAccountManager sharedManager];
|
||||
[accountManager setPushDeviceToken:nil withPushOptions:nil];
|
||||
}
|
||||
|
||||
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type
|
||||
{
|
||||
// Handle the local notifications by triggering a background sync.
|
||||
[self handleLocalNotifications];
|
||||
}
|
||||
|
||||
- (void)handleLocalNotifications
|
||||
{
|
||||
_hasPendingLocalNotifications = NO;
|
||||
|
||||
// Check whether the application is running in background.
|
||||
if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground)
|
||||
return;
|
||||
|
||||
// Launch a background sync for all existing matrix sessions
|
||||
NSArray *mxAccounts = [MXKAccountManager sharedManager].activeAccounts;
|
||||
for (MXKAccount *account in mxAccounts)
|
||||
{
|
||||
// Check the current session state
|
||||
if (account.mxSession.state != MXSessionStatePaused)
|
||||
{
|
||||
NSLog(@"[AppDelegate] handleLocalNotifications: delay the background sync");
|
||||
// Turn on the flag used to trigger a new background sync when a session is paused.
|
||||
_hasPendingLocalNotifications = YES;
|
||||
}
|
||||
|
||||
[account backgroundSync:20000 success:^{
|
||||
|
||||
NSLog(@"[AppDelegate] handleLocalNotifications: the background sync succeeds");
|
||||
|
||||
// Update icon badge number
|
||||
[UIApplication sharedApplication].applicationIconBadgeNumber = [account.mxSession riot_missedDiscussionsCount];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
NSLog(@"[AppDelegate] handleLocalNotifications: the background sync fails");
|
||||
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (nullable NSString *)notificationBodyForEvent:(MXEvent *)event withRoomState:(MXRoomState *)roomState pushRule:(MXPushRule*)rule inAccount:(MXKAccount*)account
|
||||
{
|
||||
if (!event.content || !event.content.count)
|
||||
return nil;
|
||||
|
||||
NSString *notificationBody;
|
||||
NSString *eventSenderName = [roomState memberName:event.sender];
|
||||
|
||||
if (event.eventType == MXEventTypeRoomMessage || event.eventType == MXEventTypeRoomEncrypted)
|
||||
{
|
||||
MXRoom *room = [account.mxSession roomWithRoomId:event.roomId];
|
||||
|
||||
if (room.isMentionsOnly)
|
||||
{
|
||||
// A local notification will be displayed only for highlighted notification.
|
||||
BOOL isHighlighted = NO;
|
||||
|
||||
// Check whether is there an highlight tweak on it
|
||||
for (MXPushRuleAction *ruleAction in rule.actions)
|
||||
{
|
||||
if (ruleAction.actionType == MXPushRuleActionTypeSetTweak)
|
||||
{
|
||||
if ([ruleAction.parameters[@"set_tweak"] isEqualToString:@"highlight"])
|
||||
{
|
||||
// Check the highlight tweak "value"
|
||||
// If not present, highlight. Else check its value before highlighting
|
||||
if (nil == ruleAction.parameters[@"value"] || YES == [ruleAction.parameters[@"value"] boolValue])
|
||||
{
|
||||
isHighlighted = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isHighlighted)
|
||||
{
|
||||
// Ignore this notif.
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
NSString *msgType = event.content[@"msgtype"];
|
||||
NSString *content = event.content[@"body"];
|
||||
|
||||
if (event.isEncrypted && !account.showDecryptedContentInNotifications)
|
||||
{
|
||||
// Hide the content
|
||||
msgType = nil;
|
||||
}
|
||||
|
||||
NSString *roomDisplayName = room.summary.displayname;
|
||||
|
||||
// Display the room name only if it is different than the sender name
|
||||
if (roomDisplayName.length && ![roomDisplayName isEqualToString:eventSenderName])
|
||||
{
|
||||
if ([msgType isEqualToString:@"m.text"])
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"MSG_FROM_USER_IN_ROOM_WITH_CONTENT", nil), eventSenderName,roomDisplayName, content];
|
||||
else if ([msgType isEqualToString:@"m.emote"])
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"ACTION_FROM_USER_IN_ROOM", nil), roomDisplayName, eventSenderName, content];
|
||||
else if ([msgType isEqualToString:@"m.image"])
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"IMAGE_FROM_USER_IN_ROOM", nil), eventSenderName, content, roomDisplayName];
|
||||
else
|
||||
// Encrypted messages falls here
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"MSG_FROM_USER_IN_ROOM", nil), eventSenderName, roomDisplayName];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([msgType isEqualToString:@"m.text"])
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"MSG_FROM_USER_WITH_CONTENT", nil), eventSenderName, content];
|
||||
else if ([msgType isEqualToString:@"m.emote"])
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"ACTION_FROM_USER", nil), eventSenderName, content];
|
||||
else if ([msgType isEqualToString:@"m.image"])
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"IMAGE_FROM_USER", nil), eventSenderName, content];
|
||||
else
|
||||
// Encrypted messages falls here
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"MSG_FROM_USER", nil), eventSenderName];
|
||||
}
|
||||
}
|
||||
else if (event.eventType == MXEventTypeCallInvite)
|
||||
{
|
||||
NSString *sdp = event.content[@"offer"][@"sdp"];
|
||||
BOOL isVideoCall = [sdp rangeOfString:@"m=video"].location != NSNotFound;
|
||||
|
||||
if (!isVideoCall)
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"VOICE_CALL_FROM_USER", nil), eventSenderName];
|
||||
else
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"VIDEO_CALL_FROM_USER", nil), eventSenderName];
|
||||
}
|
||||
else if (event.eventType == MXEventTypeRoomMember)
|
||||
{
|
||||
NSString *roomName = roomState.name;
|
||||
NSString *roomAlias = roomState.aliases.firstObject;
|
||||
|
||||
if (roomName)
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"USER_INVITE_TO_NAMED_ROOM", nil), eventSenderName, roomName];
|
||||
else if (roomAlias)
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"USER_INVITE_TO_NAMED_ROOM", nil), eventSenderName, roomAlias];
|
||||
else
|
||||
notificationBody = [NSString stringWithFormat:NSLocalizedString(@"USER_INVITE_TO_CHAT", nil), eventSenderName];
|
||||
}
|
||||
|
||||
return notificationBody;
|
||||
}
|
||||
|
||||
- (void)refreshApplicationIconBadgeNumber
|
||||
|
@ -1491,6 +1646,9 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
// Get modular widget events in rooms histories
|
||||
[[MXKAppSettings standardAppSettings] addSupportedEventTypes:@[kWidgetEventTypeString]];
|
||||
|
||||
// Use shared container to share data with app extensions
|
||||
sdkOptions.applicationGroupIdentifier = @"group.im.vector";
|
||||
|
||||
// Disable long press on event in bubble cells
|
||||
[MXKRoomBubbleTableViewCell disableLongPressGestureOnEvent:YES];
|
||||
|
||||
|
@ -1501,13 +1659,6 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
matrixSessionStateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
MXSession *mxSession = (MXSession*)notif.object;
|
||||
|
||||
// Remove by default potential call observer on matrix session state change
|
||||
if (matrixCallObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:matrixCallObserver];
|
||||
matrixCallObserver = nil;
|
||||
}
|
||||
|
||||
// Check whether the concerned session is a new one
|
||||
if (mxSession.state == MXSessionStateInitialised)
|
||||
{
|
||||
|
@ -1529,6 +1680,19 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
if (callStack)
|
||||
{
|
||||
[mxSession enableVoIPWithCallStack:callStack];
|
||||
|
||||
// Setup CallKit
|
||||
if ([MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
BOOL isCallKitEnabled = [MXKAppSettings standardAppSettings].isCallKitEnabled;
|
||||
[self enableCallKit:isCallKitEnabled forCallManager:mxSession.callManager];
|
||||
|
||||
// Register for changes performed by the user
|
||||
[[MXKAppSettings standardAppSettings] addObserver:self
|
||||
forKeyPath:@"enableCallKit"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:NULL];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1546,12 +1710,19 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
}
|
||||
else if (mxSession.state == MXSessionStateStoreDataReady)
|
||||
{
|
||||
// Check whether the app user wants inApp notifications on new events for this session
|
||||
// A new call observer may be added here
|
||||
[self addMatrixCallObserver];
|
||||
|
||||
// Enable local notifications
|
||||
[self enableLocalNotificationsFromMatrixSession:mxSession];
|
||||
|
||||
// Look for the account related to this session.
|
||||
NSArray *mxAccounts = [MXKAccountManager sharedManager].activeAccounts;
|
||||
for (MXKAccount *account in mxAccounts)
|
||||
{
|
||||
if (account.mxSession == mxSession)
|
||||
{
|
||||
// Enable inApp notifications (if they are allowed for this account).
|
||||
[self enableInAppNotificationsForAccount:account];
|
||||
break;
|
||||
}
|
||||
|
@ -1561,23 +1732,30 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
{
|
||||
[self removeMatrixSession:mxSession];
|
||||
}
|
||||
|
||||
// Restore call observer only if all session are running
|
||||
NSArray *mxSessions = self.mxSessions;
|
||||
BOOL shouldAddMatrixCallObserver = (mxSessions.count);
|
||||
for (mxSession in mxSessions)
|
||||
// Consider here the case where the app is running in background.
|
||||
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
|
||||
{
|
||||
if (mxSession.state != MXSessionStateRunning)
|
||||
if (mxSession.state == MXSessionStateRunning)
|
||||
{
|
||||
shouldAddMatrixCallObserver = NO;
|
||||
break;
|
||||
// Pause the session in background task
|
||||
NSArray *mxAccounts = [MXKAccountManager sharedManager].activeAccounts;
|
||||
for (MXKAccount *account in mxAccounts)
|
||||
{
|
||||
if (account.mxSession == mxSession)
|
||||
{
|
||||
[account pauseInBackgroundTask];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mxSession.state == MXSessionStatePaused)
|
||||
{
|
||||
// Check whether some local notifications must be handled by triggering a background sync.
|
||||
if (_hasPendingLocalNotifications)
|
||||
{
|
||||
[self handleLocalNotifications];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldAddMatrixCallObserver)
|
||||
{
|
||||
// A new call observer may be added here
|
||||
[self addMatrixCallObserver];
|
||||
}
|
||||
|
||||
[self handleLaunchAnimation];
|
||||
|
@ -1598,10 +1776,10 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
// Set the push gateway URL.
|
||||
account.pushGatewayURL = [[NSUserDefaults standardUserDefaults] objectForKey:@"pushGatewayURL"];
|
||||
|
||||
if (isAPNSRegistered)
|
||||
if (isPushRegistered)
|
||||
{
|
||||
// Enable push notifications by default on new added account
|
||||
account.enablePushNotifications = YES;
|
||||
account.enablePushKitNotifications = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1668,23 +1846,20 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
// Use MXFileStore as MXStore to permanently store events.
|
||||
accountManager.storeClass = [MXFileStore class];
|
||||
|
||||
// Observers have been defined, we can start a matrix session for each enabled accounts.
|
||||
// except if the app is still in background.
|
||||
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground)
|
||||
// Disable APNS use.
|
||||
if (accountManager.apnsDeviceToken)
|
||||
{
|
||||
NSLog(@"[AppDelegate] initMatrixSessions: prepareSessionForActiveAccounts");
|
||||
[accountManager prepareSessionForActiveAccounts];
|
||||
}
|
||||
else
|
||||
{
|
||||
// The app is launched in background as a result of a remote notification.
|
||||
// Presently we are not able to initialize the matrix session(s) in background. (FIXME: initialize matrix session(s) in case of a background launch).
|
||||
// Patch: the account session(s) will be opened when the app will enter foreground.
|
||||
NSLog(@"[AppDelegate] initMatrixSessions: The application has been launched in background");
|
||||
// We use now Pushkit, unregister for all remote notifications received via Apple Push Notification service.
|
||||
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
|
||||
[accountManager setApnsDeviceToken:nil];
|
||||
}
|
||||
|
||||
// Observers have been defined, we can start a matrix session for each enabled accounts.
|
||||
NSLog(@"[AppDelegate] initMatrixSessions: prepareSessionForActiveAccounts (app state: %tu)", [[UIApplication sharedApplication] applicationState]);
|
||||
[accountManager prepareSessionForActiveAccounts];
|
||||
|
||||
// Check whether we're already logged in
|
||||
NSArray *mxAccounts = accountManager.accounts;
|
||||
NSArray *mxAccounts = accountManager.activeAccounts;
|
||||
if (mxAccounts.count)
|
||||
{
|
||||
for (MXKAccount *account in mxAccounts)
|
||||
|
@ -1751,7 +1926,16 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
// If any, disable the no VoIP support workaround
|
||||
[self disableNoVoIPOnMatrixSession:mxSession];
|
||||
|
||||
// Disable local notifications from this session
|
||||
[self disableLocalNotificationsFromMatrixSession:mxSession];
|
||||
|
||||
[mxSessionArray removeObject:mxSession];
|
||||
|
||||
if (!mxSessionArray.count && matrixCallObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:matrixCallObserver];
|
||||
matrixCallObserver = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)markAllMessagesAsRead
|
||||
|
@ -1788,8 +1972,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
|
||||
- (void)logout
|
||||
{
|
||||
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
|
||||
isAPNSRegistered = NO;
|
||||
self.pushRegistry = nil;
|
||||
isPushRegistered = NO;
|
||||
|
||||
// Clear cache
|
||||
[MXMediaManager clearCache];
|
||||
|
@ -1828,28 +2012,141 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
{
|
||||
[self enableInAppNotificationsForAccount:(MXKAccount*)object];
|
||||
}
|
||||
else if (object == [MXKAppSettings standardAppSettings] && [keyPath isEqualToString:@"enableCallKit"])
|
||||
{
|
||||
BOOL isCallKitEnabled = [MXKAppSettings standardAppSettings].isCallKitEnabled;
|
||||
MXCallManager *callManager = [[[[[MXKAccountManager sharedManager] activeAccounts] firstObject] mxSession] callManager];
|
||||
[self enableCallKit:isCallKitEnabled forCallManager:callManager];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addMatrixCallObserver
|
||||
{
|
||||
if (matrixCallObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:matrixCallObserver];
|
||||
return;
|
||||
}
|
||||
|
||||
// Register call observer in order to handle new opened session
|
||||
matrixCallObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerNewCall object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
// Register call observer in order to handle incoming calls
|
||||
matrixCallObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallManagerNewCall
|
||||
object:nil
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification *notif)
|
||||
{
|
||||
// Ignore the call if a call is already in progress
|
||||
if (!currentCallViewController && !_jitsiViewController)
|
||||
{
|
||||
MXCall *mxCall = (MXCall*)notif.object;
|
||||
|
||||
// Prepare the call view controller
|
||||
currentCallViewController = [CallViewController callViewController:mxCall];
|
||||
currentCallViewController.delegate = self;
|
||||
BOOL isCallKitAvailable = [MXCallKitAdapter callKitAvailable] && [MXKAppSettings standardAppSettings].isCallKitEnabled;
|
||||
|
||||
[self presentCallViewController:nil];
|
||||
// Prepare the call view controller
|
||||
currentCallViewController = [CallViewController callViewController:nil];
|
||||
currentCallViewController.playRingtone = !isCallKitAvailable;
|
||||
currentCallViewController.mxCall = mxCall;
|
||||
currentCallViewController.delegate = self;
|
||||
|
||||
UIApplicationState applicationState = UIApplication.sharedApplication.applicationState;
|
||||
|
||||
// App has been woken by PushKit notification in the background
|
||||
if (applicationState == UIApplicationStateBackground && mxCall.isIncoming)
|
||||
{
|
||||
// Create backgound task.
|
||||
// Without CallKit this will allow us to play vibro until the call was ended
|
||||
// With CallKit we'll inform the system when the call is ended to let the system terminate our app to save resources
|
||||
id<MXBackgroundModeHandler> handler = [MXSDKOptions sharedInstance].backgroundModeHandler;
|
||||
NSUInteger callTaskIdentifier = [handler startBackgroundTaskWithName:nil completion:^{}];
|
||||
|
||||
// Start listening for call state change notifications
|
||||
__weak NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
__block id token = [[NSNotificationCenter defaultCenter] addObserverForName:kMXCallStateDidChange
|
||||
object:mxCall
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification * _Nonnull note) {
|
||||
MXCall *call = (MXCall *)note.object;
|
||||
|
||||
if (call.state == MXCallStateEnded)
|
||||
{
|
||||
// Set call vc to nil to let our app handle new incoming calls even it wasn't killed by the system
|
||||
currentCallViewController = nil;
|
||||
[notificationCenter removeObserver:token];
|
||||
|
||||
[handler endBackgrounTaskWithIdentifier:callTaskIdentifier];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
if (mxCall.isIncoming && !isCallKitAvailable)
|
||||
{
|
||||
// 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];
|
||||
|
||||
// Removing existing notification (if any)
|
||||
[_incomingCallNotification dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
_incomingCallNotification = [UIAlertController alertControllerWithTitle:callPrompt
|
||||
message:nil
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
[_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];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
@ -1956,6 +2253,105 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
}
|
||||
}
|
||||
|
||||
- (void)enableCallKit:(BOOL)enable forCallManager:(MXCallManager *)callManager
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
// Create adapter with default configuration for a while
|
||||
MXCallKitAdapter *callKitAdapter = [[MXCallKitAdapter alloc] init];
|
||||
|
||||
id<MXCallAudioSessionConfigurator> audioSessionConfigurator;
|
||||
|
||||
#ifdef MX_CALL_STACK_JINGLE
|
||||
audioSessionConfigurator = [[MXJingleCallAudioSessionConfigurator alloc] init];
|
||||
#endif
|
||||
|
||||
callKitAdapter.audioSessionConfigurator = audioSessionConfigurator;
|
||||
|
||||
callManager.callKitAdapter = callKitAdapter;
|
||||
}
|
||||
else
|
||||
{
|
||||
callManager.callKitAdapter = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)enableLocalNotificationsFromMatrixSession:(MXSession*)mxSession
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
// Look for the account related to this session.
|
||||
NSArray *mxAccounts = [MXKAccountManager sharedManager].activeAccounts;
|
||||
MXKAccount *account;
|
||||
for (account in mxAccounts)
|
||||
{
|
||||
if (account.mxSession == mxSession)
|
||||
{
|
||||
break;
|
||||
}
|
||||
account = nil;
|
||||
}
|
||||
|
||||
MXOnNotification notificationListenerBlock = ^(MXEvent *event, MXRoomState *roomState, MXPushRule *rule) {
|
||||
|
||||
// Do not display local notification if the app is not running in background.
|
||||
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not display local notifications during the initial sync.
|
||||
if (!account.mxSession.isEventStreamInitialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// For all type of event show local notifications besides the situation
|
||||
// when the type of event is call invite and we have CallKit support
|
||||
BOOL isCallKitActive = [MXCallKitAdapter callKitAvailable] && [MXKAppSettings standardAppSettings].isCallKitEnabled;
|
||||
if (!(event.eventType == MXEventTypeCallInvite && isCallKitActive))
|
||||
{
|
||||
NSString *notificationBody = [weakSelf notificationBodyForEvent:event withRoomState:roomState pushRule:rule inAccount:account];
|
||||
if (notificationBody)
|
||||
{
|
||||
UILocalNotification *eventNotification = [[UILocalNotification alloc] init];
|
||||
eventNotification.fireDate = [NSDate dateWithTimeIntervalSince1970:event.originServerTs / 1000];
|
||||
eventNotification.alertBody = notificationBody;
|
||||
eventNotification.userInfo = @{ @"room_id" : event.roomId };
|
||||
|
||||
// Set sound name based on the value provided in action of MXPushRule
|
||||
for (MXPushRuleAction *action in rule.actions)
|
||||
{
|
||||
if (action.actionType == MXPushRuleActionTypeSetTweak)
|
||||
{
|
||||
if ([action.parameters[@"set_tweak"] isEqualToString:@"sound"])
|
||||
{
|
||||
NSString *soundName = action.parameters[@"value"];
|
||||
if ([soundName isEqualToString:@"default"])
|
||||
soundName = UILocalNotificationDefaultSoundName;
|
||||
|
||||
eventNotification.soundName = soundName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[UIApplication sharedApplication] scheduleLocalNotification:eventNotification];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
[mxSession.notificationCenter listenToNotifications:notificationListenerBlock];
|
||||
notificationListenerBlocks[@(mxSession.hash)] = notificationListenerBlock;
|
||||
}
|
||||
|
||||
- (void)disableLocalNotificationsFromMatrixSession:(MXSession*)mxSession
|
||||
{
|
||||
// Stop listening to notification of this session
|
||||
[mxSession.notificationCenter removeListener:notificationListenerBlocks[@(mxSession.hash)]];
|
||||
[notificationListenerBlocks removeObjectForKey:@(mxSession.hash)];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
/**
|
||||
|
@ -2037,7 +2433,6 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
NSString* messageText = [eventFormatter stringFromEvent:event withRoomState:roomState error:&error];
|
||||
if (messageText.length && (error == MXKEventFormatterErrorNone))
|
||||
{
|
||||
|
||||
// Removing existing notification (if any)
|
||||
if (self.mxInAppNotification)
|
||||
{
|
||||
|
@ -2057,8 +2452,10 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
|||
}
|
||||
}
|
||||
|
||||
MXRoomSummary *roomSummary = [account.mxSession roomSummaryWithRoomId:event.roomId];
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
self.mxInAppNotification = [UIAlertController alertControllerWithTitle:roomState.displayname
|
||||
self.mxInAppNotification = [UIAlertController alertControllerWithTitle:roomSummary.displayname
|
||||
message:messageText
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
|
|
|
@ -155,6 +155,7 @@
|
|||
"search_default_placeholder" = "Search";
|
||||
"search_people_placeholder" = "Search by User ID, Name or email";
|
||||
"search_no_result" = "No results";
|
||||
"search_in_progress" = "Searching…";
|
||||
|
||||
// Directory
|
||||
"directory_cell_title" = "Browse directory";
|
||||
|
@ -253,7 +254,7 @@
|
|||
"room_event_action_save" = "Save";
|
||||
"room_event_action_resend" = "Resend";
|
||||
"room_event_action_delete" = "Delete";
|
||||
"room_event_action_cancel_upload" = "Cancel Upload";
|
||||
"room_event_action_cancel_send" = "Cancel Send";
|
||||
"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.";
|
||||
|
@ -297,6 +298,7 @@
|
|||
|
||||
"settings_user_settings" = "USER SETTINGS";
|
||||
"settings_notifications_settings" = "NOTIFICATION SETTINGS";
|
||||
"settings_calls_settings" = "CALLS";
|
||||
"settings_user_interface" = "USER INTERFACE";
|
||||
"settings_ignored_users" = "IGNORED USERS";
|
||||
"settings_contacts" = "LOCAL CONTACTS";
|
||||
|
@ -326,6 +328,7 @@
|
|||
"settings_fail_to_update_profile" = "Fail to update profile";
|
||||
|
||||
"settings_enable_push_notif" = "Notifications on this device";
|
||||
"settings_show_decrypted_content" = "Show decrypted content";
|
||||
"settings_global_settings_info" = "Global notification settings are available on your %@ web client";
|
||||
"settings_pin_rooms_with_missed_notif" = "Pin rooms with missed notifications";
|
||||
"settings_pin_rooms_with_unread" = "Pin rooms with unread messages";
|
||||
|
@ -338,6 +341,8 @@
|
|||
//"settings_join_leave_rooms" = "When people join or leave rooms";
|
||||
//"settings_call_invitations" = "Call invitations";
|
||||
|
||||
"settings_enable_callkit" = "Integrated calling";
|
||||
"settings_callkit_info" = "Receive incoming calls on your lock screen. See your Riot calls in the system's call history. If iCloud is enabled, this call history will be shared with Apple.";
|
||||
"settings_ui_language" = "Language";
|
||||
"settings_ui_theme" = "Theme";
|
||||
"settings_ui_theme_auto" = "Auto";
|
||||
|
@ -366,6 +371,7 @@
|
|||
"settings_privacy_policy_url" = "https://riot.im/privacy";
|
||||
"settings_third_party_notices" = "Third-party Notices";
|
||||
"settings_send_crash_report" = "Send anon crash & usage data";
|
||||
"settings_enable_rageshake" = "Rage shake to report bug";
|
||||
"settings_clear_cache" = "Clear cache";
|
||||
|
||||
"settings_change_password" = "Change password";
|
||||
|
@ -473,6 +479,7 @@
|
|||
"public_room_section_title" = "Public Rooms (at %@):";
|
||||
"bug_report_prompt" = "The application has crashed last time. Would you like to submit a crash report?";
|
||||
"rage_shake_prompt" = "You seem to be shaking the phone in frustration. Would you like to submit a bug report?";
|
||||
"do_not_ask_again" = "Do not ask again";
|
||||
"camera_access_not_granted" = "%@ doesn't have permission to use Camera, please change privacy settings";
|
||||
"large_badge_value_k_format" = "%.1fK";
|
||||
|
||||
|
|
|
@ -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" = "%@ erabiltzaileak irudi bat bidali dizu";
|
||||
"IMAGE_FROM_USER" = "%@ erabiltzaileak irudi bat %@ bidali dizu";
|
||||
/* New action message from a specific person in a named room. */
|
||||
"IMAGE_FROM_USER_IN_ROOM" = "%@ erabiltzaileak irudi bat bidali du %@ gelara";
|
||||
"IMAGE_FROM_USER_IN_ROOM" = "%@ erabiltzaileak irudi bat %@ bidali du %@ gelara";
|
||||
/* Multiple unread messages in a room */
|
||||
"UNREAD_IN_ROOM" = "%@ mezu berri %@ gelan";
|
||||
/* Multiple unread messages from a specific person, not referencing a room */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Permissions usage explanations
|
||||
"NSCameraUsageDescription" = "La caméra est utilisée pour prendre des photos, des vidéos et passer des appels vidéo.";
|
||||
"NSPhotoLibraryUsageDescription" = "La bibliothèque photo est utilisée pour envoyer des photos et des vidéos.";
|
||||
"NSCameraUsageDescription" = "L'appareil photo est utilisé pour prendre des photos et des vidéos et pour passer des appels vidéo.";
|
||||
"NSPhotoLibraryUsageDescription" = "La photothèque est utilisée pour envoyer des photos et des vidéos.";
|
||||
"NSMicrophoneUsageDescription" = "Le microphone est utilisé pour prendre des vidéos et passer des appels.";
|
||||
"NSContactsUsageDescription" = "Le carnet d'adresses est utilisé pour rechercher des utilisateurs par e-mail et numéro de téléphone sur Riot.";
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
/* Look, stuff's happened, alright? Just open the app. */
|
||||
"MSGS_IN_TWO_PLUS_ROOMS" = "%@ nouveaux messages dans %@, %@ et d'autres";
|
||||
/* A user has invited you to a chat */
|
||||
"USER_INVITE_TO_CHAT" = "%@ vous a invité";
|
||||
"USER_INVITE_TO_CHAT" = "%@ vous a invité dans une discussion";
|
||||
/* A user has invited you to an (unamed) group chat */
|
||||
"USER_INVITE_TO_CHAT_GROUP_CHAT" = "%@ vous a invité dans un salon";
|
||||
/* A user has invited you to a named room */
|
||||
|
@ -39,10 +39,10 @@
|
|||
/* Incoming one-to-one video call */
|
||||
"VIDEO_CALL_FROM_USER" = "Appel vidéo de %@";
|
||||
/* Incoming unnamed voice conference invite from a specific person */
|
||||
"VOICE_CONF_FROM_USER" = "Appel groupé depuis %@";
|
||||
"VOICE_CONF_FROM_USER" = "Téléconférence vocale de %@";
|
||||
/* Incoming unnamed video conference invite from a specific person */
|
||||
"VIDEO_CONF_FROM_USER" = "Appel vidéo groupé depuis %@";
|
||||
"VIDEO_CONF_FROM_USER" = "Téléconférence vidéo de %@";
|
||||
/* Incoming named voice conference invite from a specific person */
|
||||
"VOICE_CONF_NAMED_FROM_USER" = "Appel groupé de %@ : '%@'";
|
||||
"VOICE_CONF_NAMED_FROM_USER" = "Téléconférence vocale de %@ : '%@'";
|
||||
/* Incoming named video conference invite from a specific person */
|
||||
"VIDEO_CONF_NAMED_FROM_USER" = "Appel vidéo groupé de %@ : '%@'";
|
||||
"VIDEO_CONF_NAMED_FROM_USER" = "Téléconférence vidéo de %@ : '%@'";
|
||||
|
|
|
@ -117,6 +117,8 @@
|
|||
"search_default_placeholder" = "Recherche";
|
||||
"search_people_placeholder" = "Rechercher par identifiant, nom ou e-mail";
|
||||
"search_no_result" = "Aucun résultat";
|
||||
"search_in_progress" = "Recherche en cours…";
|
||||
|
||||
// Directory
|
||||
"directory_cell_title" = "Parcourir le répertoire";
|
||||
"directory_cell_description" = "%tu salons";
|
||||
|
@ -210,7 +212,7 @@
|
|||
"room_event_action_save" = "Enregistrer";
|
||||
"room_event_action_resend" = "Renvoyer";
|
||||
"room_event_action_delete" = "Supprimer";
|
||||
"room_event_action_cancel_upload" = "Annuler l'envoi";
|
||||
"room_event_action_cancel_send" = "Annuler l'envoi";
|
||||
"room_event_action_cancel_download" = "Annuler le téléchargement";
|
||||
"room_event_action_view_encryption" = "Informations sur le chiffrement";
|
||||
"room_warning_about_encryption" = "Le chiffrement de bout en bout est en version bêta et peut ne pas être fiable.\n\nIl ne doit pas être considéré comme fiable pour sécuriser des données.\n\nLes appareils ne pourront pas encore déchiffrer l'historique de messages d'avant leur arrivée sur le salon.\n\nLes messages chiffrés ne seront pas visibles sur les clients qui n'ont pas encore implémenté le chiffrement.";
|
||||
|
@ -257,7 +259,7 @@
|
|||
"settings_sign_out_confirmation" = "Êtes-vous sûr(e) ?";
|
||||
"settings_sign_out_e2e_warn" = "Vous perdrez vos clés de chiffrement de bout en bout. Cela signifie que vous ne pourrez plus lire les anciens messages des salons chiffrés depuis cet appareil.";
|
||||
"settings_profile_picture" = "Image de profil";
|
||||
"settings_display_name" = "Nom affiché";
|
||||
"settings_display_name" = "Nom d'affichage";
|
||||
"settings_first_name" = "Prénom";
|
||||
"settings_surname" = "Nom";
|
||||
"settings_remove_prompt_title" = "Confirmation";
|
||||
|
@ -290,6 +292,7 @@
|
|||
"settings_privacy_policy_url" = "https://riot.im/privacy";
|
||||
"settings_third_party_notices" = "Licences tierces";
|
||||
"settings_send_crash_report" = "Envoyer des rapports d'erreur anonymes et des statistiques d'utilisation";
|
||||
"settings_enable_rageshake" = "Secouer l'appareil pour signaler un bug";
|
||||
"settings_clear_cache" = "Vider le cache";
|
||||
"settings_change_password" = "Changer de mot de passe";
|
||||
"settings_old_password" = "ancien mot de passe";
|
||||
|
@ -383,6 +386,7 @@
|
|||
"public_room_section_title" = "Salons publics (sur %@) :";
|
||||
"bug_report_prompt" = "L'application s'est terminée brusquement la dernière fois. Voulez-vous envoyer un rapport d'erreur ?";
|
||||
"rage_shake_prompt" = "Vous semblez secouer le téléphone avec frustration. Souhaitez-vous soumettre un rapport d'erreur ?";
|
||||
"do_not_ask_again" = "Ne plus demander";
|
||||
"camera_access_not_granted" = "%@ n'a pas la permission pour utiliser l'appareil photo, veuillez modifier les options de vie privée";
|
||||
"large_badge_value_k_format" = "%.1fK";
|
||||
// room display name
|
||||
|
|
|
@ -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 */
|
||||
|
|
28
Riot/Categories/MXSession+Riot.h
Normal file
28
Riot/Categories/MXSession+Riot.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
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 <Foundation/Foundation.h>
|
||||
|
||||
#import <MatrixSDK/MXSession.h>
|
||||
|
||||
@interface MXSession (Riot)
|
||||
|
||||
/**
|
||||
The current number of rooms with missed notifications, including the invites.
|
||||
*/
|
||||
- (NSUInteger)riot_missedDiscussionsCount;
|
||||
|
||||
@end
|
51
Riot/Categories/MXSession+Riot.m
Normal file
51
Riot/Categories/MXSession+Riot.m
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
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 "MXSession+Riot.h"
|
||||
|
||||
#import "MXRoom+Riot.h"
|
||||
|
||||
@implementation MXSession (Riot)
|
||||
|
||||
- (NSUInteger)riot_missedDiscussionsCount
|
||||
{
|
||||
NSUInteger missedDiscussionsCount = 0;
|
||||
|
||||
// Sum all the rooms with missed notifications.
|
||||
for (MXRoomSummary *roomSummary in self.roomsSummaries)
|
||||
{
|
||||
NSUInteger notificationCount = roomSummary.notificationCount;
|
||||
|
||||
// Ignore the regular notification count if the room is in 'mentions only" mode at the Riot level.
|
||||
if (roomSummary.room.isMentionsOnly)
|
||||
{
|
||||
// Only the highlighted missed messages must be considered here.
|
||||
notificationCount = roomSummary.highlightCount;
|
||||
}
|
||||
|
||||
if (notificationCount)
|
||||
{
|
||||
missedDiscussionsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the invites count
|
||||
missedDiscussionsCount += [self invitedRooms].count;
|
||||
|
||||
return missedDiscussionsCount;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,13 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
|
@ -47,13 +49,15 @@
|
|||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-20.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-20@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
|
@ -97,6 +101,12 @@
|
|||
"idiom" : "ipad",
|
||||
"filename" : "Icon-83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-1024.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
|
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-1024.png
Normal file
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-1024.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20.png
Normal file
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20@2x-1.png
Normal file
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20@2x-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20@2x.png
Normal file
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20@3x.png
Normal file
BIN
Riot/Images.xcassets/AppIcon.appiconset/Icon-20@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
|
@ -17,11 +17,11 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.5.3</string>
|
||||
<string>0.5.6</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.5.3</string>
|
||||
<string>0.5.6</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<true/>
|
||||
<key>ITSEncryptionExportComplianceCode</key>
|
||||
|
@ -49,6 +49,8 @@
|
|||
<string>The microphone is used to take videos, make calls.</string>
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>The photo library is used to send photos and videos.</string>
|
||||
<key>NSSiriUsageDescription</key>
|
||||
<string>Siri is used to perform calls even from the lock screen.</string>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>audio</string>
|
||||
|
|
|
@ -356,8 +356,15 @@ double const kPublicRoomsDirectoryDataExpiration = 10;
|
|||
}
|
||||
else
|
||||
{
|
||||
// Show nothing while loading and in other cases
|
||||
tableViewCell.textLabel.text = @"";
|
||||
if (_searchPattern.length)
|
||||
{
|
||||
tableViewCell.textLabel.text = NSLocalizedStringFromTable(@"search_in_progress", @"Vector", nil);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show nothing in other cases
|
||||
tableViewCell.textLabel.text = @"";
|
||||
}
|
||||
}
|
||||
|
||||
return tableViewCell;
|
||||
|
|
|
@ -3,15 +3,17 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>pinRoomsWithMissedNotif</key>
|
||||
<false/>
|
||||
<true/>
|
||||
<key>pinRoomsWithUnread</key>
|
||||
<false/>
|
||||
<true/>
|
||||
<key>pushGatewayURL</key>
|
||||
<string>https://matrix.org/_matrix/push/v1/notify</string>
|
||||
<key>pusherAppIdDev</key>
|
||||
<string>im.vector.app.ios.dev</string>
|
||||
<key>pusherAppIdProd</key>
|
||||
<string>im.vector.app.ios.prod</string>
|
||||
<key>pushKitAppIdProd</key>
|
||||
<string>im.vector.app.ios.voip.prod</string>
|
||||
<key>identityserverurl</key>
|
||||
<string>https://vector.im</string>
|
||||
<key>homeserverurl</key>
|
||||
|
@ -28,8 +30,6 @@
|
|||
<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>
|
||||
<false/>
|
||||
<key>showRedactionsInRoomHistory</key>
|
||||
|
@ -42,6 +42,10 @@
|
|||
<false/>
|
||||
<key>syncLocalContacts</key>
|
||||
<false/>
|
||||
<key>createConferenceCallsWithJitsi</key>
|
||||
<true/>
|
||||
<key>enableRageShake</key>
|
||||
<true/>
|
||||
<key>maxAllowedMediaCacheSize</key>
|
||||
<integer>1073741824</integer>
|
||||
<key>presenceColorForOnlineUser</key>
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
<string>applinks:riot.im</string>
|
||||
<string>applinks:www.riot.im</string>
|
||||
</array>
|
||||
<key>com.apple.developer.siri</key>
|
||||
<true/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.im.vector</string>
|
||||
|
|
|
@ -224,9 +224,9 @@
|
|||
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;
|
||||
|
||||
BOOL refreshRiotRoomDisplayName = NO;
|
||||
BOOL refreshRiotRoomAvatarURL = NO;
|
||||
|
||||
for (MXEvent *event in stateEvents)
|
||||
{
|
||||
switch (event.eventType)
|
||||
|
@ -235,45 +235,50 @@
|
|||
case MXEventTypeRoomAliases:
|
||||
case MXEventTypeRoomCanonicalAlias:
|
||||
{
|
||||
if (!riotRoomDisplayName.length)
|
||||
{
|
||||
riotRoomDisplayName = [self riotRoomDisplayNameFromRoomState:summary.room.state];
|
||||
}
|
||||
refreshRiotRoomDisplayName = YES;
|
||||
break;
|
||||
}
|
||||
case MXEventTypeRoomMember:
|
||||
{
|
||||
if (!riotRoomDisplayName.length)
|
||||
{
|
||||
riotRoomDisplayName = [self riotRoomDisplayNameFromRoomState:summary.room.state];
|
||||
}
|
||||
refreshRiotRoomDisplayName = YES;
|
||||
// Do not break here to check avatar url too.
|
||||
}
|
||||
case MXEventTypeRoomAvatar:
|
||||
{
|
||||
if (!riotRoomAvatarURL.length)
|
||||
{
|
||||
riotRoomAvatarURL = [self riotRoomAvatarURLFromRoomState:summary.room.state];
|
||||
}
|
||||
refreshRiotRoomAvatarURL = YES;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (refreshRiotRoomDisplayName && refreshRiotRoomAvatarURL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (riotRoomDisplayName.length && ![summary.displayname isEqualToString:riotRoomDisplayName])
|
||||
|
||||
if (refreshRiotRoomDisplayName)
|
||||
{
|
||||
summary.displayname = riotRoomDisplayName;
|
||||
ret = YES;
|
||||
NSString *riotRoomDisplayName = [self riotRoomDisplayNameFromRoomState:summary.room.state];
|
||||
|
||||
if (riotRoomDisplayName.length && ![summary.displayname isEqualToString:riotRoomDisplayName])
|
||||
{
|
||||
summary.displayname = riotRoomDisplayName;
|
||||
ret = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (riotRoomAvatarURL.length && ![summary.avatar isEqualToString:riotRoomAvatarURL])
|
||||
if (refreshRiotRoomAvatarURL)
|
||||
{
|
||||
summary.avatar = riotRoomAvatarURL;
|
||||
ret = YES;
|
||||
NSString *riotRoomAvatarURL = [self riotRoomAvatarURLFromRoomState:summary.room.state];
|
||||
|
||||
if (riotRoomAvatarURL.length && ![summary.avatar isEqualToString:riotRoomAvatarURL])
|
||||
{
|
||||
summary.avatar = riotRoomAvatarURL;
|
||||
ret = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,11 +62,6 @@ extern UIStatusBarStyle kRiotDesignStatusBarStyle;
|
|||
extern UIBarStyle kRiotDesignSearchBarStyle;
|
||||
extern UIColor *kRiotDesignSearchBarTintColor;
|
||||
|
||||
// Flag to enable the display of jitsi conference widget
|
||||
// TODO: Disable it before release
|
||||
// TODO: Remove it once Riot web and android are ready
|
||||
#define USE_JITSI_WIDGET
|
||||
|
||||
/**
|
||||
`RiotDesignValues` class manages the Riot design parameters
|
||||
*/
|
||||
|
|
|
@ -96,6 +96,9 @@
|
|||
[_sendButton setTitle:NSLocalizedStringFromTable(@"bug_report_send", @"Vector", nil) forState:UIControlStateNormal];
|
||||
[_sendButton setTitle:NSLocalizedStringFromTable(@"bug_report_send", @"Vector", nil) forState:UIControlStateHighlighted];
|
||||
|
||||
// Do not send empty report
|
||||
_sendButton.enabled = NO;;
|
||||
|
||||
_sendingContainer.hidden = YES;
|
||||
|
||||
self.sendLogs = YES;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#import "AppDelegate.h"
|
||||
|
||||
#import "MXRoom+Riot.h"
|
||||
#import "MXSession+Riot.h"
|
||||
|
||||
@interface MasterTabBarController ()
|
||||
{
|
||||
|
@ -454,26 +455,7 @@
|
|||
// Considering all the current sessions.
|
||||
for (MXSession *session in mxSessionArray)
|
||||
{
|
||||
// Sum all the rooms with missed notifications.
|
||||
for (MXRoomSummary *roomSummary in session.roomsSummaries)
|
||||
{
|
||||
NSUInteger notificationCount = roomSummary.notificationCount;
|
||||
|
||||
// Ignore the regular notification count if the room is in 'mentions only" mode at the Riot level.
|
||||
if (roomSummary.room.isMentionsOnly)
|
||||
{
|
||||
// Only the highlighted missed messages must be considered here.
|
||||
notificationCount = roomSummary.highlightCount;
|
||||
}
|
||||
|
||||
if (notificationCount)
|
||||
{
|
||||
roomCount ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the invites count
|
||||
roomCount += [session invitedRooms].count;
|
||||
roomCount += [session riot_missedDiscussionsCount];
|
||||
}
|
||||
|
||||
return roomCount;
|
||||
|
|
|
@ -1945,6 +1945,34 @@
|
|||
selectedComponent = nil;
|
||||
}
|
||||
|
||||
if (level == 0)
|
||||
{
|
||||
// Check status of the selected event
|
||||
if (selectedEvent.sentState == MXEventSentStatePreparing ||
|
||||
selectedEvent.sentState == MXEventSentStateEncrypting ||
|
||||
selectedEvent.sentState == MXEventSentStateSending)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_send", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
if (weakSelf)
|
||||
{
|
||||
typeof(self) self = weakSelf;
|
||||
|
||||
self->currentAlert = nil;
|
||||
|
||||
// Cancel and remove the outgoing message
|
||||
[self.roomDataSource.room cancelSendingOperation:selectedEvent.eventId];
|
||||
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
|
||||
|
||||
[self cancelEventSelection];
|
||||
}
|
||||
|
||||
}]];
|
||||
}
|
||||
}
|
||||
|
||||
if (level == 0)
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_copy", @"Vector", nil)
|
||||
|
@ -2087,18 +2115,17 @@
|
|||
// Check status of the selected event
|
||||
if (selectedEvent.sentState == MXEventSentStatePreparing ||
|
||||
selectedEvent.sentState == MXEventSentStateEncrypting ||
|
||||
selectedEvent.sentState == MXEventSentStateUploading)
|
||||
selectedEvent.sentState == MXEventSentStateUploading ||
|
||||
selectedEvent.sentState == MXEventSentStateSending)
|
||||
{
|
||||
// Upload id is stored in attachment url (nasty trick)
|
||||
NSString *uploadId = roomBubbleTableViewCell.bubbleData.attachment.actualURL;
|
||||
if ([MXMediaManager existingUploaderWithId:uploadId])
|
||||
{
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_upload", @"Vector", nil)
|
||||
[currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"room_event_action_cancel_send", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
// TODO cancel the attachment encryption if it is in progress.
|
||||
|
||||
|
||||
// Get again the loader
|
||||
MXMediaLoader *loader = [MXMediaManager existingUploaderWithId:uploadId];
|
||||
if (loader)
|
||||
|
@ -2117,6 +2144,9 @@
|
|||
// Remove the outgoing message and its related cached file.
|
||||
[[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.cacheFilePath error:nil];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:roomBubbleTableViewCell.bubbleData.attachment.cacheThumbnailPath error:nil];
|
||||
|
||||
// Cancel and remove the outgoing message
|
||||
[self.roomDataSource.room cancelSendingOperation:selectedEvent.eventId];
|
||||
[self.roomDataSource removeEventWithEventId:selectedEvent.eventId];
|
||||
|
||||
[self cancelEventSelection];
|
||||
|
@ -2738,7 +2768,6 @@
|
|||
{
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
|
||||
#ifdef USE_JITSI_WIDGET
|
||||
// If there is already a jitsi widget, join it
|
||||
Widget *jitsiWidget = [customizedRoomDataSource jitsiWidget];
|
||||
if (jitsiWidget)
|
||||
|
@ -2775,11 +2804,8 @@
|
|||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
// Classic conference call is not supported in encrypted rooms
|
||||
if (self.roomDataSource.room.state.isEncrypted && self.roomDataSource.room.state.joinedMembers.count > 2)
|
||||
else if (self.roomDataSource.room.state.isEncrypted && self.roomDataSource.room.state.joinedMembers.count > 2)
|
||||
{
|
||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||
|
||||
|
@ -3540,7 +3566,6 @@
|
|||
} onClosePressed:nil];
|
||||
}
|
||||
}
|
||||
#ifdef USE_JITSI_WIDGET
|
||||
else if (jitsiWidget)
|
||||
{
|
||||
// The room has an active jitsi widget
|
||||
|
@ -3610,7 +3635,6 @@
|
|||
}];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if ([self checkUnsentMessages] == NO)
|
||||
{
|
||||
// Show "scroll to bottom" icon when the most recent message is not visible,
|
||||
|
|
|
@ -17,13 +17,14 @@
|
|||
|
||||
#import "SettingsViewController.h"
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import <Photos/Photos.h>
|
||||
#import <MatrixSDK/MXCallKitAdapter.h>
|
||||
#import <MediaPlayer/MediaPlayer.h>
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
#import <OLMKit/OLMKit.h>
|
||||
#import <Photos/Photos.h>
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import "MXKEncryptionKeysExportView.h"
|
||||
#import "BugReportViewController.h"
|
||||
|
@ -32,17 +33,14 @@
|
|||
|
||||
#import "CountryPickerViewController.h"
|
||||
#import "LanguagePickerViewController.h"
|
||||
#import "TableViewCellWithPhoneNumberTextField.h"
|
||||
|
||||
#import "NBPhoneNumberUtil.h"
|
||||
|
||||
#import "AvatarGenerator.h"
|
||||
|
||||
#import "OLMKit/OLMKit.h"
|
||||
#import "RageShakeManager.h"
|
||||
#import "RiotDesignValues.h"
|
||||
#import "TableViewCellWithPhoneNumberTextField.h"
|
||||
|
||||
#import "GBDeviceInfo_iOS.h"
|
||||
|
||||
|
||||
NSString* const kSettingsViewControllerPhoneBookCountryCellId = @"kSettingsViewControllerPhoneBookCountryCellId";
|
||||
|
||||
enum
|
||||
|
@ -50,6 +48,7 @@ enum
|
|||
SETTINGS_SECTION_SIGN_OUT_INDEX = 0,
|
||||
SETTINGS_SECTION_USER_SETTINGS_INDEX,
|
||||
SETTINGS_SECTION_NOTIFICATIONS_SETTINGS_INDEX,
|
||||
SETTINGS_SECTION_CALLS_INDEX,
|
||||
SETTINGS_SECTION_USER_INTERFACE_INDEX,
|
||||
SETTINGS_SECTION_IGNORED_USERS_INDEX,
|
||||
SETTINGS_SECTION_CONTACTS_INDEX,
|
||||
|
@ -64,6 +63,7 @@ enum
|
|||
enum
|
||||
{
|
||||
NOTIFICATION_SETTINGS_ENABLE_PUSH_INDEX = 0,
|
||||
NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT,
|
||||
NOTIFICATION_SETTINGS_GLOBAL_SETTINGS_INDEX,
|
||||
NOTIFICATION_SETTINGS_PIN_MISSED_NOTIFICATIONS_INDEX,
|
||||
NOTIFICATION_SETTINGS_PIN_UNREAD_INDEX,
|
||||
|
@ -76,6 +76,13 @@ enum
|
|||
NOTIFICATION_SETTINGS_COUNT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CALLS_ENABLE_CALLKIT_INDEX = 0,
|
||||
CALLS_DESCRIPTION_INDEX,
|
||||
CALLS_COUNT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
USER_INTERFACE_LANGUAGE_INDEX = 0,
|
||||
|
@ -92,6 +99,7 @@ enum
|
|||
OTHER_PRIVACY_INDEX,
|
||||
OTHER_THIRD_PARTY_INDEX,
|
||||
OTHER_CRASH_REPORT_INDEX,
|
||||
OTHER_ENABLE_RAGESHAKE_INDEX,
|
||||
OTHER_MARK_ALL_AS_READ_INDEX,
|
||||
OTHER_CLEAR_CACHE_INDEX,
|
||||
OTHER_REPORT_BUG_INDEX,
|
||||
|
@ -101,9 +109,7 @@ enum
|
|||
enum
|
||||
{
|
||||
LABS_MATRIX_APPS_INDEX = 0,
|
||||
#ifdef USE_JITSI_WIDGET
|
||||
LABS_USE_JITSI_WIDGET_INDEX,
|
||||
#endif
|
||||
LABS_CRYPTO_INDEX,
|
||||
LABS_COUNT
|
||||
};
|
||||
|
@ -128,7 +134,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
// listener
|
||||
id removedAccountObserver;
|
||||
id accountUserInfoObserver;
|
||||
id apnsInfoUpdateObserver;
|
||||
id pushInfoUpdateObserver;
|
||||
|
||||
id notificationCenterWillUpdateObserver;
|
||||
id notificationCenterDidUpdateObserver;
|
||||
|
@ -274,8 +280,8 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
|
||||
}];
|
||||
|
||||
// Add observer to apns
|
||||
apnsInfoUpdateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountAPNSActivityDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
// Add observer to push settings
|
||||
pushInfoUpdateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountPushKitActivityDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
[self stopActivityIndicator];
|
||||
|
||||
|
@ -524,10 +530,10 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
accountUserInfoObserver = nil;
|
||||
}
|
||||
|
||||
if (apnsInfoUpdateObserver)
|
||||
if (pushInfoUpdateObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:apnsInfoUpdateObserver];
|
||||
apnsInfoUpdateObserver = nil;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:pushInfoUpdateObserver];
|
||||
pushInfoUpdateObserver = nil;
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
@ -1176,6 +1182,13 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
{
|
||||
count = NOTIFICATION_SETTINGS_COUNT;
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if ([MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
count = CALLS_COUNT;
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_USER_INTERFACE_INDEX)
|
||||
{
|
||||
count = USER_INTERFACE_COUNT;
|
||||
|
@ -1617,13 +1630,25 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
|
||||
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_enable_push_notif", @"Vector", nil);
|
||||
labelAndSwitchCell.mxkSwitch.on = account.pushNotificationServiceIsActive;
|
||||
labelAndSwitchCell.mxkSwitch.on = account.isPushKitNotificationActive;
|
||||
labelAndSwitchCell.mxkSwitch.enabled = YES;
|
||||
[labelAndSwitchCell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(togglePushNotifications:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else if (row == NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT)
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
|
||||
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_show_decrypted_content", @"Vector", nil);
|
||||
labelAndSwitchCell.mxkSwitch.on = account.showDecryptedContentInNotifications;
|
||||
labelAndSwitchCell.mxkSwitch.enabled = account.isPushKitNotificationActive;
|
||||
[labelAndSwitchCell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleShowDecodedContent:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else if (row == NOTIFICATION_SETTINGS_GLOBAL_SETTINGS_INDEX)
|
||||
{
|
||||
MXKTableViewCell *globalInfoCell = [self getDefaultTableViewCell:tableView];
|
||||
|
@ -1662,6 +1687,29 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
cell = labelAndSwitchCell;
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if (row == CALLS_ENABLE_CALLKIT_INDEX)
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_enable_callkit", @"Vector", nil);
|
||||
labelAndSwitchCell.mxkSwitch.on = [MXKAppSettings standardAppSettings].isCallKitEnabled;
|
||||
labelAndSwitchCell.mxkSwitch.enabled = YES;
|
||||
[labelAndSwitchCell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
[labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleCallKit:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else if (row == CALLS_DESCRIPTION_INDEX)
|
||||
{
|
||||
MXKTableViewCell *globalInfoCell = [self getDefaultTableViewCell:tableView];
|
||||
globalInfoCell.textLabel.text = NSLocalizedStringFromTable(@"settings_callkit_info", @"Vector", nil);
|
||||
globalInfoCell.textLabel.numberOfLines = 0;
|
||||
globalInfoCell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
cell = globalInfoCell;
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_USER_INTERFACE_INDEX)
|
||||
{
|
||||
if (row == USER_INTERFACE_LANGUAGE_INDEX)
|
||||
|
@ -1867,6 +1915,18 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
|
||||
cell = sendCrashReportCell;
|
||||
}
|
||||
else if (row == OTHER_ENABLE_RAGESHAKE_INDEX)
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch* enableRageShakeCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
|
||||
enableRageShakeCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_enable_rageshake", @"Vector", nil);
|
||||
enableRageShakeCell.mxkSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:@"enableRageShake"];
|
||||
enableRageShakeCell.mxkSwitch.enabled = YES;
|
||||
[enableRageShakeCell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside];
|
||||
[enableRageShakeCell.mxkSwitch addTarget:self action:@selector(toggleEnableRageShake:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
cell = enableRageShakeCell;
|
||||
}
|
||||
else if (row == OTHER_MARK_ALL_AS_READ_INDEX)
|
||||
{
|
||||
MXKTableViewCellWithButton *markAllBtnCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithButton defaultReuseIdentifier]];
|
||||
|
@ -1957,7 +2017,6 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
#ifdef USE_JITSI_WIDGET
|
||||
else if (row == LABS_USE_JITSI_WIDGET_INDEX)
|
||||
{
|
||||
MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath];
|
||||
|
@ -1970,9 +2029,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
|
||||
cell = labelAndSwitchCell;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (row == LABS_CRYPTO_INDEX)
|
||||
else if (row == LABS_CRYPTO_INDEX)
|
||||
{
|
||||
MXSession* session = [[AppDelegate theDelegate].mxSessions objectAtIndex:0];
|
||||
|
||||
|
@ -2077,6 +2134,13 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
{
|
||||
return NSLocalizedStringFromTable(@"settings_notifications_settings", @"Vector", nil);
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if ([MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
return NSLocalizedStringFromTable(@"settings_calls_settings", @"Vector", nil);
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_USER_INTERFACE_INDEX)
|
||||
{
|
||||
return NSLocalizedStringFromTable(@"settings_user_interface", @"Vector", nil);
|
||||
|
@ -2201,6 +2265,13 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if (![MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
return SECTION_TITLE_PADDING_WHEN_HIDDEN;
|
||||
}
|
||||
}
|
||||
|
||||
return 24;
|
||||
}
|
||||
|
@ -2219,6 +2290,13 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (section == SETTINGS_SECTION_CALLS_INDEX)
|
||||
{
|
||||
if (![MXCallKitAdapter callKitAvailable])
|
||||
{
|
||||
return SECTION_TITLE_PADDING_WHEN_HIDDEN;
|
||||
}
|
||||
}
|
||||
|
||||
return 24;
|
||||
}
|
||||
|
@ -2648,9 +2726,9 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
MXKAccountManager *accountManager = [MXKAccountManager sharedManager];
|
||||
MXKAccount* account = accountManager.activeAccounts.firstObject;
|
||||
|
||||
if (accountManager.apnsDeviceToken)
|
||||
if (accountManager.pushDeviceToken)
|
||||
{
|
||||
[account setEnablePushNotifications:!account.pushNotificationServiceIsActive];
|
||||
[account setEnablePushKitNotifications:!account.isPushKitNotificationActive];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2663,13 +2741,25 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
}
|
||||
else
|
||||
{
|
||||
[account setEnablePushNotifications:YES];
|
||||
[account setEnablePushKitNotifications:YES];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)toggleCallKit:(id)sender
|
||||
{
|
||||
UISwitch *switchButton = (UISwitch*)sender;
|
||||
[MXKAppSettings standardAppSettings].enableCallKit = switchButton.isOn;
|
||||
}
|
||||
|
||||
- (void)toggleShowDecodedContent:(id)sender
|
||||
{
|
||||
MXKAccount* account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
|
||||
account.showDecryptedContentInNotifications = !account.showDecryptedContentInNotifications;
|
||||
}
|
||||
|
||||
- (void)toggleLocalContactsSync:(id)sender
|
||||
{
|
||||
UISwitch *switchButton = (UISwitch*)sender;
|
||||
|
@ -2715,6 +2805,19 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)();
|
|||
}
|
||||
}
|
||||
|
||||
- (void)toggleEnableRageShake:(id)sender
|
||||
{
|
||||
if (sender && [sender isKindOfClass:UISwitch.class])
|
||||
{
|
||||
UISwitch *switchButton = (UISwitch*)sender;
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setBool:switchButton.isOn forKey:@"enableRageShake"];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)toggleLabsMatrixApps:(id)sender
|
||||
{
|
||||
if (sender && [sender isKindOfClass:UISwitch.class])
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.5.3</string>
|
||||
<string>0.5.6</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
|
@ -29,13 +29,13 @@
|
|||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>0</integer>
|
||||
<integer>5</integer>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<false/>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
|
|
41
SiriIntents/Info.plist
Normal file
41
SiriIntents/Info.plist
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>SiriIntents</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>IntentsRestrictedWhileLocked</key>
|
||||
<array/>
|
||||
<key>IntentsSupported</key>
|
||||
<array>
|
||||
<string>INStartAudioCallIntent</string>
|
||||
<string>INStartVideoCallIntent</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.intents-service</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>IntentHandler</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
21
SiriIntents/IntentHandler.h
Normal file
21
SiriIntents/IntentHandler.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
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 <Intents/Intents.h>
|
||||
|
||||
@interface IntentHandler : INExtension
|
||||
|
||||
@end
|
302
SiriIntents/IntentHandler.m
Normal file
302
SiriIntents/IntentHandler.m
Normal file
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
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 "IntentHandler.h"
|
||||
|
||||
#import "MXKAccount.h"
|
||||
#import "MXKAccountManager.h"
|
||||
#import "MXFileStore.h"
|
||||
#import "MXSession.h"
|
||||
|
||||
@interface IntentHandler () <INStartAudioCallIntentHandling, INStartVideoCallIntentHandling>
|
||||
|
||||
@end
|
||||
|
||||
@implementation IntentHandler
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
[MXSDKOptions sharedInstance].applicationGroupIdentifier = @"group.im.vector";
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)handlerForIntent:(INIntent *)intent
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - INStartAudioCallIntentHandling
|
||||
|
||||
- (void)resolveContactsForStartAudioCall:(INStartAudioCallIntent *)intent withCompletion:(void (^)(NSArray<INPersonResolutionResult *> * _Nonnull))completion
|
||||
{
|
||||
[self resolveContacts:intent.contacts withCompletion:completion];
|
||||
}
|
||||
|
||||
- (void)confirmStartAudioCall:(INStartAudioCallIntent *)intent completion:(void (^)(INStartAudioCallIntentResponse * _Nonnull))completion
|
||||
{
|
||||
INStartAudioCallIntentResponse *response = nil;
|
||||
|
||||
MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
|
||||
if (account)
|
||||
{
|
||||
#if defined MX_CALL_STACK_OPENWEBRTC || defined MX_CALL_STACK_ENDPOINT || defined MX_CALL_STACK_JINGLE
|
||||
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartAudioCallIntent.class)];
|
||||
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeReady userActivity:userActivity];
|
||||
#else
|
||||
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeFailureCallingServiceNotAvailable userActivity:nil];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// User hasn't logged in
|
||||
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeFailureAppConfigurationRequired userActivity:nil];
|
||||
}
|
||||
|
||||
completion(response);
|
||||
}
|
||||
|
||||
- (void)handleStartAudioCall:(INStartAudioCallIntent *)intent completion:(void (^)(INStartAudioCallIntentResponse * _Nonnull))completion
|
||||
{
|
||||
INStartAudioCallIntentResponse *response = nil;
|
||||
|
||||
INPerson *person = intent.contacts.firstObject;
|
||||
if (person && person.customIdentifier)
|
||||
{
|
||||
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartAudioCallIntent.class)];
|
||||
userActivity.userInfo = @{ @"roomID" : person.customIdentifier };
|
||||
|
||||
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeContinueInApp
|
||||
userActivity:userActivity];
|
||||
}
|
||||
else
|
||||
{
|
||||
response = [[INStartAudioCallIntentResponse alloc] initWithCode:INStartAudioCallIntentResponseCodeFailure userActivity:nil];
|
||||
}
|
||||
|
||||
completion(response);
|
||||
}
|
||||
|
||||
#pragma mark - INStartVideoCallIntentHandling
|
||||
|
||||
- (void)resolveContactsForStartVideoCall:(INStartVideoCallIntent *)intent withCompletion:(void (^)(NSArray<INPersonResolutionResult *> * _Nonnull))completion
|
||||
{
|
||||
[self resolveContacts:intent.contacts withCompletion:completion];
|
||||
}
|
||||
|
||||
- (void)confirmStartVideoCall:(INStartVideoCallIntent *)intent completion:(void (^)(INStartVideoCallIntentResponse * _Nonnull))completion
|
||||
{
|
||||
INStartVideoCallIntentResponse *response = nil;
|
||||
|
||||
MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
|
||||
if (account)
|
||||
{
|
||||
#if defined MX_CALL_STACK_OPENWEBRTC || defined MX_CALL_STACK_ENDPOINT || defined MX_CALL_STACK_JINGLE
|
||||
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartVideoCallIntent.class)];
|
||||
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeReady userActivity:userActivity];
|
||||
#else
|
||||
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeFailureCallingServiceNotAvailable userActivity:nil];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// User hasn't logged in
|
||||
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeFailureRequiringAppLaunch userActivity:nil];
|
||||
}
|
||||
|
||||
completion(response);
|
||||
}
|
||||
|
||||
- (void)handleStartVideoCall:(INStartVideoCallIntent *)intent completion:(void (^)(INStartVideoCallIntentResponse * _Nonnull))completion
|
||||
{
|
||||
INStartVideoCallIntentResponse *response = nil;
|
||||
|
||||
INPerson *person = intent.contacts.firstObject;
|
||||
if (person && person.customIdentifier)
|
||||
{
|
||||
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass(INStartVideoCallIntent.class)];
|
||||
userActivity.userInfo = @{ @"roomID" : person.customIdentifier };
|
||||
|
||||
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeContinueInApp
|
||||
userActivity:userActivity];
|
||||
}
|
||||
else
|
||||
{
|
||||
response = [[INStartVideoCallIntentResponse alloc] initWithCode:INStartVideoCallIntentResponseCodeFailure userActivity:nil];
|
||||
}
|
||||
|
||||
completion(response);
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)resolveContacts:(nullable NSArray<INPerson *> *)contacts withCompletion:(void (^)(NSArray<INPersonResolutionResult *> * _Nonnull))completion
|
||||
{
|
||||
if (contacts.count == 0)
|
||||
{
|
||||
completion(@[[INPersonResolutionResult needsValue]]);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't iterate over array of contacts from passed intent
|
||||
// since it's hard to imagine scenario with several callee
|
||||
// so we just extract the first one
|
||||
INPerson *callee = contacts.firstObject;
|
||||
|
||||
// If this method is called after selection of the appropriate user, it will hold userId of an user to whom we must call
|
||||
NSString *selectedUserId;
|
||||
|
||||
// Check if the user has selected right room among several direct rooms from previous resolution process run
|
||||
if (callee.customIdentifier.length)
|
||||
{
|
||||
// If callee will have the same name as one of the contact in the system contacts app
|
||||
// Siri will pass us this contact in the intent.contacts array and we must provide the same count of
|
||||
// resolution results as elements count in the intent.contact.
|
||||
// So we just pass the same result at all iterations
|
||||
NSMutableArray *resolutionResults = [NSMutableArray array];
|
||||
for (NSInteger i = 0; i < contacts.count; ++i)
|
||||
[resolutionResults addObject:[INPersonResolutionResult successWithResolvedPerson:callee]];
|
||||
completion(resolutionResults);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This resolution process run after selecting appropriate user among suggested user list
|
||||
selectedUserId = callee.personHandle.value;
|
||||
}
|
||||
|
||||
MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject;
|
||||
if (account)
|
||||
{
|
||||
MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials];
|
||||
[fileStore asyncRoomsSummaries:^(NSArray<MXRoomSummary *> * _Nonnull roomsSummaries) {
|
||||
|
||||
// Contains userIds of all users with whom the current user has direct chats
|
||||
// Use set to avoid duplicates
|
||||
NSMutableSet<NSString *> *directUserIds = [NSMutableSet set];
|
||||
|
||||
// Contains room summaries for all direct rooms connected with particular userId
|
||||
NSMutableDictionary<NSString *, NSMutableArray<MXRoomSummary *> *> *roomSummaries = [NSMutableDictionary dictionary];
|
||||
|
||||
for (MXRoomSummary *summary in roomsSummaries)
|
||||
{
|
||||
// TODO: We also need to check if joined room members count equals 2
|
||||
// It is pointlessly to save rooms with 1 joined member or room with more than 2 joined members
|
||||
if (summary.isDirect)
|
||||
{
|
||||
NSString *diretUserId = summary.directUserId;
|
||||
|
||||
// Collect room summaries only for specified user
|
||||
if (selectedUserId && ![diretUserId isEqualToString:selectedUserId])
|
||||
continue;
|
||||
|
||||
// Save userId
|
||||
[directUserIds addObject:diretUserId];
|
||||
|
||||
// Save associated with diretUserId room summary
|
||||
NSMutableArray<MXRoomSummary *> *userRoomSummaries = roomSummaries[diretUserId];
|
||||
if (userRoomSummaries)
|
||||
[userRoomSummaries addObject:summary];
|
||||
else
|
||||
roomSummaries[diretUserId] = [NSMutableArray arrayWithObject:summary];
|
||||
}
|
||||
}
|
||||
|
||||
[fileStore asyncUsersWithUserIds:directUserIds.allObjects success:^(NSArray<MXUser *> * _Nonnull users) {
|
||||
|
||||
// Find users whose display name contains string presented us by Siri
|
||||
NSMutableArray<MXUser *> *matchingUsers = [NSMutableArray array];
|
||||
for (MXUser *user in users)
|
||||
{
|
||||
if (!user.displayname)
|
||||
continue;
|
||||
|
||||
if (!NSEqualRanges([callee.displayName rangeOfString:user.displayname options:NSCaseInsensitiveSearch], (NSRange){NSNotFound,0}))
|
||||
{
|
||||
[matchingUsers addObject:user];
|
||||
}
|
||||
}
|
||||
|
||||
NSMutableArray<INPerson *> *persons = [NSMutableArray array];
|
||||
|
||||
if (matchingUsers.count == 1)
|
||||
{
|
||||
MXUser *user = matchingUsers.firstObject;
|
||||
|
||||
// Provide to the user a list of direct rooms to choose from
|
||||
NSArray<MXRoomSummary *> *summaries = roomSummaries[user.userId];
|
||||
for (MXRoomSummary *summary in summaries)
|
||||
{
|
||||
INPersonHandle *personHandle = [[INPersonHandle alloc] initWithValue:user.userId type:INPersonHandleTypeUnknown];
|
||||
|
||||
// For rooms we try to use room display name
|
||||
NSString *displayName = summary.displayname ? summary.displayname : user.displayname;
|
||||
|
||||
INPerson *person = [[INPerson alloc] initWithPersonHandle:personHandle
|
||||
nameComponents:nil
|
||||
displayName:displayName
|
||||
image:nil
|
||||
contactIdentifier:nil
|
||||
customIdentifier:summary.roomId];
|
||||
|
||||
[persons addObject:person];
|
||||
}
|
||||
}
|
||||
else if (matchingUsers.count > 1)
|
||||
{
|
||||
// Provide to the user a list of users to choose from
|
||||
// This is the case when there are several users with the same name
|
||||
for (MXUser *user in matchingUsers)
|
||||
{
|
||||
INPersonHandle *personHandle = [[INPersonHandle alloc] initWithValue:user.userId type:INPersonHandleTypeUnknown];
|
||||
INPerson *person = [[INPerson alloc] initWithPersonHandle:personHandle
|
||||
nameComponents:nil
|
||||
displayName:user.displayname
|
||||
image:nil
|
||||
contactIdentifier:nil
|
||||
customIdentifier:nil];
|
||||
|
||||
[persons addObject:person];
|
||||
}
|
||||
}
|
||||
|
||||
if (persons.count == 0)
|
||||
{
|
||||
completion(@[[INPersonResolutionResult unsupported]]);
|
||||
}
|
||||
else if (persons.count == 1)
|
||||
{
|
||||
completion(@[[INPersonResolutionResult successWithResolvedPerson:persons.firstObject]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
completion(@[[INPersonResolutionResult disambiguationWithPeopleToDisambiguate:persons]]);
|
||||
}
|
||||
} failure:nil];
|
||||
} failure:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
completion(@[[INPersonResolutionResult notRequired]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
10
SiriIntents/SiriIntents.entitlements
Normal file
10
SiriIntents/SiriIntents.entitlements
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.im.vector</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
Loading…
Reference in a new issue