Merge branch 'release/v0.11.2'
16
CHANGES.rst
|
@ -1,3 +1,19 @@
|
|||
Changes in 0.11.2 (2020-05-01)
|
||||
===============================================
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version ([v0.12.2](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.12.2)).
|
||||
* Registration / Email addition: Support email verification link from homeserver (#3167).
|
||||
* Verification requests: Hide incoming request modal when it is no more pending (#3033).
|
||||
* Self-verification: Do not display incoming self verification requests at the top of the Complete Security screen.
|
||||
* Verification: Do not talk about QR code if only emoji is possible (#3035).
|
||||
* Registration: Prefill email field when opened with universal link (PR #3173).
|
||||
* Cross-signing: Display "Verify this session" modal at every startup if needed (#3179).
|
||||
* Complete Security: Support SAS verification start (#3183).
|
||||
|
||||
Bug fix:
|
||||
* AuthenticationViewController: Remove fallback to matrix.org when authentication failed (PR #3165).
|
||||
|
||||
Changes in 0.11.1 (2020-04-24)
|
||||
===============================================
|
||||
|
||||
|
|
2
Podfile
|
@ -7,7 +7,7 @@ use_frameworks!
|
|||
|
||||
# Different flavours of pods to MatrixKit
|
||||
# The current MatrixKit pod version
|
||||
$matrixKitVersion = '0.12.1'
|
||||
$matrixKitVersion = '0.12.2'
|
||||
|
||||
# The develop branch version
|
||||
#$matrixKitVersion = 'develop'
|
||||
|
|
34
Podfile.lock
|
@ -50,38 +50,38 @@ PODS:
|
|||
- MatomoTracker (7.2.0):
|
||||
- MatomoTracker/Core (= 7.2.0)
|
||||
- MatomoTracker/Core (7.2.0)
|
||||
- MatrixKit (0.12.1):
|
||||
- MatrixKit (0.12.2):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.21)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixKit/Core (= 0.12.1)
|
||||
- MatrixSDK (= 0.16.1)
|
||||
- MatrixKit/AppExtension (0.12.1):
|
||||
- MatrixKit/Core (= 0.12.2)
|
||||
- MatrixSDK (= 0.16.2)
|
||||
- MatrixKit/AppExtension (0.12.2):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.21)
|
||||
- DTCoreText/Extension
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.16.1)
|
||||
- MatrixKit/Core (0.12.1):
|
||||
- MatrixSDK (= 0.16.2)
|
||||
- MatrixKit/Core (0.12.2):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.21)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.16.1)
|
||||
- MatrixSDK (0.16.1):
|
||||
- MatrixSDK/Core (= 0.16.1)
|
||||
- MatrixSDK/Core (0.16.1):
|
||||
- MatrixSDK (= 0.16.2)
|
||||
- MatrixSDK (0.16.2):
|
||||
- MatrixSDK/Core (= 0.16.2)
|
||||
- MatrixSDK/Core (0.16.2):
|
||||
- AFNetworking (~> 3.2.0)
|
||||
- GZIP (~> 1.2.2)
|
||||
- libbase58 (~> 0.1.4)
|
||||
- OLMKit (~> 3.1.0)
|
||||
- Realm (~> 3.17.3)
|
||||
- MatrixSDK/JingleCallStack (0.16.1):
|
||||
- MatrixSDK/JingleCallStack (0.16.2):
|
||||
- JitsiMeetSDK (~> 2.3.1)
|
||||
- MatrixSDK/Core
|
||||
- MatrixSDK/SwiftSupport (0.16.1):
|
||||
- MatrixSDK/SwiftSupport (0.16.2):
|
||||
- MatrixSDK/Core
|
||||
- OLMKit (3.1.0):
|
||||
- OLMKit/olmc (= 3.1.0)
|
||||
|
@ -109,8 +109,8 @@ DEPENDENCIES:
|
|||
- GBDeviceInfo (~> 6.3.0)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- MatomoTracker (~> 7.2.0)
|
||||
- MatrixKit (= 0.12.1)
|
||||
- MatrixKit/AppExtension (= 0.12.1)
|
||||
- MatrixKit (= 0.12.2)
|
||||
- MatrixKit/AppExtension (= 0.12.2)
|
||||
- MatrixSDK/JingleCallStack
|
||||
- MatrixSDK/SwiftSupport
|
||||
- OLMKit
|
||||
|
@ -159,8 +159,8 @@ SPEC CHECKSUMS:
|
|||
libbase58: 7c040313537b8c44b6e2d15586af8e21f7354efd
|
||||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||
MatomoTracker: 6f89e2561083685a360e223fb663e9ccd57c1d1a
|
||||
MatrixKit: 5ebf91a3fed5a9d4110d1db53b5da6889fa42dd0
|
||||
MatrixSDK: 31c4b9d13335cf074aa3d6e90bb4b2a8c5bbb40a
|
||||
MatrixKit: 93d2c002db0aa0e0b09bd501313fb16122ff4732
|
||||
MatrixSDK: 613dba898bbeb7823034b7b30418d89be263c20d
|
||||
OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639
|
||||
Realm: 5a1d9d47bfc101dd597668b1a8af4288a2557f6d
|
||||
Reusable: 82be188f29d96dc5eff0db7b2393bcc08d2cdd5b
|
||||
|
@ -169,6 +169,6 @@ SPEC CHECKSUMS:
|
|||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: 75ef978c4b52de673fe49d04b0f1c82d51f537a0
|
||||
PODFILE CHECKSUM: d3b15ac72eb62dce4f4a61be16d91599412be420
|
||||
|
||||
COCOAPODS: 1.9.1
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
6E6F1CB1244E00FD0068B78B /* LocalContactsSectionHeaderContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E6F1CAF244E00FD0068B78B /* LocalContactsSectionHeaderContainerView.m */; };
|
||||
6E6F1CB324506EC50068B78B /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6F1CB224506EC50068B78B /* UITableViewCell.swift */; };
|
||||
6E6F1CB524506FA40068B78B /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E6F1CB424506FA40068B78B /* UITableView.swift */; };
|
||||
6E75C3E32458797D00AF497D /* UniversalLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E75C3E22458797D00AF497D /* UniversalLink.m */; };
|
||||
6E7A9E9C243E10E700FD039E /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E7A9E9B243E10E700FD039E /* UIDevice.swift */; };
|
||||
926FA53F1F4C132000F826C2 /* MXSession+Riot.m in Sources */ = {isa = PBXBuildFile; fileRef = 926FA53E1F4C132000F826C2 /* MXSession+Riot.m */; };
|
||||
92726A471F58737A004AD26F /* IntentHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 92726A461F58737A004AD26F /* IntentHandler.m */; };
|
||||
|
@ -629,6 +630,7 @@
|
|||
B1C562E5228C7C8D0037F12A /* RoomContextualMenuViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B1C562E0228C7C8C0037F12A /* RoomContextualMenuViewController.storyboard */; };
|
||||
B1C562E8228C7CF20037F12A /* ContextualMenuItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1C562E6228C7CF10037F12A /* ContextualMenuItemView.swift */; };
|
||||
B1C562E9228C7CF20037F12A /* ContextualMenuItemView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B1C562E7228C7CF20037F12A /* ContextualMenuItemView.xib */; };
|
||||
B1C960F02458308D00C5704B /* RoundedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1C960EF2458308D00C5704B /* RoundedButton.swift */; };
|
||||
B1CA3A2721EF6914000D1D89 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CA3A2621EF6913000D1D89 /* UIViewController.swift */; };
|
||||
B1CA3A2921EF692B000D1D89 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CA3A2821EF692B000D1D89 /* UIView.swift */; };
|
||||
B1CE83B62422812100D07506 /* KeyVerificationCoordinatorBridgePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE83B52422812000D07506 /* KeyVerificationCoordinatorBridgePresenter.swift */; };
|
||||
|
@ -912,6 +914,8 @@
|
|||
6E6F1CB0244E00FD0068B78B /* LocalContactsSectionHeaderContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalContactsSectionHeaderContainerView.h; sourceTree = "<group>"; };
|
||||
6E6F1CB224506EC50068B78B /* UITableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewCell.swift; sourceTree = "<group>"; };
|
||||
6E6F1CB424506FA40068B78B /* UITableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = "<group>"; };
|
||||
6E75C3E12458797D00AF497D /* UniversalLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UniversalLink.h; sourceTree = "<group>"; };
|
||||
6E75C3E22458797D00AF497D /* UniversalLink.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UniversalLink.m; sourceTree = "<group>"; };
|
||||
6E7A9E9B243E10E700FD039E /* UIDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = "<group>"; };
|
||||
926FA53D1F4C132000F826C2 /* MXSession+Riot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXSession+Riot.h"; sourceTree = "<group>"; };
|
||||
926FA53E1F4C132000F826C2 /* MXSession+Riot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MXSession+Riot.m"; sourceTree = "<group>"; };
|
||||
|
@ -1609,6 +1613,7 @@
|
|||
B1C6FFE723954CE70055347B /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
B1C6FFE823954D3B0055347B /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
B1C6FFE923954D4B0055347B /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Vector.strings; sourceTree = "<group>"; };
|
||||
B1C960EF2458308D00C5704B /* RoundedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedButton.swift; sourceTree = "<group>"; };
|
||||
B1CA3A2621EF6913000D1D89 /* UIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = "<group>"; };
|
||||
B1CA3A2821EF692B000D1D89 /* UIView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = "<group>"; };
|
||||
B1CE83B52422812000D07506 /* KeyVerificationCoordinatorBridgePresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyVerificationCoordinatorBridgePresenter.swift; sourceTree = "<group>"; };
|
||||
|
@ -2681,6 +2686,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
B183226B23F59F810035B2E8 /* CloseButton.swift */,
|
||||
B1C960EF2458308D00C5704B /* RoundedButton.swift */,
|
||||
);
|
||||
path = Close;
|
||||
sourceTree = "<group>";
|
||||
|
@ -4336,6 +4342,8 @@
|
|||
F083BC151E7009EC00A9B29C /* Tools.m */,
|
||||
B1DB4F0D22316FFF0065DBFA /* UserNameColorGenerator.swift */,
|
||||
B197B7C5243DE947005ABBF3 /* EncryptionTrustLevelBadgeImageHelper.swift */,
|
||||
6E75C3E12458797D00AF497D /* UniversalLink.h */,
|
||||
6E75C3E22458797D00AF497D /* UniversalLink.m */,
|
||||
);
|
||||
path = Utils;
|
||||
sourceTree = "<group>";
|
||||
|
@ -5013,6 +5021,7 @@
|
|||
F083BDEE1E7009ED00A9B29C /* MXRoom+Riot.m in Sources */,
|
||||
B120863722EF375F001F89E0 /* ReactionHistoryBridgeCoordinatorPresenter.swift in Sources */,
|
||||
B1B5598620EFC3E000210D55 /* RiotSettings.swift in Sources */,
|
||||
B1C960F02458308D00C5704B /* RoundedButton.swift in Sources */,
|
||||
B1CE83D52422817200D07506 /* KeyVerificationVerifyByScanningViewController.swift in Sources */,
|
||||
3232ABA3225730E100AD6A5C /* DeviceVerificationStartCoordinatorType.swift in Sources */,
|
||||
3232AB4D2256558300AD6A5C /* TemplateScreenCoordinatorType.swift in Sources */,
|
||||
|
@ -5123,6 +5132,7 @@
|
|||
3232ABC2225B996200AD6A5C /* Themable.swift in Sources */,
|
||||
32A6001B22C661100042C1D9 /* EditHistoryViewAction.swift in Sources */,
|
||||
3232ABA7225730E100AD6A5C /* DeviceVerificationStartCoordinator.swift in Sources */,
|
||||
6E75C3E32458797D00AF497D /* UniversalLink.m in Sources */,
|
||||
B1D4752721EE4E630067973F /* KeyboardAvoider.swift in Sources */,
|
||||
B1D4752821EE4E630067973F /* KeyboardNotification.swift in Sources */,
|
||||
B1D1BDA622BBAFB500831367 /* ReactionsMenuView.swift in Sources */,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#import "Analytics.h"
|
||||
|
||||
#import "ThemeService.h"
|
||||
#import "UniversalLink.h"
|
||||
|
||||
#pragma mark - Notifications
|
||||
/**
|
||||
|
@ -42,6 +43,11 @@ extern NSString *const AppDelegateDidValidateEmailNotification;
|
|||
extern NSString *const AppDelegateDidValidateEmailNotificationSIDKey;
|
||||
extern NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey;
|
||||
|
||||
/**
|
||||
Posted when the property 'lastHandledUniversalLink' has changed. Notification object and userInfo will be nil.
|
||||
*/
|
||||
extern NSString *const AppDelegateUniversalLinkDidChangeNotification;
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, MXKCallViewControllerDelegate, UISplitViewControllerDelegate, UINavigationControllerDelegate, JitsiViewControllerDelegate, UNUserNotificationCenterDelegate>
|
||||
{
|
||||
BOOL isPushRegistered;
|
||||
|
@ -65,6 +71,13 @@ extern NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey;
|
|||
@property (nonatomic) BOOL isAppForeground;
|
||||
@property (nonatomic) BOOL isOffline;
|
||||
|
||||
|
||||
/**
|
||||
Let the AppDelegate handle and display self verification requests.
|
||||
Default is YES;
|
||||
*/
|
||||
@property (nonatomic) BOOL handleSelfVerificationRequest;
|
||||
|
||||
/**
|
||||
The navigation controller of the master view controller of the main split view controller.
|
||||
*/
|
||||
|
@ -80,6 +93,11 @@ extern NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey;
|
|||
// Current selected room id. nil if no room is presently visible.
|
||||
@property (strong, nonatomic) NSString *visibleRoomId;
|
||||
|
||||
/**
|
||||
Last handled universal link (url will be formatted for several hash keys).
|
||||
*/
|
||||
@property (nonatomic, readonly) UniversalLink *lastHandledUniversalLink;
|
||||
|
||||
// New message sound id.
|
||||
@property (nonatomic, readonly) SystemSoundID messageSound;
|
||||
|
||||
|
|
|
@ -88,6 +88,8 @@ NSString *const AppDelegateDidValidateEmailNotification = @"AppDelegateDidValida
|
|||
NSString *const AppDelegateDidValidateEmailNotificationSIDKey = @"AppDelegateDidValidateEmailNotificationSIDKey";
|
||||
NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDelegateDidValidateEmailNotificationClientSecretKey";
|
||||
|
||||
NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUniversalLinkDidChangeNotification";
|
||||
|
||||
@interface AppDelegate () <PKPushRegistryDelegate, GDPRConsentViewControllerDelegate, KeyVerificationCoordinatorBridgePresenterDelegate, ServiceTermsModalCoordinatorBridgePresenterDelegate>
|
||||
{
|
||||
/**
|
||||
|
@ -493,6 +495,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
NSAssert(_masterTabBarController, @"Something wrong in Main.storyboard");
|
||||
|
||||
_isAppForeground = NO;
|
||||
_handleSelfVerificationRequest = YES;
|
||||
|
||||
// Configure our analytics. It will indeed start if the option is enabled
|
||||
[MXSDKOptions sharedInstance].analyticsDelegate = [Analytics sharedInstance];
|
||||
|
@ -2037,6 +2040,19 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
// iOS Patch: fix vector.im urls before using it
|
||||
webURL = [Tools fixURLWithSeveralHashKeys:webURL];
|
||||
|
||||
// Extract required parameters from the link
|
||||
NSArray<NSString*> *pathParams;
|
||||
NSMutableDictionary *queryParams;
|
||||
[self parseUniversalLinkFragment:webURL.absoluteString outPathParams:&pathParams outQueryParams:&queryParams];
|
||||
|
||||
UniversalLink *newLink = [[UniversalLink alloc] initWithUrl:webURL pathParams:pathParams queryParams:queryParams];
|
||||
if (![_lastHandledUniversalLink isEqual:newLink])
|
||||
{
|
||||
_lastHandledUniversalLink = [[UniversalLink alloc] initWithUrl:webURL pathParams:pathParams queryParams:queryParams];
|
||||
// notify this change
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:AppDelegateUniversalLinkDidChangeNotification object:nil];
|
||||
}
|
||||
|
||||
if ([webURL.path hasPrefix:@"/config"])
|
||||
{
|
||||
return [self handleServerProvionningLink:webURL];
|
||||
|
@ -2047,8 +2063,39 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
NSString *validateEmailSubmitTokenAPIPathV1 = [NSString stringWithFormat:@"/%@/%@", kMXIdentityAPIPrefixPathV1, validateEmailSubmitTokenPath];
|
||||
NSString *validateEmailSubmitTokenAPIPathV2 = [NSString stringWithFormat:@"/%@/%@", kMXIdentityAPIPrefixPathV2, validateEmailSubmitTokenPath];
|
||||
|
||||
// Manage email validation link
|
||||
if ([webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV1] || [webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV2])
|
||||
// Manage email validation links from homeserver for registration (/registration/email/submit_token)
|
||||
// and email addition (/add_threepid/email/submit_token)
|
||||
// They look like https://matrix.org/_matrix/client/unstable/registration/email/submit_token?token=vtQjQIZfwdoREDACTEDozrmKYSWlCXsJ&client_secret=53e679ea-oRED-ACTED-92b8-3012c49c6cfa&sid=qlBCREDACTEDEtgxD
|
||||
if ([webURL.path hasSuffix:@"/email/submit_token"])
|
||||
{
|
||||
NSLog(@"[AppDelegate] handleUniversalLink: Validate link");
|
||||
|
||||
// We just need to ping the link.
|
||||
// The app should be in the registration flow at the "waiting for email validation" polling state. The server
|
||||
// will indicate the email is validated through this polling API. Then, the app will go to the next flow step.
|
||||
NSURLSessionConfiguration *conf = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:conf];
|
||||
|
||||
NSURLSessionDataTask * task = [urlSession dataTaskWithURL:webURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||||
|
||||
NSLog(@"[AppDelegate] handleUniversalLink: Link validation response: %@\nData: %@", response,
|
||||
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
|
||||
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"[AppDelegate] handleUniversalLink: Link validation error: %@", error);
|
||||
[self showErrorAsAlert:error];
|
||||
}
|
||||
}];
|
||||
|
||||
[task resume];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Manage email validation link from Identity Server v1 or v2
|
||||
else if ([webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV1]
|
||||
|| [webURL.path isEqualToString:validateEmailSubmitTokenAPIPathV2])
|
||||
{
|
||||
// Validate the email on the passed identity server
|
||||
NSString *identityServer = [NSString stringWithFormat:@"%@://%@", webURL.scheme, webURL.host];
|
||||
|
@ -2066,12 +2113,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
}
|
||||
|
||||
MXIdentityService *identityService = [[MXIdentityService alloc] initWithIdentityServer:identityServer accessToken:nil andHomeserverRestClient:homeserverRestClient];
|
||||
|
||||
// Extract required parameters from the link
|
||||
NSArray<NSString*> *pathParams;
|
||||
NSMutableDictionary *queryParams;
|
||||
[self parseUniversalLinkFragment:webURL.absoluteString outPathParams:&pathParams outQueryParams:&queryParams];
|
||||
|
||||
|
||||
NSString *clientSecret = queryParams[@"client_secret"];
|
||||
NSString *sid = queryParams[@"sid"];
|
||||
|
||||
|
@ -4803,7 +4845,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
{
|
||||
BOOL presented = NO;
|
||||
|
||||
if (!keyVerificationCoordinatorBridgePresenter)
|
||||
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
|
||||
{
|
||||
NSLog(@"[AppDelegate] presentIncomingKeyVerificationRequest");
|
||||
|
||||
|
@ -4827,7 +4869,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
NSLog(@"[AppDelegate][MXKeyVerification] presentIncomingKeyVerification: %@", transaction);
|
||||
|
||||
BOOL presented = NO;
|
||||
if (!keyVerificationCoordinatorBridgePresenter)
|
||||
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
|
||||
{
|
||||
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
|
||||
keyVerificationCoordinatorBridgePresenter.delegate = self;
|
||||
|
@ -4848,7 +4890,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
NSLog(@"[AppDelegate][MXKeyVerification] presentUserVerificationForRoomMember: %@", roomMember);
|
||||
|
||||
BOOL presented = NO;
|
||||
if (!keyVerificationCoordinatorBridgePresenter)
|
||||
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
|
||||
{
|
||||
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
|
||||
keyVerificationCoordinatorBridgePresenter.delegate = self;
|
||||
|
@ -4869,7 +4911,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
NSLog(@"[AppDelegate][MXKeyVerification] presentSelfVerificationForOtherDeviceId: %@", deviceId);
|
||||
|
||||
BOOL presented = NO;
|
||||
if (!keyVerificationCoordinatorBridgePresenter)
|
||||
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
|
||||
{
|
||||
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
|
||||
keyVerificationCoordinatorBridgePresenter.delegate = self;
|
||||
|
@ -4965,6 +5007,12 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
{
|
||||
// Self verification
|
||||
NSLog(@"[AppDelegate][KeyVerification] keyVerificationNewRequestNotification: Self verification from %@", keyVerificationByToDeviceRequest.otherDevice);
|
||||
|
||||
if (!self.handleSelfVerificationRequest)
|
||||
{
|
||||
NSLog(@"[AppDelegate][KeyVerification] keyVerificationNewRequestNotification: Self verification handled elsewhere");
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *myUserId = keyVerificationByToDeviceRequest.otherUser;
|
||||
MXKAccount *account = [[MXKAccountManager sharedManager] accountForUserId:myUserId];
|
||||
|
@ -5006,6 +5054,12 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
senderId:(NSString*)senderId
|
||||
request:(MXKeyVerificationRequest*)keyVerificationRequest
|
||||
{
|
||||
if (keyVerificationRequest.state != MXKeyVerificationRequestStatePending)
|
||||
{
|
||||
NSLog(@"[AppDelegate] presentNewKeyVerificationRequest: Request already accepted. Do not display it");
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.incomingKeyVerificationRequestAlertController)
|
||||
{
|
||||
[self.incomingKeyVerificationRequestAlertController dismissViewControllerAnimated:NO completion:nil];
|
||||
|
@ -5021,7 +5075,17 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
{
|
||||
senderInfo = senderId;
|
||||
}
|
||||
|
||||
|
||||
__block id observer;
|
||||
void (^removeObserver)(void) = ^() {
|
||||
if (observer)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:observer];
|
||||
observer = nil;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"key_verification_tile_request_incoming_title", @"Vector", nil)
|
||||
message:senderInfo
|
||||
|
@ -5031,6 +5095,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
removeObserver();
|
||||
[self presentIncomingKeyVerificationRequest:keyVerificationRequest inSession:session];
|
||||
}]];
|
||||
|
||||
|
@ -5038,6 +5103,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
removeObserver();
|
||||
[keyVerificationRequest cancelWithCancelCode:MXTransactionCancelCode.user success:^{
|
||||
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
|
@ -5049,11 +5115,26 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction * action)
|
||||
{
|
||||
removeObserver();
|
||||
}]];
|
||||
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
|
||||
self.incomingKeyVerificationRequestAlertController = alertController;
|
||||
|
||||
observer = [[NSNotificationCenter defaultCenter] addObserverForName:MXKeyVerificationRequestDidChangeNotification
|
||||
object:keyVerificationRequest
|
||||
queue:[NSOperationQueue mainQueue]
|
||||
usingBlock:^(NSNotification * _Nonnull note)
|
||||
{
|
||||
if (keyVerificationRequest.state != MXKeyVerificationRequestStatePending)
|
||||
{
|
||||
if (self.incomingKeyVerificationRequestAlertController == alertController)
|
||||
{
|
||||
[self.incomingKeyVerificationRequestAlertController dismissViewControllerAnimated:NO completion:nil];
|
||||
removeObserver();
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - New Sign In
|
||||
|
@ -5127,14 +5208,14 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
message:alertMessage
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"continue", @"Vector", nil)
|
||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"device_verification_self_verify_alert_validate_action", @"Vector", nil)
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * action) {
|
||||
|
||||
[self presentSelfVerificationForOtherDeviceId:device.deviceId inSession:session];
|
||||
}]];
|
||||
|
||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"device_verification_self_verify_alert_cancel_action", @"Vector", nil)
|
||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"later", @"Vector", nil)
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:nil]];
|
||||
|
||||
|
@ -5150,7 +5231,7 @@ NSString *const AppDelegateDidValidateEmailNotificationClientSecretKey = @"AppDe
|
|||
NSLog(@"[AppDelegate][MXKeyVerification] presentCompleteSecurityForSession");
|
||||
|
||||
BOOL presented = NO;
|
||||
if (!keyVerificationCoordinatorBridgePresenter)
|
||||
if (!keyVerificationCoordinatorBridgePresenter.isPresenting)
|
||||
{
|
||||
keyVerificationCoordinatorBridgePresenter = [[KeyVerificationCoordinatorBridgePresenter alloc] initWithSession:mxSession];
|
||||
keyVerificationCoordinatorBridgePresenter.delegate = self;
|
||||
|
|
Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 844 B After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 334 B After Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 812 B After Width: | Height: | Size: 2.2 KiB |
|
@ -281,7 +281,7 @@
|
|||
"room_replacement_information" = "Mae'r ystafell hon wedi'i newid ac nid yw'n weithredol mwyach.";
|
||||
"room_replacement_link" = "Mae'r sgwrs yn parhau yma.";
|
||||
"room_predecessor_information" = "Mae'r ystafell hon yn barhad o sgwrs arall.";
|
||||
"room_predecessor_link" = "Cyffyrddwch yma i weld negeseuon hŷn.";
|
||||
"room_predecessor_link" = "Tapiwch yma i weld negeseuon hŷn.";
|
||||
"room_resource_limit_exceeded_message_contact_1" = " Os gwelwch yn dda ";
|
||||
"room_resource_limit_exceeded_message_contact_2_link" = "cysylltwch â'ch gweinyddwr gwasanaeth";
|
||||
"room_resource_limit_exceeded_message_contact_3" = " i barhau i ddefnyddio'r gwasanaeth hwn.";
|
||||
|
@ -418,7 +418,7 @@
|
|||
"settings_add_3pid_invalid_password_message" = "Cyfrinair annilys";
|
||||
"settings_crypto_device_name" = "Enw Sesiwn: ";
|
||||
"settings_crypto_device_id" = "\nDynodwr y sesiwn: ";
|
||||
"settings_crypto_device_key" = "Allwedd y sesiwn:\n";
|
||||
"settings_crypto_device_key" = "\nAllwedd y sesiwn:\n";
|
||||
"settings_crypto_export" = "Allfudo allweddi";
|
||||
"settings_crypto_blacklist_unverified_devices" = "Amgryptio i sesiynau wedi'u gwirio yn unig";
|
||||
"settings_deactivate_my_account" = "Dad-actifadu fy nghyfrif";
|
||||
|
@ -984,3 +984,35 @@
|
|||
"key_verification_verify_qr_code_other_scan_my_code_title" = "A sganwyd y defnyddiwr arall u côd QR yn llwyddianus?";
|
||||
"key_verification_verify_qr_code_scan_other_code_success_title" = "Côd yn ddilys!";
|
||||
"key_verification_verify_qr_code_scan_other_code_success_message" = "Mae'r côd QR wedi'i brofi'n ddilys.";
|
||||
"skip" = "Hepgor";
|
||||
// MARK: Clients
|
||||
"client_desktop_name" = "Riot Cyfrifiadur";
|
||||
"client_web_name" = "Riot Gwê";
|
||||
"client_ios_name" = "Riot iOS";
|
||||
"client_android_name" = "Riot X i Android";
|
||||
"room_participants_action_security_status_complete_security" = "Cwblhewch diogelwch";
|
||||
"room_participants_action_security_status_loading" = "Yn llwytho…";
|
||||
"room_member_power_level_admin_in" = "Gweinyddwr yn %@";
|
||||
"room_member_power_level_moderator_in" = "Cymedrolwrm yn %@";
|
||||
"room_member_power_level_custom_in" = "Addasiedig (%@) yn %@";
|
||||
"room_member_power_level_short_admin" = "Gweinyddwr";
|
||||
"room_member_power_level_short_moderator" = "Cymedrolwr";
|
||||
"room_member_power_level_short_custom" = "Addasiedig";
|
||||
"security_settings_crosssigning" = "CROES-LOFNODI";
|
||||
"security_settings_crosssigning_info_not_bootstrapped" = "Nid yw croes-lofnodi eto wedi ei gyflunio.";
|
||||
"security_settings_crosssigning_info_exists" = "Mae gan eich cyfrif hunaniaeth croes-lofnodi, ond nid yw'r sesiwn hon yn ymddiried ynddo eto. Cwblhewch diogelwch y sesiwn hon.";
|
||||
"security_settings_crosssigning_info_trusted" = "Mae croes-lofnodi wedi'i alluogi. Gallwch ymddiried yn defnyddwyr eraill a'ch sesiynau eraill yn seiliedig ar groes-lofnodi ond ni allwch groes-lofnodi o'r sesiwn hon oherwydd nad oes ganddo allweddi preifat traws-lofnodi. Cwblhewch diogelwch y sesiwn hon.";
|
||||
"security_settings_crosssigning_info_ok" = "Mae croes-lofnodi yn weithredol.";
|
||||
"security_settings_crosssigning_bootstrap" = "Ymlwytho croes-lofnodi";
|
||||
"security_settings_crosssigning_reset" = "Ailosod croes-lofnodi";
|
||||
"security_settings_crosssigning_complete_security" = "Cwblhewch diogelwch";
|
||||
"security_settings_cryptography" = "CRYPTOGRAFFEG";
|
||||
"security_settings_complete_security_alert_title" = "Cwblhewch diogelwch";
|
||||
"security_settings_complete_security_alert_message" = "Dylech gwblhau diogelwch ar eich sesiwn gyfredol yn gyntaf.";
|
||||
"security_settings_coming_soon" = "Sori. Nid yw'r weithred hon ar gael ar Riot-iOS eto. Defnyddiwch gleient Matrix arall i'w osod. Bydd Riot-iOS yn ei ddefnyddio.";
|
||||
// Recover from private key
|
||||
"key_backup_recover_from_private_key_info" = "Yn adfer copi wrth gefn…";
|
||||
"device_verification_self_verify_alert_title" = "Mewngofnodiad Newydd";
|
||||
"device_verification_self_verify_alert_message" = "Defnyddiwch y sesiwn hon i wirio'ch un newydd, gan roi mynediad iddo i negeseuon wedi'u hamgryptio :%@\nOs na wnaethoch fewngofnodi i'r sesiwn hon, mae'n bosibl y bydd eich cyfrif mewn perygl..";
|
||||
"device_verification_self_verify_alert_cancel_action" = "Nid fi oedd hwn";
|
||||
"device_verification_self_verify_start_verify_action" = "Dechrau gwirio";
|
||||
|
|
|
@ -1004,3 +1004,6 @@
|
|||
"device_verification_self_verify_wait_information" = "Benutze diese Sitzung um deine Neue zu verifizieren. Erlaube Zugriff auf die verschlüsselten Nachrichten.";
|
||||
"device_verification_self_verify_wait_waiting" = "warte…";
|
||||
"skip" = "Überspringen";
|
||||
// MARK: Clients
|
||||
"client_desktop_name" = "Riot Desktop";
|
||||
"security_settings_crosssigning_info_not_bootstrapped" = "Cross-signing ist bisher nicht konfiguriert.";
|
||||
|
|
|
@ -1035,10 +1035,12 @@
|
|||
"sign_out_key_backup_in_progress_alert_cancel_action" = "I'll wait";
|
||||
|
||||
// MARK: - Device Verification
|
||||
"device_verification_title" = "Verify session";
|
||||
"key_verification_user_title" = "Verify user";
|
||||
|
||||
"device_verification_security_advice" = "For maximum security, we recommend you do this in person or use another trusted means of communication";
|
||||
"key_verification_other_session_title" = "Verify session";
|
||||
"key_verification_new_session_title" = "Verify your new session";
|
||||
"key_verification_this_session_title" = "Verify this session";
|
||||
"key_verification_user_title" = "Verify them";
|
||||
"device_verification_security_advice_emoji" = "Compare the unique emoji, ensuring they appear in the same order.";
|
||||
"device_verification_security_advice_number" = "Compare the numbers, ensuring they appear in the same order.";
|
||||
"device_verification_cancelled" = "The other party cancelled the verification.";
|
||||
"device_verification_cancelled_by_me" = "The verification has been cancelled. Reason: %@";
|
||||
"device_verification_error_cannot_load_device" = "Cannot load session information.";
|
||||
|
@ -1057,47 +1059,57 @@
|
|||
|
||||
// MARK: Self verification start
|
||||
|
||||
"device_verification_self_verify_alert_title" = "New Sign In";
|
||||
"device_verification_self_verify_alert_message" = "Use this session to verify your new one, granting it access to encrypted messages: %@\nIf you didn’t sign in to this session, your account may be compromised.";
|
||||
"device_verification_self_verify_alert_cancel_action" = "This wasn't me";
|
||||
// New login
|
||||
"device_verification_self_verify_alert_title" = "New login. Was this you?";
|
||||
"device_verification_self_verify_alert_message" = "Verify the new login accessing your account: %@";
|
||||
"device_verification_self_verify_alert_validate_action" = "Verify";
|
||||
|
||||
"device_verification_self_verify_start_verify_action" = "Start verification";
|
||||
"device_verification_self_verify_start_information" = "Use this session to verify your new one, granting it access to encrypted messages.";
|
||||
"device_verification_self_verify_start_waiting" = "Waiting…";
|
||||
|
||||
// Current session
|
||||
|
||||
"key_verification_self_verify_current_session_alert_title" = "Verify this session";
|
||||
"key_verification_self_verify_current_session_alert_message" = "Other users may not trust it.";
|
||||
"key_verification_self_verify_current_session_alert_validate_action" = "Verify";
|
||||
|
||||
// MARK: Self verification wait
|
||||
|
||||
"device_verification_self_verify_wait_title" = "Complete security";
|
||||
"device_verification_self_verify_wait_new_sign_in_title" = "Verify this login";
|
||||
"device_verification_self_verify_wait_information" = "Verify this session from one of your others sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:";
|
||||
"device_verification_self_verify_wait_information" = "Verify this session from one of your other sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:";
|
||||
"device_verification_self_verify_wait_additional_information" = "or another cross-signing capable Matrix client";
|
||||
|
||||
// MARK: Verify
|
||||
|
||||
"key_verification_verify_sas_title_emoji" = "Compare emoji";
|
||||
"key_verification_verify_sas_title_number" = "Compare numbers";
|
||||
|
||||
"key_verification_verify_sas_cancel_action" = "They don't match";
|
||||
"key_verification_verify_sas_validate_action" = "They match";
|
||||
|
||||
"key_verification_verify_sas_additional_information" = "For ultimate security, use another trusted means of communication or do this in person.";
|
||||
|
||||
// Device
|
||||
|
||||
"device_verification_verify_title_emoji" = "Verify this session by confirming the following emoji appear on the screen of the partner";
|
||||
"device_verification_verify_title_number" = "Verify this session by confirming the following numbers appear on the screen of the partner";
|
||||
"device_verification_verify_wait_partner" = "Waiting for partner to confirm…";
|
||||
|
||||
// User
|
||||
|
||||
"key_verification_verify_user_title_emoji" = "Verify this user by confirming the following unique emoji appears on their screen, in the same order.";
|
||||
"key_verification_verify_user_title_number" = "Verify this user by confirming the following numbers appear on their screen, in the same order.";
|
||||
|
||||
// MARK: Verified
|
||||
|
||||
// Device
|
||||
|
||||
"device_verification_verified_title" = "Verified!";
|
||||
"device_verification_verified_description_1" = "You've successfully verified this session.";
|
||||
"device_verification_verified_description_2" = "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.";
|
||||
"device_verification_verified_got_it_button" = "Got it";
|
||||
"key_verification_verified_new_session_title" = "New session verified!";
|
||||
|
||||
"key_verification_verified_other_session_information" = "You can now read secure messages on your other session, and other users will know they can trust it.";
|
||||
"key_verification_verified_new_session_information" = "You can now read secure messages on your new device, and other users will know they can trust it.";
|
||||
"key_verification_verified_this_session_information" = "You can now read secure messages on this device, and other users will know they can trust it.";
|
||||
|
||||
// User
|
||||
|
||||
"key_verification_verified_user_description_1" = "You’ve successfully verified this user.";
|
||||
"key_verification_verified_user_description_2" = "Messages with this user in this room are end-to-end encrypted and can’t be read by third parties.";
|
||||
"key_verification_verified_user_information" = "Messages with this user are end-to-end encrypted and can't be read by third parties.";
|
||||
|
||||
// MARK: Emoji
|
||||
"device_verification_emoji_dog" = "Dog";
|
||||
|
@ -1220,8 +1232,10 @@
|
|||
|
||||
"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_emoji_information" = "Verify by comparing unique emoji.";
|
||||
"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_start_emoji_action" = "Verify by emoji";
|
||||
|
||||
"key_verification_verify_qr_code_other_scan_my_code_title" = "Did the other user successfully scan the QR code?";
|
||||
|
||||
|
|
|
@ -999,7 +999,7 @@
|
|||
"security_settings_crosssigning" = "ZEHARKAKO SINATZEA";
|
||||
"security_settings_cryptography" = "KRIPTOGRAFIA";
|
||||
"key_verification_bootstrap_not_setup_title" = "Errorea";
|
||||
"key_verification_bootstrap_not_setup_message" = "Zeharkako sinatzea ezarri behar duzu";
|
||||
"key_verification_bootstrap_not_setup_message" = "Aurretik zeharkako sinatzea abiatu behar duzu.";
|
||||
"key_verification_verify_qr_code_title" = "Egiaztatu eskaneatuz";
|
||||
"key_verification_verify_qr_code_information" = "Eskaneatu kodea elkar egiaztatzeko.";
|
||||
"key_verification_verify_qr_code_scan_code_action" = "Eskaneatu bestearen kodea";
|
||||
|
@ -1024,5 +1024,31 @@
|
|||
// Recover from private key
|
||||
"key_backup_recover_from_private_key_info" = "Babes-kopia berrezartzen…";
|
||||
"device_verification_self_verify_wait_title" = "Segurtasun osoa";
|
||||
"device_verification_self_verify_wait_information" = "Erabili badagoen beste saio bat berri hau egiaztatzeko, honela mezu zifratuetara sarbidea emanez.";
|
||||
"device_verification_self_verify_wait_information" = "Erabili badagoen beste saio bat berri hau egiaztatzeko, honela mezu zifratuetara sarbidea emanez.\n\nErabili azken Riot bertsioa zure beste gailuetan:";
|
||||
"device_verification_self_verify_wait_waiting" = "Itxaroten…";
|
||||
// MARK: Clients
|
||||
"client_desktop_name" = "Riot Desktop";
|
||||
"client_web_name" = "Riot Web";
|
||||
"client_ios_name" = "Riot iOS";
|
||||
"client_android_name" = "Riot X Androidentzat";
|
||||
"room_participants_action_security_status_complete_security" = "Segurtasun osoa";
|
||||
"security_settings_crosssigning_info_not_bootstrapped" = "Zeharkako sinadura ez dago ezarrita.";
|
||||
"security_settings_crosssigning_info_exists" = "Zure kontuak zeharkako sinatze identitate bat du biltegi sekretuan, baina saio honek ez du oraindik fidagarritzat. Osatu saio honen segurtasuna.";
|
||||
"security_settings_crosssigning_info_trusted" = "Zeharkako sinatzea gaituta dago. Beste erabiltzaileak eta zure beste saioak fidagarritzat jo ditzakezu zeharkako sinadurarekin, baina ezin duzu zeharka sinatu saio honekin ez dituzulako zeharkako sinadurarako gako pribatuak. Osatu saio honen segurtasuna.";
|
||||
"security_settings_crosssigning_info_ok" = "Zeharkako sinadura gaituta dago.";
|
||||
"security_settings_crosssigning_bootstrap" = "Abiatu zeharkako sinadura";
|
||||
"security_settings_crosssigning_reset" = "Berrezarri zeharkako sinadura";
|
||||
"security_settings_crosssigning_complete_security" = "Segurtasun osoa";
|
||||
"security_settings_complete_security_alert_title" = "Segurtasun osoa";
|
||||
"security_settings_complete_security_alert_message" = "Aurretik segurtasuna osatu beharko zenuke oraingo saioan.";
|
||||
"security_settings_coming_soon" = "Sentitzen dugu. Ekintza hau ez dago iOS plataformarako Riot bezeroan eskuragarri oraindik. Erabili beste Matrix bezero bat ezartzeko. Riot-iOS-ek erabili egingo du.";
|
||||
"device_verification_self_verify_wait_new_sign_in_title" = "Egiaztatu saio hau";
|
||||
"device_verification_self_verify_wait_additional_information" = "edo zeharkako sinadurarako gai den beste Matrix bezero bat";
|
||||
// Scanning
|
||||
"key_verification_scan_confirmation_scanning_title" = "Ia bukatu duzu! Baieztapenaren zain…";
|
||||
"key_verification_scan_confirmation_scanning_user_waiting_other" = "%@ itxaroten…";
|
||||
"key_verification_scan_confirmation_scanning_device_waiting_other" = "Beste gailuaren zain…";
|
||||
// Scanned
|
||||
"key_verification_scan_confirmation_scanned_title" = "Ia amaitu duzu!";
|
||||
"key_verification_scan_confirmation_scanned_user_information" = "%@ ezkutu bera erakusten ari da?";
|
||||
"key_verification_scan_confirmation_scanned_device_information" = "Beste gailuak ezkutu bera erakusten du?";
|
||||
|
|
|
@ -1012,7 +1012,7 @@
|
|||
"user_verification_session_details_verify_action_other_user" = "Vérifier manuellement";
|
||||
"security_settings_crypto_sessions_loading" = "Chargement des sessions…";
|
||||
"key_verification_bootstrap_not_setup_title" = "Erreur";
|
||||
"key_verification_bootstrap_not_setup_message" = "Vous devez configurer la signature croisée";
|
||||
"key_verification_bootstrap_not_setup_message" = "Vous devez d’abord configurer la signature croisée.";
|
||||
"key_verification_verify_qr_code_title" = "Vérifier en scannant";
|
||||
"key_verification_verify_qr_code_information" = "Scannez le code pour vous vérifier mutuellement de façon sécurisée.";
|
||||
"key_verification_verify_qr_code_scan_code_action" = "Scannez leur code";
|
||||
|
@ -1031,7 +1031,7 @@
|
|||
"device_verification_self_verify_start_waiting" = "En attente…";
|
||||
"skip" = "Passer";
|
||||
"device_verification_self_verify_wait_title" = "Compléter la sécurité";
|
||||
"device_verification_self_verify_wait_information" = "Utilisez une session existante pour vérifier celle-ci, ce qui lui permettra d’avoir accès aux messages chiffrés.";
|
||||
"device_verification_self_verify_wait_information" = "Vérifiez cette session depuis une de vos autres sessions, ce qui lui permettra d’avoir accès aux messages chiffrés.\n\nUtilisez la dernière version de Riot sur vos autres appareils :";
|
||||
"device_verification_self_verify_wait_waiting" = "En attente…";
|
||||
"room_member_power_level_admin_in" = "Administrateur dans %@";
|
||||
"room_member_power_level_moderator_in" = "Modérateur dans %@";
|
||||
|
@ -1059,4 +1059,11 @@
|
|||
"security_settings_crosssigning_complete_security" = "Compléter la sécurité";
|
||||
"security_settings_complete_security_alert_title" = "Compléter la sécurité";
|
||||
"security_settings_complete_security_alert_message" = "Vous devriez d’abord compléter la sécurité de votre session actuelle.";
|
||||
"security_settings_coming_soon" = "Désolé, cette action n’est pas encore disponible dans Riot-iOS. Utilisez un autre client Matrix.";
|
||||
"security_settings_coming_soon" = "Désolé, cette action n’est pas encore disponible dans Riot-iOS. Utilisez un autre client Matrix pour le configurer. Riot-iOS l’utilisera.";
|
||||
// MARK: Clients
|
||||
"client_desktop_name" = "Riot pour ordinateur";
|
||||
"client_web_name" = "Riot web";
|
||||
"client_ios_name" = "Riot iOS";
|
||||
"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_additional_information" = "ou un autre client Matrix qui prend en charge la signature croisée";
|
||||
|
|
|
@ -1016,7 +1016,7 @@
|
|||
"security_settings_crosssigning" = "KERESZT-ALÁÍRÁS";
|
||||
"security_settings_cryptography" = "TITKOSÍTÁS";
|
||||
"key_verification_bootstrap_not_setup_title" = "Hiba";
|
||||
"key_verification_bootstrap_not_setup_message" = "A keresztaláírás beállításait meg kell adni";
|
||||
"key_verification_bootstrap_not_setup_message" = "A keresztaláírás beállításait először meg kell adni.";
|
||||
"key_verification_verify_qr_code_title" = "Ellenőrzés kód beolvasással";
|
||||
"key_verification_verify_qr_code_information" = "Olvasd be a kódot, hogy biztonságosan ellenőrizhessétek egymást.";
|
||||
"key_verification_verify_qr_code_scan_code_action" = "Kód beolvasása";
|
||||
|
@ -1041,7 +1041,7 @@
|
|||
"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_waiting" = "Várakozik…";
|
||||
"device_verification_self_verify_wait_title" = "Biztonság beállítása";
|
||||
"device_verification_self_verify_wait_information" = "Használj egy meglévő munkamenetet ennek az újnak az ellenőrzéséhez, amivel hozzáférést adsz a titkosított üzenetekhez.";
|
||||
"device_verification_self_verify_wait_information" = "Ennek a munkamenet ellenőrzéséhez használd valamelyik másik munkamenetedet, amivel hozzáférést adsz a titkosított üzenetekhez.\n\nHasználd a legfrissebb Riotot valamelyik eszközödön:";
|
||||
"device_verification_self_verify_wait_waiting" = "Várakozik…";
|
||||
// Scanning
|
||||
"key_verification_scan_confirmation_scanning_title" = "Majdnem kész! Várakozás a megerősítésre…";
|
||||
|
@ -1052,3 +1052,20 @@
|
|||
"key_verification_scan_confirmation_scanned_user_information" = "%s is ugyanazt a pajzsot mutatja?";
|
||||
"key_verification_scan_confirmation_scanned_device_information" = "A másik eszköz is ugyanazt a pajzsot mutatja?";
|
||||
"room_participants_action_security_status_complete_security" = "Biztonsági beállítás befejezése";
|
||||
// MARK: Clients
|
||||
"client_desktop_name" = "Asztali Riot";
|
||||
"client_web_name" = "Riot Web";
|
||||
"client_ios_name" = "Riot iOS";
|
||||
"client_android_name" = "RiotX Android";
|
||||
"security_settings_crosssigning_info_not_bootstrapped" = "Az eszközök közötti hitelesítés nincs még beállítva.";
|
||||
"security_settings_crosssigning_info_exists" = "A fiókodban az eszközök közötti aláírás be van állítva, de ebben a munkamenetben még nem ellenőrizted. Végezd el a munkamenet biztonsági beállításait.";
|
||||
"security_settings_crosssigning_info_trusted" = "Eszközök közötti hitelesítés engedélyezve van. Megbízhatsz más felhasználókban és a munkameneteidben az aláírást felhasználva de ebből a munkamenetből nem tudsz aláírni mert az eszközök közötti aláíráshoz hiányzik a privát kulcs. Fejezd be a munkamenet biztonsági beállításait.";
|
||||
"security_settings_crosssigning_info_ok" = "Eszközök közti hitelesítés engedélyezve.";
|
||||
"security_settings_crosssigning_bootstrap" = "Eszközök közötti hitelesítés beállítása";
|
||||
"security_settings_crosssigning_reset" = "Eszközök közötti hitelesítés alaphelyzetbe állítása";
|
||||
"security_settings_crosssigning_complete_security" = "Biztonsági beállítás befejezése";
|
||||
"security_settings_complete_security_alert_title" = "Biztonsági beállítás befejezése";
|
||||
"security_settings_complete_security_alert_message" = "Először be kell fejezned ennek a munkamenetnek a biztonsági beállítását.";
|
||||
"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_additional_information" = "vagy másik eszközök közötti hitelesítésre alkalmas Matrix kliensre";
|
||||
|
|
|
@ -952,7 +952,7 @@
|
|||
"room_participants_action_security_status_verify" = "Verifica";
|
||||
"room_participants_action_security_status_warning" = "Attenzione";
|
||||
"room_participants_security_loading" = "Caricamento…";
|
||||
"key_verification_user_title" = "Verifica utente";
|
||||
"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_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.";
|
||||
|
@ -984,7 +984,7 @@
|
|||
"user_verification_session_details_verify_action_other_user" = "Verifica manualmente";
|
||||
"security_settings_crypto_sessions_loading" = "Caricamento sessioni…";
|
||||
"key_verification_bootstrap_not_setup_title" = "Errore";
|
||||
"key_verification_bootstrap_not_setup_message" = "Devi inizializzare la firma incrociata";
|
||||
"key_verification_bootstrap_not_setup_message" = "Devi prima inizializzare la firma incrociata.";
|
||||
"key_verification_verify_qr_code_title" = "Verifica scansionando";
|
||||
"key_verification_verify_qr_code_information" = "Scansiona il codice per verificarvi in modo sicuro.";
|
||||
"key_verification_verify_qr_code_scan_code_action" = "Scansiona il suo codice";
|
||||
|
@ -1003,7 +1003,7 @@
|
|||
"device_verification_self_verify_start_waiting" = "In attesa…";
|
||||
"skip" = "Salta";
|
||||
"device_verification_self_verify_wait_title" = "Completa la sicurezza";
|
||||
"device_verification_self_verify_wait_information" = "Usa una sessione esistente per verificare questa nuova, dandole l'accesso ai messaggi cifrati.";
|
||||
"device_verification_self_verify_wait_information" = "Verifica questa sessione da una delle tue altre sessioni, dandole l'accesso ai messaggi cifrati.\n\nUsa la versione più recente di Riot sui tuoi altri dispositivi:";
|
||||
"device_verification_self_verify_wait_waiting" = "In attesa…";
|
||||
"room_member_power_level_admin_in" = "Amministratore in %@";
|
||||
"room_member_power_level_moderator_in" = "Moderatore in %@";
|
||||
|
@ -1031,4 +1031,19 @@
|
|||
"security_settings_crosssigning_complete_security" = "Completa la sicurezza";
|
||||
"security_settings_complete_security_alert_title" = "Completa la sicurezza";
|
||||
"security_settings_complete_security_alert_message" = "Dovresti completare la sicurezza prima sulla tua sessione attuale.";
|
||||
"security_settings_coming_soon" = "Spiacenti. Questa azione non è ancora disponibile su Riot-iOS. Prova ad usare un altro client Matrix.";
|
||||
"security_settings_coming_soon" = "Spiacenti. Questa azione non è ancora disponibile su Riot-iOS. Prova ad usare un altro client Matrix per farlo. Riot-iOS lo userà.";
|
||||
// MARK: Clients
|
||||
"client_desktop_name" = "Riot Desktop";
|
||||
"client_web_name" = "Riot Web";
|
||||
"client_ios_name" = "Riot iOS";
|
||||
"client_android_name" = "Riot X per Android";
|
||||
"device_verification_self_verify_wait_new_sign_in_title" = "Verifica questo accesso";
|
||||
"device_verification_self_verify_wait_additional_information" = "o un altro client Matrix che supporti la firma incrociata";
|
||||
// MARK: - Device Verification
|
||||
"key_verification_other_session_title" = "Verifica sessione";
|
||||
"key_verification_new_session_title" = "Verifica la tua nuova sessione";
|
||||
"key_verification_this_session_title" = "Verifica questa sessione";
|
||||
"device_verification_security_advice_emoji" = "Confronta gli emoji univoci, 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_number" = "Confronta numeri";
|
||||
|
|
|
@ -212,7 +212,7 @@
|
|||
"room_delete_unsent_messages" = "未送信の文を削除";
|
||||
"room_event_action_copy" = "複写";
|
||||
"room_event_action_quote" = "引用";
|
||||
"room_event_action_redact" = "編集";
|
||||
"room_event_action_redact" = "移動して削除";
|
||||
"room_event_action_more" = "さらに";
|
||||
"room_event_action_share" = "共有";
|
||||
"room_event_action_permalink" = "直リンク";
|
||||
|
@ -568,3 +568,6 @@
|
|||
// Accessibility
|
||||
"accessibility_checkbox_label" = "チェックボックス";
|
||||
"auth_login_single_sign_on" = "シングルサインオン(SSO)でサインイン";
|
||||
"auth_softlogout_clear_data_sign_out" = "サインアウト";
|
||||
"room_message_unable_open_link_error_message" = "リンクを開くことができません。";
|
||||
"user_verification_session_details_verify_action_other_user" = "手動で確認";
|
||||
|
|
|
@ -810,22 +810,26 @@ internal enum VectorL10n {
|
|||
internal static var deviceVerificationIncomingTitle: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_incoming_title")
|
||||
}
|
||||
/// For maximum security, we recommend you do this in person or use another trusted means of communication
|
||||
internal static var deviceVerificationSecurityAdvice: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_security_advice")
|
||||
/// Compare the unique emoji, ensuring they appear in the same order.
|
||||
internal static var deviceVerificationSecurityAdviceEmoji: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_security_advice_emoji")
|
||||
}
|
||||
/// This wasn't me
|
||||
internal static var deviceVerificationSelfVerifyAlertCancelAction: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_cancel_action")
|
||||
/// Compare the numbers, ensuring they appear in the same order.
|
||||
internal static var deviceVerificationSecurityAdviceNumber: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_security_advice_number")
|
||||
}
|
||||
/// Use this session to verify your new one, granting it access to encrypted messages: %@\nIf you didn’t sign in to this session, your account may be compromised.
|
||||
/// Verify the new login accessing your account: %@
|
||||
internal static func deviceVerificationSelfVerifyAlertMessage(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_message", p1)
|
||||
}
|
||||
/// New Sign In
|
||||
/// New login. Was this you?
|
||||
internal static var deviceVerificationSelfVerifyAlertTitle: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_title")
|
||||
}
|
||||
/// Verify
|
||||
internal static var deviceVerificationSelfVerifyAlertValidateAction: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_alert_validate_action")
|
||||
}
|
||||
/// Use this session to verify your new one, granting it access to encrypted messages.
|
||||
internal static var deviceVerificationSelfVerifyStartInformation: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_start_information")
|
||||
|
@ -842,7 +846,7 @@ internal enum VectorL10n {
|
|||
internal static var deviceVerificationSelfVerifyWaitAdditionalInformation: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_additional_information")
|
||||
}
|
||||
/// Verify this session from one of your others sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:
|
||||
/// Verify this session from one of your other sessions, granting it access to encrypted messages.\n\nUse the latest Riot on your other devices:
|
||||
internal static var deviceVerificationSelfVerifyWaitInformation: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_information")
|
||||
}
|
||||
|
@ -874,18 +878,6 @@ internal enum VectorL10n {
|
|||
internal static var deviceVerificationStartWaitPartner: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_start_wait_partner")
|
||||
}
|
||||
/// Verify session
|
||||
internal static var deviceVerificationTitle: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_title")
|
||||
}
|
||||
/// You've successfully verified this session.
|
||||
internal static var deviceVerificationVerifiedDescription1: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_verified_description_1")
|
||||
}
|
||||
/// Secure messages with this user are end-to-end encrypted and not able to be read by third parties.
|
||||
internal static var deviceVerificationVerifiedDescription2: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_verified_description_2")
|
||||
}
|
||||
/// Got it
|
||||
internal static var deviceVerificationVerifiedGotItButton: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_verified_got_it_button")
|
||||
|
@ -894,14 +886,6 @@ internal enum VectorL10n {
|
|||
internal static var deviceVerificationVerifiedTitle: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_verified_title")
|
||||
}
|
||||
/// Verify this session by confirming the following emoji appear on the screen of the partner
|
||||
internal static var deviceVerificationVerifyTitleEmoji: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_verify_title_emoji")
|
||||
}
|
||||
/// Verify this session by confirming the following numbers appear on the screen of the partner
|
||||
internal static var deviceVerificationVerifyTitleNumber: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_verify_title_number")
|
||||
}
|
||||
/// Waiting for partner to confirm…
|
||||
internal static var deviceVerificationVerifyWaitPartner: String {
|
||||
return VectorL10n.tr("Vector", "device_verification_verify_wait_partner")
|
||||
|
@ -1542,6 +1526,14 @@ internal enum VectorL10n {
|
|||
internal static func keyVerificationIncomingRequestIncomingAlertMessage(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "key_verification_incoming_request_incoming_alert_message", p1)
|
||||
}
|
||||
/// Verify your new session
|
||||
internal static var keyVerificationNewSessionTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_new_session_title")
|
||||
}
|
||||
/// Verify session
|
||||
internal static var keyVerificationOtherSessionTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_other_session_title")
|
||||
}
|
||||
/// Is the other device showing the same shield?
|
||||
internal static var keyVerificationScanConfirmationScannedDeviceInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_scan_confirmation_scanned_device_information")
|
||||
|
@ -1566,6 +1558,22 @@ internal enum VectorL10n {
|
|||
internal static func keyVerificationScanConfirmationScanningUserWaitingOther(_ p1: String) -> String {
|
||||
return VectorL10n.tr("Vector", "key_verification_scan_confirmation_scanning_user_waiting_other", p1)
|
||||
}
|
||||
/// Other users may not trust it.
|
||||
internal static var keyVerificationSelfVerifyCurrentSessionAlertMessage: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_message")
|
||||
}
|
||||
/// Verify this session
|
||||
internal static var keyVerificationSelfVerifyCurrentSessionAlertTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_title")
|
||||
}
|
||||
/// Verify
|
||||
internal static var keyVerificationSelfVerifyCurrentSessionAlertValidateAction: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_self_verify_current_session_alert_validate_action")
|
||||
}
|
||||
/// Verify this session
|
||||
internal static var keyVerificationThisSessionTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_this_session_title")
|
||||
}
|
||||
/// Verified
|
||||
internal static var keyVerificationTileConclusionDoneTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_tile_conclusion_done_title")
|
||||
|
@ -1614,22 +1622,38 @@ internal enum VectorL10n {
|
|||
internal static var keyVerificationTileRequestStatusWaiting: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_tile_request_status_waiting")
|
||||
}
|
||||
/// Verify user
|
||||
/// Verify them
|
||||
internal static var keyVerificationUserTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_user_title")
|
||||
}
|
||||
/// You’ve successfully verified this user.
|
||||
internal static var keyVerificationVerifiedUserDescription1: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verified_user_description_1")
|
||||
/// You can now read secure messages on your new device, and other users will know they can trust it.
|
||||
internal static var keyVerificationVerifiedNewSessionInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verified_new_session_information")
|
||||
}
|
||||
/// Messages with this user in this room are end-to-end encrypted and can’t be read by third parties.
|
||||
internal static var keyVerificationVerifiedUserDescription2: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verified_user_description_2")
|
||||
/// New session verified!
|
||||
internal static var keyVerificationVerifiedNewSessionTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verified_new_session_title")
|
||||
}
|
||||
/// You can now read secure messages on your other session, and other users will know they can trust it.
|
||||
internal static var keyVerificationVerifiedOtherSessionInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verified_other_session_information")
|
||||
}
|
||||
/// You can now read secure messages on this device, and other users will know they can trust it.
|
||||
internal static var keyVerificationVerifiedThisSessionInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verified_this_session_information")
|
||||
}
|
||||
/// Messages with this user are end-to-end encrypted and can't be read by third parties.
|
||||
internal static var keyVerificationVerifiedUserInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verified_user_information")
|
||||
}
|
||||
/// Can't scan?
|
||||
internal static var keyVerificationVerifyQrCodeCannotScanAction: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_cannot_scan_action")
|
||||
}
|
||||
/// Verify by comparing unique emoji.
|
||||
internal static var keyVerificationVerifyQrCodeEmojiInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_emoji_information")
|
||||
}
|
||||
/// Scan the code to securely verify each other.
|
||||
internal static var keyVerificationVerifyQrCodeInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_information")
|
||||
|
@ -1650,17 +1674,33 @@ internal enum VectorL10n {
|
|||
internal static var keyVerificationVerifyQrCodeScanOtherCodeSuccessTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_scan_other_code_success_title")
|
||||
}
|
||||
/// Verify by emoji
|
||||
internal static var keyVerificationVerifyQrCodeStartEmojiAction: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_start_emoji_action")
|
||||
}
|
||||
/// Verify by scanning
|
||||
internal static var keyVerificationVerifyQrCodeTitle: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_qr_code_title")
|
||||
}
|
||||
/// Verify this user by confirming the following unique emoji appears on their screen, in the same order.
|
||||
internal static var keyVerificationVerifyUserTitleEmoji: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_user_title_emoji")
|
||||
/// For ultimate security, use another trusted means of communication or do this in person.
|
||||
internal static var keyVerificationVerifySasAdditionalInformation: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_sas_additional_information")
|
||||
}
|
||||
/// Verify this user by confirming the following numbers appear on their screen, in the same order.
|
||||
internal static var keyVerificationVerifyUserTitleNumber: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_user_title_number")
|
||||
/// They don't match
|
||||
internal static var keyVerificationVerifySasCancelAction: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_sas_cancel_action")
|
||||
}
|
||||
/// Compare emoji
|
||||
internal static var keyVerificationVerifySasTitleEmoji: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_sas_title_emoji")
|
||||
}
|
||||
/// Compare numbers
|
||||
internal static var keyVerificationVerifySasTitleNumber: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_sas_title_number")
|
||||
}
|
||||
/// They match
|
||||
internal static var keyVerificationVerifySasValidateAction: String {
|
||||
return VectorL10n.tr("Vector", "key_verification_verify_sas_validate_action")
|
||||
}
|
||||
/// %.1fK
|
||||
internal static func largeBadgeValueKFormat(_ p1: Float) -> String {
|
||||
|
|
|
@ -32,7 +32,7 @@ final class RiotSettings: NSObject {
|
|||
static let pinRoomsWithUnreadMessages = "pinRoomsWithUnread"
|
||||
static let allowStunServerFallback = "allowStunServerFallback"
|
||||
static let stunServerFallback = "stunServerFallback"
|
||||
static let enableDMKeyVerification = "enableDMKeyVerification"
|
||||
static let hideVerifyThisSessionAlert = "hideVerifyThisSessionAlert"
|
||||
}
|
||||
|
||||
static let shared = RiotSettings()
|
||||
|
@ -134,4 +134,14 @@ final class RiotSettings: NSObject {
|
|||
var stunServerFallback: String? {
|
||||
return UserDefaults.standard.string(forKey: UserDefaultsKeys.stunServerFallback)
|
||||
}
|
||||
|
||||
// MARK: Key verification
|
||||
|
||||
var hideVerifyThisSessionAlert: Bool {
|
||||
get {
|
||||
return UserDefaults.standard.bool(forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
|
||||
} set {
|
||||
UserDefaults.standard.set(newValue, forKey: UserDefaultsKeys.hideVerifyThisSessionAlert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,6 @@
|
|||
|
||||
@interface AuthenticationViewController () <AuthFallBackViewControllerDelegate, KeyVerificationCoordinatorBridgePresenterDelegate>
|
||||
{
|
||||
/**
|
||||
Store the potential login error received by using a default homeserver different from matrix.org
|
||||
while we retry a login process against the matrix.org HS.
|
||||
*/
|
||||
NSError *loginError;
|
||||
|
||||
/**
|
||||
The default country code used to initialize the mobile phone number input.
|
||||
*/
|
||||
|
@ -43,6 +37,11 @@
|
|||
*/
|
||||
id kThemeServiceDidChangeThemeNotificationObserver;
|
||||
|
||||
/**
|
||||
Observe AppDelegateUniversalLinkDidChangeNotification to handle universal link changes.
|
||||
*/
|
||||
id universalLinkDidChangeNotificationObserver;
|
||||
|
||||
/**
|
||||
Server discovery.
|
||||
*/
|
||||
|
@ -149,7 +148,12 @@
|
|||
[self userInterfaceThemeDidChange];
|
||||
|
||||
}];
|
||||
universalLinkDidChangeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:AppDelegateUniversalLinkDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) {
|
||||
[self updateUniversalLink];
|
||||
}];
|
||||
|
||||
[self userInterfaceThemeDidChange];
|
||||
[self updateUniversalLink];
|
||||
}
|
||||
|
||||
- (void)userInterfaceThemeDidChange
|
||||
|
@ -224,6 +228,20 @@
|
|||
[self setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
|
||||
- (void)updateUniversalLink
|
||||
{
|
||||
UniversalLink *link = [AppDelegate theDelegate].lastHandledUniversalLink;
|
||||
if (link)
|
||||
{
|
||||
NSString *emailAddress = link.queryParams[@"email"];
|
||||
if (emailAddress && self.authInputsView)
|
||||
{
|
||||
AuthInputsView *inputsView = (AuthInputsView *)self.authInputsView;
|
||||
inputsView.emailTextField.text = emailAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||
{
|
||||
return ThemeService.shared.theme.statusBarStyle;
|
||||
|
@ -270,6 +288,12 @@
|
|||
kThemeServiceDidChangeThemeNotificationObserver = nil;
|
||||
}
|
||||
|
||||
if (universalLinkDidChangeNotificationObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:universalLinkDidChangeNotificationObserver];
|
||||
universalLinkDidChangeNotificationObserver = nil;
|
||||
}
|
||||
|
||||
autoDiscovery = nil;
|
||||
_keyVerificationCoordinatorBridgePresenter = nil;
|
||||
}
|
||||
|
@ -288,16 +312,7 @@
|
|||
}
|
||||
|
||||
super.authType = authType;
|
||||
|
||||
// Check a potential stored error.
|
||||
if (loginError)
|
||||
{
|
||||
// Restore the default HS
|
||||
NSLog(@"[AuthenticationVC] Switch back to default homeserver");
|
||||
[self setHomeServerTextFieldText:nil];
|
||||
loginError = nil;
|
||||
}
|
||||
|
||||
|
||||
if (authType == MXKAuthenticationTypeLogin)
|
||||
{
|
||||
[self.submitButton setTitle:NSLocalizedStringFromTable(@"auth_login", @"Vector", nil) forState:UIControlStateNormal];
|
||||
|
@ -683,6 +698,7 @@
|
|||
if ([self.authInputsView isKindOfClass:AuthInputsView.class])
|
||||
{
|
||||
authInputsview = (AuthInputsView*)self.authInputsView;
|
||||
[self updateUniversalLink];
|
||||
}
|
||||
|
||||
// Hide "Forgot password" and "Log in" buttons in case of SSO
|
||||
|
@ -845,76 +861,14 @@
|
|||
|
||||
- (void)onFailureDuringAuthRequest:(NSError *)error
|
||||
{
|
||||
// Homeserver migration: When the default homeserver url is different from matrix.org,
|
||||
// the login (or forgot pwd) process with an existing matrix.org accounts will then fail.
|
||||
// Patch: Falling back to matrix.org HS so we don't break everyone's logins
|
||||
if ([self.homeServerTextField.text isEqualToString:self.defaultHomeServerUrl] && ![self.defaultHomeServerUrl isEqualToString:@"https://matrix.org"] && !self.softLogoutCredentials)
|
||||
MXError *mxError = [[MXError alloc] initWithNSError:error];
|
||||
if ([mxError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded])
|
||||
{
|
||||
MXError *mxError = [[MXError alloc] initWithNSError:error];
|
||||
|
||||
if (self.authType == MXKAuthenticationTypeLogin)
|
||||
{
|
||||
if (mxError && [mxError.errcode isEqualToString:kMXErrCodeStringForbidden])
|
||||
{
|
||||
// Falling back to matrix.org HS
|
||||
NSLog(@"[AuthenticationVC] Retry login against matrix.org");
|
||||
|
||||
// Store the current error, and change the homeserver url
|
||||
loginError = error;
|
||||
[self setHomeServerTextFieldText:@"https://matrix.org"];
|
||||
|
||||
// Trigger a new request
|
||||
[self onButtonPressed:self.submitButton];
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (self.authType == MXKAuthenticationTypeForgotPassword)
|
||||
{
|
||||
if (mxError && [mxError.errcode isEqualToString:kMXErrCodeStringNotFound])
|
||||
{
|
||||
// Sanity check
|
||||
if ([self.authInputsView isKindOfClass:ForgotPasswordInputsView.class])
|
||||
{
|
||||
// Falling back to matrix.org HS
|
||||
NSLog(@"[AuthenticationVC] Retry forgot password against matrix.org");
|
||||
|
||||
// Store the current error, and change the homeserver url
|
||||
loginError = error;
|
||||
[self setHomeServerTextFieldText:@"https://matrix.org"];
|
||||
|
||||
// Trigger a new request
|
||||
ForgotPasswordInputsView *authInputsView = (ForgotPasswordInputsView*)self.authInputsView;
|
||||
[authInputsView.nextStepButton sendActionsForControlEvents:UIControlEventTouchUpInside];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether we were retrying against matrix.org HS
|
||||
if (loginError)
|
||||
{
|
||||
// This is not an existing matrix.org accounts
|
||||
NSLog(@"[AuthenticationVC] This is not an existing matrix.org accounts");
|
||||
|
||||
// Restore the default HS
|
||||
[self setHomeServerTextFieldText:nil];
|
||||
|
||||
// Consider the original login error
|
||||
[super onFailureDuringAuthRequest:loginError];
|
||||
loginError = nil;
|
||||
[self showResourceLimitExceededError:mxError.userInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
MXError *mxError = [[MXError alloc] initWithNSError:error];
|
||||
if ([mxError.errcode isEqualToString:kMXErrCodeStringResourceLimitExceeded])
|
||||
{
|
||||
[self showResourceLimitExceededError:mxError.userInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
[super onFailureDuringAuthRequest:error];
|
||||
}
|
||||
[super onFailureDuringAuthRequest:error];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
85
Riot/Modules/Common/Buttons/Close/RoundedButton.swift
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
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 RoundedButton: UIButton, Themable {
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
private enum Constants {
|
||||
static let backgroundColorAlpha: CGFloat = 0.2
|
||||
static let cornerRadius: CGFloat = 6.0
|
||||
static let fontSize: CGFloat = 17.0
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var theme: Theme?
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var actionStyle: UIAlertAction.Style = .default {
|
||||
didSet {
|
||||
self.updateButtonStyle()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Life cycle
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
self.layer.masksToBounds = true
|
||||
self.titleLabel?.font = UIFont.systemFont(ofSize: Constants.fontSize)
|
||||
self.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
self.layer.cornerRadius = Constants.cornerRadius
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func updateButtonStyle() {
|
||||
guard let theme = theme else {
|
||||
return
|
||||
}
|
||||
|
||||
let backgroundColor: UIColor
|
||||
|
||||
switch self.actionStyle {
|
||||
case .default:
|
||||
backgroundColor = theme.tintColor
|
||||
default:
|
||||
backgroundColor = theme.noticeColor
|
||||
}
|
||||
|
||||
self.vc_setBackgroundColor(backgroundColor.withAlphaComponent(Constants.backgroundColorAlpha), for: .normal)
|
||||
self.setTitleColor(backgroundColor, for: .normal)
|
||||
}
|
||||
|
||||
// MARK: - Themable
|
||||
|
||||
func update(theme: Theme) {
|
||||
self.theme = theme
|
||||
self.updateButtonStyle()
|
||||
}
|
||||
}
|
|
@ -91,17 +91,27 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
|
|||
self.session = session
|
||||
self.verificationFlow = flow
|
||||
|
||||
if case let .incomingRequest(request) = flow {
|
||||
let verificationKind: KeyVerificationKind
|
||||
|
||||
switch flow {
|
||||
case .incomingRequest(let request):
|
||||
if request.isFromMyUser {
|
||||
self.verificationKind = .device
|
||||
// TODO: Check for .newSession case
|
||||
verificationKind = .otherSession
|
||||
} else {
|
||||
self.verificationKind = .user
|
||||
verificationKind = .user
|
||||
}
|
||||
} else if case .verifyUser = flow {
|
||||
self.verificationKind = .user
|
||||
} else {
|
||||
self.verificationKind = .device
|
||||
case .verifyUser:
|
||||
verificationKind = .user
|
||||
case .completeSecurity:
|
||||
verificationKind = .thisSession
|
||||
case .verifyDevice:
|
||||
verificationKind = .otherSession
|
||||
case .incomingSASTransaction:
|
||||
verificationKind = .otherSession
|
||||
}
|
||||
|
||||
self.verificationKind = verificationKind
|
||||
}
|
||||
|
||||
// MARK: - Public methods
|
||||
|
@ -172,7 +182,7 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
|
|||
}
|
||||
|
||||
private func createDataLoadingScreenCoordinator(otherUserId: String, otherDeviceId: String) -> KeyVerificationDataLoadingCoordinator {
|
||||
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
|
||||
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, verificationKind: self.verificationKind, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
|
||||
|
@ -180,7 +190,7 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
|
|||
}
|
||||
|
||||
private func createDataLoadingScreenCoordinator(with keyVerificationRequest: MXKeyVerificationRequest) -> KeyVerificationDataLoadingCoordinator {
|
||||
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, incomingKeyVerificationRequest: keyVerificationRequest)
|
||||
let coordinator = KeyVerificationDataLoadingCoordinator(session: self.session, verificationKind: self.verificationKind, incomingKeyVerificationRequest: keyVerificationRequest)
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
|
||||
|
@ -229,7 +239,7 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
|
|||
}
|
||||
|
||||
private func showVerifyByScanning(keyVerificationRequest: MXKeyVerificationRequest, animated: Bool) {
|
||||
let coordinator = KeyVerificationVerifyByScanningCoordinator(session: self.session, keyVerificationRequest: keyVerificationRequest)
|
||||
let coordinator = KeyVerificationVerifyByScanningCoordinator(session: self.session, verificationKind: self.verificationKind, keyVerificationRequest: keyVerificationRequest)
|
||||
coordinator.delegate = self
|
||||
coordinator.start()
|
||||
|
||||
|
@ -363,10 +373,6 @@ extension KeyVerificationCoordinator: KeyVerificationVerifyByScanningCoordinator
|
|||
self.didCancel()
|
||||
}
|
||||
|
||||
func keyVerificationVerifyByScanningCoordinatorCannotScan(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType) {
|
||||
self.showVerified(animated: true)
|
||||
}
|
||||
|
||||
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, didScanOtherQRCodeData qrCodeData: MXQRCodeData, withTransaction transaction: MXQRCodeTransaction) {
|
||||
self.showScanConfirmation(for: transaction, codeScanning: .scannedOtherQRCode(qrCodeData), animated: true)
|
||||
}
|
||||
|
@ -394,10 +400,15 @@ extension KeyVerificationCoordinator: KeyVerificationSelfVerifyStartCoordinatorD
|
|||
|
||||
// MARK: - KeyVerificationSelfVerifyWaitCoordinatorDelegate
|
||||
extension KeyVerificationCoordinator: KeyVerificationSelfVerifyWaitCoordinatorDelegate {
|
||||
|
||||
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
self.showVerifyByScanning(keyVerificationRequest: keyVerificationRequest, animated: true)
|
||||
}
|
||||
|
||||
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction) {
|
||||
self.showVerifyBySAS(transaction: incomingSASTransaction, animated: true)
|
||||
}
|
||||
|
||||
func keyVerificationSelfVerifyWaitCoordinatorDidCancel(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType) {
|
||||
self.didCancel()
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ final class KeyVerificationCoordinatorBridgePresenter: NSObject {
|
|||
|
||||
weak var delegate: KeyVerificationCoordinatorBridgePresenterDelegate?
|
||||
|
||||
var isPresenting: Bool {
|
||||
return self.coordinator != nil
|
||||
}
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession) {
|
||||
|
|
|
@ -16,6 +16,26 @@
|
|||
import Foundation
|
||||
|
||||
enum KeyVerificationKind {
|
||||
case device
|
||||
case user
|
||||
case otherSession // An other session
|
||||
case thisSession // My current session is new
|
||||
case newSession // My other session is new
|
||||
case user // Another user
|
||||
|
||||
var verificationTitle: String {
|
||||
|
||||
let title: String
|
||||
|
||||
switch self {
|
||||
case .otherSession:
|
||||
title = VectorL10n.keyVerificationOtherSessionTitle
|
||||
case .thisSession:
|
||||
title = VectorL10n.keyVerificationThisSessionTitle
|
||||
case .newSession:
|
||||
title = VectorL10n.keyVerificationNewSessionTitle
|
||||
case .user:
|
||||
title = VectorL10n.keyVerificationUserTitle
|
||||
}
|
||||
|
||||
return title
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,15 +37,15 @@ final class KeyVerificationDataLoadingCoordinator: KeyVerificationDataLoadingCoo
|
|||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession, otherUserId: String, otherDeviceId: String) {
|
||||
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
|
||||
init(session: MXSession, verificationKind: KeyVerificationKind, otherUserId: String, otherDeviceId: String) {
|
||||
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, verificationKind: verificationKind, otherUserId: otherUserId, otherDeviceId: otherDeviceId)
|
||||
let keyVerificationDataLoadingViewController = KeyVerificationDataLoadingViewController.instantiate(with: keyVerificationDataLoadingViewModel)
|
||||
self.keyVerificationDataLoadingViewModel = keyVerificationDataLoadingViewModel
|
||||
self.keyVerificationDataLoadingViewController = keyVerificationDataLoadingViewController
|
||||
}
|
||||
|
||||
init(session: MXSession, incomingKeyVerificationRequest: MXKeyVerificationRequest) {
|
||||
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, keyVerificationRequest: incomingKeyVerificationRequest)
|
||||
init(session: MXSession, verificationKind: KeyVerificationKind, incomingKeyVerificationRequest: MXKeyVerificationRequest) {
|
||||
let keyVerificationDataLoadingViewModel = KeyVerificationDataLoadingViewModel(session: session, verificationKind: verificationKind, keyVerificationRequest: incomingKeyVerificationRequest)
|
||||
let keyVerificationDataLoadingViewController = KeyVerificationDataLoadingViewController.instantiate(with: keyVerificationDataLoadingViewModel)
|
||||
self.keyVerificationDataLoadingViewModel = keyVerificationDataLoadingViewModel
|
||||
self.keyVerificationDataLoadingViewController = keyVerificationDataLoadingViewController
|
||||
|
|
|
@ -47,7 +47,7 @@ final class KeyVerificationDataLoadingViewController: UIViewController {
|
|||
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
self.title = VectorL10n.deviceVerificationTitle
|
||||
self.title = self.viewModel.verificationKind.verificationTitle
|
||||
self.vc_removeBackTitle()
|
||||
|
||||
self.setupViews()
|
||||
|
|
|
@ -31,6 +31,7 @@ final class KeyVerificationDataLoadingViewModel: KeyVerificationDataLoadingViewM
|
|||
// MARK: Private
|
||||
|
||||
private let session: MXSession
|
||||
private(set) var verificationKind: KeyVerificationKind
|
||||
private let otherUserId: String?
|
||||
private let otherDeviceId: String?
|
||||
private let keyVerificationService = KeyVerificationService()
|
||||
|
@ -46,15 +47,17 @@ final class KeyVerificationDataLoadingViewModel: KeyVerificationDataLoadingViewM
|
|||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession, otherUserId: String, otherDeviceId: String) {
|
||||
init(session: MXSession, verificationKind: KeyVerificationKind, otherUserId: String, otherDeviceId: String) {
|
||||
self.session = session
|
||||
self.verificationKind = verificationKind
|
||||
self.otherUserId = otherUserId
|
||||
self.otherDeviceId = otherDeviceId
|
||||
self.keyVerificationRequest = nil
|
||||
}
|
||||
|
||||
init(session: MXSession, keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
init(session: MXSession, verificationKind: KeyVerificationKind, keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
self.session = session
|
||||
self.verificationKind = verificationKind
|
||||
self.otherUserId = nil
|
||||
self.otherDeviceId = nil
|
||||
self.keyVerificationRequest = keyVerificationRequest
|
||||
|
|
|
@ -35,5 +35,7 @@ protocol KeyVerificationDataLoadingViewModelType {
|
|||
var viewDelegate: KeyVerificationDataLoadingViewModelViewDelegate? { get set }
|
||||
var coordinatorDelegate: KeyVerificationDataLoadingViewModelCoordinatorDelegate? { get set }
|
||||
|
||||
var verificationKind: KeyVerificationKind { get }
|
||||
|
||||
func process(viewAction: KeyVerificationDataLoadingViewAction)
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="8Ou-Xh-0rC">
|
||||
<rect key="frame" x="0.0" y="48" width="374" height="40"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kBt-2D-25V">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kBt-2D-25V" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="182" height="40"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="No">
|
||||
|
@ -71,7 +71,7 @@
|
|||
<action selector="rejectButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="qCV-Oh-YAG"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="03A-fe-h3s">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="03A-fe-h3s" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="192" y="0.0" width="182" height="40"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="Yes">
|
||||
|
|
|
@ -22,11 +22,6 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
|
|||
|
||||
// MARK: - Constants
|
||||
|
||||
private enum Constants {
|
||||
static let buttonBackgroundColorAlpha: CGFloat = 0.2
|
||||
static let buttonCornerRadius: CGFloat = 6.0
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Outlets
|
||||
|
@ -39,8 +34,8 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
|
|||
|
||||
@IBOutlet private weak var scannedContentView: UIView!
|
||||
@IBOutlet private weak var scannedInformationLabel: UILabel!
|
||||
@IBOutlet private weak var rejectButton: UIButton!
|
||||
@IBOutlet private weak var confirmButton: UIButton!
|
||||
@IBOutlet private weak var rejectButton: RoundedButton!
|
||||
@IBOutlet private weak var confirmButton: RoundedButton!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
|
@ -76,15 +71,6 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
|
|||
|
||||
self.viewModel.process(viewAction: .loadData)
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
|
||||
if self.scannedContentView.isHidden == false {
|
||||
self.confirmButton.layer.cornerRadius = Constants.buttonCornerRadius
|
||||
self.rejectButton.layer.cornerRadius = Constants.buttonCornerRadius
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
@ -111,8 +97,8 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
|
|||
self.titleLabel.textColor = theme.textPrimaryColor
|
||||
self.waitingLabel.textColor = theme.textSecondaryColor
|
||||
self.scannedInformationLabel.textColor = theme.textPrimaryColor
|
||||
self.confirmButton.vc_setBackgroundColor(theme.tintColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
|
||||
self.rejectButton.vc_setBackgroundColor(theme.noticeColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
|
||||
self.confirmButton.update(theme: theme)
|
||||
self.rejectButton.update(theme: theme)
|
||||
}
|
||||
|
||||
private func registerThemeServiceDidChangeThemeNotification() {
|
||||
|
@ -130,10 +116,12 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
|
|||
|
||||
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
||||
|
||||
self.title = VectorL10n.keyVerificationVerifyQrCodeTitle
|
||||
|
||||
self.confirmButton.layer.masksToBounds = true
|
||||
self.rejectButton.layer.masksToBounds = true
|
||||
|
||||
self.confirmButton.setTitle(Bundle.mxk_localizedString(forKey: "yes"), for: .normal)
|
||||
self.rejectButton.setTitle(Bundle.mxk_localizedString(forKey: "no"), for: .normal)
|
||||
self.rejectButton.actionStyle = .cancel
|
||||
}
|
||||
|
||||
private func render(viewState: KeyVerificationScanConfirmationViewState) {
|
||||
|
@ -169,7 +157,7 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
|
|||
title = VectorL10n.keyVerificationScanConfirmationScanningTitle
|
||||
|
||||
switch viewData.verificationKind {
|
||||
case .device:
|
||||
case .otherSession, .thisSession, .newSession:
|
||||
waitingInfo = VectorL10n.keyVerificationScanConfirmationScanningDeviceWaitingOther
|
||||
case .user:
|
||||
waitingInfo = VectorL10n.keyVerificationScanConfirmationScanningUserWaitingOther(viewData.otherDisplayName)
|
||||
|
@ -178,13 +166,14 @@ final class KeyVerificationScanConfirmationViewController: UIViewController {
|
|||
title = VectorL10n.keyVerificationScanConfirmationScannedTitle
|
||||
|
||||
switch viewData.verificationKind {
|
||||
case .device:
|
||||
case .otherSession, .thisSession, .newSession:
|
||||
scannedInfo = VectorL10n.keyVerificationScanConfirmationScannedDeviceInformation
|
||||
case .user:
|
||||
scannedInfo = VectorL10n.keyVerificationScanConfirmationScannedUserInformation(viewData.otherDisplayName)
|
||||
}
|
||||
}
|
||||
|
||||
self.title = viewData.verificationKind.verificationTitle
|
||||
self.titleLabel.text = title
|
||||
self.waitingLabel.text = waitingInfo
|
||||
self.scannedInformationLabel.text = scannedInfo
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="c4q-B8-hPy">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="432.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="345"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fNE-v3-2lx">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="432.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="345"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Verified!" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1Nw-CZ-lKr">
|
||||
<rect key="frame" x="20" y="60" width="335" height="20.5"/>
|
||||
|
@ -33,73 +33,49 @@
|
|||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="12d-Dc-Rlv">
|
||||
<rect key="frame" x="20" y="160.5" width="335" height="102"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="You've successfully verified this device." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5dj-7z-eH5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Secure messages with this user are end-to-end encrypted and not able to be read by third parties." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="spd-ah-EYp">
|
||||
<rect key="frame" x="0.0" y="48" width="335" height="54"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="50" translatesAutoresizingMaskIntoConstraints="NO" id="4Ll-vk-JLe">
|
||||
<rect key="frame" x="0.0" y="362.5" width="375" height="50"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wbk-EX-kTs">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kgv-EZ-dF9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="50"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="WcJ-IL-5KV"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
|
||||
<state key="normal" title="Got it">
|
||||
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<state key="disabled">
|
||||
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="0.5" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="validateButtonAction:" destination="dBQ-CG-VDL" eventType="touchUpInside" id="kpR-g5-ogv"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kgv-EZ-dF9" firstAttribute="top" secondItem="Wbk-EX-kTs" secondAttribute="top" id="1mu-8N-etF"/>
|
||||
<constraint firstAttribute="bottom" secondItem="kgv-EZ-dF9" secondAttribute="bottom" id="2ce-b1-aV5"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kgv-EZ-dF9" secondAttribute="trailing" id="OHz-zo-Uvl"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="500" id="eud-Ba-XSx"/>
|
||||
<constraint firstItem="kgv-EZ-dF9" firstAttribute="leading" secondItem="Wbk-EX-kTs" secondAttribute="leading" id="gPb-HX-NWn"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="You've successfully verified this device." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Sql-oR-dMk">
|
||||
<rect key="frame" x="20" y="103" width="335" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="key_verification_success_shield" translatesAutoresizingMaskIntoConstraints="NO" id="ie2-LW-ek2">
|
||||
<rect key="frame" x="127.5" y="141" width="120" height="120"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="ie2-LW-ek2" secondAttribute="height" multiplier="1:1" id="Re6-8V-peU"/>
|
||||
<constraint firstAttribute="width" constant="120" id="qg0-4Z-ffM"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4i8-Se-1Ae" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="20" y="281" width="335" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="XNP-zj-OmI"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="Got it">
|
||||
<color key="titleColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="doneButtonAction:" destination="dBQ-CG-VDL" eventType="touchUpInside" id="LL5-rw-xwL"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="12d-Dc-Rlv" firstAttribute="leading" secondItem="1Nw-CZ-lKr" secondAttribute="leading" id="5Kb-MI-4lP"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="500" id="9am-iX-rzi"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4Ll-vk-JLe" secondAttribute="trailing" id="CU4-Sr-hLT"/>
|
||||
<constraint firstItem="12d-Dc-Rlv" firstAttribute="trailing" secondItem="1Nw-CZ-lKr" secondAttribute="trailing" id="Cax-X9-xf8"/>
|
||||
<constraint firstItem="4Ll-vk-JLe" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" id="FGu-8C-v1U"/>
|
||||
<constraint firstItem="4Ll-vk-JLe" firstAttribute="top" secondItem="12d-Dc-Rlv" secondAttribute="bottom" constant="100" id="Hue-GK-ORf"/>
|
||||
<constraint firstItem="ie2-LW-ek2" firstAttribute="centerX" secondItem="fNE-v3-2lx" secondAttribute="centerX" id="BN9-ZW-6DE"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Sql-oR-dMk" secondAttribute="trailing" constant="20" id="JtB-5o-vhc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="4i8-Se-1Ae" secondAttribute="bottom" constant="20" id="KB5-ba-4Rb"/>
|
||||
<constraint firstItem="1Nw-CZ-lKr" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" constant="20" id="LK5-9b-xDf"/>
|
||||
<constraint firstItem="1Nw-CZ-lKr" firstAttribute="top" secondItem="fNE-v3-2lx" secondAttribute="top" constant="60" id="MUK-4D-vke"/>
|
||||
<constraint firstAttribute="bottom" secondItem="4Ll-vk-JLe" secondAttribute="bottom" constant="20" id="Vn1-zQ-G8t"/>
|
||||
<constraint firstItem="4i8-Se-1Ae" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" constant="20" id="WK8-b7-t31"/>
|
||||
<constraint firstAttribute="trailing" secondItem="1Nw-CZ-lKr" secondAttribute="trailing" constant="20" id="WKJ-Ta-cVg"/>
|
||||
<constraint firstItem="12d-Dc-Rlv" firstAttribute="centerX" secondItem="fNE-v3-2lx" secondAttribute="centerX" id="ksz-nC-DeX"/>
|
||||
<constraint firstItem="12d-Dc-Rlv" firstAttribute="top" secondItem="1Nw-CZ-lKr" secondAttribute="bottom" constant="80" id="rhF-BF-2cR"/>
|
||||
<constraint firstItem="Sql-oR-dMk" firstAttribute="leading" secondItem="fNE-v3-2lx" secondAttribute="leading" constant="20" id="kev-re-wea"/>
|
||||
<constraint firstItem="Sql-oR-dMk" firstAttribute="top" secondItem="1Nw-CZ-lKr" secondAttribute="bottom" constant="22.5" id="kjt-Ha-so6"/>
|
||||
<constraint firstItem="4i8-Se-1Ae" firstAttribute="top" secondItem="ie2-LW-ek2" secondAttribute="bottom" constant="20" id="miU-BN-TBQ"/>
|
||||
<constraint firstItem="ie2-LW-ek2" firstAttribute="top" secondItem="Sql-oR-dMk" secondAttribute="bottom" constant="20" id="w1A-1P-Q9Q"/>
|
||||
<constraint firstAttribute="trailing" secondItem="4i8-Se-1Ae" secondAttribute="trailing" constant="20" id="wEW-BU-RMg"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
|
@ -134,16 +110,17 @@
|
|||
<viewLayoutGuide key="safeArea" id="6ex-OQ-2sZ"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="description1Label" destination="5dj-7z-eH5" id="y4w-i9-5hB"/>
|
||||
<outlet property="description2Label" destination="spd-ah-EYp" id="TXD-8P-gF0"/>
|
||||
<outlet property="okButton" destination="kgv-EZ-dF9" id="do0-Ot-OKn"/>
|
||||
<outlet property="okButtonBackgroundView" destination="Wbk-EX-kTs" id="2gv-gg-ROL"/>
|
||||
<outlet property="doneButton" destination="4i8-Se-1Ae" id="K4a-4m-cU2"/>
|
||||
<outlet property="informationLabel" destination="Sql-oR-dMk" id="aIw-XY-wP1"/>
|
||||
<outlet property="titleLabel" destination="1Nw-CZ-lKr" id="zXP-Xt-Zl9"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="bLY-II-iJ3" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-1703" y="255"/>
|
||||
<point key="canvasLocation" x="-1703.2" y="254.12293853073464"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="key_verification_success_shield" width="120" height="120"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
@ -30,11 +30,8 @@ final class KeyVerificationVerifiedViewController: UIViewController {
|
|||
// MARK: Outlets
|
||||
|
||||
@IBOutlet private weak var titleLabel: UILabel!
|
||||
@IBOutlet private weak var description1Label: UILabel!
|
||||
@IBOutlet private weak var description2Label: UILabel!
|
||||
|
||||
@IBOutlet private weak var okButtonBackgroundView: UIView!
|
||||
@IBOutlet private weak var okButton: UIButton!
|
||||
@IBOutlet private weak var informationLabel: UILabel!
|
||||
@IBOutlet private weak var doneButton: RoundedButton!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
|
@ -82,30 +79,29 @@ final class KeyVerificationVerifiedViewController: UIViewController {
|
|||
// MARK: - Private
|
||||
|
||||
private func setupViews() {
|
||||
let title: String
|
||||
let bodyTitle: String
|
||||
let descriptionTextPart1: String
|
||||
let descriptionTextPart2: String
|
||||
let informationText: String
|
||||
|
||||
switch self.verificationKind {
|
||||
case .device:
|
||||
title = VectorL10n.deviceVerificationTitle
|
||||
case .otherSession:
|
||||
bodyTitle = VectorL10n.deviceVerificationVerifiedTitle
|
||||
descriptionTextPart1 = VectorL10n.deviceVerificationVerifiedDescription1
|
||||
descriptionTextPart2 = VectorL10n.deviceVerificationVerifiedDescription2
|
||||
informationText = VectorL10n.keyVerificationVerifiedOtherSessionInformation
|
||||
case .newSession:
|
||||
bodyTitle = VectorL10n.keyVerificationVerifiedNewSessionTitle
|
||||
informationText = VectorL10n.keyVerificationVerifiedNewSessionInformation
|
||||
case .thisSession:
|
||||
bodyTitle = VectorL10n.deviceVerificationVerifiedTitle
|
||||
informationText = VectorL10n.keyVerificationVerifiedThisSessionInformation
|
||||
case .user:
|
||||
title = VectorL10n.keyVerificationUserTitle
|
||||
bodyTitle = VectorL10n.deviceVerificationVerifiedTitle
|
||||
descriptionTextPart1 = VectorL10n.keyVerificationVerifiedUserDescription1
|
||||
descriptionTextPart2 = VectorL10n.keyVerificationVerifiedUserDescription2
|
||||
informationText = VectorL10n.keyVerificationVerifiedUserInformation
|
||||
}
|
||||
|
||||
self.title = title
|
||||
self.title = self.verificationKind.verificationTitle
|
||||
self.titleLabel.text = bodyTitle
|
||||
self.description1Label.text = descriptionTextPart1
|
||||
self.description2Label.text = descriptionTextPart2
|
||||
self.informationLabel.text = informationText
|
||||
|
||||
self.okButton.setTitle(VectorL10n.deviceVerificationVerifiedGotItButton, for: .normal)
|
||||
self.doneButton.setTitle(VectorL10n.deviceVerificationVerifiedGotItButton, for: .normal)
|
||||
}
|
||||
|
||||
private func update(theme: Theme) {
|
||||
|
@ -118,11 +114,8 @@ final class KeyVerificationVerifiedViewController: UIViewController {
|
|||
}
|
||||
|
||||
self.titleLabel.textColor = theme.textPrimaryColor
|
||||
self.description1Label.textColor = theme.textPrimaryColor
|
||||
self.description2Label.textColor = theme.textPrimaryColor
|
||||
|
||||
self.okButtonBackgroundView.backgroundColor = theme.backgroundColor
|
||||
theme.applyStyle(onButton: self.okButton)
|
||||
self.informationLabel.textColor = theme.textPrimaryColor
|
||||
self.doneButton.update(theme: theme)
|
||||
}
|
||||
|
||||
private func registerThemeServiceDidChangeThemeNotification() {
|
||||
|
@ -135,7 +128,7 @@ final class KeyVerificationVerifiedViewController: UIViewController {
|
|||
self.update(theme: ThemeService.shared().theme)
|
||||
}
|
||||
|
||||
@IBAction private func validateButtonAction(_ sender: Any) {
|
||||
@IBAction private func doneButtonAction(_ sender: Any) {
|
||||
self.delegate?.keyVerificationVerifiedViewControllerDidTapSetupAction(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e7g-um-WO4">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="485"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="502"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="voD-3Q-ryt">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="485"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="502"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Verify this device by confirming the following emoji appear on the screen of the partner" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="he8-pl-xE9">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Compare emoji" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="he8-pl-xE9">
|
||||
<rect key="frame" x="20" y="35" width="335" height="61"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="61" id="Nam-ca-50k"/>
|
||||
|
@ -37,16 +37,13 @@
|
|||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For maximum security, we recommend you do this in person or use another trusted means of communication." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bxI-mu-qng">
|
||||
<rect key="frame" x="20" y="115" width="335" height="80"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="80" id="3ag-pn-F2b"/>
|
||||
</constraints>
|
||||
<rect key="frame" x="20" y="115" width="335" height="54"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3152 3307 8179" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RD6-ue-X5c">
|
||||
<rect key="frame" x="37.5" y="290.5" width="300" height="29"/>
|
||||
<rect key="frame" x="37.5" y="264.5" width="300" height="29"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="300" id="6Q5-M2-ifj"/>
|
||||
</constraints>
|
||||
|
@ -54,39 +51,8 @@
|
|||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="DtR-jx-UKY">
|
||||
<rect key="frame" x="0.0" y="415" width="375" height="50"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DOt-5E-FjF">
|
||||
<rect key="frame" x="156.5" y="10" width="62" height="30"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Continue">
|
||||
<color key="titleColor" red="0.47843137250000001" green="0.78823529410000004" blue="0.63137254899999995" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="continueButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="uvI-tt-Nfj"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="DOt-5E-FjF" firstAttribute="centerY" secondItem="DtR-jx-UKY" secondAttribute="centerY" id="5eX-a5-zpP"/>
|
||||
<constraint firstItem="DOt-5E-FjF" firstAttribute="centerX" secondItem="DtR-jx-UKY" secondAttribute="centerX" id="6v9-MN-mk2"/>
|
||||
<constraint firstAttribute="height" constant="50" id="QNq-au-ZdL"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Waiting for partner to confirm..." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6yX-xD-4X5">
|
||||
<rect key="frame" x="20" y="242" width="335" height="54"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="335" id="9C0-ev-AVw"/>
|
||||
<constraint firstAttribute="height" constant="54" id="pta-eP-0yH"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="34i-3X-YvQ">
|
||||
<rect key="frame" x="27.5" y="215" width="320" height="180"/>
|
||||
<rect key="frame" x="27.5" y="189" width="320" height="180"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="180" id="kpT-ty-CDI"/>
|
||||
|
@ -138,25 +104,75 @@
|
|||
<outlet property="dataSource" destination="V8j-Lb-PgC" id="3m4-oH-KIj"/>
|
||||
</connections>
|
||||
</collectionView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="6xJ-uL-C85">
|
||||
<rect key="frame" x="20" y="389" width="335" height="44"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Zsb-KY-oCN" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="162.5" 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="They don't match">
|
||||
<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="1NK-nX-rMW"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FvW-07-g2Q" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="172.5" y="0.0" width="162.5" height="44"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="They match">
|
||||
<color key="titleColor" red="0.01176470588" green="0.70196078429999997" blue="0.50588235290000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="validateButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="rFZ-xl-1u8"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Zsb-KY-oCN" firstAttribute="height" secondItem="6xJ-uL-C85" secondAttribute="height" priority="999" id="Ndm-lB-EyV"/>
|
||||
<constraint firstItem="FvW-07-g2Q" firstAttribute="height" secondItem="6xJ-uL-C85" secondAttribute="height" priority="999" id="hq6-8l-unN"/>
|
||||
<constraint firstAttribute="height" priority="750" constant="44" id="lIN-Z9-vVI"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Waiting for partner to confirm..." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6yX-xD-4X5">
|
||||
<rect key="frame" x="20" y="242" width="335" height="54"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="335" id="9C0-ev-AVw"/>
|
||||
<constraint firstAttribute="height" constant="54" id="pta-eP-0yH"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For ultimate security, use another trusted means of communication or do this in person." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gDW-77-nwN">
|
||||
<rect key="frame" x="20" y="453" width="335" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="6yX-xD-4X5" firstAttribute="top" secondItem="bxI-mu-qng" secondAttribute="bottom" constant="47" id="6Bh-e4-HVr"/>
|
||||
<constraint firstAttribute="bottom" secondItem="DtR-jx-UKY" secondAttribute="bottom" constant="20" id="Cnb-UW-hYt"/>
|
||||
<constraint firstAttribute="trailing" secondItem="DtR-jx-UKY" secondAttribute="trailing" id="K7y-Df-dgz"/>
|
||||
<constraint firstItem="6xJ-uL-C85" firstAttribute="top" secondItem="34i-3X-YvQ" secondAttribute="bottom" constant="20" id="BaX-9q-msm"/>
|
||||
<constraint firstAttribute="trailing" secondItem="6xJ-uL-C85" secondAttribute="trailing" constant="20" id="G5w-nx-cbM"/>
|
||||
<constraint firstAttribute="trailing" secondItem="gDW-77-nwN" secondAttribute="trailing" constant="20" id="Iel-ki-dp5"/>
|
||||
<constraint firstItem="6xJ-uL-C85" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="MET-AV-3jS"/>
|
||||
<constraint firstItem="he8-pl-xE9" firstAttribute="leading" secondItem="bxI-mu-qng" secondAttribute="leading" id="Q9n-7p-gHl"/>
|
||||
<constraint firstItem="he8-pl-xE9" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="QSg-yz-aaB"/>
|
||||
<constraint firstItem="6yX-xD-4X5" firstAttribute="centerX" secondItem="voD-3Q-ryt" secondAttribute="centerX" id="Rg4-jV-Nht"/>
|
||||
<constraint firstItem="bxI-mu-qng" firstAttribute="top" secondItem="he8-pl-xE9" secondAttribute="top" constant="80" id="UL4-x0-oFT"/>
|
||||
<constraint firstItem="gDW-77-nwN" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" constant="20" id="YAC-Wy-mPL"/>
|
||||
<constraint firstItem="he8-pl-xE9" firstAttribute="centerX" secondItem="voD-3Q-ryt" secondAttribute="centerX" id="ZP8-mV-RBh"/>
|
||||
<constraint firstItem="he8-pl-xE9" firstAttribute="trailing" secondItem="bxI-mu-qng" secondAttribute="trailing" id="Zeg-U8-uis"/>
|
||||
<constraint firstAttribute="width" priority="750" constant="375" id="glD-Sz-73O"/>
|
||||
<constraint firstItem="RD6-ue-X5c" firstAttribute="centerY" secondItem="34i-3X-YvQ" secondAttribute="centerY" id="h8F-gc-do4"/>
|
||||
<constraint firstItem="DtR-jx-UKY" firstAttribute="leading" secondItem="voD-3Q-ryt" secondAttribute="leading" id="hK0-aA-d9H"/>
|
||||
<constraint firstItem="RD6-ue-X5c" firstAttribute="centerX" secondItem="34i-3X-YvQ" secondAttribute="centerX" id="lBM-R8-C6b"/>
|
||||
<constraint firstItem="DtR-jx-UKY" firstAttribute="top" secondItem="34i-3X-YvQ" secondAttribute="bottom" constant="20" id="liF-Qn-tiw"/>
|
||||
<constraint firstItem="34i-3X-YvQ" firstAttribute="top" secondItem="bxI-mu-qng" secondAttribute="bottom" constant="20" id="r7A-9g-Mmb"/>
|
||||
<constraint firstAttribute="bottom" secondItem="gDW-77-nwN" secondAttribute="bottom" constant="20" id="rpv-yg-1jT"/>
|
||||
<constraint firstItem="he8-pl-xE9" firstAttribute="top" secondItem="voD-3Q-ryt" secondAttribute="top" constant="35" id="s3k-Io-834"/>
|
||||
<constraint firstItem="gDW-77-nwN" firstAttribute="top" secondItem="6xJ-uL-C85" secondAttribute="bottom" constant="20" id="wL6-tr-pO2"/>
|
||||
<constraint firstItem="34i-3X-YvQ" firstAttribute="centerX" secondItem="voD-3Q-ryt" secondAttribute="centerX" id="ydb-Fs-K0a"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
|
@ -179,7 +195,7 @@
|
|||
<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" constant="70" 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="top" secondItem="9U2-KL-ZVA" secondAttribute="top" id="pFN-bA-SHw"/>
|
||||
</constraints>
|
||||
|
@ -195,13 +211,15 @@
|
|||
<viewLayoutGuide key="safeArea" id="bFg-jh-JZB"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="continueButton" destination="DOt-5E-FjF" id="ktw-U4-efQ"/>
|
||||
<outlet property="continueButtonBackgroundView" destination="DtR-jx-UKY" id="9yG-wP-u8A"/>
|
||||
<outlet property="additionalInformationLabel" destination="gDW-77-nwN" id="leX-Mb-wlj"/>
|
||||
<outlet property="buttonsStackView" destination="6xJ-uL-C85" id="vK1-e2-OYg"/>
|
||||
<outlet property="cancelButton" destination="Zsb-KY-oCN" id="xdE-MX-gp9"/>
|
||||
<outlet property="decimalLabel" destination="RD6-ue-X5c" id="wlK-nl-CB6"/>
|
||||
<outlet property="emojisCollectionView" destination="34i-3X-YvQ" id="wDE-oG-peo"/>
|
||||
<outlet property="informationLabel" destination="bxI-mu-qng" id="pbX-aZ-inC"/>
|
||||
<outlet property="scrollView" destination="9U2-KL-ZVA" id="ojG-2y-X7b"/>
|
||||
<outlet property="titleLabel" destination="he8-pl-xE9" id="btA-kv-E2B"/>
|
||||
<outlet property="validateButton" destination="FvW-07-g2Q" id="cT2-ds-ORQ"/>
|
||||
<outlet property="waitingPartnerLabel" destination="6yX-xD-4X5" id="fre-bc-Kma"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
|
|
@ -33,9 +33,12 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
|
|||
@IBOutlet private weak var decimalLabel: UILabel!
|
||||
@IBOutlet private weak var emojisCollectionView: UICollectionView!
|
||||
@IBOutlet private weak var waitingPartnerLabel: UILabel!
|
||||
@IBOutlet private weak var continueButtonBackgroundView: UIView!
|
||||
@IBOutlet private weak var continueButton: UIButton!
|
||||
|
||||
|
||||
@IBOutlet private weak var buttonsStackView: UIStackView!
|
||||
@IBOutlet private weak var cancelButton: RoundedButton!
|
||||
@IBOutlet private weak var validateButton: RoundedButton!
|
||||
@IBOutlet private weak var additionalInformationLabel: UILabel!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var viewModel: KeyVerificationVerifyBySASViewModelType!
|
||||
|
@ -99,8 +102,8 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
|
|||
self.decimalLabel.textColor = theme.textPrimaryColor
|
||||
self.waitingPartnerLabel.textColor = theme.textPrimaryColor
|
||||
|
||||
self.continueButtonBackgroundView.backgroundColor = theme.backgroundColor
|
||||
theme.applyStyle(onButton: self.continueButton)
|
||||
self.cancelButton.update(theme: theme)
|
||||
self.validateButton.update(theme: theme)
|
||||
|
||||
emojisCollectionView.reloadData()
|
||||
}
|
||||
|
@ -115,7 +118,7 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
|
|||
|
||||
private func setupViews() {
|
||||
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
|
||||
self?.cancelButtonAction()
|
||||
self?.cancelAction()
|
||||
}
|
||||
|
||||
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
||||
|
@ -131,29 +134,29 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
|
|||
self.decimalLabel.text = self.viewModel.decimal
|
||||
}
|
||||
|
||||
let title: String
|
||||
let instructionText: String
|
||||
let adviceText: String
|
||||
|
||||
switch viewModel.verificationKind {
|
||||
case .device:
|
||||
title = VectorL10n.deviceVerificationTitle
|
||||
instructionText = isVerificationByEmoji ? VectorL10n.deviceVerificationVerifyTitleEmoji : VectorL10n.deviceVerificationVerifyTitleNumber
|
||||
adviceText = VectorL10n.deviceVerificationSecurityAdvice
|
||||
case .user:
|
||||
title = VectorL10n.keyVerificationUserTitle
|
||||
instructionText = isVerificationByEmoji ? VectorL10n.keyVerificationVerifyUserTitleEmoji : VectorL10n.keyVerificationVerifyUserTitleNumber
|
||||
adviceText = VectorL10n.deviceVerificationSecurityAdvice
|
||||
if isVerificationByEmoji {
|
||||
instructionText = VectorL10n.keyVerificationVerifySasTitleEmoji
|
||||
adviceText = VectorL10n.deviceVerificationSecurityAdviceEmoji
|
||||
} else {
|
||||
instructionText = VectorL10n.keyVerificationVerifySasTitleNumber
|
||||
adviceText = VectorL10n.deviceVerificationSecurityAdviceNumber
|
||||
}
|
||||
|
||||
self.title = title
|
||||
self.title = self.viewModel.verificationKind.verificationTitle
|
||||
self.titleLabel.text = instructionText
|
||||
self.informationLabel.text = adviceText
|
||||
self.waitingPartnerLabel.text = VectorL10n.deviceVerificationVerifyWaitPartner
|
||||
|
||||
self.waitingPartnerLabel.isHidden = true
|
||||
|
||||
self.continueButton.setTitle(VectorL10n.continue, for: .normal)
|
||||
self.cancelButton.setTitle(VectorL10n.keyVerificationVerifySasCancelAction, for: .normal)
|
||||
self.cancelButton.actionStyle = .cancel
|
||||
self.validateButton.setTitle(VectorL10n.keyVerificationVerifySasValidateAction, for: .normal)
|
||||
|
||||
self.additionalInformationLabel.text = VectorL10n.keyVerificationVerifySasAdditionalInformation
|
||||
}
|
||||
|
||||
private func render(viewState: KeyVerificationVerifyViewState) {
|
||||
|
@ -177,8 +180,8 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
|
|||
|
||||
private func renderVerified() {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
|
||||
self.continueButtonBackgroundView.isHidden = true
|
||||
|
||||
self.buttonsStackView.isHidden = true
|
||||
self.waitingPartnerLabel.isHidden = false
|
||||
}
|
||||
|
||||
|
@ -210,13 +213,17 @@ final class KeyVerificationVerifyBySASViewController: UIViewController {
|
|||
|
||||
// MARK: - Actions
|
||||
|
||||
@IBAction private func continueButtonAction(_ sender: Any) {
|
||||
self.viewModel.process(viewAction: .confirm)
|
||||
}
|
||||
|
||||
private func cancelButtonAction() {
|
||||
private func cancelAction() {
|
||||
self.viewModel.process(viewAction: .cancel)
|
||||
}
|
||||
|
||||
@IBAction private func cancelButtonAction(_ sender: Any) {
|
||||
self.cancelAction()
|
||||
}
|
||||
|
||||
@IBAction private func validateButtonAction(_ sender: Any) {
|
||||
self.viewModel.process(viewAction: .confirm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -40,11 +40,11 @@ final class KeyVerificationVerifyByScanningCoordinator: KeyVerificationVerifyByS
|
|||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession, keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
init(session: MXSession, verificationKind: KeyVerificationKind, keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
self.session = session
|
||||
self.keyVerificationRequest = keyVerificationRequest
|
||||
|
||||
let keyVerificationVerifyByScanningViewModel = KeyVerificationVerifyByScanningViewModel(session: self.session, keyVerificationRequest: keyVerificationRequest)
|
||||
let keyVerificationVerifyByScanningViewModel = KeyVerificationVerifyByScanningViewModel(session: self.session, verificationKind: verificationKind, keyVerificationRequest: keyVerificationRequest)
|
||||
let keyVerificationVerifyByScanningViewController = KeyVerificationVerifyByScanningViewController.instantiate(with: keyVerificationVerifyByScanningViewModel)
|
||||
self.keyVerificationVerifyByScanningViewModel = keyVerificationVerifyByScanningViewModel
|
||||
self.keyVerificationVerifyByScanningViewController = keyVerificationVerifyByScanningViewController
|
||||
|
@ -66,11 +66,7 @@ extension KeyVerificationVerifyByScanningCoordinator: KeyVerificationVerifyBySca
|
|||
|
||||
func keyVerificationVerifyByScanningViewModelDidCancel(_ viewModel: KeyVerificationVerifyByScanningViewModelType) {
|
||||
self.delegate?.keyVerificationVerifyByScanningCoordinatorDidCancel(self)
|
||||
}
|
||||
|
||||
func keyVerificationVerifyByScanningViewModelCannotScan(_ viewModel: KeyVerificationVerifyByScanningViewModelType) {
|
||||
self.delegate?.keyVerificationVerifyByScanningCoordinatorCannotScan(self)
|
||||
}
|
||||
}
|
||||
|
||||
func keyVerificationVerifyByScanningViewModel(_ viewModel: KeyVerificationVerifyByScanningViewModelType, didStartSASVerificationWithTransaction transaction: MXSASTransaction) {
|
||||
self.delegate?.keyVerificationVerifyByScanningCoordinator(self, didCompleteWithSASTransaction: transaction)
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
import Foundation
|
||||
|
||||
protocol KeyVerificationVerifyByScanningCoordinatorDelegate: class {
|
||||
func keyVerificationVerifyByScanningCoordinatorDidCancel(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType)
|
||||
func keyVerificationVerifyByScanningCoordinatorCannotScan(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType)
|
||||
func keyVerificationVerifyByScanningCoordinatorDidCancel(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType)
|
||||
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, didScanOtherQRCodeData qrCodeData: MXQRCodeData, withTransaction transaction: MXQRCodeTransaction)
|
||||
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, qrCodeDidScannedByOtherWithTransaction transaction: MXQRCodeTransaction)
|
||||
func keyVerificationVerifyByScanningCoordinator(_ coordinator: KeyVerificationVerifyByScanningCoordinatorType, didCompleteWithSASTransaction transaction: MXSASTransaction)
|
||||
|
|
|
@ -180,8 +180,16 @@ final class KeyVerificationVerifyByScanningViewController: UIViewController {
|
|||
hideQRCodeImage = true
|
||||
}
|
||||
|
||||
self.title = viewData.verificationKind.verificationTitle
|
||||
self.titleLabel.text = viewData.verificationKind.verificationTitle
|
||||
self.qrCodeContainerView.isHidden = hideQRCodeImage
|
||||
self.scanButtonContainerView.isHidden = !viewData.showScanAction
|
||||
|
||||
if viewData.qrCodeData == nil && viewData.showScanAction == false {
|
||||
// Update the copy if QR code scanning is not possible at all
|
||||
self.informationLabel.text = VectorL10n.keyVerificationVerifyQrCodeEmojiInformation
|
||||
self.cannotScanButton.setTitle(VectorL10n.keyVerificationVerifyQrCodeStartEmojiAction, for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
private func render(error: Error) {
|
||||
|
|
|
@ -29,6 +29,7 @@ final class KeyVerificationVerifyByScanningViewModel: KeyVerificationVerifyBySca
|
|||
// MARK: Private
|
||||
|
||||
private let session: MXSession
|
||||
private let verificationKind: KeyVerificationKind
|
||||
private let keyVerificationRequest: MXKeyVerificationRequest
|
||||
private let qrCodeDataCoder: MXQRCodeDataCoder
|
||||
private let keyVerificationManager: MXKeyVerificationManager
|
||||
|
@ -43,8 +44,9 @@ final class KeyVerificationVerifyByScanningViewModel: KeyVerificationVerifyBySca
|
|||
|
||||
// MARK: - Setup
|
||||
|
||||
init(session: MXSession, keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
init(session: MXSession, verificationKind: KeyVerificationKind, keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
self.session = session
|
||||
self.verificationKind = verificationKind
|
||||
self.keyVerificationManager = self.session.crypto.keyVerificationManager
|
||||
self.keyVerificationRequest = keyVerificationRequest
|
||||
self.qrCodeDataCoder = MXQRCodeDataCoder()
|
||||
|
@ -94,7 +96,8 @@ final class KeyVerificationVerifyByScanningViewModel: KeyVerificationVerifyBySca
|
|||
canShowScanAction = false
|
||||
}
|
||||
|
||||
let viewData = KeyVerificationVerifyByScanningViewData(qrCodeData: qrCodePlayloadData,
|
||||
let viewData = KeyVerificationVerifyByScanningViewData(verificationKind: self.verificationKind,
|
||||
qrCodeData: qrCodePlayloadData,
|
||||
showScanAction: canShowScanAction)
|
||||
|
||||
self.update(viewState: .loaded(viewData: viewData))
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
import Foundation
|
||||
|
||||
struct KeyVerificationVerifyByScanningViewData {
|
||||
let verificationKind: KeyVerificationKind
|
||||
let qrCodeData: Data?
|
||||
let showScanAction: Bool
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ final class DeviceVerificationIncomingViewController: UIViewController {
|
|||
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
self.title = VectorL10n.deviceVerificationTitle
|
||||
self.title = VectorL10n.keyVerificationOtherSessionTitle
|
||||
self.vc_removeBackTitle()
|
||||
|
||||
self.setupViews()
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
<action selector="startVerificationButtonAction:" destination="KS5-Uc-kth" eventType="touchUpInside" id="XRr-SM-v5B"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="To be secure, do this in person or use another way to communicate." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9u5-8O-e7v">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="To be secure, do this in person or use another way to communicate." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9u5-8O-e7v">
|
||||
<rect key="frame" x="20" y="130" width="335" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<nil key="textColor"/>
|
||||
|
|
|
@ -60,7 +60,7 @@ final class KeyVerificationSelfVerifyStartViewController: UIViewController {
|
|||
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
self.title = VectorL10n.deviceVerificationTitle
|
||||
self.title = VectorL10n.keyVerificationNewSessionTitle
|
||||
|
||||
self.setupViews()
|
||||
self.activityPresenter = ActivityIndicatorPresenter()
|
||||
|
|
|
@ -60,10 +60,15 @@ final class KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyW
|
|||
|
||||
// MARK: - KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate
|
||||
extension KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate {
|
||||
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest) {
|
||||
self.delegate?.keyVerificationSelfVerifyWaitCoordinator(self, didAcceptKeyVerificationRequest: keyVerificationRequest)
|
||||
}
|
||||
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction) {
|
||||
self.delegate?.keyVerificationSelfVerifyWaitCoordinator(self, didAcceptIncomingSASTransaction: incomingSASTransaction)
|
||||
}
|
||||
|
||||
func keyVerificationSelfVerifyWaitViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType) {
|
||||
self.delegate?.keyVerificationSelfVerifyWaitCoordinatorDidCancel(self)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import Foundation
|
|||
|
||||
protocol KeyVerificationSelfVerifyWaitCoordinatorDelegate: class {
|
||||
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest)
|
||||
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction)
|
||||
func keyVerificationSelfVerifyWaitCoordinatorDidCancel(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType)
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,10 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
|||
self.renderLoading()
|
||||
case .loaded(let isNewSignIn):
|
||||
self.renderLoaded(isNewSignIn: isNewSignIn)
|
||||
case .cancelled(let reason):
|
||||
self.renderCancelled(reason: reason)
|
||||
case .cancelledByMe(let reason):
|
||||
self.renderCancelledByMe(reason: reason)
|
||||
case .error(let error):
|
||||
self.render(error: error)
|
||||
}
|
||||
|
@ -150,6 +154,26 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
|
|||
self.cancelBarButtonItem?.title = isNewSignIn ? VectorL10n.skip : VectorL10n.cancel
|
||||
}
|
||||
|
||||
private func renderCancelled(reason: MXTransactionCancelCode) {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
|
||||
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelled, animated: true) {
|
||||
self.viewModel.process(viewAction: .cancel)
|
||||
}
|
||||
}
|
||||
|
||||
private func renderCancelledByMe(reason: MXTransactionCancelCode) {
|
||||
if reason.value != MXTransactionCancelCode.user().value {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
|
||||
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelledByMe(reason.humanReadable), animated: true) {
|
||||
self.viewModel.process(viewAction: .cancel)
|
||||
}
|
||||
} else {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
private func render(error: Error) {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
self.errorPresenter.presentError(from: self, forError: error, animated: true, handler: nil)
|
||||
|
|
|
@ -46,6 +46,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
}
|
||||
|
||||
deinit {
|
||||
self.unregisterKeyVerificationManagerNewRequestNotification()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
@ -64,6 +65,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
private func loadData() {
|
||||
self.registerKeyVerificationManagerNewRequestNotification(for: self.verificationManager)
|
||||
self.update(viewState: .loaded(self.isNewSignIn))
|
||||
self.registerTransactionDidStateChangeNotification()
|
||||
}
|
||||
|
||||
private func cancel() {
|
||||
|
@ -87,6 +89,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
return
|
||||
}
|
||||
|
||||
self.unregisterKeyVerificationManagerNewRequestNotification()
|
||||
self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, didAcceptKeyVerificationRequest: keyVerificationRequest)
|
||||
|
||||
}, failure: { [weak self] (error) in
|
||||
|
@ -101,9 +104,11 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
|
||||
private func registerKeyVerificationManagerNewRequestNotification(for verificationManager: MXKeyVerificationManager) {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyVerificationManagerNewRequestNotification(notification:)), name: .MXKeyVerificationManagerNewRequest, object: verificationManager)
|
||||
AppDelegate.the()?.handleSelfVerificationRequest = false
|
||||
}
|
||||
|
||||
private func unregisterKeyVerificationManagerNewRequestNotification() {
|
||||
AppDelegate.the()?.handleSelfVerificationRequest = true
|
||||
NotificationCenter.default.removeObserver(self, name: .MXKeyVerificationManagerNewRequest, object: nil)
|
||||
}
|
||||
|
||||
|
@ -119,6 +124,51 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
|
|||
return
|
||||
}
|
||||
|
||||
self.unregisterTransactionDidStateChangeNotification()
|
||||
self.acceptKeyVerificationRequest(keyVerificationRequest)
|
||||
}
|
||||
|
||||
// MARK: MXKeyVerificationTransactionDidChange
|
||||
|
||||
private func registerTransactionDidStateChangeNotification() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(transactionDidStateChange(notification:)), name: .MXKeyVerificationTransactionDidChange, object: nil)
|
||||
}
|
||||
|
||||
private func unregisterTransactionDidStateChangeNotification() {
|
||||
NotificationCenter.default.removeObserver(self, name: .MXKeyVerificationTransactionDidChange, object: nil)
|
||||
}
|
||||
|
||||
@objc private func transactionDidStateChange(notification: Notification) {
|
||||
guard let sasTransaction = notification.object as? MXIncomingSASTransaction,
|
||||
sasTransaction.otherUserId == self.session.myUserId else {
|
||||
return
|
||||
}
|
||||
self.sasTransactionDidStateChange(sasTransaction)
|
||||
}
|
||||
|
||||
private func sasTransactionDidStateChange(_ transaction: MXIncomingSASTransaction) {
|
||||
switch transaction.state {
|
||||
case MXSASTransactionStateIncomingShowAccept:
|
||||
// Stop listening for incoming request
|
||||
self.unregisterKeyVerificationManagerNewRequestNotification()
|
||||
transaction.accept()
|
||||
case MXSASTransactionStateShowSAS:
|
||||
self.unregisterTransactionDidStateChangeNotification()
|
||||
self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, didAcceptIncomingSASTransaction: transaction)
|
||||
case MXSASTransactionStateCancelled:
|
||||
guard let reason = transaction.reasonCancelCode else {
|
||||
return
|
||||
}
|
||||
self.unregisterTransactionDidStateChangeNotification()
|
||||
self.update(viewState: .cancelled(reason))
|
||||
case MXSASTransactionStateCancelledByMe:
|
||||
guard let reason = transaction.reasonCancelCode else {
|
||||
return
|
||||
}
|
||||
self.unregisterTransactionDidStateChangeNotification()
|
||||
self.update(viewState: .cancelledByMe(reason))
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ protocol KeyVerificationSelfVerifyWaitViewModelViewDelegate: class {
|
|||
|
||||
protocol KeyVerificationSelfVerifyWaitViewModelCoordinatorDelegate: class {
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptKeyVerificationRequest keyVerificationRequest: MXKeyVerificationRequest)
|
||||
func keyVerificationSelfVerifyWaitViewModel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType, didAcceptIncomingSASTransaction incomingSASTransaction: MXIncomingSASTransaction)
|
||||
func keyVerificationSelfVerifyWaitViewModelDidCancel(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,5 +22,7 @@ import Foundation
|
|||
enum KeyVerificationSelfVerifyWaitViewState {
|
||||
case loading
|
||||
case loaded(_ isNewSignIn: Bool)
|
||||
case cancelled(MXTransactionCancelCode)
|
||||
case cancelledByMe(MXTransactionCancelCode)
|
||||
case error(Error)
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ final class DeviceVerificationStartViewController: UIViewController {
|
|||
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
self.title = VectorL10n.deviceVerificationTitle
|
||||
self.title = VectorL10n.keyVerificationOtherSessionTitle
|
||||
self.vc_removeBackTitle()
|
||||
|
||||
self.setupViews()
|
||||
|
@ -116,7 +116,7 @@ final class DeviceVerificationStartViewController: UIViewController {
|
|||
self.scrollView.keyboardDismissMode = .interactive
|
||||
|
||||
self.titleLabel.text = VectorL10n.deviceVerificationStartTitle
|
||||
self.informationLabel.text = VectorL10n.deviceVerificationSecurityAdvice
|
||||
self.informationLabel.text = VectorL10n.deviceVerificationSecurityAdviceNumber
|
||||
self.waitingPartnerLabel.text = VectorL10n.deviceVerificationStartWaitPartner
|
||||
self.useLegacyVerificationLabel.text = VectorL10n.deviceVerificationStartUseLegacy
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
|
|||
|
||||
private enum Constants {
|
||||
static let cornerRadius: CGFloat = 8.0
|
||||
static let buttonBackgroundColorAlpha: CGFloat = 0.2
|
||||
static let buttonCornerRadius: CGFloat = 6.0
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
@ -39,8 +37,8 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
|
|||
@IBOutlet private weak var requestStatusLabel: UILabel!
|
||||
|
||||
@IBOutlet private weak var buttonsContainerView: UIView!
|
||||
@IBOutlet private weak var acceptButton: UIButton!
|
||||
@IBOutlet private weak var declineButton: UIButton!
|
||||
@IBOutlet private weak var acceptButton: RoundedButton!
|
||||
@IBOutlet private weak var declineButton: RoundedButton!
|
||||
|
||||
// MARK: Public
|
||||
|
||||
|
@ -110,20 +108,16 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
|
|||
super.awakeFromNib()
|
||||
|
||||
self.layer.masksToBounds = true
|
||||
self.acceptButton.layer.masksToBounds = true
|
||||
|
||||
self.acceptButton.titleLabel?.adjustsFontSizeToFitWidth = true
|
||||
self.acceptButton.titleLabel?.minimumScaleFactor = 0.5
|
||||
self.acceptButton.titleLabel?.baselineAdjustment = .alignCenters
|
||||
|
||||
self.acceptButton.setTitle(VectorL10n.keyVerificationTileRequestIncomingApprovalAccept, for: .normal)
|
||||
|
||||
self.declineButton.layer.masksToBounds = true
|
||||
|
||||
self.declineButton.titleLabel?.adjustsFontSizeToFitWidth = true
|
||||
self.declineButton.titleLabel?.minimumScaleFactor = 0.5
|
||||
self.declineButton.titleLabel?.baselineAdjustment = .alignCenters
|
||||
|
||||
self.declineButton.actionStyle = .cancel
|
||||
self.declineButton.setTitle(VectorL10n.keyVerificationTileRequestIncomingApprovalDecline, for: .normal)
|
||||
}
|
||||
|
||||
|
@ -131,11 +125,6 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
|
|||
super.layoutSubviews()
|
||||
|
||||
self.layer.cornerRadius = Constants.cornerRadius
|
||||
|
||||
if self.isButtonsHidden == false {
|
||||
self.acceptButton.layer.cornerRadius = Constants.buttonCornerRadius
|
||||
self.declineButton.layer.cornerRadius = Constants.buttonCornerRadius
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
@ -145,8 +134,8 @@ final class KeyVerificationCellInnerContentView: UIView, NibLoadable {
|
|||
self.titleLabel.textColor = theme.textPrimaryColor
|
||||
self.otherUserInformationLabel.textColor = theme.textSecondaryColor
|
||||
|
||||
self.acceptButton.vc_setBackgroundColor(theme.tintColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
|
||||
self.declineButton.vc_setBackgroundColor(theme.noticeColor.withAlphaComponent(Constants.buttonBackgroundColorAlpha), for: .normal)
|
||||
self.acceptButton.update(theme: theme)
|
||||
self.declineButton.update(theme: theme)
|
||||
}
|
||||
|
||||
func updateSenderInfo(with userId: String, userDisplayName: String?) {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<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="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
@ -46,7 +50,7 @@
|
|||
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="WxG-vh-Bn0">
|
||||
<rect key="frame" x="71" y="0.0" width="151" height="40"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="atD-LF-sGH">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="atD-LF-sGH" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="72" height="40"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="Decline">
|
||||
|
@ -56,7 +60,7 @@
|
|||
<action selector="declineButtonAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="dS6-Xr-6jZ"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="irs-8W-qcs">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="irs-8W-qcs" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="82" y="0.0" width="69" height="40"/>
|
||||
<inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="Accept">
|
||||
|
|
|
@ -675,7 +675,14 @@ UIDocumentInteractionControllerDelegate>
|
|||
{
|
||||
if (!self.mainSession.crypto.crossSigning.canCrossSign)
|
||||
{
|
||||
return [UIImage imageNamed:@"encryption_normal"];
|
||||
if ([deviceId isEqualToString:self.mainSession.myDeviceId])
|
||||
{
|
||||
return [UIImage imageNamed:@"encryption_warning"];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [UIImage imageNamed:@"encryption_normal"];
|
||||
}
|
||||
}
|
||||
|
||||
UIImage* shieldImageForDevice = [UIImage imageNamed:@"encryption_warning"];
|
||||
|
|
|
@ -66,6 +66,8 @@
|
|||
|
||||
@property(nonatomic,getter=isHidden) BOOL hidden;
|
||||
|
||||
@property(nonatomic) BOOL verifyCurrentSessionAlertHasBeenDisplayed;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MasterTabBarController
|
||||
|
@ -206,6 +208,8 @@
|
|||
|
||||
[childViewControllers removeAllObjects];
|
||||
}
|
||||
|
||||
[self presentVerifyCurrentSessionAlertIfNeeded];
|
||||
}
|
||||
|
||||
if (unifiedSearchViewController)
|
||||
|
@ -215,6 +219,55 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (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
|
||||
{
|
||||
[super viewDidDisappear:animated];
|
||||
|
@ -339,6 +392,9 @@
|
|||
|
||||
// Prepare data sources and return
|
||||
[self initializeDataSources];
|
||||
|
||||
// Add matrix sessions observer on first added session
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMatrixSessionStateDidChange:) name:kMXSessionStateDidChangeNotification object:nil];
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -387,6 +443,8 @@
|
|||
- (void)onMatrixSessionStateDidChange:(NSNotification *)notif
|
||||
{
|
||||
[self refreshTabBarBadges];
|
||||
|
||||
[self presentVerifyCurrentSessionAlertIfNeeded];
|
||||
}
|
||||
|
||||
- (void)showAuthenticationScreen
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.11.1</string>
|
||||
<string>0.11.2</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.11.1</string>
|
||||
<string>0.11.2</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<true/>
|
||||
<key>ITSEncryptionExportComplianceCode</key>
|
||||
|
|
35
Riot/Utils/UniversalLink.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Copyright 2020 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UniversalLink : NSObject
|
||||
|
||||
@property (nonatomic, copy, readonly) NSURL *url;
|
||||
|
||||
@property (nonatomic, copy, readonly) NSArray<NSString*> *pathParams;
|
||||
|
||||
@property (nonatomic, copy, readonly) NSDictionary<NSString*, NSString*> *queryParams;
|
||||
|
||||
- (id)initWithUrl:(NSURL *)url
|
||||
pathParams:(NSArray<NSString*> *)pathParams
|
||||
queryParams:(NSDictionary<NSString*, NSString*> *)queryParams;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
60
Riot/Utils/UniversalLink.m
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2020 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "UniversalLink.h"
|
||||
|
||||
@implementation UniversalLink
|
||||
|
||||
- (id)initWithUrl:(NSURL *)url pathParams:(NSArray<NSString *> *)pathParams queryParams:(NSDictionary<NSString *,NSString *> *)queryParams
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
_url = url;
|
||||
_pathParams = pathParams;
|
||||
_queryParams = queryParams;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(id)other
|
||||
{
|
||||
if (other == self)
|
||||
return YES;
|
||||
|
||||
if (![other isKindOfClass:UniversalLink.class])
|
||||
return NO;
|
||||
|
||||
UniversalLink *otherLink = (UniversalLink *)other;
|
||||
|
||||
return [_url isEqual:otherLink.url]
|
||||
&& [_pathParams isEqualToArray:otherLink.pathParams]
|
||||
&& [_queryParams isEqualToDictionary:otherLink.queryParams];
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger prime = 31;
|
||||
NSUInteger result = 1;
|
||||
|
||||
result = prime * result + [_url hash];
|
||||
result = prime * result + [_pathParams hash];
|
||||
result = prime * result + [_queryParams hash];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
|
@ -17,9 +17,9 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.11.1</string>
|
||||
<string>0.11.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.11.1</string>
|
||||
<string>0.11.2</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.11.1</string>
|
||||
<string>0.11.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.11.1</string>
|
||||
<string>0.11.2</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
|
|