mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-30 08:12:40 +00:00
Merge branch 'release/v0.11.3'
This commit is contained in:
commit
fd8ebb29d4
55 changed files with 1510 additions and 192 deletions
13
CHANGES.rst
13
CHANGES.rst
|
@ -1,3 +1,16 @@
|
||||||
|
Changes in 0.11.3 (2020-05-07)
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
* Upgrade MatrixKit version ([v0.12.3](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.12.3)).
|
||||||
|
* Cross-signing: Display "Verify your other sessions" modal at every startup if needed (#3180).
|
||||||
|
* Cross-signing: The "Complete Security" button now triggers a verification request to all user devices.
|
||||||
|
* Secrets: On startup, request again private keys we are missing locally.
|
||||||
|
|
||||||
|
Bug fix:
|
||||||
|
* KeyVerificationSelfVerifyStartViewController has no navigation (#3195).
|
||||||
|
* Self-verification: QR code scanning screen refers to other-person scanning (#3189).
|
||||||
|
|
||||||
Changes in 0.11.2 (2020-05-01)
|
Changes in 0.11.2 (2020-05-01)
|
||||||
===============================================
|
===============================================
|
||||||
|
|
||||||
|
|
2
Podfile
2
Podfile
|
@ -7,7 +7,7 @@ use_frameworks!
|
||||||
|
|
||||||
# Different flavours of pods to MatrixKit
|
# Different flavours of pods to MatrixKit
|
||||||
# The current MatrixKit pod version
|
# The current MatrixKit pod version
|
||||||
$matrixKitVersion = '0.12.2'
|
$matrixKitVersion = '0.12.3'
|
||||||
|
|
||||||
# The develop branch version
|
# The develop branch version
|
||||||
#$matrixKitVersion = 'develop'
|
#$matrixKitVersion = 'develop'
|
||||||
|
|
34
Podfile.lock
34
Podfile.lock
|
@ -50,38 +50,38 @@ PODS:
|
||||||
- MatomoTracker (7.2.0):
|
- MatomoTracker (7.2.0):
|
||||||
- MatomoTracker/Core (= 7.2.0)
|
- MatomoTracker/Core (= 7.2.0)
|
||||||
- MatomoTracker/Core (7.2.0)
|
- MatomoTracker/Core (7.2.0)
|
||||||
- MatrixKit (0.12.2):
|
- MatrixKit (0.12.3):
|
||||||
- cmark (~> 0.24.1)
|
- cmark (~> 0.24.1)
|
||||||
- DTCoreText (~> 1.6.21)
|
- DTCoreText (~> 1.6.21)
|
||||||
- HPGrowingTextView (~> 1.1)
|
- HPGrowingTextView (~> 1.1)
|
||||||
- libPhoneNumber-iOS (~> 0.9.13)
|
- libPhoneNumber-iOS (~> 0.9.13)
|
||||||
- MatrixKit/Core (= 0.12.2)
|
- MatrixKit/Core (= 0.12.3)
|
||||||
- MatrixSDK (= 0.16.2)
|
- MatrixSDK (= 0.16.3)
|
||||||
- MatrixKit/AppExtension (0.12.2):
|
- MatrixKit/AppExtension (0.12.3):
|
||||||
- cmark (~> 0.24.1)
|
- cmark (~> 0.24.1)
|
||||||
- DTCoreText (~> 1.6.21)
|
- DTCoreText (~> 1.6.21)
|
||||||
- DTCoreText/Extension
|
- DTCoreText/Extension
|
||||||
- HPGrowingTextView (~> 1.1)
|
- HPGrowingTextView (~> 1.1)
|
||||||
- libPhoneNumber-iOS (~> 0.9.13)
|
- libPhoneNumber-iOS (~> 0.9.13)
|
||||||
- MatrixSDK (= 0.16.2)
|
- MatrixSDK (= 0.16.3)
|
||||||
- MatrixKit/Core (0.12.2):
|
- MatrixKit/Core (0.12.3):
|
||||||
- cmark (~> 0.24.1)
|
- cmark (~> 0.24.1)
|
||||||
- DTCoreText (~> 1.6.21)
|
- DTCoreText (~> 1.6.21)
|
||||||
- HPGrowingTextView (~> 1.1)
|
- HPGrowingTextView (~> 1.1)
|
||||||
- libPhoneNumber-iOS (~> 0.9.13)
|
- libPhoneNumber-iOS (~> 0.9.13)
|
||||||
- MatrixSDK (= 0.16.2)
|
- MatrixSDK (= 0.16.3)
|
||||||
- MatrixSDK (0.16.2):
|
- MatrixSDK (0.16.3):
|
||||||
- MatrixSDK/Core (= 0.16.2)
|
- MatrixSDK/Core (= 0.16.3)
|
||||||
- MatrixSDK/Core (0.16.2):
|
- MatrixSDK/Core (0.16.3):
|
||||||
- AFNetworking (~> 3.2.0)
|
- AFNetworking (~> 3.2.0)
|
||||||
- GZIP (~> 1.2.2)
|
- GZIP (~> 1.2.2)
|
||||||
- libbase58 (~> 0.1.4)
|
- libbase58 (~> 0.1.4)
|
||||||
- OLMKit (~> 3.1.0)
|
- OLMKit (~> 3.1.0)
|
||||||
- Realm (~> 3.17.3)
|
- Realm (~> 3.17.3)
|
||||||
- MatrixSDK/JingleCallStack (0.16.2):
|
- MatrixSDK/JingleCallStack (0.16.3):
|
||||||
- JitsiMeetSDK (~> 2.3.1)
|
- JitsiMeetSDK (~> 2.3.1)
|
||||||
- MatrixSDK/Core
|
- MatrixSDK/Core
|
||||||
- MatrixSDK/SwiftSupport (0.16.2):
|
- MatrixSDK/SwiftSupport (0.16.3):
|
||||||
- MatrixSDK/Core
|
- MatrixSDK/Core
|
||||||
- OLMKit (3.1.0):
|
- OLMKit (3.1.0):
|
||||||
- OLMKit/olmc (= 3.1.0)
|
- OLMKit/olmc (= 3.1.0)
|
||||||
|
@ -109,8 +109,8 @@ DEPENDENCIES:
|
||||||
- GBDeviceInfo (~> 6.3.0)
|
- GBDeviceInfo (~> 6.3.0)
|
||||||
- KTCenterFlowLayout (~> 1.3.1)
|
- KTCenterFlowLayout (~> 1.3.1)
|
||||||
- MatomoTracker (~> 7.2.0)
|
- MatomoTracker (~> 7.2.0)
|
||||||
- MatrixKit (= 0.12.2)
|
- MatrixKit (= 0.12.3)
|
||||||
- MatrixKit/AppExtension (= 0.12.2)
|
- MatrixKit/AppExtension (= 0.12.3)
|
||||||
- MatrixSDK/JingleCallStack
|
- MatrixSDK/JingleCallStack
|
||||||
- MatrixSDK/SwiftSupport
|
- MatrixSDK/SwiftSupport
|
||||||
- OLMKit
|
- OLMKit
|
||||||
|
@ -159,8 +159,8 @@ SPEC CHECKSUMS:
|
||||||
libbase58: 7c040313537b8c44b6e2d15586af8e21f7354efd
|
libbase58: 7c040313537b8c44b6e2d15586af8e21f7354efd
|
||||||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||||
MatomoTracker: 6f89e2561083685a360e223fb663e9ccd57c1d1a
|
MatomoTracker: 6f89e2561083685a360e223fb663e9ccd57c1d1a
|
||||||
MatrixKit: 93d2c002db0aa0e0b09bd501313fb16122ff4732
|
MatrixKit: fbf24e0e62878e76ac5e28ed10649b37cbdf5cfc
|
||||||
MatrixSDK: 613dba898bbeb7823034b7b30418d89be263c20d
|
MatrixSDK: e0adc76d921d7a50eb6031ed5c7cf3342c8f3166
|
||||||
OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639
|
OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639
|
||||||
Realm: 5a1d9d47bfc101dd597668b1a8af4288a2557f6d
|
Realm: 5a1d9d47bfc101dd597668b1a8af4288a2557f6d
|
||||||
Reusable: 82be188f29d96dc5eff0db7b2393bcc08d2cdd5b
|
Reusable: 82be188f29d96dc5eff0db7b2393bcc08d2cdd5b
|
||||||
|
@ -169,6 +169,6 @@ SPEC CHECKSUMS:
|
||||||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||||
|
|
||||||
PODFILE CHECKSUM: d3b15ac72eb62dce4f4a61be16d91599412be420
|
PODFILE CHECKSUM: 1775b118460fd52106eea1e61084b3afb948de7f
|
||||||
|
|
||||||
COCOAPODS: 1.9.1
|
COCOAPODS: 1.9.1
|
||||||
|
|
|
@ -210,6 +210,14 @@
|
||||||
B140B4A821F8AB4600E3F5FE /* KeyBackupRecoverCoordinatorBridgePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B140B4A721F8AB4600E3F5FE /* KeyBackupRecoverCoordinatorBridgePresenter.swift */; };
|
B140B4A821F8AB4600E3F5FE /* KeyBackupRecoverCoordinatorBridgePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B140B4A721F8AB4600E3F5FE /* KeyBackupRecoverCoordinatorBridgePresenter.swift */; };
|
||||||
B142317A22CCFA2000FFA96A /* EditHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B142317822CCFA2000FFA96A /* EditHistoryCell.swift */; };
|
B142317A22CCFA2000FFA96A /* EditHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B142317822CCFA2000FFA96A /* EditHistoryCell.swift */; };
|
||||||
B142317B22CCFA2000FFA96A /* EditHistoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B142317922CCFA2000FFA96A /* EditHistoryCell.xib */; };
|
B142317B22CCFA2000FFA96A /* EditHistoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = B142317922CCFA2000FFA96A /* EditHistoryCell.xib */; };
|
||||||
|
B14B17602462C69000C2751E /* KeyVerificationManuallyVerifyViewAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B17582462C68F00C2751E /* KeyVerificationManuallyVerifyViewAction.swift */; };
|
||||||
|
B14B17612462C69000C2751E /* KeyVerificationManuallyVerifyCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B17592462C68F00C2751E /* KeyVerificationManuallyVerifyCoordinator.swift */; };
|
||||||
|
B14B17622462C69000C2751E /* KeyVerificationManuallyVerifyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B175A2462C68F00C2751E /* KeyVerificationManuallyVerifyViewController.swift */; };
|
||||||
|
B14B17632462C69000C2751E /* KeyVerificationManuallyVerifyViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B14B175B2462C68F00C2751E /* KeyVerificationManuallyVerifyViewController.storyboard */; };
|
||||||
|
B14B17642462C69000C2751E /* KeyVerificationManuallyVerifyViewModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B175C2462C68F00C2751E /* KeyVerificationManuallyVerifyViewModelType.swift */; };
|
||||||
|
B14B17652462C69000C2751E /* KeyVerificationManuallyVerifyViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B175D2462C68F00C2751E /* KeyVerificationManuallyVerifyViewModel.swift */; };
|
||||||
|
B14B17662462C69000C2751E /* KeyVerificationManuallyVerifyCoordinatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B175E2462C68F00C2751E /* KeyVerificationManuallyVerifyCoordinatorType.swift */; };
|
||||||
|
B14B17672462C69000C2751E /* KeyVerificationManuallyVerifyViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14B175F2462C68F00C2751E /* KeyVerificationManuallyVerifyViewState.swift */; };
|
||||||
B14F142E22144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B14F142622144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewController.storyboard */; };
|
B14F142E22144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B14F142622144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewController.storyboard */; };
|
||||||
B14F142F22144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyViewModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14F142722144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewModelType.swift */; };
|
B14F142F22144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyViewModelType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14F142722144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewModelType.swift */; };
|
||||||
B14F143022144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14F142822144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift */; };
|
B14F143022144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B14F142822144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift */; };
|
||||||
|
@ -1004,6 +1012,14 @@
|
||||||
B140B4A721F8AB4600E3F5FE /* KeyBackupRecoverCoordinatorBridgePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyBackupRecoverCoordinatorBridgePresenter.swift; sourceTree = "<group>"; };
|
B140B4A721F8AB4600E3F5FE /* KeyBackupRecoverCoordinatorBridgePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyBackupRecoverCoordinatorBridgePresenter.swift; sourceTree = "<group>"; };
|
||||||
B142317822CCFA2000FFA96A /* EditHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditHistoryCell.swift; sourceTree = "<group>"; };
|
B142317822CCFA2000FFA96A /* EditHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditHistoryCell.swift; sourceTree = "<group>"; };
|
||||||
B142317922CCFA2000FFA96A /* EditHistoryCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EditHistoryCell.xib; sourceTree = "<group>"; };
|
B142317922CCFA2000FFA96A /* EditHistoryCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EditHistoryCell.xib; sourceTree = "<group>"; };
|
||||||
|
B14B17582462C68F00C2751E /* KeyVerificationManuallyVerifyViewAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationManuallyVerifyViewAction.swift; sourceTree = "<group>"; };
|
||||||
|
B14B17592462C68F00C2751E /* KeyVerificationManuallyVerifyCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationManuallyVerifyCoordinator.swift; sourceTree = "<group>"; };
|
||||||
|
B14B175A2462C68F00C2751E /* KeyVerificationManuallyVerifyViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationManuallyVerifyViewController.swift; sourceTree = "<group>"; };
|
||||||
|
B14B175B2462C68F00C2751E /* KeyVerificationManuallyVerifyViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = KeyVerificationManuallyVerifyViewController.storyboard; sourceTree = "<group>"; };
|
||||||
|
B14B175C2462C68F00C2751E /* KeyVerificationManuallyVerifyViewModelType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationManuallyVerifyViewModelType.swift; sourceTree = "<group>"; };
|
||||||
|
B14B175D2462C68F00C2751E /* KeyVerificationManuallyVerifyViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationManuallyVerifyViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
B14B175E2462C68F00C2751E /* KeyVerificationManuallyVerifyCoordinatorType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationManuallyVerifyCoordinatorType.swift; sourceTree = "<group>"; };
|
||||||
|
B14B175F2462C68F00C2751E /* KeyVerificationManuallyVerifyViewState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationManuallyVerifyViewState.swift; sourceTree = "<group>"; };
|
||||||
B14F142622144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = KeyBackupRecoverFromRecoveryKeyViewController.storyboard; sourceTree = "<group>"; };
|
B14F142622144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewController.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = KeyBackupRecoverFromRecoveryKeyViewController.storyboard; sourceTree = "<group>"; };
|
||||||
B14F142722144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewModelType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyBackupRecoverFromRecoveryKeyViewModelType.swift; sourceTree = "<group>"; };
|
B14F142722144F6400FA0595 /* KeyBackupRecoverFromRecoveryKeyViewModelType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyBackupRecoverFromRecoveryKeyViewModelType.swift; sourceTree = "<group>"; };
|
||||||
B14F142822144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift; sourceTree = "<group>"; };
|
B14F142822144F6500FA0595 /* KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyBackupRecoverFromRecoveryKeyCoordinatorType.swift; sourceTree = "<group>"; };
|
||||||
|
@ -2312,6 +2328,21 @@
|
||||||
path = Start;
|
path = Start;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
B14B17572462C68F00C2751E /* ManuallyVerify */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B14B175E2462C68F00C2751E /* KeyVerificationManuallyVerifyCoordinatorType.swift */,
|
||||||
|
B14B17592462C68F00C2751E /* KeyVerificationManuallyVerifyCoordinator.swift */,
|
||||||
|
B14B17582462C68F00C2751E /* KeyVerificationManuallyVerifyViewAction.swift */,
|
||||||
|
B14B175F2462C68F00C2751E /* KeyVerificationManuallyVerifyViewState.swift */,
|
||||||
|
B14B175C2462C68F00C2751E /* KeyVerificationManuallyVerifyViewModelType.swift */,
|
||||||
|
B14B175D2462C68F00C2751E /* KeyVerificationManuallyVerifyViewModel.swift */,
|
||||||
|
B14B175A2462C68F00C2751E /* KeyVerificationManuallyVerifyViewController.swift */,
|
||||||
|
B14B175B2462C68F00C2751E /* KeyVerificationManuallyVerifyViewController.storyboard */,
|
||||||
|
);
|
||||||
|
path = ManuallyVerify;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B14F142522144F6400FA0595 /* RecoveryKey */ = {
|
B14F142522144F6400FA0595 /* RecoveryKey */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -2780,6 +2811,7 @@
|
||||||
B18DEDAB243372560075FEF7 /* SelfVerifyWait */,
|
B18DEDAB243372560075FEF7 /* SelfVerifyWait */,
|
||||||
324A2046225FC571004FE8B0 /* Incoming */,
|
324A2046225FC571004FE8B0 /* Incoming */,
|
||||||
3232AB96225730E100AD6A5C /* Start */,
|
3232AB96225730E100AD6A5C /* Start */,
|
||||||
|
B14B17572462C68F00C2751E /* ManuallyVerify */,
|
||||||
);
|
);
|
||||||
path = Device;
|
path = Device;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -4704,6 +4736,7 @@
|
||||||
B1B5583D20EF6E7F00210D55 /* GroupRoomTableViewCell.xib in Resources */,
|
B1B5583D20EF6E7F00210D55 /* GroupRoomTableViewCell.xib in Resources */,
|
||||||
B1B5572D20EE6C4D00210D55 /* RoomParticipantsViewController.xib in Resources */,
|
B1B5572D20EE6C4D00210D55 /* RoomParticipantsViewController.xib in Resources */,
|
||||||
32A6001C22C661100042C1D9 /* EditHistoryViewController.storyboard in Resources */,
|
32A6001C22C661100042C1D9 /* EditHistoryViewController.storyboard in Resources */,
|
||||||
|
B14B17632462C69000C2751E /* KeyVerificationManuallyVerifyViewController.storyboard in Resources */,
|
||||||
B1B5577220EE702800210D55 /* JitsiViewController.xib in Resources */,
|
B1B5577220EE702800210D55 /* JitsiViewController.xib in Resources */,
|
||||||
B1B557D720EF5EA900210D55 /* RoomActivitiesView.xib in Resources */,
|
B1B557D720EF5EA900210D55 /* RoomActivitiesView.xib in Resources */,
|
||||||
B1098BF821ECFE65000DDA48 /* KeyBackupSetupPassphraseViewController.storyboard in Resources */,
|
B1098BF821ECFE65000DDA48 /* KeyBackupSetupPassphraseViewController.storyboard in Resources */,
|
||||||
|
@ -5021,6 +5054,7 @@
|
||||||
F083BDEE1E7009ED00A9B29C /* MXRoom+Riot.m in Sources */,
|
F083BDEE1E7009ED00A9B29C /* MXRoom+Riot.m in Sources */,
|
||||||
B120863722EF375F001F89E0 /* ReactionHistoryBridgeCoordinatorPresenter.swift in Sources */,
|
B120863722EF375F001F89E0 /* ReactionHistoryBridgeCoordinatorPresenter.swift in Sources */,
|
||||||
B1B5598620EFC3E000210D55 /* RiotSettings.swift in Sources */,
|
B1B5598620EFC3E000210D55 /* RiotSettings.swift in Sources */,
|
||||||
|
B14B17622462C69000C2751E /* KeyVerificationManuallyVerifyViewController.swift in Sources */,
|
||||||
B1C960F02458308D00C5704B /* RoundedButton.swift in Sources */,
|
B1C960F02458308D00C5704B /* RoundedButton.swift in Sources */,
|
||||||
B1CE83D52422817200D07506 /* KeyVerificationVerifyByScanningViewController.swift in Sources */,
|
B1CE83D52422817200D07506 /* KeyVerificationVerifyByScanningViewController.swift in Sources */,
|
||||||
3232ABA3225730E100AD6A5C /* DeviceVerificationStartCoordinatorType.swift in Sources */,
|
3232ABA3225730E100AD6A5C /* DeviceVerificationStartCoordinatorType.swift in Sources */,
|
||||||
|
@ -5082,6 +5116,8 @@
|
||||||
B125FE1D231D5DE400B72806 /* SettingsDiscoveryViewModel.swift in Sources */,
|
B125FE1D231D5DE400B72806 /* SettingsDiscoveryViewModel.swift in Sources */,
|
||||||
32863A5A2384070300D07C4A /* RiotSharedSettings.swift in Sources */,
|
32863A5A2384070300D07C4A /* RiotSharedSettings.swift in Sources */,
|
||||||
B1B5594720EF7BD000210D55 /* RoomCollectionViewCell.m in Sources */,
|
B1B5594720EF7BD000210D55 /* RoomCollectionViewCell.m in Sources */,
|
||||||
|
B14B17652462C69000C2751E /* KeyVerificationManuallyVerifyViewModel.swift in Sources */,
|
||||||
|
B14B17662462C69000C2751E /* KeyVerificationManuallyVerifyCoordinatorType.swift in Sources */,
|
||||||
B10CFBC32268D99D00A5842E /* JitsiService.swift in Sources */,
|
B10CFBC32268D99D00A5842E /* JitsiService.swift in Sources */,
|
||||||
B1A6C10B23882B6C002882FD /* SlidingModalPresentationAnimator.swift in Sources */,
|
B1A6C10B23882B6C002882FD /* SlidingModalPresentationAnimator.swift in Sources */,
|
||||||
B1B558C120EF768F00210D55 /* RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m in Sources */,
|
B1B558C120EF768F00210D55 /* RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m in Sources */,
|
||||||
|
@ -5310,6 +5346,7 @@
|
||||||
B1B558D020EF768F00210D55 /* RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m in Sources */,
|
B1B558D020EF768F00210D55 /* RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m in Sources */,
|
||||||
B1B558CF20EF768F00210D55 /* RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m in Sources */,
|
B1B558CF20EF768F00210D55 /* RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m in Sources */,
|
||||||
B140B4A221F87F7100E3F5FE /* OperationQueue.swift in Sources */,
|
B140B4A221F87F7100E3F5FE /* OperationQueue.swift in Sources */,
|
||||||
|
B14B17612462C69000C2751E /* KeyVerificationManuallyVerifyCoordinator.swift in Sources */,
|
||||||
B183226C23F59F810035B2E8 /* CloseButton.swift in Sources */,
|
B183226C23F59F810035B2E8 /* CloseButton.swift in Sources */,
|
||||||
B1B5575120EE6C4D00210D55 /* AuthenticationViewController.m in Sources */,
|
B1B5575120EE6C4D00210D55 /* AuthenticationViewController.m in Sources */,
|
||||||
B1CE83BA2422815C00D07506 /* KeyVerificationService.swift in Sources */,
|
B1CE83BA2422815C00D07506 /* KeyVerificationService.swift in Sources */,
|
||||||
|
@ -5411,6 +5448,7 @@
|
||||||
6E6F1CAA244DC1E90068B78B /* SectionHeaderView.m in Sources */,
|
6E6F1CAA244DC1E90068B78B /* SectionHeaderView.m in Sources */,
|
||||||
B1B558EE20EF768F00210D55 /* RoomOutgoingAttachmentBubbleCell.m in Sources */,
|
B1B558EE20EF768F00210D55 /* RoomOutgoingAttachmentBubbleCell.m in Sources */,
|
||||||
32BF994F21FA29A400698084 /* SettingsKeyBackupViewModel.swift in Sources */,
|
32BF994F21FA29A400698084 /* SettingsKeyBackupViewModel.swift in Sources */,
|
||||||
|
B14B17602462C69000C2751E /* KeyVerificationManuallyVerifyViewAction.swift in Sources */,
|
||||||
B190F55D22CE5A9700AEB493 /* EditHistorySection.swift in Sources */,
|
B190F55D22CE5A9700AEB493 /* EditHistorySection.swift in Sources */,
|
||||||
32DB557E22FDADE50016329E /* ServiceTermsModalScreenViewAction.swift in Sources */,
|
32DB557E22FDADE50016329E /* ServiceTermsModalScreenViewAction.swift in Sources */,
|
||||||
32A6002022C66FCF0042C1D9 /* EditHistoryMessage.swift in Sources */,
|
32A6002022C66FCF0042C1D9 /* EditHistoryMessage.swift in Sources */,
|
||||||
|
@ -5436,10 +5474,12 @@
|
||||||
B16932E720F3C37100746532 /* HomeMessagesSearchDataSource.m in Sources */,
|
B16932E720F3C37100746532 /* HomeMessagesSearchDataSource.m in Sources */,
|
||||||
B12D79FF23E2462200FACEDC /* UserVerificationStartViewState.swift in Sources */,
|
B12D79FF23E2462200FACEDC /* UserVerificationStartViewState.swift in Sources */,
|
||||||
B1B558CE20EF768F00210D55 /* RoomOutgoingEncryptedAttachmentBubbleCell.m in Sources */,
|
B1B558CE20EF768F00210D55 /* RoomOutgoingEncryptedAttachmentBubbleCell.m in Sources */,
|
||||||
|
B14B17672462C69000C2751E /* KeyVerificationManuallyVerifyViewState.swift in Sources */,
|
||||||
B1B5577D20EE84BF00210D55 /* CircleButton.m in Sources */,
|
B1B5577D20EE84BF00210D55 /* CircleButton.m in Sources */,
|
||||||
32607D6D243E0A55006674CC /* KeyBackupRecoverFromPrivateKeyCoordinatorType.swift in Sources */,
|
32607D6D243E0A55006674CC /* KeyBackupRecoverFromPrivateKeyCoordinatorType.swift in Sources */,
|
||||||
32BF995521FA2AB700698084 /* SettingsKeyBackupViewAction.swift in Sources */,
|
32BF995521FA2AB700698084 /* SettingsKeyBackupViewAction.swift in Sources */,
|
||||||
B109D6F1222D8C400061B6D9 /* UIApplication.swift in Sources */,
|
B109D6F1222D8C400061B6D9 /* UIApplication.swift in Sources */,
|
||||||
|
B14B17642462C69000C2751E /* KeyVerificationManuallyVerifyViewModelType.swift in Sources */,
|
||||||
B1BEE73723DF44A60003A4CB /* UserVerificationSessionsStatusViewState.swift in Sources */,
|
B1BEE73723DF44A60003A4CB /* UserVerificationSessionsStatusViewState.swift in Sources */,
|
||||||
B108932823ABEE6800802670 /* BubbleCellReadReceiptsDisplayable.swift in Sources */,
|
B108932823ABEE6800802670 /* BubbleCellReadReceiptsDisplayable.swift in Sources */,
|
||||||
B1B558FF20EF768F00210D55 /* RoomIncomingTextMsgBubbleCell.m in Sources */,
|
B1B558FF20EF768F00210D55 /* RoomIncomingTextMsgBubbleCell.m in Sources */,
|
||||||
|
|
|
@ -2769,6 +2769,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||||
|
|
||||||
// Register to new key verification request
|
// Register to new key verification request
|
||||||
[self registerNewRequestNotificationForSession:mxSession];
|
[self registerNewRequestNotificationForSession:mxSession];
|
||||||
|
|
||||||
|
[self checkLocalPrivateKeysInSession:mxSession];
|
||||||
}
|
}
|
||||||
else if (mxSession.state == MXSessionStateClosed)
|
else if (mxSession.state == MXSessionStateClosed)
|
||||||
{
|
{
|
||||||
|
@ -3523,6 +3525,33 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
|
||||||
[eventsToNotify removeObjectForKey:@(mxSession.hash)];
|
[eventsToNotify removeObjectForKey:@(mxSession.hash)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)checkLocalPrivateKeysInSession:(MXSession*)mxSession
|
||||||
|
{
|
||||||
|
id<MXCryptoStore> cryptoStore = mxSession.crypto.store;
|
||||||
|
NSUInteger keysCount = 0;
|
||||||
|
if ([cryptoStore secretWithSecretId:MXSecretId.keyBackup])
|
||||||
|
{
|
||||||
|
keysCount++;
|
||||||
|
}
|
||||||
|
if ([cryptoStore secretWithSecretId:MXSecretId.crossSigningUserSigning])
|
||||||
|
{
|
||||||
|
keysCount++;
|
||||||
|
}
|
||||||
|
if ([cryptoStore secretWithSecretId:MXSecretId.crossSigningSelfSigning])
|
||||||
|
{
|
||||||
|
keysCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((keysCount > 0 && keysCount < 3)
|
||||||
|
|| (mxSession.crypto.crossSigning.canTrustCrossSigning && !mxSession.crypto.crossSigning.canCrossSign))
|
||||||
|
{
|
||||||
|
// We should have 3 of them. If not, request them again as mitigation
|
||||||
|
NSLog(@"[AppDelegate] checkLocalPrivateKeysInSession: request keys because keysCount = %@", @(keysCount));
|
||||||
|
[mxSession.crypto requestAllPrivateKeys];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -303,7 +303,7 @@
|
||||||
<!--Settings-->
|
<!--Settings-->
|
||||||
<scene sceneID="9we-7Q-LBo">
|
<scene sceneID="9we-7Q-LBo">
|
||||||
<objects>
|
<objects>
|
||||||
<tableViewController title="Settings" id="taU-5Q-sdv" customClass="SettingsViewController" sceneMemberID="viewController">
|
<tableViewController storyboardIdentifier="SettingsViewController" title="Settings" id="taU-5Q-sdv" customClass="SettingsViewController" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="interactive" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="egL-pK-Xhr">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="interactive" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="egL-pK-Xhr">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
@ -555,15 +555,16 @@
|
||||||
<image name="logo" width="120" height="101"/>
|
<image name="logo" width="120" height="101"/>
|
||||||
<image name="search_icon" width="22" height="22"/>
|
<image name="search_icon" width="22" height="22"/>
|
||||||
<image name="settings_icon" width="24" height="24"/>
|
<image name="settings_icon" width="24" height="24"/>
|
||||||
<image name="tab_favourites" width="25" height="25"/>
|
<image name="tab_favourites" width="30" height="30"/>
|
||||||
<image name="tab_favourites_selected" width="25" height="25"/>
|
<image name="tab_favourites_selected" width="30" height="30"/>
|
||||||
<image name="tab_groups" width="25" height="25"/>
|
<image name="tab_groups" width="30" height="30"/>
|
||||||
<image name="tab_groups_selected" width="25" height="25"/>
|
<image name="tab_groups_selected" width="30" height="30"/>
|
||||||
<image name="tab_home" width="25" height="25"/>
|
<image name="tab_home" width="30" height="30"/>
|
||||||
<image name="tab_home_selected" width="25" height="25"/>
|
<image name="tab_home_selected" width="30" height="30"/>
|
||||||
<image name="tab_people" width="25" height="25"/>
|
<image name="tab_people" width="30" height="30"/>
|
||||||
<image name="tab_people_selected" width="25" height="25"/>
|
<image name="tab_people_selected" width="30" height="30"/>
|
||||||
<image name="tab_rooms" width="25" height="25"/>
|
<image name="tab_rooms" width="30" height="30"/>
|
||||||
|
<image name="tab_rooms_selected" width="30" height="30"/>
|
||||||
</resources>
|
</resources>
|
||||||
<inferredMetricsTieBreakers>
|
<inferredMetricsTieBreakers>
|
||||||
<segue reference="bwO-oZ-2vj"/>
|
<segue reference="bwO-oZ-2vj"/>
|
||||||
|
|
|
@ -955,3 +955,14 @@
|
||||||
"security_settings_title" = "Сигурност";
|
"security_settings_title" = "Сигурност";
|
||||||
"security_settings_crypto_sessions" = "МОИТЕ СЕСИИ";
|
"security_settings_crypto_sessions" = "МОИТЕ СЕСИИ";
|
||||||
"security_settings_crypto_sessions_loading" = "Зареждан на сесии…";
|
"security_settings_crypto_sessions_loading" = "Зареждан на сесии…";
|
||||||
|
// MARK: Clients
|
||||||
|
"client_desktop_name" = "Riot Desktop";
|
||||||
|
"client_web_name" = "Riot Web";
|
||||||
|
"client_ios_name" = "Riot iOS";
|
||||||
|
"client_android_name" = "Riot X за Android";
|
||||||
|
"room_member_power_level_admin_in" = "Админ в %@";
|
||||||
|
"room_member_power_level_moderator_in" = "Модератор в %@";
|
||||||
|
"room_member_power_level_custom_in" = "Собствен (%@) в %@";
|
||||||
|
"room_member_power_level_short_admin" = "Админ";
|
||||||
|
"room_member_power_level_short_moderator" = "Модератор";
|
||||||
|
"room_member_power_level_short_custom" = "Собствен";
|
||||||
|
|
|
@ -1074,6 +1074,12 @@
|
||||||
"key_verification_self_verify_current_session_alert_message" = "Other users may not trust it.";
|
"key_verification_self_verify_current_session_alert_message" = "Other users may not trust it.";
|
||||||
"key_verification_self_verify_current_session_alert_validate_action" = "Verify";
|
"key_verification_self_verify_current_session_alert_validate_action" = "Verify";
|
||||||
|
|
||||||
|
// Unverified sessions
|
||||||
|
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_title" = "Review where you're logged in";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_message" = "Verify all your sessions to ensure your account & messages are safe.";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_validate_action" = "Review";
|
||||||
|
|
||||||
// MARK: Self verification wait
|
// MARK: Self verification wait
|
||||||
|
|
||||||
"device_verification_self_verify_wait_title" = "Complete security";
|
"device_verification_self_verify_wait_title" = "Complete security";
|
||||||
|
@ -1091,6 +1097,16 @@
|
||||||
|
|
||||||
"key_verification_verify_sas_additional_information" = "For ultimate security, use another trusted means of communication or do this in person.";
|
"key_verification_verify_sas_additional_information" = "For ultimate security, use another trusted means of communication or do this in person.";
|
||||||
|
|
||||||
|
// MARK: Manually Verify Device
|
||||||
|
|
||||||
|
"key_verification_manually_verify_device_title" = "Manually Verify by Text";
|
||||||
|
"key_verification_manually_verify_device_instruction" = "Confirm by comparing the following with the User Settings in your other session:";
|
||||||
|
"key_verification_manually_verify_device_name_title" = "Session name";
|
||||||
|
"key_verification_manually_verify_device_id_title" = "Session ID";
|
||||||
|
"key_verification_manually_verify_device_key_title" = "Session key";
|
||||||
|
"key_verification_manually_verify_device_additional_information" = "If they don't match, the security of your communication may be compromised.";
|
||||||
|
"key_verification_manually_verify_device_validate_action" = "Verify";
|
||||||
|
|
||||||
// Device
|
// Device
|
||||||
|
|
||||||
"device_verification_verify_wait_partner" = "Waiting for partner to confirm…";
|
"device_verification_verify_wait_partner" = "Waiting for partner to confirm…";
|
||||||
|
@ -1232,6 +1248,7 @@
|
||||||
|
|
||||||
"key_verification_verify_qr_code_title" = "Verify by scanning";
|
"key_verification_verify_qr_code_title" = "Verify by scanning";
|
||||||
"key_verification_verify_qr_code_information" = "Scan the code to securely verify each other.";
|
"key_verification_verify_qr_code_information" = "Scan the code to securely verify each other.";
|
||||||
|
"key_verification_verify_qr_code_information_other_device" = "Scan the code below to verify:";
|
||||||
"key_verification_verify_qr_code_emoji_information" = "Verify by comparing unique emoji.";
|
"key_verification_verify_qr_code_emoji_information" = "Verify by comparing unique emoji.";
|
||||||
"key_verification_verify_qr_code_scan_code_action" = "Scan their code";
|
"key_verification_verify_qr_code_scan_code_action" = "Scan their code";
|
||||||
"key_verification_verify_qr_code_cannot_scan_action" = "Can't scan?";
|
"key_verification_verify_qr_code_cannot_scan_action" = "Can't scan?";
|
||||||
|
@ -1277,7 +1294,7 @@
|
||||||
// Session details
|
// Session details
|
||||||
|
|
||||||
"user_verification_session_details_trusted_title" = "Trusted";
|
"user_verification_session_details_trusted_title" = "Trusted";
|
||||||
"user_verification_session_details_untrusted_title" = "Warning";
|
"user_verification_session_details_untrusted_title" = "Not Trusted";
|
||||||
|
|
||||||
"user_verification_session_details_information_trusted_current_user" = "This session is trusted for secure messaging because you verified it:";
|
"user_verification_session_details_information_trusted_current_user" = "This session is trusted for secure messaging because you verified it:";
|
||||||
"user_verification_session_details_information_trusted_other_user_part1" = "This session is trusted for secure messaging because ";
|
"user_verification_session_details_information_trusted_other_user_part1" = "This session is trusted for secure messaging because ";
|
||||||
|
@ -1289,5 +1306,6 @@
|
||||||
"user_verification_session_details_additional_information_untrusted_other_user" = "Until this user trusts this session, messages sent to and from it are labelled with warnings. Alternatively, you can manually verify it.";
|
"user_verification_session_details_additional_information_untrusted_other_user" = "Until this user trusts this session, messages sent to and from it are labelled with warnings. Alternatively, you can manually verify it.";
|
||||||
"user_verification_session_details_additional_information_untrusted_current_user" = "If you didn’t sign in to this session, your account may be compromised.";
|
"user_verification_session_details_additional_information_untrusted_current_user" = "If you didn’t sign in to this session, your account may be compromised.";
|
||||||
|
|
||||||
"user_verification_session_details_verify_action_current_user" = "Verify";
|
"user_verification_session_details_verify_action_current_user" = "Interactively Verify";
|
||||||
|
"user_verification_session_details_verify_action_current_user_manually" = "Manually Verify by Text";
|
||||||
"user_verification_session_details_verify_action_other_user" = "Manually verify";
|
"user_verification_session_details_verify_action_other_user" = "Manually verify";
|
||||||
|
|
|
@ -1023,8 +1023,8 @@
|
||||||
"security_settings_crosssigning" = "SIGNATURE CROISÉE";
|
"security_settings_crosssigning" = "SIGNATURE CROISÉE";
|
||||||
"security_settings_cryptography" = "CRYPTOGRAPHIE";
|
"security_settings_cryptography" = "CRYPTOGRAPHIE";
|
||||||
"room_participants_action_security_status_loading" = "Chargement…";
|
"room_participants_action_security_status_loading" = "Chargement…";
|
||||||
"device_verification_self_verify_alert_title" = "Nouvelle connexion";
|
"device_verification_self_verify_alert_title" = "Nouvelle connexion. Était-ce vous ?";
|
||||||
"device_verification_self_verify_alert_message" = "Utilisez cette session pour vérifier la nouvelle, ce qui lui permettra d’accéder aux messages chiffrés : %@\nSi vous ne vous êtes pas connecté à cette session, votre compte est peut-être compromis.";
|
"device_verification_self_verify_alert_message" = "Vérifiez la nouvelle connexion pour accéder à votre compte : %@";
|
||||||
"device_verification_self_verify_alert_cancel_action" = "Ce n’était pas moi";
|
"device_verification_self_verify_alert_cancel_action" = "Ce n’était pas moi";
|
||||||
"device_verification_self_verify_start_verify_action" = "Commencer la vérification";
|
"device_verification_self_verify_start_verify_action" = "Commencer la vérification";
|
||||||
"device_verification_self_verify_start_information" = "Utilisez cette session pour vérifier la nouvelle, ce qui lui permettra d’accéder aux messages chiffrés.";
|
"device_verification_self_verify_start_information" = "Utilisez cette session pour vérifier la nouvelle, ce qui lui permettra d’accéder aux messages chiffrés.";
|
||||||
|
@ -1067,3 +1067,29 @@
|
||||||
"client_android_name" = "Riot X pour Android";
|
"client_android_name" = "Riot X pour Android";
|
||||||
"device_verification_self_verify_wait_new_sign_in_title" = "Vérifier cette connexion";
|
"device_verification_self_verify_wait_new_sign_in_title" = "Vérifier cette connexion";
|
||||||
"device_verification_self_verify_wait_additional_information" = "ou un autre client Matrix qui prend en charge la signature croisée";
|
"device_verification_self_verify_wait_additional_information" = "ou un autre client Matrix qui prend en charge la signature croisée";
|
||||||
|
// MARK: - Device Verification
|
||||||
|
"key_verification_other_session_title" = "Vérifier la session";
|
||||||
|
"key_verification_new_session_title" = "Vérifiez votre nouvelle session";
|
||||||
|
"key_verification_this_session_title" = "Vérifier cette session";
|
||||||
|
"device_verification_security_advice_emoji" = "Comparez les émojis uniques, en vérifiant qu’ils apparaissent bien dans le même ordre.";
|
||||||
|
"device_verification_security_advice_number" = "Comparez les nombres, en vérifiant qu’ils apparaissent bien dans le même ordre.";
|
||||||
|
"key_verification_verify_sas_title_emoji" = "Comparer les émojis";
|
||||||
|
"key_verification_verify_sas_title_number" = "Comparer les nombres";
|
||||||
|
"key_verification_verify_sas_cancel_action" = "Ils ne correspondent pas";
|
||||||
|
"key_verification_verify_sas_validate_action" = "Ils correspondent";
|
||||||
|
"key_verification_verify_sas_additional_information" = "Pour une sécurité optimale, utilisez un autre moyen de communication fiable ou faites cela en personne.";
|
||||||
|
"key_verification_verified_new_session_title" = "Nouvelle session vérifiée !";
|
||||||
|
"key_verification_verified_other_session_information" = "Vous pouvez à présent lire les messages sécurisés sur votre autre session, et les autres utilisateurs sauront qu’ils peuvent lui faire confiance.";
|
||||||
|
"key_verification_verified_new_session_information" = "Vous pouvez à présent lire les messages sécurisés sur votre nouvel appareil et les autres utilisateurs sauront qu’ils peuvent lui faire confiance.";
|
||||||
|
"key_verification_verified_this_session_information" = "Vous pouvez à présent lire les messages sécurisés sur cet appareil et les autres utilisateurs sauront qu’ils peuvent lui faire confiance.";
|
||||||
|
"key_verification_verified_user_information" = "Les messages avec cet utilisateurs sont chiffrés de bout en bout et ne peuvent être lus par des tiers.";
|
||||||
|
"key_verification_verify_qr_code_emoji_information" = "Vérifier en comparant des émojis uniques.";
|
||||||
|
"key_verification_verify_qr_code_start_emoji_action" = "Vérifier par émojis";
|
||||||
|
"device_verification_self_verify_alert_validate_action" = "Vérifier";
|
||||||
|
"key_verification_self_verify_current_session_alert_title" = "Vérifier cette session";
|
||||||
|
"key_verification_self_verify_current_session_alert_message" = "Les autres utilisateurs peuvent ne pas lui faire confiance.";
|
||||||
|
"key_verification_self_verify_current_session_alert_validate_action" = "Vérifier";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_title" = "Vérifiez où vous vous êtes connecté";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_message" = "Vérifiez toutes vos sessions pour vous assurer que votre compte et vos message sont en sécurité.";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_validate_action" = "Vérifier";
|
||||||
|
"key_verification_verify_qr_code_information_other_device" = "Scannez le code ci-dessous pour vérifier :";
|
||||||
|
|
|
@ -984,7 +984,7 @@
|
||||||
"room_participants_security_loading" = "Betöltés…";
|
"room_participants_security_loading" = "Betöltés…";
|
||||||
"room_participants_security_information_room_not_encrypted" = "Az üzenetek a szobában nincsenek végponttól végpontig titkosítva.";
|
"room_participants_security_information_room_not_encrypted" = "Az üzenetek a szobában nincsenek végponttól végpontig titkosítva.";
|
||||||
"room_participants_security_information_room_encrypted" = "A szobában az üzenetek végponttól végpontig titkosítva vannak.\n\nAz üzeneteidet lakattal vannak biztosítva és csak neked és a címzetteknek van meg a kulcs hozzá.";
|
"room_participants_security_information_room_encrypted" = "A szobában az üzenetek végponttól végpontig titkosítva vannak.\n\nAz üzeneteidet lakattal vannak biztosítva és csak neked és a címzetteknek van meg a kulcs hozzá.";
|
||||||
"key_verification_user_title" = "Felhasználó ellenőrzése";
|
"key_verification_user_title" = "Ezek ellenőrzése";
|
||||||
"key_verification_verify_user_title_emoji" = "Hitelesítheted a felhasználót, ha megerősíted, hogy az alábbi egyedi emoji-k azok amik megjelentek a képernyőjén.";
|
"key_verification_verify_user_title_emoji" = "Hitelesítheted a felhasználót, ha megerősíted, hogy az alábbi egyedi emoji-k azok amik megjelentek a képernyőjén.";
|
||||||
"key_verification_verify_user_title_number" = "Hitelesítheted a felhasználót, ha megerősíted, hogy az alábbi számok jelentek meg az ő képernyőjén is.";
|
"key_verification_verify_user_title_number" = "Hitelesítheted a felhasználót, ha megerősíted, hogy az alábbi számok jelentek meg az ő képernyőjén is.";
|
||||||
"key_verification_verified_user_description_1" = "Sikeresen ellenőrizted ezt a felhasználót.";
|
"key_verification_verified_user_description_1" = "Sikeresen ellenőrizted ezt a felhasználót.";
|
||||||
|
@ -1034,8 +1034,8 @@
|
||||||
"room_member_power_level_short_custom" = "Egyedi";
|
"room_member_power_level_short_custom" = "Egyedi";
|
||||||
// Recover from private key
|
// Recover from private key
|
||||||
"key_backup_recover_from_private_key_info" = "Mentés visszaállítás…";
|
"key_backup_recover_from_private_key_info" = "Mentés visszaállítás…";
|
||||||
"device_verification_self_verify_alert_title" = "Új Bejelentkezés";
|
"device_verification_self_verify_alert_title" = "Új bejelentkezés. Ez te vagy?";
|
||||||
"device_verification_self_verify_alert_message" = "Használd ezt a munkamenetet az új ellenőrzéséhez, amivel hozzáférést biztosíthatsz a titkosított üzenethez: %@\nHa nem te jelentkeztél be ebbe a munkamenetbe akkor lehetséges, hogy a fiókodat feltörték.";
|
"device_verification_self_verify_alert_message" = "Ellenőrizd ezt az új bejelentkezést ami hozzáfér a fiókodhoz: %@";
|
||||||
"device_verification_self_verify_alert_cancel_action" = "Nem én voltam";
|
"device_verification_self_verify_alert_cancel_action" = "Nem én voltam";
|
||||||
"device_verification_self_verify_start_verify_action" = "Ellenőrzés elindítása";
|
"device_verification_self_verify_start_verify_action" = "Ellenőrzés elindítása";
|
||||||
"device_verification_self_verify_start_information" = "Az új munkamenet ellenőrzéséhez használd ezt, amivel hozzáférést adsz a titkosított üzenetekhez.";
|
"device_verification_self_verify_start_information" = "Az új munkamenet ellenőrzéséhez használd ezt, amivel hozzáférést adsz a titkosított üzenetekhez.";
|
||||||
|
@ -1069,3 +1069,29 @@
|
||||||
"security_settings_coming_soon" = "Bocsánat. Riot-iOS-n ez a művelet egyenlőre nem érhető el. Kérlek használj másik Matrix klienst a beállításához. Riot-iOS használni fogja.";
|
"security_settings_coming_soon" = "Bocsánat. Riot-iOS-n ez a művelet egyenlőre nem érhető el. Kérlek használj másik Matrix klienst a beállításához. Riot-iOS használni fogja.";
|
||||||
"device_verification_self_verify_wait_new_sign_in_title" = "Belépés ellenőrzése";
|
"device_verification_self_verify_wait_new_sign_in_title" = "Belépés ellenőrzése";
|
||||||
"device_verification_self_verify_wait_additional_information" = "vagy másik eszközök közötti hitelesítésre alkalmas Matrix kliensre";
|
"device_verification_self_verify_wait_additional_information" = "vagy másik eszközök közötti hitelesítésre alkalmas Matrix kliensre";
|
||||||
|
// MARK: - Device Verification
|
||||||
|
"key_verification_other_session_title" = "Munkamenet hitelesítése";
|
||||||
|
"key_verification_new_session_title" = "Új munkamenet ellenőrzése";
|
||||||
|
"key_verification_this_session_title" = "Munkamenet ellenőrzése";
|
||||||
|
"device_verification_security_advice_emoji" = "Hasonlítsd össze ezeket az egyedi emodzsikat és győződj meg arról, hogy ugyanabban a sorrendben jelentek meg.";
|
||||||
|
"device_verification_security_advice_number" = "Hasonlítsd össze a számokat, győződj meg arról, hogy ugyanabban a sorrendben jelennek meg.";
|
||||||
|
"device_verification_self_verify_alert_validate_action" = "Ellenőriz";
|
||||||
|
"key_verification_self_verify_current_session_alert_title" = "Munkamenet ellenőrzése";
|
||||||
|
"key_verification_self_verify_current_session_alert_message" = "Más felhasználók lehet, hogy nem bíznak benne.";
|
||||||
|
"key_verification_self_verify_current_session_alert_validate_action" = "Ellenőriz";
|
||||||
|
"key_verification_verify_sas_title_emoji" = "Emodzsik összehasonlítása";
|
||||||
|
"key_verification_verify_sas_title_number" = "Számok összehasonlítása";
|
||||||
|
"key_verification_verify_sas_cancel_action" = "Nem egyeznek";
|
||||||
|
"key_verification_verify_sas_validate_action" = "Egyeznek";
|
||||||
|
"key_verification_verify_sas_additional_information" = "A legnagyobb biztonság érdekében használj megbízható kommunikációs csatornát vagy tedd meg személyesen.";
|
||||||
|
"key_verification_verified_new_session_title" = "Új munkamenet hitelesítve!";
|
||||||
|
"key_verification_verified_other_session_information" = "A másik munkamenetekben is el tudod olvasni a titkosított üzeneteket és más felhasználók tudni fogják, hogy megbízhatnak benne.";
|
||||||
|
"key_verification_verified_new_session_information" = "Az új eszközödön is el tudod olvasni a titkosított üzeneteket és más felhasználók tudni fogják, hogy megbízhatnak benne.";
|
||||||
|
"key_verification_verified_this_session_information" = "Ezen az eszközödön is el tudod olvasni a titkosított üzeneteket és más felhasználók tudni fogják, hogy megbízhatnak benne.";
|
||||||
|
"key_verification_verified_user_information" = "Az üzenetek ezzel a felhasználóval a végpontok között titkosítva vannak és más nem tudja elolvasni.";
|
||||||
|
"key_verification_verify_qr_code_emoji_information" = "Ellenőrzés egyedi emodzsik összehasonlításával.";
|
||||||
|
"key_verification_verify_qr_code_start_emoji_action" = "Ellenőrzés emodzsival";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_title" = "Tekintsd át hol vagy bejelentkezve";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_message" = "Ellenőrizd minden munkamenetedet, hogy a fiókod és az üzeneteid biztonságban legyenek.";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_validate_action" = "Átnézés";
|
||||||
|
"key_verification_verify_qr_code_information_other_device" = "Ellenőrzéshez olvasd be a kódot alább:";
|
||||||
|
|
|
@ -952,7 +952,7 @@
|
||||||
"room_participants_action_security_status_verify" = "Verifica";
|
"room_participants_action_security_status_verify" = "Verifica";
|
||||||
"room_participants_action_security_status_warning" = "Attenzione";
|
"room_participants_action_security_status_warning" = "Attenzione";
|
||||||
"room_participants_security_loading" = "Caricamento…";
|
"room_participants_security_loading" = "Caricamento…";
|
||||||
"key_verification_user_title" = "verificale";
|
"key_verification_user_title" = "Verificale";
|
||||||
"room_participants_security_information_room_not_encrypted" = "I messaggi in questa stanza non sono cifrati end-to-end.";
|
"room_participants_security_information_room_not_encrypted" = "I messaggi in questa stanza non sono cifrati end-to-end.";
|
||||||
"room_participants_security_information_room_encrypted" = "I messaggi in questa stanza sono cifrati end-to-end.\n\nI tuoi messaggi sono protetti con lucchetti e solo te ed il destinatario avete le chiavi univoche per sbloccarli.";
|
"room_participants_security_information_room_encrypted" = "I messaggi in questa stanza sono cifrati end-to-end.\n\nI tuoi messaggi sono protetti con lucchetti e solo te ed il destinatario avete le chiavi univoche per sbloccarli.";
|
||||||
"key_verification_verify_user_title_emoji" = "Verifica questo utente confermando che le seguenti emoji appaiono sul suo schermo, nello stesso ordine.";
|
"key_verification_verify_user_title_emoji" = "Verifica questo utente confermando che le seguenti emoji appaiono sul suo schermo, nello stesso ordine.";
|
||||||
|
@ -995,8 +995,8 @@
|
||||||
"security_settings_crosssigning" = "FIRMA INCROCIATA";
|
"security_settings_crosssigning" = "FIRMA INCROCIATA";
|
||||||
"security_settings_cryptography" = "CRITTOGRAFIA";
|
"security_settings_cryptography" = "CRITTOGRAFIA";
|
||||||
"room_participants_action_security_status_loading" = "Caricamento…";
|
"room_participants_action_security_status_loading" = "Caricamento…";
|
||||||
"device_verification_self_verify_alert_title" = "Nuovo accesso";
|
"device_verification_self_verify_alert_title" = "Nuovo accesso. Eri tu?";
|
||||||
"device_verification_self_verify_alert_message" = "Usa questa sessione per verificare quella nuova, dandole l'accesso ai messaggi cifrati: %@\nSe non hai fatto l'accesso a questa sessione, il tuo account potrebbe essere compromesso.";
|
"device_verification_self_verify_alert_message" = "Verifica il nuovo accesso entrando nel tuo account: %@";
|
||||||
"device_verification_self_verify_alert_cancel_action" = "Non ero io";
|
"device_verification_self_verify_alert_cancel_action" = "Non ero io";
|
||||||
"device_verification_self_verify_start_verify_action" = "Inizia la verifica";
|
"device_verification_self_verify_start_verify_action" = "Inizia la verifica";
|
||||||
"device_verification_self_verify_start_information" = "Usa questa sessione per verificare quella nuova, dandole l'accesso ai messaggi cifrati.";
|
"device_verification_self_verify_start_information" = "Usa questa sessione per verificare quella nuova, dandole l'accesso ai messaggi cifrati.";
|
||||||
|
@ -1047,3 +1047,23 @@
|
||||||
"device_verification_security_advice_number" = "Confronta i numeri, assicurandoti che compaiono nello stesso ordine.";
|
"device_verification_security_advice_number" = "Confronta i numeri, assicurandoti che compaiono nello stesso ordine.";
|
||||||
"key_verification_verify_title_emoji" = "Confronta emoji";
|
"key_verification_verify_title_emoji" = "Confronta emoji";
|
||||||
"key_verification_verify_title_number" = "Confronta numeri";
|
"key_verification_verify_title_number" = "Confronta numeri";
|
||||||
|
"device_verification_self_verify_alert_validate_action" = "Verifica";
|
||||||
|
"key_verification_self_verify_current_session_alert_title" = "Verifica questa sessione";
|
||||||
|
"key_verification_self_verify_current_session_alert_message" = "Altri utenti potrebbero non fidarsi.";
|
||||||
|
"key_verification_self_verify_current_session_alert_validate_action" = "Verifica";
|
||||||
|
"key_verification_verify_sas_title_emoji" = "Confronta emoji";
|
||||||
|
"key_verification_verify_sas_title_number" = "Confronta numeri";
|
||||||
|
"key_verification_verify_sas_cancel_action" = "Non corrispondono";
|
||||||
|
"key_verification_verify_sas_validate_action" = "Corrispondono";
|
||||||
|
"key_verification_verify_sas_additional_information" = "Per la massima sicurezza, usate un altro mezzo di comunicazione fidato o fatelo di persona.";
|
||||||
|
"key_verification_verified_new_session_title" = "Nuova sessione verificata!";
|
||||||
|
"key_verification_verified_other_session_information" = "Ora puoi leggere i messaggi sicuri nell'altra tua sessione e gli altri utenti sapranno che si possono fidare.";
|
||||||
|
"key_verification_verified_new_session_information" = "Ora puoi leggere i messaggi sicuri nell'altro tuo dispositivo e gli altri utenti sapranno che si possono fidare.";
|
||||||
|
"key_verification_verified_this_session_information" = "Ora puoi leggere i messaggi sicuri in questo dispositivo e gli altri utenti sapranno che si possono fidare.";
|
||||||
|
"key_verification_verified_user_information" = "I messaggi con questo utente sono cifrati end-to-end e non possono essere letti da terze parti.";
|
||||||
|
"key_verification_verify_qr_code_emoji_information" = "Verifica confrontando emoji univoci.";
|
||||||
|
"key_verification_verify_qr_code_start_emoji_action" = "Verifica con emoji";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_title" = "Controlla dove hai fatto l'accesso";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_message" = "Verifica tutte le tue sessioni per assicurarti che l'account e i messaggi siano protetti.";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_validate_action" = "Controlla";
|
||||||
|
"key_verification_verify_qr_code_information_other_device" = "Scansiona il codice sotto per verificare:";
|
||||||
|
|
|
@ -976,7 +976,7 @@
|
||||||
"manage_session_trusted" = "Besuar prej jush";
|
"manage_session_trusted" = "Besuar prej jush";
|
||||||
"manage_session_not_trusted" = "Jo i besuar";
|
"manage_session_not_trusted" = "Jo i besuar";
|
||||||
"manage_session_sign_out" = "Dilni nga ky sesion";
|
"manage_session_sign_out" = "Dilni nga ky sesion";
|
||||||
"key_verification_user_title" = "Verifikoni përdoruesin";
|
"key_verification_user_title" = "Verifikojini";
|
||||||
"key_verification_verify_user_title_emoji" = "Verifikojeni këtë përdorues duke ripohuar se <em>emoji</em> unik vijues shfaqet në ekranin e tij, në të njëjtën radhë.";
|
"key_verification_verify_user_title_emoji" = "Verifikojeni këtë përdorues duke ripohuar se <em>emoji</em> unik vijues shfaqet në ekranin e tij, në të njëjtën radhë.";
|
||||||
"key_verification_verify_user_title_number" = "Verifikojeni këtë përdorues duke ripohuar se numrat vijues shfaqen në ekranin e tij, në të njëjtën radhë.";
|
"key_verification_verify_user_title_number" = "Verifikojeni këtë përdorues duke ripohuar se numrat vijues shfaqen në ekranin e tij, në të njëjtën radhë.";
|
||||||
"key_verification_verified_user_description_1" = "E verifikuat me sukses këtë përdorues.";
|
"key_verification_verified_user_description_1" = "E verifikuat me sukses këtë përdorues.";
|
||||||
|
@ -1016,20 +1016,70 @@
|
||||||
"key_verification_verify_qr_code_scan_other_code_success_message" = "Kodi QR u vlerësua me sukses.";
|
"key_verification_verify_qr_code_scan_other_code_success_message" = "Kodi QR u vlerësua me sukses.";
|
||||||
"skip" = "Anashkaloje";
|
"skip" = "Anashkaloje";
|
||||||
"room_participants_action_security_status_loading" = "Po ngarkohet…";
|
"room_participants_action_security_status_loading" = "Po ngarkohet…";
|
||||||
"device_verification_self_verify_alert_title" = "Hyrje e Re";
|
"device_verification_self_verify_alert_title" = "Hyrje e re. Ju qetë?";
|
||||||
"device_verification_self_verify_alert_message" = "Përdoreni këtë sesion që të verifikoni atë të riun tuaj, duke i akorduar hyrje te mesazhe të fshehtëzuar: %@\nNëse hyrjen te ky sesion s’e keni bërë ju, llogaria juaj mund të jetë komprometuar.";
|
"device_verification_self_verify_alert_message" = "Verifikoni kredencialet e reja për hyrje te llogaria juaj: %@";
|
||||||
"device_verification_self_verify_alert_cancel_action" = "Ky s’qeshë unë";
|
"device_verification_self_verify_alert_cancel_action" = "Ky s’qeshë unë";
|
||||||
"device_verification_self_verify_start_verify_action" = "Fillo verifikimin";
|
"device_verification_self_verify_start_verify_action" = "Fillo verifikimin";
|
||||||
"device_verification_self_verify_start_information" = "Përdoreni këtë sesion që të verifikoni atë të riun tuaj, duke i akorduar hyrje te mesazhe të fshehtëzuar.";
|
"device_verification_self_verify_start_information" = "Përdoreni këtë sesion që të verifikoni atë të riun tuaj, duke i akorduar hyrje te mesazhe të fshehtëzuar.";
|
||||||
"device_verification_self_verify_start_waiting" = "Po pritet…";
|
"device_verification_self_verify_start_waiting" = "Po pritet…";
|
||||||
"device_verification_self_verify_wait_title" = "Siguri e plotë";
|
"device_verification_self_verify_wait_title" = "Siguri e plotë";
|
||||||
"device_verification_self_verify_wait_information" = "Përdorni një sesion ekzistues që të verifikoni këtë të riun, duke i akorduar hyrje te mesazhe të fshehtëzuar.";
|
"device_verification_self_verify_wait_information" = "Verifikoni këtë sesion prej një nga sesionet tuaj të tjera, duke i akorduar hyrje te mesazhe të fshehtëzuar.\n\nPërdorni Riot-in më të ri në pajisjet tuaja të tjera:";
|
||||||
"device_verification_self_verify_wait_waiting" = "Po pritet…";
|
"device_verification_self_verify_wait_waiting" = "Po pritet…";
|
||||||
"room_member_power_level_admin_in" = "Përgjegjës te %@";
|
"room_member_power_level_admin_in" = "Përgjegjës te %@";
|
||||||
"room_member_power_level_moderator_in" = "Moderator te %@";
|
"room_member_power_level_moderator_in" = "Moderator te %@";
|
||||||
"room_member_power_level_custom_in" = "Vetjak (%@) te %@";
|
"room_member_power_level_custom_in" = "Vetjak (%@) te %@";
|
||||||
"room_member_power_level_short_admin" = "Përgjegjës";
|
"room_member_power_level_short_admin" = "Përgjegjës";
|
||||||
"room_member_power_level_short_moderator" = "Mod";
|
"room_member_power_level_short_moderator" = "Moderator";
|
||||||
"room_member_power_level_short_custom" = "Vetjak";
|
"room_member_power_level_short_custom" = "Vetjak";
|
||||||
// Recover from private key
|
// Recover from private key
|
||||||
"key_backup_recover_from_private_key_info" = "Po rikthehet kopjeruajtje…";
|
"key_backup_recover_from_private_key_info" = "Po rikthehet kopjeruajtje…";
|
||||||
|
// MARK: Clients
|
||||||
|
"client_desktop_name" = "Riot Desktop";
|
||||||
|
"client_web_name" = "Riot Web";
|
||||||
|
"client_ios_name" = "Riot iOS";
|
||||||
|
"client_android_name" = "Riot X për Android";
|
||||||
|
"room_participants_action_security_status_complete_security" = "Siguri e plotë";
|
||||||
|
"security_settings_crosssigning_info_not_bootstrapped" = "<em>Cross-signing</em> s’është ujdisur ende.";
|
||||||
|
"security_settings_crosssigning_info_exists" = "Llogaria juaj ka një identitet <em>cross-signing</em>, por s’është ende i besuar nga ky sesion. Plotësoni sigurinë e këtij sesioni.";
|
||||||
|
"security_settings_crosssigning_info_trusted" = "<em>Cross-signing</em> është i aktivizuar. Mund të besoni përdorues të tjerë dhe sesionet tuaj të tjerë bazuar në <em>cross-signing</em>, por s’mund të kryeni <em>cross-sign</em> që nga ky sesion,ngaqë nuk ka kyçe privatë për <em>cross-signing</em>. Plotësoni sigurinë e këtij sesioni.";
|
||||||
|
"security_settings_crosssigning_info_ok" = "<em>Cross-signing</em> është i aktivizuar.";
|
||||||
|
"security_settings_crosssigning_complete_security" = "Siguri e plotë";
|
||||||
|
"security_settings_complete_security_alert_title" = "Siguri e plotë";
|
||||||
|
"security_settings_complete_security_alert_message" = "Së pari duhet të plotësoni sigurinë në sesionin tuaj të tanishëm.";
|
||||||
|
"security_settings_coming_soon" = "Na ndjeni. Ky veprim s’është ende pjesë e Riot-iOS-it. Ju lutemi, për ta pasur, përdorni një klient tjetër Matrix. Riot-iOS-i do ta përdorë.";
|
||||||
|
// MARK: - Device Verification
|
||||||
|
"key_verification_other_session_title" = "Verifiko sesion";
|
||||||
|
"key_verification_new_session_title" = "Verifikoni sesionin tuaj të ri";
|
||||||
|
"key_verification_this_session_title" = "Verifikoni këtë sesion";
|
||||||
|
"device_verification_security_advice_emoji" = "Krahasoni emoji-n unik, duke u siguruar se shfaqen në të njëjtën radhë.";
|
||||||
|
"device_verification_security_advice_number" = "Krahasoni numrat, duke u siguruar se shfaqen në të njëjtën radhë.";
|
||||||
|
"device_verification_self_verify_alert_validate_action" = "Verifikoje";
|
||||||
|
"key_verification_self_verify_current_session_alert_title" = "Verifikoni këtë sesion";
|
||||||
|
"key_verification_self_verify_current_session_alert_message" = "Përdorues të tjerë mund të mos e besojnë.";
|
||||||
|
"key_verification_self_verify_current_session_alert_validate_action" = "Verifikoje";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_title" = "Shqyrtojini kur të jeni i futur";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_message" = "Verifikoni krejt sesionet tuaj që të siguroheni se llogaria & mesazhet tuaja janë të sigurt.";
|
||||||
|
"key_verification_self_verify_unverified_sessions_alert_validate_action" = "Shqyrtojeni";
|
||||||
|
"device_verification_self_verify_wait_new_sign_in_title" = "Verifikoni këto kredenciale hyrjeje";
|
||||||
|
"device_verification_self_verify_wait_additional_information" = "ose një tjetër klient Matrix i aftë për <em>cross-signing</em";
|
||||||
|
"key_verification_verify_sas_title_emoji" = "Krahasoni emoji";
|
||||||
|
"key_verification_verify_sas_title_number" = "Krahasoni numra";
|
||||||
|
"key_verification_verify_sas_cancel_action" = "S’përputhen";
|
||||||
|
"key_verification_verify_sas_validate_action" = "Përputhen";
|
||||||
|
"key_verification_verify_sas_additional_information" = "Për sigurinë përfundimtare, përdorni mjete të tjera të besuara komunikimi ose bëjeni këtë personalisht.";
|
||||||
|
"key_verification_verified_new_session_title" = "U verifikua sesion i ri!";
|
||||||
|
"key_verification_verified_other_session_information" = "Tani mund të lexoni mesazhe të sigurt në sesionin tuaj tjetër, dhe përdorues të tjerë do ta dinë se mund t’i besojnë.";
|
||||||
|
"key_verification_verified_new_session_information" = "Tani mund të lexoni mesazhe të sigurt në pajisjen tuaj të re, dhe përdorues të tjerë do ta dinë se mund t’i besojnë.";
|
||||||
|
"key_verification_verified_this_session_information" = "Tani mund të lexoni mesazhe të sigurt në këtë pajisje, dhe përdorues të tjerë do ta dinë se mund t’i besojnë.";
|
||||||
|
"key_verification_verified_user_information" = "Mesazhet me këtë përdorues fshehtëzohen skaj-më-skaj dhe s’mund të lexohen nga palë të treta.";
|
||||||
|
"key_verification_verify_qr_code_information_other_device" = "Për ta verifikuar, skanoni kodin më poshtë:";
|
||||||
|
"key_verification_verify_qr_code_emoji_information" = "Verifikoje duke krahasuar emoji unik.";
|
||||||
|
"key_verification_verify_qr_code_start_emoji_action" = "Verifikojeni përmes emoji-t";
|
||||||
|
// Scanning
|
||||||
|
"key_verification_scan_confirmation_scanning_title" = "Thuajse mbërritëm! Po pritet për ripohim…";
|
||||||
|
"key_verification_scan_confirmation_scanning_user_waiting_other" = "Po pritet për %@…";
|
||||||
|
"key_verification_scan_confirmation_scanning_device_waiting_other" = "Po pritet për pajisje tjetër…";
|
||||||
|
// Scanned
|
||||||
|
"key_verification_scan_confirmation_scanned_title" = "Thuajse mbërritëm!";
|
||||||
|
"key_verification_scan_confirmation_scanned_user_information" = "A shfaq %@ të njëjtën mburojë?";
|
||||||
|
"key_verification_scan_confirmation_scanned_device_information" = "A shfaq pajisja juaj tjetër të njëjtën mburojë?";
|
||||||
|
|
|
@ -28,4 +28,13 @@ extension UILabel {
|
||||||
|
|
||||||
self.attributedText = attributeString
|
self.attributedText = attributeString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix multiline label height with auto layout. After performing orientation multiline label text appears on one line. For more information see https://www.objc.io/issues/3-views/advanced-auto-layout-toolbox/#intrinsic-content-size-of-multi-line-text
|
||||||
|
@objc func vc_fixMultilineHeight() {
|
||||||
|
let width = self.frame.size.width
|
||||||
|
|
||||||
|
if self.preferredMaxLayoutWidth != width {
|
||||||
|
self.preferredMaxLayoutWidth = width
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ extension UIViewController {
|
||||||
|
|
||||||
/// Remove back bar button title when pushing a view controller.
|
/// Remove back bar button title when pushing a view controller.
|
||||||
/// This method should be called on the previous controller in UINavigationController stack.
|
/// This method should be called on the previous controller in UINavigationController stack.
|
||||||
func vc_removeBackTitle() {
|
@objc func vc_removeBackTitle() {
|
||||||
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
|
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,11 @@ internal enum StoryboardScene {
|
||||||
|
|
||||||
internal static let initialScene = InitialSceneType<Riot.KeyVerificationDataLoadingViewController>(storyboard: KeyVerificationDataLoadingViewController.self)
|
internal static let initialScene = InitialSceneType<Riot.KeyVerificationDataLoadingViewController>(storyboard: KeyVerificationDataLoadingViewController.self)
|
||||||
}
|
}
|
||||||
|
internal enum KeyVerificationManuallyVerifyViewController: StoryboardType {
|
||||||
|
internal static let storyboardName = "KeyVerificationManuallyVerifyViewController"
|
||||||
|
|
||||||
|
internal static let initialScene = InitialSceneType<Riot.KeyVerificationManuallyVerifyViewController>(storyboard: KeyVerificationManuallyVerifyViewController.self)
|
||||||
|
}
|
||||||
internal enum KeyVerificationScanConfirmationViewController: StoryboardType {
|
internal enum KeyVerificationScanConfirmationViewController: StoryboardType {
|
||||||
internal static let storyboardName = "KeyVerificationScanConfirmationViewController"
|
internal static let storyboardName = "KeyVerificationScanConfirmationViewController"
|
||||||
|
|
||||||
|
|
|
@ -1526,6 +1526,34 @@ internal enum VectorL10n {
|
||||||
internal static func keyVerificationIncomingRequestIncomingAlertMessage(_ p1: String) -> String {
|
internal static func keyVerificationIncomingRequestIncomingAlertMessage(_ p1: String) -> String {
|
||||||
return VectorL10n.tr("Vector", "key_verification_incoming_request_incoming_alert_message", p1)
|
return VectorL10n.tr("Vector", "key_verification_incoming_request_incoming_alert_message", p1)
|
||||||
}
|
}
|
||||||
|
/// If they don't match, the security of your communication may be compromised.
|
||||||
|
internal static var keyVerificationManuallyVerifyDeviceAdditionalInformation: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_manually_verify_device_additional_information")
|
||||||
|
}
|
||||||
|
/// Session ID
|
||||||
|
internal static var keyVerificationManuallyVerifyDeviceIdTitle: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_manually_verify_device_id_title")
|
||||||
|
}
|
||||||
|
/// Confirm by comparing the following with the User Settings in your other session:
|
||||||
|
internal static var keyVerificationManuallyVerifyDeviceInstruction: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_manually_verify_device_instruction")
|
||||||
|
}
|
||||||
|
/// Session key
|
||||||
|
internal static var keyVerificationManuallyVerifyDeviceKeyTitle: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_manually_verify_device_key_title")
|
||||||
|
}
|
||||||
|
/// Session name
|
||||||
|
internal static var keyVerificationManuallyVerifyDeviceNameTitle: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_manually_verify_device_name_title")
|
||||||
|
}
|
||||||
|
/// Manually Verify by Text
|
||||||
|
internal static var keyVerificationManuallyVerifyDeviceTitle: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_manually_verify_device_title")
|
||||||
|
}
|
||||||
|
/// Verify
|
||||||
|
internal static var keyVerificationManuallyVerifyDeviceValidateAction: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_manually_verify_device_validate_action")
|
||||||
|
}
|
||||||
/// Verify your new session
|
/// Verify your new session
|
||||||
internal static var keyVerificationNewSessionTitle: String {
|
internal static var keyVerificationNewSessionTitle: String {
|
||||||
return VectorL10n.tr("Vector", "key_verification_new_session_title")
|
return VectorL10n.tr("Vector", "key_verification_new_session_title")
|
||||||
|
@ -1570,6 +1598,18 @@ internal enum VectorL10n {
|
||||||
internal static var keyVerificationSelfVerifyCurrentSessionAlertValidateAction: String {
|
internal static var keyVerificationSelfVerifyCurrentSessionAlertValidateAction: String {
|
||||||
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_validate_action")
|
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_validate_action")
|
||||||
}
|
}
|
||||||
|
/// Verify all your sessions to ensure your account & messages are safe.
|
||||||
|
internal static var keyVerificationSelfVerifyUnverifiedSessionsAlertMessage: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_self_verify_unverified_sessions_alert_message")
|
||||||
|
}
|
||||||
|
/// Review where you're logged in
|
||||||
|
internal static var keyVerificationSelfVerifyUnverifiedSessionsAlertTitle: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_self_verify_unverified_sessions_alert_title")
|
||||||
|
}
|
||||||
|
/// Review
|
||||||
|
internal static var keyVerificationSelfVerifyUnverifiedSessionsAlertValidateAction: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_self_verify_unverified_sessions_alert_validate_action")
|
||||||
|
}
|
||||||
/// Verify this session
|
/// Verify this session
|
||||||
internal static var keyVerificationThisSessionTitle: String {
|
internal static var keyVerificationThisSessionTitle: String {
|
||||||
return VectorL10n.tr("Vector", "key_verification_this_session_title")
|
return VectorL10n.tr("Vector", "key_verification_this_session_title")
|
||||||
|
@ -1658,6 +1698,10 @@ internal enum VectorL10n {
|
||||||
internal static var keyVerificationVerifyQrCodeInformation: String {
|
internal static var keyVerificationVerifyQrCodeInformation: String {
|
||||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_information")
|
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_information")
|
||||||
}
|
}
|
||||||
|
/// Scan the code below to verify:
|
||||||
|
internal static var keyVerificationVerifyQrCodeInformationOtherDevice: String {
|
||||||
|
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_information_other_device")
|
||||||
|
}
|
||||||
/// Did the other user successfully scan the QR code?
|
/// Did the other user successfully scan the QR code?
|
||||||
internal static var keyVerificationVerifyQrCodeOtherScanMyCodeTitle: String {
|
internal static var keyVerificationVerifyQrCodeOtherScanMyCodeTitle: String {
|
||||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_other_scan_my_code_title")
|
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_other_scan_my_code_title")
|
||||||
|
@ -3726,14 +3770,18 @@ internal enum VectorL10n {
|
||||||
internal static var userVerificationSessionDetailsTrustedTitle: String {
|
internal static var userVerificationSessionDetailsTrustedTitle: String {
|
||||||
return VectorL10n.tr("Vector", "user_verification_session_details_trusted_title")
|
return VectorL10n.tr("Vector", "user_verification_session_details_trusted_title")
|
||||||
}
|
}
|
||||||
/// Warning
|
/// Not Trusted
|
||||||
internal static var userVerificationSessionDetailsUntrustedTitle: String {
|
internal static var userVerificationSessionDetailsUntrustedTitle: String {
|
||||||
return VectorL10n.tr("Vector", "user_verification_session_details_untrusted_title")
|
return VectorL10n.tr("Vector", "user_verification_session_details_untrusted_title")
|
||||||
}
|
}
|
||||||
/// Verify
|
/// Interactively Verify
|
||||||
internal static var userVerificationSessionDetailsVerifyActionCurrentUser: String {
|
internal static var userVerificationSessionDetailsVerifyActionCurrentUser: String {
|
||||||
return VectorL10n.tr("Vector", "user_verification_session_details_verify_action_current_user")
|
return VectorL10n.tr("Vector", "user_verification_session_details_verify_action_current_user")
|
||||||
}
|
}
|
||||||
|
/// Manually Verify by Text
|
||||||
|
internal static var userVerificationSessionDetailsVerifyActionCurrentUserManually: String {
|
||||||
|
return VectorL10n.tr("Vector", "user_verification_session_details_verify_action_current_user_manually")
|
||||||
|
}
|
||||||
/// Manually verify
|
/// Manually verify
|
||||||
internal static var userVerificationSessionDetailsVerifyActionOtherUser: String {
|
internal static var userVerificationSessionDetailsVerifyActionOtherUser: String {
|
||||||
return VectorL10n.tr("Vector", "user_verification_session_details_verify_action_other_user")
|
return VectorL10n.tr("Vector", "user_verification_session_details_verify_action_other_user")
|
||||||
|
|
|
@ -33,6 +33,7 @@ final class RiotSettings: NSObject {
|
||||||
static let allowStunServerFallback = "allowStunServerFallback"
|
static let allowStunServerFallback = "allowStunServerFallback"
|
||||||
static let stunServerFallback = "stunServerFallback"
|
static let stunServerFallback = "stunServerFallback"
|
||||||
static let hideVerifyThisSessionAlert = "hideVerifyThisSessionAlert"
|
static let hideVerifyThisSessionAlert = "hideVerifyThisSessionAlert"
|
||||||
|
static let hideReviewSessionsAlert = "hideReviewSessionsAlert"
|
||||||
}
|
}
|
||||||
|
|
||||||
static let shared = RiotSettings()
|
static let shared = RiotSettings()
|
||||||
|
@ -144,4 +145,12 @@ final class RiotSettings: NSObject {
|
||||||
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
|
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hideReviewSessionsAlert: Bool {
|
||||||
|
get {
|
||||||
|
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.hideReviewSessionsAlert)
|
||||||
|
} set {
|
||||||
|
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideReviewSessionsAlert)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,17 @@ final class KeyVerificationDataLoadingViewController: UIViewController {
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
|
|
||||||
|
if let navigationController = self.navigationController {
|
||||||
|
if navigationController.navigationBar.isHidden == true {
|
||||||
|
self.navigationItem.hidesBackButton = true
|
||||||
|
// Show navigation bar if needed
|
||||||
|
navigationController.setNavigationBarHidden(false, animated: animated)
|
||||||
|
} else {
|
||||||
// Hide back button
|
// Hide back button
|
||||||
self.navigationItem.setHidesBackButton(true, animated: animated)
|
self.navigationItem.setHidesBackButton(true, animated: animated)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,13 @@
|
||||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fyB-h5-5v2">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fyB-h5-5v2">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="453"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="443"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D7P-C8-cqw">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="D7P-C8-cqw">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="103"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="113"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="lPc-YT-wnY">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="lPc-YT-wnY">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="103"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="113"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="J1F-ba-sZ7">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="J1F-ba-sZ7">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
|
||||||
|
@ -64,10 +64,10 @@
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SLA-sa-fBw">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SLA-sa-fBw">
|
||||||
<rect key="frame" x="0.0" y="50" width="375" height="53"/>
|
<rect key="frame" x="0.0" y="50" width="375" height="63"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="253" text="Scan the code to securely verify each other." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="y2w-7m-BE3">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="253" verticalCompressionResistancePriority="751" text="Scan the code to securely verify each other." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="y2w-7m-BE3">
|
||||||
<rect key="frame" x="20" y="15" width="335" height="38"/>
|
<rect key="frame" x="20" y="20" width="335" height="18"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
|
@ -75,16 +75,17 @@
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="y2w-7m-BE3" firstAttribute="top" secondItem="SLA-sa-fBw" secondAttribute="top" constant="15" id="4Hi-G4-ifY"/>
|
<constraint firstItem="y2w-7m-BE3" firstAttribute="top" secondItem="SLA-sa-fBw" secondAttribute="top" constant="20" id="4Hi-G4-ifY"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="y2w-7m-BE3" secondAttribute="trailing" constant="20" id="5xb-BK-tXG"/>
|
<constraint firstAttribute="trailing" secondItem="y2w-7m-BE3" secondAttribute="trailing" constant="20" id="5xb-BK-tXG"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="y2w-7m-BE3" secondAttribute="bottom" id="NIx-Ms-nsQ"/>
|
<constraint firstAttribute="bottom" secondItem="y2w-7m-BE3" secondAttribute="bottom" constant="25" id="NIx-Ms-nsQ"/>
|
||||||
<constraint firstAttribute="height" priority="250" id="xbN-ph-dHU"/>
|
<constraint firstAttribute="height" priority="750" id="xbN-ph-dHU"/>
|
||||||
<constraint firstItem="y2w-7m-BE3" firstAttribute="leading" secondItem="SLA-sa-fBw" secondAttribute="leading" constant="20" id="zoQ-Pi-GNl"/>
|
<constraint firstItem="y2w-7m-BE3" firstAttribute="leading" secondItem="SLA-sa-fBw" secondAttribute="leading" constant="20" id="zoQ-Pi-GNl"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
</subviews>
|
</subviews>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="J1F-ba-sZ7" firstAttribute="width" secondItem="lPc-YT-wnY" secondAttribute="width" id="AYv-UT-c0c"/>
|
<constraint firstItem="J1F-ba-sZ7" firstAttribute="width" secondItem="lPc-YT-wnY" secondAttribute="width" id="AYv-UT-c0c"/>
|
||||||
|
<constraint firstItem="SLA-sa-fBw" firstAttribute="width" secondItem="lPc-YT-wnY" secondAttribute="width" id="elW-WH-1hZ"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</stackView>
|
</stackView>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
@ -98,13 +99,13 @@
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="bQd-8A-8hf">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="bQd-8A-8hf">
|
||||||
<rect key="frame" x="0.0" y="103" width="375" height="350"/>
|
<rect key="frame" x="0.0" y="113" width="375" height="330"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vrz-UO-PDk">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vrz-UO-PDk">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="220"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="200"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="NFT-6Y-5rt">
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="NFT-6Y-5rt">
|
||||||
<rect key="frame" x="97.5" y="20" width="180" height="180"/>
|
<rect key="frame" x="97.5" y="0.0" width="180" height="180"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="180" id="X3y-ER-PrC"/>
|
<constraint firstAttribute="width" constant="180" id="X3y-ER-PrC"/>
|
||||||
<constraint firstAttribute="width" secondItem="NFT-6Y-5rt" secondAttribute="height" multiplier="1:1" id="sOD-Bb-lIr"/>
|
<constraint firstAttribute="width" secondItem="NFT-6Y-5rt" secondAttribute="height" multiplier="1:1" id="sOD-Bb-lIr"/>
|
||||||
|
@ -115,11 +116,11 @@
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="bottom" secondItem="NFT-6Y-5rt" secondAttribute="bottom" constant="20" id="0Wi-uC-aoj"/>
|
<constraint firstAttribute="bottom" secondItem="NFT-6Y-5rt" secondAttribute="bottom" constant="20" id="0Wi-uC-aoj"/>
|
||||||
<constraint firstItem="NFT-6Y-5rt" firstAttribute="centerX" secondItem="vrz-UO-PDk" secondAttribute="centerX" id="8UT-Ob-m92"/>
|
<constraint firstItem="NFT-6Y-5rt" firstAttribute="centerX" secondItem="vrz-UO-PDk" secondAttribute="centerX" id="8UT-Ob-m92"/>
|
||||||
<constraint firstItem="NFT-6Y-5rt" firstAttribute="top" secondItem="vrz-UO-PDk" secondAttribute="top" constant="20" id="Sfi-ob-xej"/>
|
<constraint firstItem="NFT-6Y-5rt" firstAttribute="top" secondItem="vrz-UO-PDk" secondAttribute="top" id="Sfi-ob-xej"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s4G-bW-EGe">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s4G-bW-EGe">
|
||||||
<rect key="frame" x="0.0" y="220" width="375" height="55"/>
|
<rect key="frame" x="0.0" y="200" width="375" height="55"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="a4h-x5-COe">
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="a4h-x5-COe">
|
||||||
<rect key="frame" x="20" y="0.0" width="335" height="50"/>
|
<rect key="frame" x="20" y="0.0" width="335" height="50"/>
|
||||||
|
@ -146,7 +147,7 @@
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="n73-GU-j8x">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="n73-GU-j8x">
|
||||||
<rect key="frame" x="0.0" y="275" width="375" height="75"/>
|
<rect key="frame" x="0.0" y="255" width="375" height="75"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bRZ-4Z-DEJ">
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bRZ-4Z-DEJ">
|
||||||
<rect key="frame" x="20" y="5" width="335" height="50"/>
|
<rect key="frame" x="20" y="5" width="335" height="50"/>
|
||||||
|
|
|
@ -189,6 +189,17 @@ final class KeyVerificationVerifyByScanningViewController: UIViewController {
|
||||||
// Update the copy if QR code scanning is not possible at all
|
// Update the copy if QR code scanning is not possible at all
|
||||||
self.informationLabel.text = VectorL10n.keyVerificationVerifyQrCodeEmojiInformation
|
self.informationLabel.text = VectorL10n.keyVerificationVerifyQrCodeEmojiInformation
|
||||||
self.cannotScanButton.setTitle(VectorL10n.keyVerificationVerifyQrCodeStartEmojiAction, for: .normal)
|
self.cannotScanButton.setTitle(VectorL10n.keyVerificationVerifyQrCodeStartEmojiAction, for: .normal)
|
||||||
|
} else {
|
||||||
|
let informationText: String
|
||||||
|
|
||||||
|
switch viewData.verificationKind {
|
||||||
|
case .user:
|
||||||
|
informationText = VectorL10n.keyVerificationVerifyQrCodeInformation
|
||||||
|
default:
|
||||||
|
informationText = VectorL10n.keyVerificationVerifyQrCodeInformationOtherDevice
|
||||||
|
}
|
||||||
|
|
||||||
|
self.informationLabel.text = informationText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
// File created from ScreenTemplate
|
||||||
|
// $ createScreen.sh KeyVerification/Device/ManuallyVerify KeyVerificationManuallyVerify
|
||||||
|
/*
|
||||||
|
Copyright 2020 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class KeyVerificationManuallyVerifyCoordinator: KeyVerificationManuallyVerifyCoordinatorType {
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private let session: MXSession
|
||||||
|
private var keyVerificationManuallyVerifyViewModel: KeyVerificationManuallyVerifyViewModelType
|
||||||
|
private let keyVerificationManuallyVerifyViewController: KeyVerificationManuallyVerifyViewController
|
||||||
|
|
||||||
|
// MARK: Public
|
||||||
|
|
||||||
|
// Must be used only internally
|
||||||
|
var childCoordinators: [Coordinator] = []
|
||||||
|
|
||||||
|
weak var delegate: KeyVerificationManuallyVerifyCoordinatorDelegate?
|
||||||
|
|
||||||
|
// MARK: - Setup
|
||||||
|
|
||||||
|
init(session: MXSession, deviceId: String, userId: String) {
|
||||||
|
self.session = session
|
||||||
|
|
||||||
|
let keyVerificationManuallyVerifyViewModel = KeyVerificationManuallyVerifyViewModel(session: self.session, deviceId: deviceId, userId: userId)
|
||||||
|
let keyVerificationManuallyVerifyViewController = KeyVerificationManuallyVerifyViewController.instantiate(with: keyVerificationManuallyVerifyViewModel)
|
||||||
|
self.keyVerificationManuallyVerifyViewModel = keyVerificationManuallyVerifyViewModel
|
||||||
|
self.keyVerificationManuallyVerifyViewController = keyVerificationManuallyVerifyViewController
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public methods
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
self.keyVerificationManuallyVerifyViewModel.coordinatorDelegate = self
|
||||||
|
}
|
||||||
|
|
||||||
|
func toPresentable() -> UIViewController {
|
||||||
|
return self.keyVerificationManuallyVerifyViewController
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - KeyVerificationManuallyVerifyViewModelCoordinatorDelegate
|
||||||
|
extension KeyVerificationManuallyVerifyCoordinator: KeyVerificationManuallyVerifyViewModelCoordinatorDelegate {
|
||||||
|
|
||||||
|
func keyVerificationManuallyVerifyViewModel(_ viewModel: KeyVerificationManuallyVerifyViewModelType, didVerifiedDeviceWithId deviceId: String, of userId: String) {
|
||||||
|
self.delegate?.keyVerificationManuallyVerifyCoordinator(self, didVerifiedDeviceWithId: deviceId, of: userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyVerificationManuallyVerifyViewModelDidCancel(_ viewModel: KeyVerificationManuallyVerifyViewModelType) {
|
||||||
|
self.delegate?.keyVerificationManuallyVerifyCoordinatorDidCancel(self)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
// File created from ScreenTemplate
|
||||||
|
// $ createScreen.sh KeyVerification/Device/ManuallyVerify KeyVerificationManuallyVerify
|
||||||
|
/*
|
||||||
|
Copyright 2020 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol KeyVerificationManuallyVerifyCoordinatorDelegate: class {
|
||||||
|
func keyVerificationManuallyVerifyCoordinator(_ coordinator: KeyVerificationManuallyVerifyCoordinatorType, didVerifiedDeviceWithId deviceId: String, of userId: String)
|
||||||
|
func keyVerificationManuallyVerifyCoordinatorDidCancel(_ coordinator: KeyVerificationManuallyVerifyCoordinatorType)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `KeyVerificationManuallyVerifyCoordinatorType` is a protocol describing a Coordinator that handle key backup setup passphrase navigation flow.
|
||||||
|
protocol KeyVerificationManuallyVerifyCoordinatorType: Coordinator, Presentable {
|
||||||
|
var delegate: KeyVerificationManuallyVerifyCoordinatorDelegate? { get }
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
// File created from ScreenTemplate
|
||||||
|
// $ createScreen.sh KeyVerification/Device/ManuallyVerify KeyVerificationManuallyVerify
|
||||||
|
/*
|
||||||
|
Copyright 2020 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// KeyVerificationManuallyVerifyViewController view actions exposed to view model
|
||||||
|
enum KeyVerificationManuallyVerifyViewAction {
|
||||||
|
case loadData
|
||||||
|
case verify
|
||||||
|
case cancel
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="V8j-Lb-PgC">
|
||||||
|
<device id="retina6_1" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--Key Verification Manually Verify View Controller-->
|
||||||
|
<scene sceneID="mt5-wz-YKA">
|
||||||
|
<objects>
|
||||||
|
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="V8j-Lb-PgC" customClass="KeyVerificationManuallyVerifyViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="EL9-GA-lwo">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9U2-KL-ZVA">
|
||||||
|
<rect key="frame" x="0.0" y="44" width="414" height="852"/>
|
||||||
|
<subviews>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e7g-um-WO4">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="414" height="502"/>
|
||||||
|
<subviews>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="voD-3Q-ryt">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="414" height="502"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Confirm by comparing the following with the User Settings in your other session:" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RIj-L9-tZn">
|
||||||
|
<rect key="frame" x="20" y="20" width="374" height="33.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="qfH-9X-kBZ">
|
||||||
|
<rect key="frame" x="20" y="73.5" width="374" height="201"/>
|
||||||
|
<subviews>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YcY-tZ-Ga6">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="374" height="59"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Session name" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tp3-dZ-JyO">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="374" height="17"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://riot.im" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9SQ-lH-Hur">
|
||||||
|
<rect key="frame" x="0.0" y="22" width="374" height="37"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="tp3-dZ-JyO" firstAttribute="top" secondItem="YcY-tZ-Ga6" secondAttribute="top" id="Eai-tB-VyY"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="9SQ-lH-Hur" secondAttribute="bottom" id="MOQ-bv-PAZ"/>
|
||||||
|
<constraint firstItem="9SQ-lH-Hur" firstAttribute="top" secondItem="tp3-dZ-JyO" secondAttribute="bottom" constant="5" id="RuS-7X-CNf"/>
|
||||||
|
<constraint firstAttribute="height" priority="250" id="Y0c-6A-FOP"/>
|
||||||
|
<constraint firstItem="9SQ-lH-Hur" firstAttribute="leading" secondItem="tp3-dZ-JyO" secondAttribute="leading" id="Y9I-6j-wkw"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="tp3-dZ-JyO" secondAttribute="trailing" id="cVj-3V-bmi"/>
|
||||||
|
<constraint firstItem="tp3-dZ-JyO" firstAttribute="leading" secondItem="YcY-tZ-Ga6" secondAttribute="leading" id="dDq-eF-TRE"/>
|
||||||
|
<constraint firstItem="9SQ-lH-Hur" firstAttribute="trailing" secondItem="tp3-dZ-JyO" secondAttribute="trailing" id="rzJ-k3-tSZ"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jWK-JI-wHI">
|
||||||
|
<rect key="frame" x="0.0" y="71" width="374" height="59"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Session ID" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uVC-qK-ET7">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="374" height="17"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://riot.im" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WHf-qc-H4w">
|
||||||
|
<rect key="frame" x="0.0" y="22" width="374" height="37"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="uVC-qK-ET7" secondAttribute="trailing" id="Cq3-wf-eMz"/>
|
||||||
|
<constraint firstAttribute="height" priority="250" id="IhG-aQ-Ez2"/>
|
||||||
|
<constraint firstItem="WHf-qc-H4w" firstAttribute="top" secondItem="uVC-qK-ET7" secondAttribute="bottom" constant="5" id="Ivk-6g-bPa"/>
|
||||||
|
<constraint firstItem="WHf-qc-H4w" firstAttribute="trailing" secondItem="uVC-qK-ET7" secondAttribute="trailing" id="MFO-Gp-1oy"/>
|
||||||
|
<constraint firstItem="uVC-qK-ET7" firstAttribute="top" secondItem="jWK-JI-wHI" secondAttribute="top" id="POZ-uv-KVR"/>
|
||||||
|
<constraint firstItem="WHf-qc-H4w" firstAttribute="leading" secondItem="uVC-qK-ET7" secondAttribute="leading" id="o6y-OG-KcW"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="WHf-qc-H4w" secondAttribute="bottom" id="pX1-4I-5fr"/>
|
||||||
|
<constraint firstItem="uVC-qK-ET7" firstAttribute="leading" secondItem="jWK-JI-wHI" secondAttribute="leading" id="qky-qV-dcB"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EKr-6X-weJ">
|
||||||
|
<rect key="frame" x="0.0" y="142" width="374" height="59"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Session key" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tBF-i0-Q4C">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="374" height="17"/>
|
||||||
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="https://riot.im" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5fG-Wi-cVH">
|
||||||
|
<rect key="frame" x="0.0" y="22" width="374" height="37"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="5fG-Wi-cVH" firstAttribute="leading" secondItem="tBF-i0-Q4C" secondAttribute="leading" id="Kyc-YY-gzQ"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="5fG-Wi-cVH" secondAttribute="bottom" id="ZCc-3Y-ECo"/>
|
||||||
|
<constraint firstItem="5fG-Wi-cVH" firstAttribute="trailing" secondItem="tBF-i0-Q4C" secondAttribute="trailing" id="Zga-sP-Zc6"/>
|
||||||
|
<constraint firstItem="5fG-Wi-cVH" firstAttribute="top" secondItem="tBF-i0-Q4C" secondAttribute="bottom" constant="5" id="cr4-9q-O5W"/>
|
||||||
|
<constraint firstItem="tBF-i0-Q4C" firstAttribute="top" secondItem="EKr-6X-weJ" secondAttribute="top" id="jVr-qa-EU3"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="tBF-i0-Q4C" secondAttribute="trailing" id="mPM-qs-32S"/>
|
||||||
|
<constraint firstAttribute="height" priority="250" id="sHG-MG-dz7"/>
|
||||||
|
<constraint firstItem="tBF-i0-Q4C" firstAttribute="leading" secondItem="EKr-6X-weJ" secondAttribute="leading" id="taB-4o-BQf"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="YcY-tZ-Ga6" firstAttribute="width" secondItem="qfH-9X-kBZ" secondAttribute="width" id="5XJ-Oq-N4o"/>
|
||||||
|
</constraints>
|
||||||
|
</stackView>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="If they don't match, the security of your communication may be compromised." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wT1-a7-XOh">
|
||||||
|
<rect key="frame" x="20" y="294.5" width="374" height="33.5"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||||
|
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="mVH-0o-ZrL">
|
||||||
|
<rect key="frame" x="20" y="358" width="374" height="44"/>
|
||||||
|
<subviews>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6wi-YQ-QmI" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="177" height="44"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||||
|
<state key="normal" title="Cancel">
|
||||||
|
<color key="titleColor" red="1" green="0.29411764709999999" blue="0.33333333329999998" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
</state>
|
||||||
|
<connections>
|
||||||
|
<action selector="cancelButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="ytK-85-toE"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3pY-eX-Qfn" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="197" y="0.0" width="177" height="44"/>
|
||||||
|
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||||
|
<state key="normal" title="Verify">
|
||||||
|
<color key="titleColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
</state>
|
||||||
|
<connections>
|
||||||
|
<action selector="verifyButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="cfQ-bJ-jrr"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" priority="750" constant="44" id="BCf-fL-ZMJ"/>
|
||||||
|
<constraint firstItem="3pY-eX-Qfn" firstAttribute="height" secondItem="mVH-0o-ZrL" secondAttribute="height" priority="999" id="WUy-05-S5d"/>
|
||||||
|
<constraint firstItem="6wi-YQ-QmI" firstAttribute="height" secondItem="mVH-0o-ZrL" secondAttribute="height" priority="999" id="mZw-S9-WUz"/>
|
||||||
|
</constraints>
|
||||||
|
</stackView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="mVH-0o-ZrL" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="1x2-p1-gBl"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="mVH-0o-ZrL" secondAttribute="bottom" constant="100" id="3Ks-I4-3Pa"/>
|
||||||
|
<constraint firstItem="qfH-9X-kBZ" firstAttribute="top" secondItem="RIj-L9-tZn" secondAttribute="bottom" constant="20" id="7wU-kb-txG"/>
|
||||||
|
<constraint firstItem="wT1-a7-XOh" firstAttribute="trailing" secondItem="qfH-9X-kBZ" secondAttribute="trailing" id="9ws-hQ-6ag"/>
|
||||||
|
<constraint firstItem="RIj-L9-tZn" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="B24-EF-h5n"/>
|
||||||
|
<constraint firstItem="RIj-L9-tZn" firstAttribute="top" secondItem="voD-3Q-ryt" secondAttribute="top" constant="20" id="BMO-Kj-hUI"/>
|
||||||
|
<constraint firstItem="qfH-9X-kBZ" firstAttribute="trailing" secondItem="RIj-L9-tZn" secondAttribute="trailing" id="f5i-AM-Rae"/>
|
||||||
|
<constraint firstAttribute="width" priority="750" constant="500" id="glD-Sz-73O"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="mVH-0o-ZrL" secondAttribute="trailing" constant="20" id="oL7-Le-sqy"/>
|
||||||
|
<constraint firstItem="mVH-0o-ZrL" firstAttribute="top" secondItem="wT1-a7-XOh" secondAttribute="bottom" constant="30" id="rxl-Le-eol"/>
|
||||||
|
<constraint firstItem="qfH-9X-kBZ" firstAttribute="leading" secondItem="RIj-L9-tZn" secondAttribute="leading" id="sNm-19-5lu"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="RIj-L9-tZn" secondAttribute="trailing" constant="20" id="ucH-Ci-kvn"/>
|
||||||
|
<constraint firstItem="wT1-a7-XOh" firstAttribute="leading" secondItem="qfH-9X-kBZ" secondAttribute="leading" id="w6D-nQ-QPq"/>
|
||||||
|
<constraint firstItem="wT1-a7-XOh" firstAttribute="top" secondItem="qfH-9X-kBZ" secondAttribute="bottom" constant="20" id="zv7-lG-ks8"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="voD-3Q-ryt" secondAttribute="bottom" id="63a-5e-ptU"/>
|
||||||
|
<constraint firstItem="voD-3Q-ryt" firstAttribute="centerX" secondItem="e7g-um-WO4" secondAttribute="centerX" id="P2G-mq-gQW"/>
|
||||||
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="voD-3Q-ryt" secondAttribute="trailing" id="QgV-SO-5yf"/>
|
||||||
|
<constraint firstItem="voD-3Q-ryt" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="e7g-um-WO4" secondAttribute="leading" id="YPo-u1-PtT"/>
|
||||||
|
<constraint firstItem="voD-3Q-ryt" firstAttribute="top" secondItem="e7g-um-WO4" secondAttribute="top" id="rhQ-96-szL"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="e7g-um-WO4" secondAttribute="trailing" id="GyG-Fh-PME"/>
|
||||||
|
<constraint firstItem="e7g-um-WO4" firstAttribute="width" secondItem="9U2-KL-ZVA" secondAttribute="width" id="Ok2-WQ-Zgc"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="e7g-um-WO4" secondAttribute="bottom" id="Y46-NP-zAc"/>
|
||||||
|
<constraint firstItem="e7g-um-WO4" firstAttribute="leading" secondItem="9U2-KL-ZVA" secondAttribute="leading" id="aoV-Yh-AcD"/>
|
||||||
|
<constraint firstItem="e7g-um-WO4" firstAttribute="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="pFN-bA-SHw"/>
|
||||||
|
</constraints>
|
||||||
|
</scrollView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" red="0.94509803921568625" green="0.96078431372549022" blue="0.97254901960784312" alpha="1" colorSpace="calibratedRGB"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="9U2-KL-ZVA" secondAttribute="bottom" id="7Cb-nY-CsO"/>
|
||||||
|
<constraint firstItem="9U2-KL-ZVA" firstAttribute="leading" secondItem="bFg-jh-JZB" secondAttribute="leading" id="GdQ-hK-muG"/>
|
||||||
|
<constraint firstItem="bFg-jh-JZB" firstAttribute="trailing" secondItem="9U2-KL-ZVA" secondAttribute="trailing" id="sbD-ek-vGJ"/>
|
||||||
|
<constraint firstItem="bFg-jh-JZB" firstAttribute="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="wTB-V6-IHV"/>
|
||||||
|
</constraints>
|
||||||
|
<viewLayoutGuide key="safeArea" id="bFg-jh-JZB"/>
|
||||||
|
</view>
|
||||||
|
<connections>
|
||||||
|
<outlet property="additionalInformationLabel" destination="wT1-a7-XOh" id="5a3-Q0-gKF"/>
|
||||||
|
<outlet property="cancelButton" destination="6wi-YQ-QmI" id="0t1-M8-B6e"/>
|
||||||
|
<outlet property="deviceIdLabel" destination="WHf-qc-H4w" id="jmP-9Y-cXH"/>
|
||||||
|
<outlet property="deviceIdTitleLabel" destination="uVC-qK-ET7" id="ObX-Ys-hcO"/>
|
||||||
|
<outlet property="deviceKeyLabel" destination="5fG-Wi-cVH" id="a71-J8-TuA"/>
|
||||||
|
<outlet property="deviceKeyTitleLabel" destination="tBF-i0-Q4C" id="hBk-B1-Htu"/>
|
||||||
|
<outlet property="deviceNameLabel" destination="9SQ-lH-Hur" id="jqo-Y2-JzC"/>
|
||||||
|
<outlet property="deviceNameTitleLabel" destination="tp3-dZ-JyO" id="4Mt-qK-wfm"/>
|
||||||
|
<outlet property="informationLabel" destination="RIj-L9-tZn" id="TlB-EU-XGq"/>
|
||||||
|
<outlet property="scrollView" destination="9U2-KL-ZVA" id="ojG-2y-X7b"/>
|
||||||
|
<outlet property="verifyButton" destination="3pY-eX-Qfn" id="qhX-1D-gp9"/>
|
||||||
|
</connections>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="zK0-v6-7Wt" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="-3198.5507246376815" y="-647.54464285714278"/>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
|
@ -0,0 +1,224 @@
|
||||||
|
// File created from ScreenTemplate
|
||||||
|
// $ createScreen.sh KeyVerification/Device/ManuallyVerify KeyVerificationManuallyVerify
|
||||||
|
/*
|
||||||
|
Copyright 2020 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class KeyVerificationManuallyVerifyViewController: UIViewController {
|
||||||
|
|
||||||
|
// MARK: - Constants
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
// MARK: Outlets
|
||||||
|
|
||||||
|
@IBOutlet private weak var scrollView: UIScrollView!
|
||||||
|
|
||||||
|
@IBOutlet private weak var informationLabel: UILabel!
|
||||||
|
|
||||||
|
@IBOutlet private weak var deviceNameTitleLabel: UILabel!
|
||||||
|
@IBOutlet private weak var deviceNameLabel: UILabel!
|
||||||
|
|
||||||
|
@IBOutlet private weak var deviceIdTitleLabel: UILabel!
|
||||||
|
@IBOutlet private weak var deviceIdLabel: UILabel!
|
||||||
|
|
||||||
|
@IBOutlet private weak var deviceKeyTitleLabel: UILabel!
|
||||||
|
@IBOutlet private weak var deviceKeyLabel: UILabel!
|
||||||
|
|
||||||
|
@IBOutlet private weak var additionalInformationLabel: UILabel!
|
||||||
|
|
||||||
|
@IBOutlet private weak var verifyButton: RoundedButton!
|
||||||
|
@IBOutlet private weak var cancelButton: RoundedButton!
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private var viewModel: KeyVerificationManuallyVerifyViewModelType!
|
||||||
|
private var theme: Theme!
|
||||||
|
private var errorPresenter: MXKErrorPresentation!
|
||||||
|
private var activityPresenter: ActivityIndicatorPresenter!
|
||||||
|
|
||||||
|
// MARK: - Setup
|
||||||
|
|
||||||
|
class func instantiate(with viewModel: KeyVerificationManuallyVerifyViewModelType) -> KeyVerificationManuallyVerifyViewController {
|
||||||
|
let viewController = StoryboardScene.KeyVerificationManuallyVerifyViewController.initialScene.instantiate()
|
||||||
|
viewController.viewModel = viewModel
|
||||||
|
viewController.theme = ThemeService.shared().theme
|
||||||
|
return viewController
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Life cycle
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
// Do any additional setup after loading the view.
|
||||||
|
|
||||||
|
self.setupViews()
|
||||||
|
self.activityPresenter = ActivityIndicatorPresenter()
|
||||||
|
self.errorPresenter = MXKErrorAlertPresentation()
|
||||||
|
|
||||||
|
self.registerThemeServiceDidChangeThemeNotification()
|
||||||
|
self.update(theme: self.theme)
|
||||||
|
|
||||||
|
self.viewModel.viewDelegate = self
|
||||||
|
|
||||||
|
self.viewModel.process(viewAction: .loadData)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
|
||||||
|
if let navigationController = self.navigationController {
|
||||||
|
if navigationController.navigationBar.isHidden == true {
|
||||||
|
self.navigationItem.hidesBackButton = true
|
||||||
|
// Show navigation bar if needed
|
||||||
|
navigationController.setNavigationBarHidden(false, animated: animated)
|
||||||
|
} else {
|
||||||
|
// Hide back button
|
||||||
|
self.navigationItem.setHidesBackButton(true, animated: animated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidLayoutSubviews() {
|
||||||
|
super.viewDidLayoutSubviews()
|
||||||
|
|
||||||
|
// Fix label height after orientation change. See here https://www.objc.io/issues/3-views/advanced-auto-layout-toolbox/#intrinsic-content-size-of-multi-line-text for more information.
|
||||||
|
self.informationLabel.vc_fixMultilineHeight()
|
||||||
|
self.deviceNameTitleLabel.vc_fixMultilineHeight()
|
||||||
|
self.deviceNameLabel.vc_fixMultilineHeight()
|
||||||
|
self.deviceIdLabel.vc_fixMultilineHeight()
|
||||||
|
self.deviceIdTitleLabel.vc_fixMultilineHeight()
|
||||||
|
self.deviceKeyTitleLabel.vc_fixMultilineHeight()
|
||||||
|
self.deviceKeyLabel.vc_fixMultilineHeight()
|
||||||
|
self.additionalInformationLabel.vc_fixMultilineHeight()
|
||||||
|
|
||||||
|
self.view.layoutIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||||
|
return self.theme.statusBarStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func update(theme: Theme) {
|
||||||
|
self.theme = theme
|
||||||
|
|
||||||
|
self.view.backgroundColor = theme.headerBackgroundColor
|
||||||
|
|
||||||
|
if let navigationBar = self.navigationController?.navigationBar {
|
||||||
|
theme.applyStyle(onNavigationBar: navigationBar)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.informationLabel.textColor = theme.textPrimaryColor
|
||||||
|
|
||||||
|
self.deviceNameTitleLabel.textColor = theme.textPrimaryColor
|
||||||
|
self.deviceNameLabel.textColor = theme.textPrimaryColor
|
||||||
|
|
||||||
|
self.deviceIdTitleLabel.textColor = theme.textPrimaryColor
|
||||||
|
self.deviceIdLabel.textColor = theme.textPrimaryColor
|
||||||
|
|
||||||
|
self.deviceKeyTitleLabel.textColor = theme.textPrimaryColor
|
||||||
|
self.deviceKeyLabel.textColor = theme.textPrimaryColor
|
||||||
|
|
||||||
|
self.additionalInformationLabel.textColor = theme.textPrimaryColor
|
||||||
|
|
||||||
|
self.cancelButton.update(theme: theme)
|
||||||
|
self.verifyButton.update(theme: theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func registerThemeServiceDidChangeThemeNotification() {
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange), name: .themeServiceDidChangeTheme, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func themeDidChange() {
|
||||||
|
self.update(theme: ThemeService.shared().theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setupViews() {
|
||||||
|
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
|
||||||
|
self?.cancelAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
||||||
|
|
||||||
|
self.title = VectorL10n.keyVerificationManuallyVerifyDeviceTitle
|
||||||
|
self.informationLabel.text = VectorL10n.keyVerificationManuallyVerifyDeviceInstruction
|
||||||
|
self.deviceNameTitleLabel.text = VectorL10n.keyVerificationManuallyVerifyDeviceNameTitle
|
||||||
|
self.deviceIdTitleLabel.text = VectorL10n.keyVerificationManuallyVerifyDeviceIdTitle
|
||||||
|
self.deviceKeyTitleLabel.text = VectorL10n.keyVerificationManuallyVerifyDeviceKeyTitle
|
||||||
|
self.additionalInformationLabel.text = VectorL10n.keyVerificationManuallyVerifyDeviceAdditionalInformation
|
||||||
|
|
||||||
|
self.deviceNameLabel.text = nil
|
||||||
|
self.deviceIdLabel.text = nil
|
||||||
|
self.deviceKeyLabel.text = nil
|
||||||
|
|
||||||
|
self.cancelButton.actionStyle = .cancel
|
||||||
|
}
|
||||||
|
|
||||||
|
private func render(viewState: KeyVerificationManuallyVerifyViewState) {
|
||||||
|
switch viewState {
|
||||||
|
case .loading:
|
||||||
|
self.renderLoading()
|
||||||
|
case .loaded(let viewData):
|
||||||
|
self.renderLoaded(viewData: viewData)
|
||||||
|
case .error(let error):
|
||||||
|
self.render(error: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func renderLoading() {
|
||||||
|
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func renderLoaded(viewData: KeyVerificationManuallyVerifyViewData) {
|
||||||
|
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||||
|
|
||||||
|
self.deviceNameLabel.text = viewData.deviceName
|
||||||
|
self.deviceIdLabel.text = viewData.deviceId
|
||||||
|
self.deviceKeyLabel.text = viewData.deviceKey
|
||||||
|
}
|
||||||
|
|
||||||
|
private func render(error: Error) {
|
||||||
|
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||||
|
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Actions
|
||||||
|
|
||||||
|
@IBAction private func verifyButtonAction(_ sender: Any) {
|
||||||
|
self.viewModel.process(viewAction: .verify)
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction private func cancelButtonAction(_ sender: Any) {
|
||||||
|
self.cancelAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func cancelAction() {
|
||||||
|
self.viewModel.process(viewAction: .cancel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: - KeyVerificationManuallyVerifyViewModelViewDelegate
|
||||||
|
extension KeyVerificationManuallyVerifyViewController: KeyVerificationManuallyVerifyViewModelViewDelegate {
|
||||||
|
|
||||||
|
func keyVerificationManuallyVerifyViewModel(_ viewModel: KeyVerificationManuallyVerifyViewModelType, didUpdateViewState viewSate: KeyVerificationManuallyVerifyViewState) {
|
||||||
|
self.render(viewState: viewSate)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
// File created from ScreenTemplate
|
||||||
|
// $ createScreen.sh KeyVerification/Device/ManuallyVerify KeyVerificationManuallyVerify
|
||||||
|
/*
|
||||||
|
Copyright 2020 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum KeyVerificationManuallyVerifyViewModelError: Error {
|
||||||
|
case unknown
|
||||||
|
case deviceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
final class KeyVerificationManuallyVerifyViewModel: KeyVerificationManuallyVerifyViewModelType {
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
// MARK: Private
|
||||||
|
|
||||||
|
private let session: MXSession
|
||||||
|
private let deviceId: String
|
||||||
|
private let userId: String
|
||||||
|
|
||||||
|
private var currentOperation: MXHTTPOperation?
|
||||||
|
|
||||||
|
// MARK: Public
|
||||||
|
|
||||||
|
weak var viewDelegate: KeyVerificationManuallyVerifyViewModelViewDelegate?
|
||||||
|
weak var coordinatorDelegate: KeyVerificationManuallyVerifyViewModelCoordinatorDelegate?
|
||||||
|
|
||||||
|
// MARK: - Setup
|
||||||
|
|
||||||
|
init(session: MXSession, deviceId: String, userId: String) {
|
||||||
|
self.session = session
|
||||||
|
self.deviceId = deviceId
|
||||||
|
self.userId = userId
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.cancelOperations()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
func process(viewAction: KeyVerificationManuallyVerifyViewAction) {
|
||||||
|
switch viewAction {
|
||||||
|
case .loadData:
|
||||||
|
self.loadData()
|
||||||
|
case .verify:
|
||||||
|
self.verifyDevice()
|
||||||
|
case .cancel:
|
||||||
|
self.cancelOperations()
|
||||||
|
self.coordinatorDelegate?.keyVerificationManuallyVerifyViewModelDidCancel(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func loadData() {
|
||||||
|
|
||||||
|
guard let deviceInfo = self.session.crypto.device(withDeviceId: self.deviceId, ofUser: self.userId) else {
|
||||||
|
self.update(viewState: .error(KeyVerificationManuallyVerifyViewModelError.deviceNotFound))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var deviceKey: String?
|
||||||
|
|
||||||
|
if let deviceFingerprint = deviceInfo.fingerprint {
|
||||||
|
deviceKey = MXTools.addWhiteSpaces(to: deviceFingerprint, every: 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
let viewData = KeyVerificationManuallyVerifyViewData(deviceId: self.deviceId, deviceName: deviceInfo.displayName, deviceKey: deviceKey)
|
||||||
|
self.update(viewState: .loaded(viewData))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func update(viewState: KeyVerificationManuallyVerifyViewState) {
|
||||||
|
self.viewDelegate?.keyVerificationManuallyVerifyViewModel(self, didUpdateViewState: viewState)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func verifyDevice() {
|
||||||
|
|
||||||
|
self.update(viewState: .loading)
|
||||||
|
|
||||||
|
self.session.crypto.setDeviceVerification(.verified, forDevice: self.deviceId, ofUser: self.userId, success: { [weak self] in
|
||||||
|
guard let self = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.coordinatorDelegate?.keyVerificationManuallyVerifyViewModel(self, didVerifiedDeviceWithId: self.deviceId, of: self.userId)
|
||||||
|
}, failure: { [weak self] (error) in
|
||||||
|
guard let self = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let finalError = error ?? KeyVerificationManuallyVerifyViewModelError.unknown
|
||||||
|
self.update(viewState: .error(finalError))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private func cancelOperations() {
|
||||||
|
self.currentOperation?.cancel()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
// File created from ScreenTemplate
|
||||||
|
// $ createScreen.sh KeyVerification/Device/ManuallyVerify KeyVerificationManuallyVerify
|
||||||
|
/*
|
||||||
|
Copyright 2020 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol KeyVerificationManuallyVerifyViewModelViewDelegate: class {
|
||||||
|
func keyVerificationManuallyVerifyViewModel(_ viewModel: KeyVerificationManuallyVerifyViewModelType, didUpdateViewState viewSate: KeyVerificationManuallyVerifyViewState)
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol KeyVerificationManuallyVerifyViewModelCoordinatorDelegate: class {
|
||||||
|
func keyVerificationManuallyVerifyViewModel(_ viewModel: KeyVerificationManuallyVerifyViewModelType, didVerifiedDeviceWithId deviceId: String, of userId: String)
|
||||||
|
func keyVerificationManuallyVerifyViewModelDidCancel(_ viewModel: KeyVerificationManuallyVerifyViewModelType)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Protocol describing the view model used by `KeyVerificationManuallyVerifyViewController`
|
||||||
|
protocol KeyVerificationManuallyVerifyViewModelType {
|
||||||
|
|
||||||
|
var viewDelegate: KeyVerificationManuallyVerifyViewModelViewDelegate? { get set }
|
||||||
|
var coordinatorDelegate: KeyVerificationManuallyVerifyViewModelCoordinatorDelegate? { get set }
|
||||||
|
|
||||||
|
func process(viewAction: KeyVerificationManuallyVerifyViewAction)
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// File created from ScreenTemplate
|
||||||
|
// $ createScreen.sh KeyVerification/Device/ManuallyVerify KeyVerificationManuallyVerify
|
||||||
|
/*
|
||||||
|
Copyright 2020 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct KeyVerificationManuallyVerifyViewData {
|
||||||
|
let deviceId: String
|
||||||
|
let deviceName: String?
|
||||||
|
let deviceKey: String?
|
||||||
|
}
|
||||||
|
|
||||||
|
/// KeyVerificationManuallyVerifyViewController view state
|
||||||
|
enum KeyVerificationManuallyVerifyViewState {
|
||||||
|
case loading
|
||||||
|
case loaded(_ viewData: KeyVerificationManuallyVerifyViewData)
|
||||||
|
case error(Error)
|
||||||
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RcA-LK-bqZ">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="RcA-LK-bqZ">
|
||||||
<rect key="frame" x="0.0" y="254" width="375" height="179"/>
|
<rect key="frame" x="0.0" y="254" width="375" height="179"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For extra security, verify @user:matrix.org by checking a one-time code on both your devices." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ii0-Vq-vuo">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For extra security, verify @user:matrix.org by checking a one-time code on both your devices." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ii0-Vq-vuo">
|
||||||
<rect key="frame" x="20" y="10" width="335" height="36"/>
|
<rect key="frame" x="20" y="10" width="335" height="36"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
|
|
|
@ -74,6 +74,21 @@ final class KeyVerificationSelfVerifyStartViewController: UIViewController {
|
||||||
self.viewModel.process(viewAction: .loadData)
|
self.viewModel.process(viewAction: .loadData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
|
||||||
|
if let navigationController = self.navigationController {
|
||||||
|
if navigationController.navigationBar.isHidden == true {
|
||||||
|
self.navigationItem.hidesBackButton = true
|
||||||
|
// Show navigation bar if needed
|
||||||
|
navigationController.setNavigationBarHidden(false, animated: animated)
|
||||||
|
} else {
|
||||||
|
// Hide back button
|
||||||
|
self.navigationItem.setHidesBackButton(true, animated: animated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func viewDidLayoutSubviews() {
|
override func viewDidLayoutSubviews() {
|
||||||
super.viewDidLayoutSubviews()
|
super.viewDidLayoutSubviews()
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,23 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func loadData() {
|
private func loadData() {
|
||||||
|
|
||||||
|
if !self.isNewSignIn {
|
||||||
|
print("[KeyVerificationSelfVerifyWaitViewModel] loadData: Send a verification request to all devices")
|
||||||
|
|
||||||
|
let keyVerificationService = KeyVerificationService()
|
||||||
|
self.verificationManager.requestVerificationByToDevice(withUserId: self.session.myUserId, deviceIds: nil, methods: keyVerificationService.supportedKeyVerificationMethods(), success: { [weak self] (keyVerificationRequest) in
|
||||||
|
guard let self = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.keyVerificationRequest = keyVerificationRequest
|
||||||
|
|
||||||
|
}, failure: { [weak self] error in
|
||||||
|
self?.update(viewState: .error(error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
self.registerKeyVerificationManagerNewRequestNotification(for: self.verificationManager)
|
self.registerKeyVerificationManagerNewRequestNotification(for: self.verificationManager)
|
||||||
self.update(viewState: .loaded(self.isNewSignIn))
|
self.update(viewState: .loaded(self.isNewSignIn))
|
||||||
self.registerTransactionDidStateChangeNotification()
|
self.registerTransactionDidStateChangeNotification()
|
||||||
|
|
|
@ -65,6 +65,10 @@ final class UserVerificationSessionStatusCoordinator: UserVerificationSessionSta
|
||||||
// MARK: - UserVerificationSessionStatusViewModelCoordinatorDelegate
|
// MARK: - UserVerificationSessionStatusViewModelCoordinatorDelegate
|
||||||
extension UserVerificationSessionStatusCoordinator: UserVerificationSessionStatusViewModelCoordinatorDelegate {
|
extension UserVerificationSessionStatusCoordinator: UserVerificationSessionStatusViewModelCoordinatorDelegate {
|
||||||
|
|
||||||
|
func userVerificationSessionStatusViewModel(_ viewModel: UserVerificationSessionStatusViewModelType, wantsToVerifyDeviceWithId deviceId: String, for userId: String) {
|
||||||
|
self.delegate?.userVerificationSessionStatusCoordinator(self, wantsToVerifyDeviceWithId: deviceId, for: userId)
|
||||||
|
}
|
||||||
|
|
||||||
func userVerificationSessionStatusViewModel(_ viewModel: UserVerificationSessionStatusViewModelType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String) {
|
func userVerificationSessionStatusViewModel(_ viewModel: UserVerificationSessionStatusViewModelType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String) {
|
||||||
self.delegate?.userVerificationSessionStatusCoordinator(self, wantsToManuallyVerifyDeviceWithId: deviceId, for: userId)
|
self.delegate?.userVerificationSessionStatusCoordinator(self, wantsToManuallyVerifyDeviceWithId: deviceId, for: userId)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol UserVerificationSessionStatusCoordinatorDelegate: class {
|
protocol UserVerificationSessionStatusCoordinatorDelegate: class {
|
||||||
|
func userVerificationSessionStatusCoordinator(_ coordinator: UserVerificationSessionStatusCoordinatorType, wantsToVerifyDeviceWithId deviceId: String, for userId: String)
|
||||||
func userVerificationSessionStatusCoordinator(_ coordinator: UserVerificationSessionStatusCoordinatorType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String)
|
func userVerificationSessionStatusCoordinator(_ coordinator: UserVerificationSessionStatusCoordinatorType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String)
|
||||||
func userVerificationSessionStatusCoordinatorDidClose(_ coordinator: UserVerificationSessionStatusCoordinatorType)
|
func userVerificationSessionStatusCoordinatorDidClose(_ coordinator: UserVerificationSessionStatusCoordinatorType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,6 @@ import Foundation
|
||||||
enum UserVerificationSessionStatusViewAction {
|
enum UserVerificationSessionStatusViewAction {
|
||||||
case loadData
|
case loadData
|
||||||
case verify
|
case verify
|
||||||
|
case verifyManually
|
||||||
case close
|
case close
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sX2-Xu-9f5">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sX2-Xu-9f5">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="296.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="348.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1lx-d3-6c2">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1lx-d3-6c2">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="108"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="108"/>
|
||||||
|
@ -102,10 +102,10 @@
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="rB7-Ct-Mq7">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="rB7-Ct-Mq7">
|
||||||
<rect key="frame" x="0.0" y="148.5" width="375" height="148"/>
|
<rect key="frame" x="0.0" y="148.5" width="375" height="200"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oRN-W6-TVF">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oRN-W6-TVF">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="148"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="200"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dd2-N5-GEx">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dd2-N5-GEx">
|
||||||
<rect key="frame" x="20" y="10" width="335" height="54"/>
|
<rect key="frame" x="20" y="10" width="335" height="54"/>
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
</constraints>
|
</constraints>
|
||||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
|
||||||
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
|
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
|
||||||
<state key="normal" title="Manually verify">
|
<state key="normal" title="Verify">
|
||||||
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</state>
|
</state>
|
||||||
|
@ -131,15 +131,36 @@
|
||||||
<action selector="verifyButtonAction:" destination="edG-Ef-G5W" eventType="touchUpInside" id="gGx-OT-X5w"/>
|
<action selector="verifyButtonAction:" destination="edG-Ef-G5W" eventType="touchUpInside" id="gGx-OT-X5w"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zpI-gc-wUh">
|
||||||
|
<rect key="frame" x="76" y="136" width="223" height="44"/>
|
||||||
|
<accessibility key="accessibilityConfiguration" identifier="AuthenticationVCLoginButton"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="100" id="e0g-or-1Fr"/>
|
||||||
|
<constraint firstAttribute="height" constant="44" id="m7k-72-n0t"/>
|
||||||
|
</constraints>
|
||||||
|
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="15"/>
|
||||||
|
<inset key="contentEdgeInsets" minX="30" minY="0.0" maxX="30" maxY="0.0"/>
|
||||||
|
<state key="normal" title="Manually Verify by Text">
|
||||||
|
<color key="titleColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</state>
|
||||||
|
<connections>
|
||||||
|
<action selector="manuallyVerifyButtonAction:" destination="edG-Ef-G5W" eventType="touchUpInside" id="fpP-Yv-6dD"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="bottom" secondItem="HiI-uV-Hjw" secondAttribute="bottom" constant="20" id="3bP-Hs-m42"/>
|
<constraint firstItem="zpI-gc-wUh" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="oRN-W6-TVF" secondAttribute="leading" constant="20" id="3AK-6W-oYS"/>
|
||||||
<constraint firstAttribute="trailing" secondItem="dd2-N5-GEx" secondAttribute="trailing" constant="20" id="BHw-Yv-ceG"/>
|
<constraint firstAttribute="trailing" secondItem="dd2-N5-GEx" secondAttribute="trailing" constant="20" id="BHw-Yv-ceG"/>
|
||||||
<constraint firstItem="dd2-N5-GEx" firstAttribute="leading" secondItem="oRN-W6-TVF" secondAttribute="leading" constant="20" id="BV7-Vu-PQR"/>
|
<constraint firstItem="dd2-N5-GEx" firstAttribute="leading" secondItem="oRN-W6-TVF" secondAttribute="leading" constant="20" id="BV7-Vu-PQR"/>
|
||||||
<constraint firstItem="HiI-uV-Hjw" firstAttribute="top" secondItem="dd2-N5-GEx" secondAttribute="bottom" constant="20" id="BtT-Mg-Okq"/>
|
<constraint firstItem="HiI-uV-Hjw" firstAttribute="top" secondItem="dd2-N5-GEx" secondAttribute="bottom" constant="20" id="BtT-Mg-Okq"/>
|
||||||
<constraint firstItem="HiI-uV-Hjw" firstAttribute="centerX" secondItem="oRN-W6-TVF" secondAttribute="centerX" id="Ign-Yp-tpB"/>
|
<constraint firstItem="HiI-uV-Hjw" firstAttribute="centerX" secondItem="oRN-W6-TVF" secondAttribute="centerX" id="Ign-Yp-tpB"/>
|
||||||
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="zpI-gc-wUh" secondAttribute="trailing" constant="20" id="T1v-Iv-kls"/>
|
||||||
<constraint firstItem="dd2-N5-GEx" firstAttribute="top" secondItem="oRN-W6-TVF" secondAttribute="top" constant="10" id="Ygn-tl-ahK"/>
|
<constraint firstItem="dd2-N5-GEx" firstAttribute="top" secondItem="oRN-W6-TVF" secondAttribute="top" constant="10" id="Ygn-tl-ahK"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="zpI-gc-wUh" secondAttribute="bottom" constant="20" id="bsQ-04-17O"/>
|
||||||
|
<constraint firstItem="zpI-gc-wUh" firstAttribute="top" secondItem="HiI-uV-Hjw" secondAttribute="bottom" constant="8" symbolic="YES" id="i06-nz-c3n"/>
|
||||||
|
<constraint firstItem="zpI-gc-wUh" firstAttribute="centerX" secondItem="oRN-W6-TVF" secondAttribute="centerX" id="lCz-Rb-vQB"/>
|
||||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="HiI-uV-Hjw" secondAttribute="trailing" constant="20" id="nqA-lS-ubx"/>
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="HiI-uV-Hjw" secondAttribute="trailing" constant="20" id="nqA-lS-ubx"/>
|
||||||
<constraint firstItem="HiI-uV-Hjw" firstAttribute="width" secondItem="oRN-W6-TVF" secondAttribute="width" priority="250" id="qp1-z5-eP9"/>
|
<constraint firstItem="HiI-uV-Hjw" firstAttribute="width" secondItem="oRN-W6-TVF" secondAttribute="width" priority="250" id="qp1-z5-eP9"/>
|
||||||
<constraint firstItem="HiI-uV-Hjw" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="oRN-W6-TVF" secondAttribute="leading" constant="20" id="uNl-Ok-uee"/>
|
<constraint firstItem="HiI-uV-Hjw" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="oRN-W6-TVF" secondAttribute="leading" constant="20" id="uNl-Ok-uee"/>
|
||||||
|
@ -191,6 +212,7 @@
|
||||||
<outlet property="deviceInformationLabel" destination="FET-ZT-Q69" id="D8n-5b-H4p"/>
|
<outlet property="deviceInformationLabel" destination="FET-ZT-Q69" id="D8n-5b-H4p"/>
|
||||||
<outlet property="deviceStatusImageView" destination="0ME-4K-MWA" id="kgp-dT-Q0P"/>
|
<outlet property="deviceStatusImageView" destination="0ME-4K-MWA" id="kgp-dT-Q0P"/>
|
||||||
<outlet property="informationLabel" destination="CTY-XM-iLf" id="qVC-lS-YOY"/>
|
<outlet property="informationLabel" destination="CTY-XM-iLf" id="qVC-lS-YOY"/>
|
||||||
|
<outlet property="manuallyVerifyButton" destination="zpI-gc-wUh" id="tt1-h1-TrK"/>
|
||||||
<outlet property="titleLabel" destination="mXI-Sg-wYe" id="Wrj-QM-srt"/>
|
<outlet property="titleLabel" destination="mXI-Sg-wYe" id="Wrj-QM-srt"/>
|
||||||
<outlet property="untrustedSessionContainerView" destination="oRN-W6-TVF" id="9sc-53-MWY"/>
|
<outlet property="untrustedSessionContainerView" destination="oRN-W6-TVF" id="9sc-53-MWY"/>
|
||||||
<outlet property="untrustedSessionInformationLabel" destination="dd2-N5-GEx" id="6TB-Ve-OyC"/>
|
<outlet property="untrustedSessionInformationLabel" destination="dd2-N5-GEx" id="6TB-Ve-OyC"/>
|
||||||
|
|
|
@ -45,6 +45,7 @@ final class UserVerificationSessionStatusViewController: UIViewController {
|
||||||
@IBOutlet private weak var untrustedSessionContainerView: UIView!
|
@IBOutlet private weak var untrustedSessionContainerView: UIView!
|
||||||
@IBOutlet private weak var untrustedSessionInformationLabel: UILabel!
|
@IBOutlet private weak var untrustedSessionInformationLabel: UILabel!
|
||||||
@IBOutlet private weak var verifyButton: UIButton!
|
@IBOutlet private weak var verifyButton: UIButton!
|
||||||
|
@IBOutlet private weak var manuallyVerifyButton: UIButton!
|
||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
|
@ -111,6 +112,8 @@ final class UserVerificationSessionStatusViewController: UIViewController {
|
||||||
|
|
||||||
self.untrustedSessionInformationLabel.textColor = theme.textPrimaryColor
|
self.untrustedSessionInformationLabel.textColor = theme.textPrimaryColor
|
||||||
self.verifyButton.vc_setBackgroundColor(theme.tintColor, for: .normal)
|
self.verifyButton.vc_setBackgroundColor(theme.tintColor, for: .normal)
|
||||||
|
|
||||||
|
theme.applyStyle(onButton: self.manuallyVerifyButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func registerThemeServiceDidChangeThemeNotification() {
|
private func registerThemeServiceDidChangeThemeNotification() {
|
||||||
|
@ -124,6 +127,8 @@ final class UserVerificationSessionStatusViewController: UIViewController {
|
||||||
private func setupViews() {
|
private func setupViews() {
|
||||||
self.closeButton.layer.masksToBounds = true
|
self.closeButton.layer.masksToBounds = true
|
||||||
self.verifyButton.layer.masksToBounds = true
|
self.verifyButton.layer.masksToBounds = true
|
||||||
|
|
||||||
|
self.manuallyVerifyButton.setTitle(VectorL10n.userVerificationSessionDetailsVerifyActionCurrentUserManually, for: .normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func render(viewState: UserVerificationSessionStatusViewState) {
|
private func render(viewState: UserVerificationSessionStatusViewState) {
|
||||||
|
@ -149,6 +154,8 @@ final class UserVerificationSessionStatusViewController: UIViewController {
|
||||||
|
|
||||||
self.untrustedSessionContainerView.isHidden = viewData.isDeviceTrusted
|
self.untrustedSessionContainerView.isHidden = viewData.isDeviceTrusted
|
||||||
|
|
||||||
|
self.manuallyVerifyButton.isHidden = !viewData.isCurrentUser
|
||||||
|
|
||||||
if viewData.isDeviceTrusted {
|
if viewData.isDeviceTrusted {
|
||||||
badgeImage = Asset.Images.encryptionTrusted.image
|
badgeImage = Asset.Images.encryptionTrusted.image
|
||||||
title = VectorL10n.userVerificationSessionDetailsTrustedTitle
|
title = VectorL10n.userVerificationSessionDetailsTrustedTitle
|
||||||
|
@ -181,7 +188,12 @@ final class UserVerificationSessionStatusViewController: UIViewController {
|
||||||
|
|
||||||
private func render(error: Error) {
|
private func render(error: Error) {
|
||||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||||
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)
|
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: {
|
||||||
|
|
||||||
|
if case UserVerificationSessionStatusViewModelError.deviceNotFound = error {
|
||||||
|
self.viewModel.process(viewAction: .close)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private func buildUserInfoText(with userId: String, userDisplayName: String?) -> String {
|
private func buildUserInfoText(with userId: String, userDisplayName: String?) -> String {
|
||||||
|
@ -258,6 +270,10 @@ final class UserVerificationSessionStatusViewController: UIViewController {
|
||||||
@IBAction private func verifyButtonAction(_ sender: Any) {
|
@IBAction private func verifyButtonAction(_ sender: Any) {
|
||||||
self.viewModel.process(viewAction: .verify)
|
self.viewModel.process(viewAction: .verify)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@IBAction private func manuallyVerifyButtonAction(_ sender: Any) {
|
||||||
|
self.viewModel.process(viewAction: .verifyManually)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ final class UserVerificationSessionStatusViewModel: UserVerificationSessionStatu
|
||||||
case .loadData:
|
case .loadData:
|
||||||
self.loadData()
|
self.loadData()
|
||||||
case .verify:
|
case .verify:
|
||||||
|
self.coordinatorDelegate?.userVerificationSessionStatusViewModel(self, wantsToVerifyDeviceWithId: self.deviceId, for: self.userId)
|
||||||
|
case .verifyManually:
|
||||||
self.coordinatorDelegate?.userVerificationSessionStatusViewModel(self, wantsToManuallyVerifyDeviceWithId: self.deviceId, for: self.userId)
|
self.coordinatorDelegate?.userVerificationSessionStatusViewModel(self, wantsToManuallyVerifyDeviceWithId: self.deviceId, for: self.userId)
|
||||||
case .close:
|
case .close:
|
||||||
self.coordinatorDelegate?.userVerificationSessionStatusViewModelDidClose(self)
|
self.coordinatorDelegate?.userVerificationSessionStatusViewModelDidClose(self)
|
||||||
|
|
|
@ -23,6 +23,7 @@ protocol UserVerificationSessionStatusViewModelViewDelegate: class {
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol UserVerificationSessionStatusViewModelCoordinatorDelegate: class {
|
protocol UserVerificationSessionStatusViewModelCoordinatorDelegate: class {
|
||||||
|
func userVerificationSessionStatusViewModel(_ viewModel: UserVerificationSessionStatusViewModelType, wantsToVerifyDeviceWithId deviceId: String, for userId: String)
|
||||||
func userVerificationSessionStatusViewModel(_ viewModel: UserVerificationSessionStatusViewModelType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String)
|
func userVerificationSessionStatusViewModel(_ viewModel: UserVerificationSessionStatusViewModelType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String)
|
||||||
func userVerificationSessionStatusViewModelDidClose(_ viewModel: UserVerificationSessionStatusViewModelType)
|
func userVerificationSessionStatusViewModelDidClose(_ viewModel: UserVerificationSessionStatusViewModelType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,16 @@ final class UserVerificationCoordinator: NSObject, UserVerificationCoordinatorTy
|
||||||
|
|
||||||
self.presenter.toPresentable().present(alert, animated: true, completion: nil)
|
self.presenter.toPresentable().present(alert, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func presentManualDeviceVerification(for deviceId: String, of userId: String) {
|
||||||
|
let coordinator = KeyVerificationManuallyVerifyCoordinator(session: self.session, deviceId: deviceId, userId: userId)
|
||||||
|
coordinator.delegate = self
|
||||||
|
coordinator.start()
|
||||||
|
|
||||||
|
self.navigationRouter.push(coordinator, animated: true) {
|
||||||
|
self.remove(childCoordinator: coordinator)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UserVerificationSessionsStatusCoordinatorDelegate
|
// MARK: - UserVerificationSessionsStatusCoordinatorDelegate
|
||||||
|
@ -159,11 +169,14 @@ extension UserVerificationCoordinator: UserVerificationSessionsStatusCoordinator
|
||||||
// MARK: - UserVerificationSessionStatusCoordinatorDelegate
|
// MARK: - UserVerificationSessionStatusCoordinatorDelegate
|
||||||
extension UserVerificationCoordinator: UserVerificationSessionStatusCoordinatorDelegate {
|
extension UserVerificationCoordinator: UserVerificationSessionStatusCoordinatorDelegate {
|
||||||
|
|
||||||
func userVerificationSessionStatusCoordinator(_ coordinator: UserVerificationSessionStatusCoordinatorType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String) {
|
func userVerificationSessionStatusCoordinator(_ coordinator: UserVerificationSessionStatusCoordinatorType, wantsToVerifyDeviceWithId deviceId: String, for userId: String) {
|
||||||
|
|
||||||
self.presentDeviceVerification(for: deviceId)
|
self.presentDeviceVerification(for: deviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func userVerificationSessionStatusCoordinator(_ coordinator: UserVerificationSessionStatusCoordinatorType, wantsToManuallyVerifyDeviceWithId deviceId: String, for userId: String) {
|
||||||
|
self.presentManualDeviceVerification(for: deviceId, of: userId)
|
||||||
|
}
|
||||||
|
|
||||||
func userVerificationSessionStatusCoordinatorDidClose(_ coordinator: UserVerificationSessionStatusCoordinatorType) {
|
func userVerificationSessionStatusCoordinatorDidClose(_ coordinator: UserVerificationSessionStatusCoordinatorType) {
|
||||||
|
|
||||||
self.presenter.toPresentable().dismiss(animated: true) {
|
self.presenter.toPresentable().dismiss(animated: true) {
|
||||||
|
@ -189,3 +202,19 @@ extension UserVerificationCoordinator: KeyVerificationCoordinatorDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - KeyVerificationManuallyVerifyCoordinatorDelegate
|
||||||
|
extension UserVerificationCoordinator: KeyVerificationManuallyVerifyCoordinatorDelegate {
|
||||||
|
|
||||||
|
func keyVerificationManuallyVerifyCoordinator(_ coordinator: KeyVerificationManuallyVerifyCoordinatorType, didVerifiedDeviceWithId deviceId: String, of userId: String) {
|
||||||
|
self.presenter.toPresentable().dismiss(animated: true) {
|
||||||
|
self.remove(childCoordinator: coordinator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyVerificationManuallyVerifyCoordinatorDidCancel(_ coordinator: KeyVerificationManuallyVerifyCoordinatorType) {
|
||||||
|
self.presenter.toPresentable().dismiss(animated: true) {
|
||||||
|
self.remove(childCoordinator: coordinator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -468,10 +468,17 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self.mxRoom.mxSession.crypto downloadKeys:@[userId] forceDownload:YES success:^(MXUsersDevicesMap<MXDeviceInfo *> *usersDevicesInfoMap, NSDictionary<NSString *,MXCrossSigningInfo *> *crossSigningKeysMap) {
|
||||||
[self.mxRoom encryptionTrustLevelForUserId:userId onComplete:^(UserEncryptionTrustLevel userEncryptionTrustLevel) {
|
[self.mxRoom encryptionTrustLevelForUserId:userId onComplete:^(UserEncryptionTrustLevel userEncryptionTrustLevel) {
|
||||||
self.encryptionTrustLevel = userEncryptionTrustLevel;
|
self.encryptionTrustLevel = userEncryptionTrustLevel;
|
||||||
[self updateMemberInfo];
|
[self updateMemberInfo];
|
||||||
}];
|
}];
|
||||||
|
} failure:^(NSError *error) {
|
||||||
|
[self.mxRoom encryptionTrustLevelForUserId:userId onComplete:^(UserEncryptionTrustLevel userEncryptionTrustLevel) {
|
||||||
|
self.encryptionTrustLevel = userEncryptionTrustLevel;
|
||||||
|
[self updateMemberInfo];
|
||||||
|
}];
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isRoomMemberCurrentUser
|
- (BOOL)isRoomMemberCurrentUser
|
||||||
|
|
|
@ -20,5 +20,7 @@
|
||||||
|
|
||||||
@interface SettingsViewController : MXKTableViewController<UITextFieldDelegate, MXKCountryPickerViewControllerDelegate, MXKLanguagePickerViewControllerDelegate, MXKDataSourceDelegate>
|
@interface SettingsViewController : MXKTableViewController<UITextFieldDelegate, MXKCountryPickerViewControllerDelegate, MXKLanguagePickerViewControllerDelegate, MXKDataSourceDelegate>
|
||||||
|
|
||||||
|
+ (instancetype)instantiate;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -261,6 +261,13 @@ SettingsIdentityServerCoordinatorBridgePresenterDelegate>
|
||||||
|
|
||||||
@implementation SettingsViewController
|
@implementation SettingsViewController
|
||||||
|
|
||||||
|
+ (instancetype)instantiate
|
||||||
|
{
|
||||||
|
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
|
||||||
|
SettingsViewController *settingsViewController = [storyboard instantiateViewControllerWithIdentifier:@"SettingsViewController"];
|
||||||
|
return settingsViewController;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)finalizeInit
|
- (void)finalizeInit
|
||||||
{
|
{
|
||||||
[super finalizeInit];
|
[super finalizeInit];
|
||||||
|
|
|
@ -27,6 +27,9 @@
|
||||||
#import "MXRoom+Riot.h"
|
#import "MXRoom+Riot.h"
|
||||||
#import "MXSession+Riot.h"
|
#import "MXSession+Riot.h"
|
||||||
|
|
||||||
|
#import "SettingsViewController.h"
|
||||||
|
#import "SecurityViewController.h"
|
||||||
|
|
||||||
#import "Riot-Swift.h"
|
#import "Riot-Swift.h"
|
||||||
|
|
||||||
@interface MasterTabBarController ()
|
@interface MasterTabBarController ()
|
||||||
|
@ -66,7 +69,7 @@
|
||||||
|
|
||||||
@property(nonatomic,getter=isHidden) BOOL hidden;
|
@property(nonatomic,getter=isHidden) BOOL hidden;
|
||||||
|
|
||||||
@property(nonatomic) BOOL verifyCurrentSessionAlertHasBeenDisplayed;
|
@property(nonatomic) BOOL reviewSessionAlertHasBeenDisplayed;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -77,6 +80,9 @@
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
// Do any additional setup after loading the view, typically from a nib.
|
// Do any additional setup after loading the view, typically from a nib.
|
||||||
|
|
||||||
|
// Note: UITabBarViewController shoud not be embed in a UINavigationController (https://github.com/vector-im/riot-ios/issues/3086)
|
||||||
|
[self vc_removeBackTitle];
|
||||||
|
|
||||||
// Retrieve the all view controllers
|
// Retrieve the all view controllers
|
||||||
_homeViewController = self.viewControllers[TABBAR_HOME_INDEX];
|
_homeViewController = self.viewControllers[TABBAR_HOME_INDEX];
|
||||||
_favouritesViewController = self.viewControllers[TABBAR_FAVOURITES_INDEX];
|
_favouritesViewController = self.viewControllers[TABBAR_FAVOURITES_INDEX];
|
||||||
|
@ -209,7 +215,7 @@
|
||||||
[childViewControllers removeAllObjects];
|
[childViewControllers removeAllObjects];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self presentVerifyCurrentSessionAlertIfNeeded];
|
[self presentReviewSessionsAlertIfNeeded];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unifiedSearchViewController)
|
if (unifiedSearchViewController)
|
||||||
|
@ -219,55 +225,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)presentVerifyCurrentSessionAlertIfNeeded
|
|
||||||
{
|
|
||||||
if (RiotSettings.shared.hideVerifyThisSessionAlert || self.verifyCurrentSessionAlertHasBeenDisplayed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MXSession *mainSession = self.mxSessions.firstObject;
|
|
||||||
|
|
||||||
if (self.viewLoaded
|
|
||||||
&& mainSession.state >= MXSessionStateStoreDataReady
|
|
||||||
&& mainSession.crypto.crossSigning
|
|
||||||
&& mainSession.crypto.crossSigning.state == MXCrossSigningStateCrossSigningExists)
|
|
||||||
{
|
|
||||||
self.verifyCurrentSessionAlertHasBeenDisplayed = YES;
|
|
||||||
[self presentVerifyCurrentSessionAlertWithSession:mainSession];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)presentVerifyCurrentSessionAlertWithSession:(MXSession*)session
|
|
||||||
{
|
|
||||||
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
|
||||||
|
|
||||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_title", @"Vector", nil)
|
|
||||||
message:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_message", @"Vector", nil)
|
|
||||||
preferredStyle:UIAlertControllerStyleAlert];
|
|
||||||
|
|
||||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_validate_action", @"Vector", nil)
|
|
||||||
style:UIAlertActionStyleDefault
|
|
||||||
handler:^(UIAlertAction * action) {
|
|
||||||
[[AppDelegate theDelegate] presentCompleteSecurityForSession:session];
|
|
||||||
}]];
|
|
||||||
|
|
||||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"later", @"Vector", nil)
|
|
||||||
style:UIAlertActionStyleCancel
|
|
||||||
handler:nil]];
|
|
||||||
|
|
||||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"do_not_ask_again", @"Vector", nil)
|
|
||||||
style:UIAlertActionStyleDestructive
|
|
||||||
handler:^(UIAlertAction * action) {
|
|
||||||
RiotSettings.shared.hideVerifyThisSessionAlert = YES;
|
|
||||||
}]];
|
|
||||||
|
|
||||||
|
|
||||||
[self presentViewController:alert animated:YES completion:nil];
|
|
||||||
|
|
||||||
currentAlert = alert;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)viewDidDisappear:(BOOL)animated
|
- (void)viewDidDisappear:(BOOL)animated
|
||||||
{
|
{
|
||||||
[super viewDidDisappear:animated];
|
[super viewDidDisappear:animated];
|
||||||
|
@ -444,7 +401,7 @@
|
||||||
{
|
{
|
||||||
[self refreshTabBarBadges];
|
[self refreshTabBarBadges];
|
||||||
|
|
||||||
[self presentVerifyCurrentSessionAlertIfNeeded];
|
[self presentReviewSessionsAlertIfNeeded];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showAuthenticationScreen
|
- (void)showAuthenticationScreen
|
||||||
|
@ -456,6 +413,8 @@
|
||||||
{
|
{
|
||||||
isAuthViewControllerPreparing = YES;
|
isAuthViewControllerPreparing = YES;
|
||||||
|
|
||||||
|
[self resetReviewSessionsFlags];
|
||||||
|
|
||||||
[[AppDelegate theDelegate] restoreInitialDisplay:^{
|
[[AppDelegate theDelegate] restoreInitialDisplay:^{
|
||||||
|
|
||||||
[self performSegueWithIdentifier:@"showAuth" sender:self];
|
[self performSegueWithIdentifier:@"showAuth" sender:self];
|
||||||
|
@ -1034,6 +993,147 @@
|
||||||
[self presentViewController:currentAlert animated:YES completion:nil];
|
[self presentViewController:currentAlert animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Review session
|
||||||
|
|
||||||
|
- (void)presentReviewSessionsAlertIfNeeded
|
||||||
|
{
|
||||||
|
MXSession *mainSession = self.mxSessions.firstObject;
|
||||||
|
|
||||||
|
if (!(self.viewLoaded
|
||||||
|
&& mainSession.state >= MXSessionStateStoreDataReady
|
||||||
|
&& mainSession.crypto.crossSigning))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mainSession.crypto.crossSigning.state) {
|
||||||
|
case MXCrossSigningStateCrossSigningExists:
|
||||||
|
[self presentVerifyCurrentSessionAlertIfNeededWithSession:mainSession];
|
||||||
|
break;
|
||||||
|
case MXCrossSigningStateCanCrossSign:
|
||||||
|
[self presentReviewUnverifiedSessionsAlertIfNeededWithSession:mainSession];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)presentVerifyCurrentSessionAlertIfNeededWithSession:(MXSession*)session
|
||||||
|
{
|
||||||
|
if (RiotSettings.shared.hideVerifyThisSessionAlert || self.reviewSessionAlertHasBeenDisplayed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reviewSessionAlertHasBeenDisplayed = YES;
|
||||||
|
[self presentVerifyCurrentSessionAlertWithSession:session];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)presentVerifyCurrentSessionAlertWithSession:(MXSession*)session
|
||||||
|
{
|
||||||
|
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
|
||||||
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_title", @"Vector", nil)
|
||||||
|
message:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_message", @"Vector", nil)
|
||||||
|
preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_current_session_alert_validate_action", @"Vector", nil)
|
||||||
|
style:UIAlertActionStyleDefault
|
||||||
|
handler:^(UIAlertAction * action) {
|
||||||
|
[[AppDelegate theDelegate] presentCompleteSecurityForSession:session];
|
||||||
|
}]];
|
||||||
|
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"later", @"Vector", nil)
|
||||||
|
style:UIAlertActionStyleCancel
|
||||||
|
handler:nil]];
|
||||||
|
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"do_not_ask_again", @"Vector", nil)
|
||||||
|
style:UIAlertActionStyleDestructive
|
||||||
|
handler:^(UIAlertAction * action) {
|
||||||
|
RiotSettings.shared.hideVerifyThisSessionAlert = YES;
|
||||||
|
}]];
|
||||||
|
|
||||||
|
|
||||||
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
|
|
||||||
|
currentAlert = alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)presentReviewUnverifiedSessionsAlertIfNeededWithSession:(MXSession*)session
|
||||||
|
{
|
||||||
|
if (RiotSettings.shared.hideReviewSessionsAlert || self.reviewSessionAlertHasBeenDisplayed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray<MXDeviceInfo*> *devices = [session.crypto.store devicesForUser:session.myUserId].allValues;
|
||||||
|
|
||||||
|
BOOL isUserHasOneUnverifiedDevice = NO;
|
||||||
|
|
||||||
|
for (MXDeviceInfo *device in devices)
|
||||||
|
{
|
||||||
|
if (device.trustLevel.localVerificationStatus == MXDeviceUnknown)
|
||||||
|
{
|
||||||
|
isUserHasOneUnverifiedDevice = YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUserHasOneUnverifiedDevice)
|
||||||
|
{
|
||||||
|
self.reviewSessionAlertHasBeenDisplayed = YES;
|
||||||
|
[self presentReviewUnverifiedSessionsAlertWithSession:session];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)presentReviewUnverifiedSessionsAlertWithSession:(MXSession*)session
|
||||||
|
{
|
||||||
|
[currentAlert dismissViewControllerAnimated:NO completion:nil];
|
||||||
|
|
||||||
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_unverified_sessions_alert_title", @"Vector", nil)
|
||||||
|
message:NSLocalizedStringFromTable(@"key_verification_self_verify_unverified_sessions_alert_message", @"Vector", nil)
|
||||||
|
preferredStyle:UIAlertControllerStyleAlert];
|
||||||
|
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_unverified_sessions_alert_validate_action", @"Vector", nil)
|
||||||
|
style:UIAlertActionStyleDefault
|
||||||
|
handler:^(UIAlertAction * action) {
|
||||||
|
[self showSettingsSecurityScreenForSession:session];
|
||||||
|
}]];
|
||||||
|
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"later", @"Vector", nil)
|
||||||
|
style:UIAlertActionStyleCancel
|
||||||
|
handler:nil]];
|
||||||
|
|
||||||
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"do_not_ask_again", @"Vector", nil)
|
||||||
|
style:UIAlertActionStyleDestructive
|
||||||
|
handler:^(UIAlertAction * action) {
|
||||||
|
RiotSettings.shared.hideReviewSessionsAlert = YES;
|
||||||
|
}]];
|
||||||
|
|
||||||
|
|
||||||
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
|
|
||||||
|
currentAlert = alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showSettingsSecurityScreenForSession:(MXSession*)session
|
||||||
|
{
|
||||||
|
SettingsViewController *settingsViewController = [SettingsViewController instantiate];
|
||||||
|
[settingsViewController loadViewIfNeeded];
|
||||||
|
SecurityViewController *securityViewController = [SecurityViewController instantiateWithMatrixSession:session];
|
||||||
|
|
||||||
|
[[AppDelegate theDelegate] restoreInitialDisplay:^{
|
||||||
|
self.navigationController.viewControllers = @[self, settingsViewController, securityViewController];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resetReviewSessionsFlags
|
||||||
|
{
|
||||||
|
self.reviewSessionAlertHasBeenDisplayed = NO;
|
||||||
|
RiotSettings.shared.hideVerifyThisSessionAlert = NO;
|
||||||
|
RiotSettings.shared.hideReviewSessionsAlert = NO;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - UITabBarDelegate
|
#pragma mark - UITabBarDelegate
|
||||||
|
|
||||||
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
|
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.11.2</string>
|
<string>0.11.3</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.11.2</string>
|
<string>0.11.3</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>ITSEncryptionExportComplianceCode</key>
|
<key>ITSEncryptionExportComplianceCode</key>
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>XPC!</string>
|
<string>XPC!</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.11.2</string>
|
<string>0.11.3</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.11.2</string>
|
<string>0.11.3</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionAttributes</key>
|
<key>NSExtensionAttributes</key>
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>XPC!</string>
|
<string>XPC!</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.11.2</string>
|
<string>0.11.3</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>0.11.2</string>
|
<string>0.11.3</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionAttributes</key>
|
<key>NSExtensionAttributes</key>
|
||||||
|
|
|
@ -68,7 +68,7 @@ final class FlowTemplateCoordinator: FlowTemplateCoordinatorType {
|
||||||
|
|
||||||
// MARK: - TemplateScreenCoordinatorDelegate
|
// MARK: - TemplateScreenCoordinatorDelegate
|
||||||
extension FlowTemplateCoordinator: TemplateScreenCoordinatorDelegate {
|
extension FlowTemplateCoordinator: TemplateScreenCoordinatorDelegate {
|
||||||
func templateScreenCoordinator(_ coordinator: TemplateScreenCoordinatorType, didCompleteWithMessage message: String) {
|
func templateScreenCoordinator(_ coordinator: TemplateScreenCoordinatorType, didCompleteWithUserDisplayName userDisplayName: String?) {
|
||||||
self.delegate?.flowTemplateCoordinatorDidComplete(self)
|
self.delegate?.flowTemplateCoordinatorDidComplete(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,8 @@ final class TemplateScreenCoordinator: TemplateScreenCoordinatorType {
|
||||||
// MARK: - TemplateScreenViewModelCoordinatorDelegate
|
// MARK: - TemplateScreenViewModelCoordinatorDelegate
|
||||||
extension TemplateScreenCoordinator: TemplateScreenViewModelCoordinatorDelegate {
|
extension TemplateScreenCoordinator: TemplateScreenViewModelCoordinatorDelegate {
|
||||||
|
|
||||||
func templateScreenViewModel(_ viewModel: TemplateScreenViewModelType, didCompleteWithMessage message: String) {
|
func templateScreenViewModel(_ viewModel: TemplateScreenViewModelType, didCompleteWithUserDisplayName userDisplayName: String?) {
|
||||||
self.delegate?.templateScreenCoordinator(self, didCompleteWithMessage: message)
|
self.delegate?.templateScreenCoordinator(self, didCompleteWithUserDisplayName: userDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func templateScreenViewModelDidCancel(_ viewModel: TemplateScreenViewModelType) {
|
func templateScreenViewModelDidCancel(_ viewModel: TemplateScreenViewModelType) {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
protocol TemplateScreenCoordinatorDelegate: class {
|
protocol TemplateScreenCoordinatorDelegate: class {
|
||||||
func templateScreenCoordinator(_ coordinator: TemplateScreenCoordinatorType, didCompleteWithMessage message: String)
|
func templateScreenCoordinator(_ coordinator: TemplateScreenCoordinatorType, didCompleteWithUserDisplayName userDisplayName: String?)
|
||||||
func templateScreenCoordinatorDidCancel(_ coordinator: TemplateScreenCoordinatorType)
|
func templateScreenCoordinatorDidCancel(_ coordinator: TemplateScreenCoordinatorType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import Foundation
|
||||||
|
|
||||||
/// TemplateScreenViewController view actions exposed to view model
|
/// TemplateScreenViewController view actions exposed to view model
|
||||||
enum TemplateScreenViewAction {
|
enum TemplateScreenViewAction {
|
||||||
case sayHello
|
case loadData
|
||||||
case complete
|
case complete
|
||||||
case cancel
|
case cancel
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="V8j-Lb-PgC">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="V8j-Lb-PgC">
|
||||||
<device id="retina4_7" orientation="portrait">
|
<device id="retina6_1" orientation="portrait">
|
||||||
<adaptation id="fullscreen"/>
|
<adaptation id="fullscreen"/>
|
||||||
</device>
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -15,36 +15,41 @@
|
||||||
<objects>
|
<objects>
|
||||||
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="V8j-Lb-PgC" customClass="TemplateScreenViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
|
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="V8j-Lb-PgC" customClass="TemplateScreenViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<view key="view" contentMode="scaleToFill" id="EL9-GA-lwo">
|
<view key="view" contentMode="scaleToFill" id="EL9-GA-lwo">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9U2-KL-ZVA">
|
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9U2-KL-ZVA">
|
||||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
<rect key="frame" x="0.0" y="44" width="414" height="852"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e7g-um-WO4">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e7g-um-WO4">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="500"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="208"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="voD-3Q-ryt">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="voD-3Q-ryt">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="500"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="208"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="A message" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bxI-mu-qng">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="A message" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bxI-mu-qng">
|
||||||
<rect key="frame" x="20" y="86" width="335" height="108"/>
|
<rect key="frame" x="20" y="40" width="374" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||||
<nil key="textColor"/>
|
<nil key="textColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DOt-5E-FjF">
|
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DOt-5E-FjF">
|
||||||
<rect key="frame" x="104" y="368" width="167" height="30"/>
|
<rect key="frame" x="20" y="158" width="374" height="30"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
|
||||||
<state key="normal" title="OK"/>
|
<state key="normal" title="OK"/>
|
||||||
<connections>
|
<connections>
|
||||||
<action selector="okButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="uvI-tt-Nfj"/>
|
<action selector="doneButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="uvI-tt-Nfj"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="bxI-mu-qng" secondAttribute="trailing" constant="20" id="2v5-vH-NEd"/>
|
||||||
|
<constraint firstItem="DOt-5E-FjF" firstAttribute="top" secondItem="bxI-mu-qng" secondAttribute="bottom" constant="100" id="C4r-0w-VXj"/>
|
||||||
|
<constraint firstItem="bxI-mu-qng" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="I1A-QW-IJG"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="DOt-5E-FjF" secondAttribute="trailing" constant="20" id="NKP-2G-Czj"/>
|
||||||
|
<constraint firstItem="bxI-mu-qng" firstAttribute="top" secondItem="voD-3Q-ryt" secondAttribute="top" constant="40" id="bU7-a2-LIj"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="DOt-5E-FjF" secondAttribute="bottom" constant="20" id="dmC-vE-FeB"/>
|
||||||
|
<constraint firstItem="DOt-5E-FjF" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="flU-tM-8hK"/>
|
||||||
<constraint firstAttribute="width" priority="750" constant="500" id="glD-Sz-73O"/>
|
<constraint firstAttribute="width" priority="750" constant="500" id="glD-Sz-73O"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
@ -55,7 +60,6 @@
|
||||||
<constraint firstItem="voD-3Q-ryt" firstAttribute="centerX" secondItem="e7g-um-WO4" secondAttribute="centerX" id="P2G-mq-gQW"/>
|
<constraint firstItem="voD-3Q-ryt" firstAttribute="centerX" secondItem="e7g-um-WO4" secondAttribute="centerX" id="P2G-mq-gQW"/>
|
||||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="voD-3Q-ryt" secondAttribute="trailing" id="QgV-SO-5yf"/>
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="voD-3Q-ryt" secondAttribute="trailing" id="QgV-SO-5yf"/>
|
||||||
<constraint firstItem="voD-3Q-ryt" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="e7g-um-WO4" secondAttribute="leading" id="YPo-u1-PtT"/>
|
<constraint firstItem="voD-3Q-ryt" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="e7g-um-WO4" secondAttribute="leading" id="YPo-u1-PtT"/>
|
||||||
<constraint firstAttribute="height" constant="500" id="n8g-KW-BYU"/>
|
|
||||||
<constraint firstItem="voD-3Q-ryt" firstAttribute="top" secondItem="e7g-um-WO4" secondAttribute="top" id="rhQ-96-szL"/>
|
<constraint firstItem="voD-3Q-ryt" firstAttribute="top" secondItem="e7g-um-WO4" secondAttribute="top" id="rhQ-96-szL"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
|
@ -63,7 +67,7 @@
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="trailing" secondItem="e7g-um-WO4" secondAttribute="trailing" id="GyG-Fh-PME"/>
|
<constraint firstAttribute="trailing" secondItem="e7g-um-WO4" secondAttribute="trailing" id="GyG-Fh-PME"/>
|
||||||
<constraint firstItem="e7g-um-WO4" firstAttribute="width" secondItem="9U2-KL-ZVA" secondAttribute="width" id="Ok2-WQ-Zgc"/>
|
<constraint firstItem="e7g-um-WO4" firstAttribute="width" secondItem="9U2-KL-ZVA" secondAttribute="width" id="Ok2-WQ-Zgc"/>
|
||||||
<constraint firstAttribute="bottom" secondItem="e7g-um-WO4" secondAttribute="bottom" constant="147" id="Y46-NP-zAc"/>
|
<constraint firstAttribute="bottom" secondItem="e7g-um-WO4" secondAttribute="bottom" id="Y46-NP-zAc"/>
|
||||||
<constraint firstItem="e7g-um-WO4" firstAttribute="leading" secondItem="9U2-KL-ZVA" secondAttribute="leading" id="aoV-Yh-AcD"/>
|
<constraint firstItem="e7g-um-WO4" firstAttribute="leading" secondItem="9U2-KL-ZVA" secondAttribute="leading" id="aoV-Yh-AcD"/>
|
||||||
<constraint firstItem="e7g-um-WO4" firstAttribute="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="pFN-bA-SHw"/>
|
<constraint firstItem="e7g-um-WO4" firstAttribute="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="pFN-bA-SHw"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
@ -79,8 +83,8 @@
|
||||||
<viewLayoutGuide key="safeArea" id="bFg-jh-JZB"/>
|
<viewLayoutGuide key="safeArea" id="bFg-jh-JZB"/>
|
||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="messageLabel" destination="bxI-mu-qng" id="pbX-aZ-inC"/>
|
<outlet property="doneButton" destination="DOt-5E-FjF" id="ktw-U4-efQ"/>
|
||||||
<outlet property="okButton" destination="DOt-5E-FjF" id="ktw-U4-efQ"/>
|
<outlet property="informationLabel" destination="bxI-mu-qng" id="pbX-aZ-inC"/>
|
||||||
<outlet property="scrollView" destination="9U2-KL-ZVA" id="ojG-2y-X7b"/>
|
<outlet property="scrollView" destination="9U2-KL-ZVA" id="ojG-2y-X7b"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
|
|
|
@ -30,8 +30,8 @@ final class TemplateScreenViewController: UIViewController {
|
||||||
|
|
||||||
@IBOutlet private weak var scrollView: UIScrollView!
|
@IBOutlet private weak var scrollView: UIScrollView!
|
||||||
|
|
||||||
@IBOutlet private weak var messageLabel: UILabel!
|
@IBOutlet private weak var informationLabel: UILabel!
|
||||||
@IBOutlet private weak var okButton: UIButton!
|
@IBOutlet private weak var doneButton: UIButton!
|
||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
|
@ -57,8 +57,6 @@ final class TemplateScreenViewController: UIViewController {
|
||||||
|
|
||||||
// Do any additional setup after loading the view.
|
// Do any additional setup after loading the view.
|
||||||
|
|
||||||
self.title = "Template"
|
|
||||||
|
|
||||||
self.setupViews()
|
self.setupViews()
|
||||||
self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView)
|
self.keyboardAvoider = KeyboardAvoider(scrollViewContainerView: self.view, scrollView: self.scrollView)
|
||||||
self.activityPresenter = ActivityIndicatorPresenter()
|
self.activityPresenter = ActivityIndicatorPresenter()
|
||||||
|
@ -69,7 +67,7 @@ final class TemplateScreenViewController: UIViewController {
|
||||||
|
|
||||||
self.viewModel.viewDelegate = self
|
self.viewModel.viewDelegate = self
|
||||||
|
|
||||||
self.viewModel.process(viewAction: .sayHello)
|
self.viewModel.process(viewAction: .loadData)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
@ -100,11 +98,11 @@ final class TemplateScreenViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO:
|
// TODO: Set view colors here
|
||||||
self.messageLabel.textColor = theme.textPrimaryColor
|
self.informationLabel.textColor = theme.textPrimaryColor
|
||||||
|
|
||||||
self.okButton.backgroundColor = theme.backgroundColor
|
self.doneButton.backgroundColor = theme.backgroundColor
|
||||||
theme.applyStyle(onButton: self.okButton)
|
theme.applyStyle(onButton: self.doneButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func registerThemeServiceDidChangeThemeNotification() {
|
private func registerThemeServiceDidChangeThemeNotification() {
|
||||||
|
@ -122,18 +120,19 @@ final class TemplateScreenViewController: UIViewController {
|
||||||
|
|
||||||
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
||||||
|
|
||||||
|
self.title = "Template"
|
||||||
|
|
||||||
self.scrollView.keyboardDismissMode = .interactive
|
self.scrollView.keyboardDismissMode = .interactive
|
||||||
|
|
||||||
self.messageLabel.text = "VectorL10n.templateScreenTitle"
|
self.informationLabel.text = "VectorL10n.templateScreenTitle"
|
||||||
self.messageLabel.isHidden = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func render(viewState: TemplateScreenViewState) {
|
private func render(viewState: TemplateScreenViewState) {
|
||||||
switch viewState {
|
switch viewState {
|
||||||
case .loading:
|
case .loading:
|
||||||
self.renderLoading()
|
self.renderLoading()
|
||||||
case .loaded:
|
case .loaded(let displayName):
|
||||||
self.renderLoaded()
|
self.renderLoaded(displayName: displayName)
|
||||||
case .error(let error):
|
case .error(let error):
|
||||||
self.render(error: error)
|
self.render(error: error)
|
||||||
}
|
}
|
||||||
|
@ -141,13 +140,13 @@ final class TemplateScreenViewController: UIViewController {
|
||||||
|
|
||||||
private func renderLoading() {
|
private func renderLoading() {
|
||||||
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
|
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
|
||||||
|
self.informationLabel.text = "Fetch display name"
|
||||||
}
|
}
|
||||||
|
|
||||||
private func renderLoaded() {
|
private func renderLoaded(displayName: String) {
|
||||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||||
|
|
||||||
self.messageLabel.text = self.viewModel.message
|
self.informationLabel.text = "You display name: \(displayName)"
|
||||||
self.messageLabel.isHidden = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func render(error: Error) {
|
private func render(error: Error) {
|
||||||
|
@ -158,7 +157,7 @@ final class TemplateScreenViewController: UIViewController {
|
||||||
|
|
||||||
// MARK: - Actions
|
// MARK: - Actions
|
||||||
|
|
||||||
@IBAction private func okButtonAction(_ sender: Any) {
|
@IBAction private func doneButtonAction(_ sender: Any) {
|
||||||
self.viewModel.process(viewAction: .complete)
|
self.viewModel.process(viewAction: .complete)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,10 @@ final class TemplateScreenViewModel: TemplateScreenViewModelType {
|
||||||
|
|
||||||
private let session: MXSession
|
private let session: MXSession
|
||||||
|
|
||||||
// MARK: Public
|
private var currentOperation: MXHTTPOperation?
|
||||||
|
private var userDisplayName: String?
|
||||||
|
|
||||||
var message: String?
|
// MARK: Public
|
||||||
|
|
||||||
weak var viewDelegate: TemplateScreenViewModelViewDelegate?
|
weak var viewDelegate: TemplateScreenViewModelViewDelegate?
|
||||||
weak var coordinatorDelegate: TemplateScreenViewModelCoordinatorDelegate?
|
weak var coordinatorDelegate: TemplateScreenViewModelCoordinatorDelegate?
|
||||||
|
@ -35,46 +36,45 @@ final class TemplateScreenViewModel: TemplateScreenViewModelType {
|
||||||
|
|
||||||
init(session: MXSession) {
|
init(session: MXSession) {
|
||||||
self.session = session
|
self.session = session
|
||||||
self.message = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
self.cancelOperations()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
func process(viewAction: TemplateScreenViewAction) {
|
func process(viewAction: TemplateScreenViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
case .sayHello:
|
case .loadData:
|
||||||
self.setupHelloMessage()
|
self.loadData()
|
||||||
case .complete:
|
case .complete:
|
||||||
if let message = self.message {
|
self.coordinatorDelegate?.templateScreenViewModel(self, didCompleteWithUserDisplayName: self.userDisplayName)
|
||||||
self.coordinatorDelegate?.templateScreenViewModel(self, didCompleteWithMessage: message)
|
|
||||||
}
|
|
||||||
case .cancel:
|
case .cancel:
|
||||||
|
self.cancelOperations()
|
||||||
self.coordinatorDelegate?.templateScreenViewModelDidCancel(self)
|
self.coordinatorDelegate?.templateScreenViewModelDidCancel(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func setupHelloMessage() {
|
private func loadData() {
|
||||||
|
|
||||||
self.update(viewState: .loading)
|
self.update(viewState: .loading)
|
||||||
|
|
||||||
// Check first that the user homeserver is federated with the Riot-bot homeserver
|
// Check first that the user homeserver is federated with the Riot-bot homeserver
|
||||||
self.session.matrixRestClient.displayName(forUser: self.session.myUser.userId) { [weak self] (response) in
|
self.currentOperation = self.session.matrixRestClient.displayName(forUser: self.session.myUser.userId) { [weak self] (response) in
|
||||||
|
|
||||||
guard let sself = self else {
|
guard let self = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch response {
|
switch response {
|
||||||
case .success:
|
case .success(let userDisplayName):
|
||||||
sself.message = "Hello \(response.value ?? "you")"
|
self.update(viewState: .loaded(userDisplayName))
|
||||||
sself.update(viewState: .loaded)
|
self.userDisplayName = userDisplayName
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
sself.update(viewState: .error(error))
|
self.update(viewState: .error(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,4 +82,8 @@ final class TemplateScreenViewModel: TemplateScreenViewModelType {
|
||||||
private func update(viewState: TemplateScreenViewState) {
|
private func update(viewState: TemplateScreenViewState) {
|
||||||
self.viewDelegate?.templateScreenViewModel(self, didUpdateViewState: viewState)
|
self.viewDelegate?.templateScreenViewModel(self, didUpdateViewState: viewState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func cancelOperations() {
|
||||||
|
self.currentOperation?.cancel()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,13 @@ protocol TemplateScreenViewModelViewDelegate: class {
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol TemplateScreenViewModelCoordinatorDelegate: class {
|
protocol TemplateScreenViewModelCoordinatorDelegate: class {
|
||||||
func templateScreenViewModel(_ viewModel: TemplateScreenViewModelType, didCompleteWithMessage message: String)
|
func templateScreenViewModel(_ viewModel: TemplateScreenViewModelType, didCompleteWithUserDisplayName userDisplayName: String?)
|
||||||
func templateScreenViewModelDidCancel(_ viewModel: TemplateScreenViewModelType)
|
func templateScreenViewModelDidCancel(_ viewModel: TemplateScreenViewModelType)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Protocol describing the view model used by `TemplateScreenViewController`
|
/// Protocol describing the view model used by `TemplateScreenViewController`
|
||||||
protocol TemplateScreenViewModelType {
|
protocol TemplateScreenViewModelType {
|
||||||
|
|
||||||
var message: String? { get set }
|
|
||||||
|
|
||||||
var viewDelegate: TemplateScreenViewModelViewDelegate? { get set }
|
var viewDelegate: TemplateScreenViewModelViewDelegate? { get set }
|
||||||
var coordinatorDelegate: TemplateScreenViewModelCoordinatorDelegate? { get set }
|
var coordinatorDelegate: TemplateScreenViewModelCoordinatorDelegate? { get set }
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,6 @@ import Foundation
|
||||||
/// TemplateScreenViewController view state
|
/// TemplateScreenViewController view state
|
||||||
enum TemplateScreenViewState {
|
enum TemplateScreenViewState {
|
||||||
case loading
|
case loading
|
||||||
case loaded
|
case loaded(_ displayName: String)
|
||||||
case error(Error)
|
case error(Error)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue