Merge branch 'dev' into profile-pictures

pull/65/head
gmbnt 5 years ago committed by GitHub
commit 031b2f8eff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -564,7 +564,6 @@
B8162F0522892C5F00D46544 /* FriendRequestViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */; }; B8162F0522892C5F00D46544 /* FriendRequestViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */; };
B821F2F82272CED3002C88C0 /* DisplayNameVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F72272CED3002C88C0 /* DisplayNameVC.swift */; }; B821F2F82272CED3002C88C0 /* DisplayNameVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F72272CED3002C88C0 /* DisplayNameVC.swift */; };
B821F2FA2272CEEE002C88C0 /* SeedVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedVC.swift */; }; B821F2FA2272CEEE002C88C0 /* SeedVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedVC.swift */; };
B8258493230FA5E9001B41CB /* ScanQRCodeVC.m in Sources */ = {isa = PBXBuildFile; fileRef = B8258492230FA5E9001B41CB /* ScanQRCodeVC.m */; };
B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; }; B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; };
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; }; B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
B84664F5235022F30083A1CD /* MentionUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84664F4235022F30083A1CD /* MentionUtilities.swift */; }; B84664F5235022F30083A1CD /* MentionUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84664F4235022F30083A1CD /* MentionUtilities.swift */; };
@ -576,6 +575,7 @@
B891105C2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; }; B891105C2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B891105E2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; }; B891105E2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B891105F2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; }; B891105F2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
B893063F2383961A005EAA8E /* ScanQRCodeWrapperVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */; };
B894D0712339D6F300B4D94D /* DeviceLinkingModalDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0702339D6F300B4D94D /* DeviceLinkingModalDelegate.swift */; }; B894D0712339D6F300B4D94D /* DeviceLinkingModalDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0702339D6F300B4D94D /* DeviceLinkingModalDelegate.swift */; };
B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0742339EDCF00B4D94D /* NukeDataModal.swift */; }; B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0742339EDCF00B4D94D /* NukeDataModal.swift */; };
B89841E322B7579F00B1BDC6 /* NewConversationVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */; }; B89841E322B7579F00B1BDC6 /* NewConversationVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */; };
@ -1375,8 +1375,6 @@
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendRequestViewDelegate.swift; sourceTree = "<group>"; }; B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendRequestViewDelegate.swift; sourceTree = "<group>"; };
B821F2F72272CED3002C88C0 /* DisplayNameVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameVC.swift; sourceTree = "<group>"; }; B821F2F72272CED3002C88C0 /* DisplayNameVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayNameVC.swift; sourceTree = "<group>"; };
B821F2F92272CEEE002C88C0 /* SeedVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedVC.swift; sourceTree = "<group>"; }; B821F2F92272CEEE002C88C0 /* SeedVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedVC.swift; sourceTree = "<group>"; };
B8258491230FA5DA001B41CB /* ScanQRCodeVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScanQRCodeVC.h; sourceTree = "<group>"; };
B8258492230FA5E9001B41CB /* ScanQRCodeVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScanQRCodeVC.m; sourceTree = "<group>"; };
B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = "<group>"; }; B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = "<group>"; };
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; }; B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
B84664F4235022F30083A1CD /* MentionUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionUtilities.swift; sourceTree = "<group>"; }; B84664F4235022F30083A1CD /* MentionUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionUtilities.swift; sourceTree = "<group>"; };
@ -1386,6 +1384,7 @@
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModal.swift; sourceTree = "<group>"; }; B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModal.swift; sourceTree = "<group>"; };
B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = "<group>"; }; B885D5F52334A32100EE0D8E /* UIView+Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraint.swift"; sourceTree = "<group>"; };
B891105B2320872800F15FCC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; }; B891105B2320872800F15FCC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQRCodeWrapperVC.swift; sourceTree = "<group>"; };
B894D0702339D6F300B4D94D /* DeviceLinkingModalDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModalDelegate.swift; sourceTree = "<group>"; }; B894D0702339D6F300B4D94D /* DeviceLinkingModalDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModalDelegate.swift; sourceTree = "<group>"; };
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NukeDataModal.swift; sourceTree = "<group>"; }; B894D0742339EDCF00B4D94D /* NukeDataModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NukeDataModal.swift; sourceTree = "<group>"; };
B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationVC.swift; sourceTree = "<group>"; }; B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationVC.swift; sourceTree = "<group>"; };
@ -2708,8 +2707,7 @@
B8B26C90234D8CBD004ED98C /* MentionCandidateSelectionViewDelegate.swift */, B8B26C90234D8CBD004ED98C /* MentionCandidateSelectionViewDelegate.swift */,
B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */, B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */,
24BD2608234DA2050008EB0A /* NewPublicChatVC.swift */, 24BD2608234DA2050008EB0A /* NewPublicChatVC.swift */,
B8258491230FA5DA001B41CB /* ScanQRCodeVC.h */, B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */,
B8258492230FA5E9001B41CB /* ScanQRCodeVC.m */,
); );
path = Messaging; path = Messaging;
sourceTree = "<group>"; sourceTree = "<group>";
@ -3734,6 +3732,7 @@
34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */, 34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */,
340FC8B8204DAC8D007AEB0F /* AddToGroupViewController.m in Sources */, 340FC8B8204DAC8D007AEB0F /* AddToGroupViewController.m in Sources */,
341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */, 341F2C0F1F2B8AE700D07D6B /* DebugUIMisc.m in Sources */,
B893063F2383961A005EAA8E /* ScanQRCodeWrapperVC.swift in Sources */,
340FC8AF204DAC8D007AEB0F /* OWSLinkDeviceViewController.m in Sources */, 340FC8AF204DAC8D007AEB0F /* OWSLinkDeviceViewController.m in Sources */,
34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */, 34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */,
454A84042059C787008B8C75 /* MediaTileViewController.swift in Sources */, 454A84042059C787008B8C75 /* MediaTileViewController.swift in Sources */,
@ -3930,7 +3929,6 @@
B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */, B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */,
34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */, 34D1F0861F8678AA0066283D /* ConversationViewController.m in Sources */,
3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */, 3427C64320F500E000EEC730 /* OWSMessageTimerView.m in Sources */,
B8258493230FA5E9001B41CB /* ScanQRCodeVC.m in Sources */,
B90418E6183E9DD40038554A /* DateUtil.m in Sources */, B90418E6183E9DD40038554A /* DateUtil.m in Sources */,
3448E15E221333F5004B052E /* OnboardingController.swift in Sources */, 3448E15E221333F5004B052E /* OnboardingController.swift in Sources */,
340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */, 340FC8BD204DAC8D007AEB0F /* ShowGroupMembersViewController.m in Sources */,
@ -4088,7 +4086,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 21; CURRENT_PROJECT_VERSION = 22;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = SUQ8J2PCT7; DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = "$(inherited)"; FRAMEWORK_SEARCH_PATHS = "$(inherited)";
@ -4102,7 +4100,7 @@
INFOPLIST_FILE = SignalShareExtension/Info.plist; INFOPLIST_FILE = SignalShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 1.4.0; MARKETING_VERSION = 1.5.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.share-extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.share-extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -4150,7 +4148,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 21; CURRENT_PROJECT_VERSION = 22;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = SUQ8J2PCT7; DEVELOPMENT_TEAM = SUQ8J2PCT7;
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
@ -4169,7 +4167,7 @@
INFOPLIST_FILE = SignalShareExtension/Info.plist; INFOPLIST_FILE = SignalShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 1.4.0; MARKETING_VERSION = 1.5.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.share-extension"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.share-extension";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -4223,7 +4221,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.4.0; MARKETING_VERSION = 1.5.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.utilities"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.utilities";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@ -4297,7 +4295,7 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 10.0; IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MARKETING_VERSION = 1.4.0; MARKETING_VERSION = 1.5.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.utilities"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.utilities";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@ -4482,7 +4480,7 @@
CODE_SIGN_ENTITLEMENTS = Signal/Signal.entitlements; CODE_SIGN_ENTITLEMENTS = Signal/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 21; CURRENT_PROJECT_VERSION = 22;
DEVELOPMENT_TEAM = SUQ8J2PCT7; DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -4517,7 +4515,7 @@
"$(SRCROOT)", "$(SRCROOT)",
); );
LLVM_LTO = NO; LLVM_LTO = NO;
MARKETING_VERSION = 1.4.0; MARKETING_VERSION = 1.5.0;
OTHER_LDFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
PRODUCT_NAME = "Loki Messenger"; PRODUCT_NAME = "Loki Messenger";
@ -4549,7 +4547,7 @@
CODE_SIGN_ENTITLEMENTS = Signal/Signal.entitlements; CODE_SIGN_ENTITLEMENTS = Signal/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 21; CURRENT_PROJECT_VERSION = 22;
DEVELOPMENT_TEAM = SUQ8J2PCT7; DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -4584,7 +4582,7 @@
"$(SRCROOT)", "$(SRCROOT)",
); );
LLVM_LTO = NO; LLVM_LTO = NO;
MARKETING_VERSION = 1.4.0; MARKETING_VERSION = 1.5.0;
OTHER_LDFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
PRODUCT_NAME = "Loki Messenger"; PRODUCT_NAME = "Loki Messenger";

@ -81,9 +81,10 @@ final class NewConversationVC : OWSViewController, OWSQRScannerDelegate {
@objc private func scanQRCode() { @objc private func scanQRCode() {
ows_ask(forCameraPermissions: { [weak self] hasCameraAccess in ows_ask(forCameraPermissions: { [weak self] hasCameraAccess in
if hasCameraAccess { if hasCameraAccess {
let scanQRCodeVC = ScanQRCodeVC() let message = NSLocalizedString("Scan the QR code of the person you'd like to securely message. They can find their QR code by going into Loki Messenger's in-app settings and clicking \"Show QR Code\".", comment: "")
scanQRCodeVC.delegate = self let scanQRCodeWrapperVC = ScanQRCodeWrapperVC(message: message)
self?.navigationController!.pushViewController(scanQRCodeVC, animated: true) scanQRCodeWrapperVC.delegate = self
self?.navigationController!.pushViewController(scanQRCodeWrapperVC, animated: true)
} else { } else {
// Do nothing // Do nothing
} }

@ -1,12 +0,0 @@
#import <SignalMessaging/OWSViewController.h>
#import "OWSQRCodeScanningViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface ScanQRCodeVC : OWSViewController
@property (nonatomic, weak) UIViewController<OWSQRScannerDelegate> *delegate;
@end
NS_ASSUME_NONNULL_END

@ -1,62 +0,0 @@
#import "ScanQRCodeVC.h"
#import "Session-Swift.h"
NS_ASSUME_NONNULL_BEGIN
@interface ScanQRCodeVC ()
@property (nonatomic) OWSQRCodeScanningViewController *qrCodeScanningVC;
@end
@implementation ScanQRCodeVC
- (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
- (void)viewDidLoad
{
[super viewDidLoad];
// Background color
self.view.backgroundColor = Theme.backgroundColor;
// QR code scanning VC
self.qrCodeScanningVC = [OWSQRCodeScanningViewController new];
self.qrCodeScanningVC.scanDelegate = self.delegate;
[self.view addSubview:self.qrCodeScanningVC.view];
[self.qrCodeScanningVC.view autoPinEdgeToSuperviewEdge:ALEdgeLeading];
[self.qrCodeScanningVC.view autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
[self.qrCodeScanningVC.view autoPinToTopLayoutGuideOfViewController:self withInset:0.0];
[self.qrCodeScanningVC.view autoPinToSquareAspectRatio];
// Explanation label
UILabel *explanationLabel = [UILabel new];
explanationLabel.text = NSLocalizedString(@"Scan the QR code of the person you'd like to securely message. They can find their QR code by going into Loki Messenger's in-app settings and clicking \"Show QR Code\".", @"");
explanationLabel.textColor = Theme.primaryColor;
explanationLabel.font = UIFont.ows_dynamicTypeSubheadlineClampedFont;
explanationLabel.numberOfLines = 0;
explanationLabel.lineBreakMode = NSLineBreakByWordWrapping;
explanationLabel.textAlignment = NSTextAlignmentCenter;
// Bottom view
UIView *bottomView = [UIView new];
[self.view addSubview:bottomView];
[bottomView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.qrCodeScanningVC.view];
[bottomView autoPinEdgeToSuperviewEdge:ALEdgeLeading];
[bottomView autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
[bottomView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[bottomView addSubview:explanationLabel];
[explanationLabel autoPinWidthToSuperviewWithMargin:32];
[explanationLabel autoPinHeightToSuperviewWithMargin:32];
// Title
self.title = NSLocalizedString(@"Scan QR Code", "");
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[UIDevice.currentDevice ows_setOrientation:UIInterfaceOrientationPortrait];
dispatch_async(dispatch_get_main_queue(), ^{
[self.qrCodeScanningVC startCapture];
});
}
@end
NS_ASSUME_NONNULL_END

@ -0,0 +1,74 @@
final class ScanQRCodeWrapperVC : UIViewController {
var delegate: (UIViewController & OWSQRScannerDelegate)? = nil
var isPresentedModally = false
private let message: String
private let scanQRCodeVC = OWSQRCodeScanningViewController()
// MARK: Settings
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait }
// MARK: Lifecycle
init(message: String) {
self.message = message
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
preconditionFailure("Use init(title:) instead.")
}
override init(nibName: String?, bundle: Bundle?) {
preconditionFailure("Use init(title:) instead.")
}
override func viewDidLoad() {
// Navigation bar
if isPresentedModally {
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(objc_dismiss))
}
// Background color
view.backgroundColor = Theme.backgroundColor
// Scan QR code VC
scanQRCodeVC.scanDelegate = delegate
let scanQRCodeVCView = scanQRCodeVC.view!
view.addSubview(scanQRCodeVCView)
scanQRCodeVCView.pin(.leading, to: .leading, of: view)
scanQRCodeVCView.pin(.trailing, to: .trailing, of: view)
scanQRCodeVCView.autoPin(toTopLayoutGuideOf: self, withInset: 0)
scanQRCodeVCView.autoPinToSquareAspectRatio()
// Bottom view
let bottomView = UIView()
view.addSubview(bottomView)
bottomView.pin(.top, to: .bottom, of: scanQRCodeVCView)
bottomView.pin(.leading, to: .leading, of: view)
bottomView.pin(.trailing, to: .trailing, of: view)
bottomView.pin(.bottom, to: .bottom, of: view)
// Explanation label
let explanationLabel = UILabel()
explanationLabel.text = message
explanationLabel.textColor = Theme.primaryColor
explanationLabel.font = .ows_dynamicTypeSubheadlineClamped
explanationLabel.numberOfLines = 0
explanationLabel.lineBreakMode = .byWordWrapping
explanationLabel.textAlignment = .center
bottomView.addSubview(explanationLabel)
explanationLabel.autoPinWidthToSuperview(withMargin: 32)
explanationLabel.autoPinHeightToSuperview(withMargin: 32)
// Title
title = NSLocalizedString("Scan QR Code", comment: "")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIDevice.current.ows_setOrientation(.portrait)
DispatchQueue.main.async { [weak self] in
self?.scanQRCodeVC.startCapture()
}
}
// MARK: Interaction
@objc private func objc_dismiss() {
presentingViewController?.dismiss(animated: true, completion: nil)
}
}

@ -1,21 +1,19 @@
// TODO: Split this into multiple VCs final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate, OWSQRScannerDelegate {
final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
private var mode: Mode = .register { didSet { if mode != oldValue { handleModeChanged() } } } private var mode: Mode = .register { didSet { if mode != oldValue { handleModeChanged() } } }
private var seed: Data! { didSet { updateMnemonic() } } private var seed: Data! { didSet { updateMnemonic() } }
private var mnemonic: String! { didSet { handleMnemonicChanged() } } private var mnemonic: String! { didSet { handleMnemonicChanged() } }
// MARK: Components // MARK: Components
private lazy var registerStackView: UIStackView = { private lazy var registerStackView: UIStackView = {
let result = UIStackView(arrangedSubviews: [ explanationLabel1, UIView.spacer(withHeight: 32), mnemonicLabel, UIView.spacer(withHeight: 24), copyButton, restoreButton1, linkButton1 ]) let result = UIStackView(arrangedSubviews: [ explanationLabel1, UIView.spacer(withHeight: 32), mnemonicLabel, UIView.spacer(withHeight: 24), copyButton, restoreButton, linkButton1 ])
result.accessibilityIdentifier = "onboarding.keyPairStep.registerStackView" result.accessibilityIdentifier = "onboarding.keyPairStep.registerStackView"
result.axis = .vertical result.axis = .vertical
return result return result
}() }()
private lazy var explanationLabel1: UILabel = { private lazy var explanationLabel1: UILabel = {
let result = createExplanationLabel(text: NSLocalizedString("Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate to a new device.", comment: "")) let result = createExplanationLabel(text: NSLocalizedString("Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate your account to a new device.", comment: ""))
result.accessibilityIdentifier = "onboarding.keyPairStep.explanationLabel1" result.accessibilityIdentifier = "onboarding.keyPairStep.explanationLabel1"
result.textColor = Theme.primaryColor result.textColor = Theme.primaryColor
var fontTraits = result.font.fontDescriptor.symbolicTraits var fontTraits = result.font.fontDescriptor.symbolicTraits
@ -41,22 +39,22 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
return result return result
}() }()
private lazy var restoreButton1: OWSFlatButton = { private lazy var restoreButton: OWSFlatButton = {
let result = createLinkButton(title: NSLocalizedString("Restore Using Seed", comment: ""), selector: #selector(handleSwitchModeButton1Tapped)) let result = createLinkButton(title: NSLocalizedString("Restore Using Seed", comment: ""), selector: #selector(handleSwitchModeButton1Tapped))
result.accessibilityIdentifier = "onboarding.keyPairStep.restoreButton1" result.accessibilityIdentifier = "onboarding.keyPairStep.restoreButton"
result.setBackgroundColors(upColor: .clear, downColor: .clear) result.setBackgroundColors(upColor: .clear, downColor: .clear)
return result return result
}() }()
private lazy var linkButton1: OWSFlatButton = { private lazy var linkButton1: OWSFlatButton = {
let result = createLinkButton(title: NSLocalizedString("Link Device", comment: ""), selector: #selector(handleSwitchModeButton2Tapped)) let result = createLinkButton(title: NSLocalizedString("Link Device", comment: ""), selector: #selector(handleLinkButtonTapped))
result.accessibilityIdentifier = "onboarding.keyPairStep.linkButton1" result.accessibilityIdentifier = "onboarding.keyPairStep.linkButton1"
result.setBackgroundColors(upColor: .clear, downColor: .clear) result.setBackgroundColors(upColor: .clear, downColor: .clear)
return result return result
}() }()
private lazy var restoreStackView: UIStackView = { private lazy var restoreStackView: UIStackView = {
let result = UIStackView(arrangedSubviews: [ explanationLabel2, UIView.spacer(withHeight: 32), errorLabel1, errorLabel1Spacer, mnemonicTextField, UIView.spacer(withHeight: 24), registerButton1, linkButton2 ]) let result = UIStackView(arrangedSubviews: [ explanationLabel2, UIView.spacer(withHeight: 32), errorLabel, errorLabelSpacer, mnemonicTextField, UIView.spacer(withHeight: 24), registerButton, linkButton2 ])
result.accessibilityIdentifier = "onboarding.keyPairStep.restoreStackView" result.accessibilityIdentifier = "onboarding.keyPairStep.restoreStackView"
result.axis = .vertical result.axis = .vertical
return result return result
@ -72,9 +70,9 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
return result return result
}() }()
private lazy var errorLabel1: UILabel = { private lazy var errorLabel: UILabel = {
let result = createExplanationLabel(text: "") let result = createExplanationLabel(text: "")
result.accessibilityIdentifier = "onboarding.keyPairStep.errorLabel1" result.accessibilityIdentifier = "onboarding.keyPairStep.errorLabel"
result.textColor = UIColor.red result.textColor = UIColor.red
var fontTraits = result.font.fontDescriptor.symbolicTraits var fontTraits = result.font.fontDescriptor.symbolicTraits
fontTraits.insert(.traitBold) fontTraits.insert(.traitBold)
@ -82,7 +80,7 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
return result return result
}() }()
private lazy var errorLabel1Spacer: UIView = { private lazy var errorLabelSpacer: UIView = {
let result = UIView.spacer(withHeight: 32) let result = UIView.spacer(withHeight: 32)
result.isHidden = true result.isHidden = true
return result return result
@ -102,90 +100,28 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
return result return result
}() }()
private lazy var registerButton1: OWSFlatButton = { private lazy var registerButton: OWSFlatButton = {
let result = createLinkButton(title: NSLocalizedString("Register a New Account", comment: ""), selector: #selector(handleSwitchModeButton1Tapped)) let result = createLinkButton(title: NSLocalizedString("Register a New Account", comment: ""), selector: #selector(handleSwitchModeButton1Tapped))
result.accessibilityIdentifier = "onboarding.keyPairStep.registerButton1" result.accessibilityIdentifier = "onboarding.keyPairStep.registerButton"
result.setBackgroundColors(upColor: .clear, downColor: .clear) result.setBackgroundColors(upColor: .clear, downColor: .clear)
return result return result
}() }()
private lazy var linkButton2: OWSFlatButton = { private lazy var linkButton2: OWSFlatButton = {
let result = createLinkButton(title: NSLocalizedString("Link Device", comment: ""), selector: #selector(handleSwitchModeButton2Tapped)) let result = createLinkButton(title: NSLocalizedString("Link Device", comment: ""), selector: #selector(handleLinkButtonTapped))
result.accessibilityIdentifier = "onboarding.keyPairStep.linkButton2" result.accessibilityIdentifier = "onboarding.keyPairStep.linkButton2"
result.setBackgroundColors(upColor: .clear, downColor: .clear) result.setBackgroundColors(upColor: .clear, downColor: .clear)
return result return result
}() }()
private lazy var linkStackView: UIStackView = {
let result = UIStackView(arrangedSubviews: [ explanationLabel3, UIView.spacer(withHeight: 32), errorLabel2, errorLabel2Spacer, masterHexEncodedPublicKeyTextField, UIView.spacer(withHeight: 24), registerButton2, restoreButton2 ])
result.accessibilityIdentifier = "onboarding.keyPairStep.linkStackView"
result.axis = .vertical
return result
}()
private lazy var explanationLabel3: UILabel = {
let result = createExplanationLabel(text: NSLocalizedString("Link to an existing device by going into its in-app settings and clicking \"Link Device\".", comment: ""))
result.accessibilityIdentifier = "onboarding.keyPairStep.explanationLabel3"
result.textColor = Theme.primaryColor
var fontTraits = result.font.fontDescriptor.symbolicTraits
fontTraits.insert(.traitBold)
result.font = UIFont(descriptor: result.font.fontDescriptor.withSymbolicTraits(fontTraits)!, size: result.font.pointSize)
return result
}()
private lazy var errorLabel2: UILabel = {
let result = createExplanationLabel(text: "")
result.accessibilityIdentifier = "onboarding.keyPairStep.errorLabel2"
result.textColor = UIColor.red
var fontTraits = result.font.fontDescriptor.symbolicTraits
fontTraits.insert(.traitBold)
result.font = UIFont(descriptor: result.font.fontDescriptor.withSymbolicTraits(fontTraits)!, size: 12)
return result
}()
private lazy var errorLabel2Spacer: UIView = {
let result = UIView.spacer(withHeight: 32)
result.isHidden = true
return result
}()
private lazy var masterHexEncodedPublicKeyTextField: UITextField = {
let result = UITextField(frame: CGRect.zero)
result.textColor = Theme.primaryColor
result.font = UIFont.ows_dynamicTypeBodyClamped
result.textAlignment = .center
let placeholder = NSMutableAttributedString(string: NSLocalizedString("Enter the Other Device's Public Key", comment: ""))
placeholder.addAttribute(.foregroundColor, value: Theme.placeholderColor, range: NSRange(location: 0, length: placeholder.length))
result.attributedPlaceholder = placeholder
result.tintColor = UIColor.lokiGreen()
result.accessibilityIdentifier = "onboarding.keyPairStep.masterHexEncodedPublicKeyTextField"
result.keyboardAppearance = .dark
return result
}()
private lazy var registerButton2: OWSFlatButton = {
let result = createLinkButton(title: NSLocalizedString("Register a New Account", comment: ""), selector: #selector(handleSwitchModeButton1Tapped))
result.accessibilityIdentifier = "onboarding.keyPairStep.registerButton2"
result.setBackgroundColors(upColor: .clear, downColor: .clear)
return result
}()
private lazy var restoreButton2: OWSFlatButton = {
let result = createLinkButton(title: NSLocalizedString("Restore Using Seed", comment: ""), selector: #selector(handleSwitchModeButton2Tapped))
result.accessibilityIdentifier = "onboarding.keyPairStep.restoreButton2"
result.setBackgroundColors(upColor: .clear, downColor: .clear)
return result
}()
// Shared
private lazy var mainButton: OWSFlatButton = { private lazy var mainButton: OWSFlatButton = {
let result = createButton(title: "", selector: #selector(handleMainButtonTapped)) let result = createButton(title: "", selector: #selector(objc_proceed))
result.accessibilityIdentifier = "onboarding.keyPairStep.mainButton" result.accessibilityIdentifier = "onboarding.keyPairStep.mainButton"
return result return result
}() }()
// MARK: Types // MARK: Types
enum Mode { case register, restore, link } enum Mode { case register, restore }
// MARK: Lifecycle // MARK: Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
@ -207,7 +143,6 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
let mainView = UIView(frame: CGRect.zero) let mainView = UIView(frame: CGRect.zero)
mainView.addSubview(restoreStackView) mainView.addSubview(restoreStackView)
mainView.addSubview(registerStackView) mainView.addSubview(registerStackView)
mainView.addSubview(linkStackView)
let mainStackView = UIStackView(arrangedSubviews: [ titleLabel, mainView, mainButton ]) let mainStackView = UIStackView(arrangedSubviews: [ titleLabel, mainView, mainButton ])
mainStackView.axis = .vertical mainStackView.axis = .vertical
mainStackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32) mainStackView.layoutMargins = UIEdgeInsets(top: 32, left: 32, bottom: 32, right: 32)
@ -221,8 +156,6 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
registerStackView.autoVCenterInSuperview() registerStackView.autoVCenterInSuperview()
restoreStackView.autoPinWidthToSuperview() restoreStackView.autoPinWidthToSuperview()
restoreStackView.autoVCenterInSuperview() restoreStackView.autoVCenterInSuperview()
linkStackView.autoPinWidthToSuperview()
linkStackView.autoVCenterInSuperview()
} }
// MARK: General // MARK: General
@ -237,9 +170,8 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
private func handleModeChanged() { private func handleModeChanged() {
let (activeStackView, otherStackViews) = { () -> (UIStackView, [UIStackView]) in let (activeStackView, otherStackViews) = { () -> (UIStackView, [UIStackView]) in
switch mode { switch mode {
case .register: return (registerStackView, [ restoreStackView, linkStackView ]) case .register: return (registerStackView, [ restoreStackView ])
case .restore: return (restoreStackView, [ registerStackView, linkStackView ]) case .restore: return (restoreStackView, [ registerStackView ])
case .link: return (linkStackView, [ registerStackView, restoreStackView ])
} }
}() }()
UIView.animate(withDuration: 0.25) { UIView.animate(withDuration: 0.25) {
@ -250,14 +182,12 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
switch mode { switch mode {
case .register: return NSLocalizedString("Register", comment: "") case .register: return NSLocalizedString("Register", comment: "")
case .restore: return NSLocalizedString("Restore", comment: "") case .restore: return NSLocalizedString("Restore", comment: "")
case .link: return NSLocalizedString("Link", comment: "")
} }
}() }()
UIView.transition(with: mainButton, duration: 0.25, options: .transitionCrossDissolve, animations: { UIView.transition(with: mainButton, duration: 0.25, options: .transitionCrossDissolve, animations: {
self.mainButton.setTitle(mainButtonTitle) self.mainButton.setTitle(mainButtonTitle)
}, completion: nil) }, completion: nil)
if mode != .restore { mnemonicTextField.resignFirstResponder() } if mode != .restore { mnemonicTextField.resignFirstResponder() }
if mode != .link { masterHexEncodedPublicKeyTextField.resignFirstResponder() }
} }
private func updateSeed() { private func updateSeed() {
@ -287,39 +217,60 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
switch mode { switch mode {
case .register: mode = .restore case .register: mode = .restore
case .restore: mode = .register case .restore: mode = .register
case .link: mode = .register
} }
} }
@objc private func handleSwitchModeButton2Tapped() { @objc private func handleLinkButtonTapped() {
switch mode { ows_ask(forCameraPermissions: { [weak self] hasCameraAccess in
case .register: mode = .link guard let self = self else { return }
case .restore: mode = .link if hasCameraAccess {
case .link: mode = .restore let message = NSLocalizedString("Link to an existing device by going into its in-app settings and clicking \"Link Device\".", comment: "")
let scanQRCodeWrapperVC = ScanQRCodeWrapperVC(message: message)
scanQRCodeWrapperVC.delegate = self
scanQRCodeWrapperVC.isPresentedModally = true
let navigationVC = OWSNavigationController(rootViewController: scanQRCodeWrapperVC)
self.present(navigationVC, animated: true, completion: nil)
} else {
// Do nothing
}
})
}
func controller(_ controller: OWSQRCodeScanningViewController, didDetectQRCodeWith string: String) {
dismiss(animated: true, completion: nil)
DispatchQueue.main.async { [weak self] in
self?.proceed(with: string)
} }
} }
@objc private func handleMainButtonTapped() { @objc private func objc_proceed() {
proceed()
}
private func proceed(with masterHexEncodedPublicKey: String? = nil) {
var seed: Data var seed: Data
let mode = self.mode if let masterHexEncodedPublicKey = masterHexEncodedPublicKey {
switch mode {
case .register: seed = self.seed
case .restore:
let mnemonic = mnemonicTextField.text!
do {
let hexEncodedSeed = try Mnemonic.decode(mnemonic: mnemonic)
seed = Data(hex: hexEncodedSeed)
} catch let error {
let error = error as? Mnemonic.DecodingError ?? Mnemonic.DecodingError.generic
errorLabel1Spacer.isHidden = false
return errorLabel1.text = error.errorDescription
}
case .link:
seed = self.seed seed = self.seed
let masterHexEncodedPublicKey = masterHexEncodedPublicKeyTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces)
if !ECKeyPair.isValidHexEncodedPublicKey(candidate: masterHexEncodedPublicKey) { if !ECKeyPair.isValidHexEncodedPublicKey(candidate: masterHexEncodedPublicKey) {
errorLabel2Spacer.isHidden = false let alert = UIAlertController(title: NSLocalizedString("Invalid QR Code", comment: ""), message: NSLocalizedString("Please make sure the QR code you scanned is correct and try again.", comment: ""), preferredStyle: .alert)
return errorLabel2.text = NSLocalizedString("Invalid public key", comment: "") alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: ""), accessibilityIdentifier: nil, style: .default, handler: nil))
return present(alert, animated: true, completion: nil)
}
Analytics.shared.track("Device Linking Attempted")
} else {
let mode = self.mode
switch mode {
case .register: seed = self.seed
case .restore:
let mnemonic = mnemonicTextField.text!
do {
let hexEncodedSeed = try Mnemonic.decode(mnemonic: mnemonic)
seed = Data(hex: hexEncodedSeed)
} catch let error {
let error = error as? Mnemonic.DecodingError ?? Mnemonic.DecodingError.generic
errorLabelSpacer.isHidden = false
return errorLabel.text = error.errorDescription
}
} }
} }
// Use KVC to access dbConnection even though it's private // Use KVC to access dbConnection even though it's private
@ -335,10 +286,8 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
switch mode { switch mode {
case .register: Analytics.shared.track("Seed Created") case .register: Analytics.shared.track("Seed Created")
case .restore: Analytics.shared.track("Seed Restored") case .restore: Analytics.shared.track("Seed Restored")
case .link: Analytics.shared.track("Device Linking Attempted")
} }
if mode == .link { if let masterHexEncodedPublicKey = masterHexEncodedPublicKey {
let masterHexEncodedPublicKey = masterHexEncodedPublicKeyTextField.text!.trimmingCharacters(in: CharacterSet.whitespaces)
TSAccountManager.sharedInstance().didRegister() TSAccountManager.sharedInstance().didRegister()
setUserInteractionEnabled(false) setUserInteractionEnabled(false)
let _ = LokiStorageAPI.getDeviceLinks(associatedWith: masterHexEncodedPublicKey).done(on: DispatchQueue.main) { [weak self] deviceLinks in let _ = LokiStorageAPI.getDeviceLinks(associatedWith: masterHexEncodedPublicKey).done(on: DispatchQueue.main) { [weak self] deviceLinks in
@ -384,8 +333,8 @@ final class SeedVC : OnboardingBaseViewController, DeviceLinkingModalDelegate {
// MARK: Convenience // MARK: Convenience
private func setUserInteractionEnabled(_ isEnabled: Bool) { private func setUserInteractionEnabled(_ isEnabled: Bool) {
registerButton2.isUserInteractionEnabled = isEnabled [ copyButton, restoreButton, linkButton1, registerButton, linkButton2, mainButton ].forEach {
restoreButton2.isUserInteractionEnabled = isEnabled $0.isUserInteractionEnabled = isEnabled
mainButton.isUserInteractionEnabled = isEnabled }
} }
} }

@ -32,7 +32,7 @@ final class SeedModal : Modal {
let subtitleLabel = UILabel() let subtitleLabel = UILabel()
subtitleLabel.textColor = Theme.primaryColor subtitleLabel.textColor = Theme.primaryColor
subtitleLabel.font = UIFont.ows_dynamicTypeCaption1Clamped subtitleLabel.font = UIFont.ows_dynamicTypeCaption1Clamped
subtitleLabel.text = NSLocalizedString("This is your personal secret. It can be used to restore your account if you lose access, or to migrate to a new device.", comment: "") subtitleLabel.text = NSLocalizedString("This is your personal secret. It can be used to restore your account if you lose access, or to migrate your account to a new device.", comment: "")
subtitleLabel.numberOfLines = 0 subtitleLabel.numberOfLines = 0
subtitleLabel.lineBreakMode = .byWordWrapping subtitleLabel.lineBreakMode = .byWordWrapping
subtitleLabel.textAlignment = .center subtitleLabel.textAlignment = .center

@ -44,7 +44,7 @@
#import "PrivacySettingsTableViewController.h" #import "PrivacySettingsTableViewController.h"
#import "ProfileViewController.h" #import "ProfileViewController.h"
#import "RemoteVideoView.h" #import "RemoteVideoView.h"
#import "ScanQRCodeVC.h" #import "OWSQRCodeScanningViewController.h"
#import "SignalApp.h" #import "SignalApp.h"
#import "UIViewController+Permissions.h" #import "UIViewController+Permissions.h"
#import "ViewControllerUtils.h" #import "ViewControllerUtils.h"

@ -31,9 +31,10 @@ public class OnboardingSplashViewController: OnboardingBaseViewController {
lokiLogoContainer.addSubview(lokiLogoImageView) lokiLogoContainer.addSubview(lokiLogoImageView)
let betaTermsLabel = UILabel() let betaTermsLabel = UILabel()
betaTermsLabel.text = NSLocalizedString("Loki Messenger is currently in beta. For development purposes the beta version collects basic usage statistics and crash logs. In addition, the beta version doesn't provide full privacy and shouldn't be used to transmit sensitive information.", comment: "") betaTermsLabel.text = NSLocalizedString("Loki Messenger is currently in beta. For development purposes the beta version collects basic usage statistics and crash logs. In addition, the beta version doesn't yet provide full privacy and shouldn't be used to transmit sensitive information.", comment: "")
betaTermsLabel.textColor = .white betaTermsLabel.textColor = .white
betaTermsLabel.font = .ows_dynamicTypeSubheadlineClamped let font = UIFont.ows_dynamicTypeCaption1Clamped
betaTermsLabel.font = UIFont(descriptor: font.fontDescriptor.withSymbolicTraits(.traitBold)!, size: font.pointSize)
betaTermsLabel.numberOfLines = 0 betaTermsLabel.numberOfLines = 0
betaTermsLabel.textAlignment = .center betaTermsLabel.textAlignment = .center
betaTermsLabel.lineBreakMode = .byWordWrapping betaTermsLabel.lineBreakMode = .byWordWrapping

@ -2552,7 +2552,7 @@
"Password (Optional)" = "Password (Optional)"; "Password (Optional)" = "Password (Optional)";
"Next" = "Next"; "Next" = "Next";
"Add" = "Add"; "Add" = "Add";
"Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate to a new device." = "Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate to a new device."; "Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate your account to a new device." = "Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate your account to a new device.";
"Restore your account by entering your seed below." = "Restore your account by entering your seed below."; "Restore your account by entering your seed below." = "Restore your account by entering your seed below.";
"Copy" = "Copy"; "Copy" = "Copy";
"Copied ✓" = "Copied ✓"; "Copied ✓" = "Copied ✓";
@ -2621,7 +2621,7 @@
"Loki" = "Loki"; "Loki" = "Loki";
"Can't Start Conversation" = "Can't Start Conversation"; "Can't Start Conversation" = "Can't Start Conversation";
"Please enter the public key of the person you'd like to message." = "Please enter the public key of the person you'd like to message."; "Please enter the public key of the person you'd like to message." = "Please enter the public key of the person you'd like to message.";
"Loki Messenger is currently in beta. For development purposes the beta version collects basic usage statistics and crash logs. In addition, the beta version doesn't provide full privacy and shouldn't be used to transmit sensitive information." = "Loki Messenger is currently in beta. For development purposes the beta version collects basic usage statistics and crash logs. In addition, the beta version doesn't provide full privacy and shouldn't be used to transmit sensitive information."; "Loki Messenger is currently in beta. For development purposes the beta version collects basic usage statistics and crash logs. In addition, the beta version doesn't yet provide full privacy and shouldn't be used to transmit sensitive information." = "Loki Messenger is currently in beta. For development purposes the beta version collects basic usage statistics and crash logs. In addition, the beta version doesn't yet provide full privacy and shouldn't be used to transmit sensitive information.";
"Copy Public Key" = "Copy Public Key"; "Copy Public Key" = "Copy Public Key";
"Link Device" = "Link Device"; "Link Device" = "Link Device";
"Waiting for Device" = "Waiting for Device"; "Waiting for Device" = "Waiting for Device";
@ -2633,7 +2633,7 @@
"Link to an existing device by going into its in-app settings and clicking \"Link Device\"." = "Link to an existing device by going into its in-app settings and clicking \"Link Device\"."; "Link to an existing device by going into its in-app settings and clicking \"Link Device\"." = "Link to an existing device by going into its in-app settings and clicking \"Link Device\".";
"Authorize" = "Authorize"; "Authorize" = "Authorize";
"Enter the Other Device's Public Key" = "Enter the Other Device's Public Key"; "Enter the Other Device's Public Key" = "Enter the Other Device's Public Key";
"This is your personal secret. It can be used to restore your account if you lose access, or to migrate to a new device." = "This is your personal secret. It can be used to restore your account if you lose access, or to migrate to a new device."; "This is your personal secret. It can be used to restore your account if you lose access, or to migrate your account to a new device." = "This is your personal secret. It can be used to restore your account if you lose access, or to migrate your account to a new device.";
"Device Link Authorized" = "Device Link Authorized"; "Device Link Authorized" = "Device Link Authorized";
"Your device has been linked successfully" = "Your device has been linked successfully"; "Your device has been linked successfully" = "Your device has been linked successfully";
"Link" = "Link"; "Link" = "Link";
@ -2653,3 +2653,5 @@
"Profile Picture" = "Profile Picture"; "Profile Picture" = "Profile Picture";
"Set Profile Picture" = "Set Profile Picture"; "Set Profile Picture" = "Set Profile Picture";
"Clear Profile Picture" = "Clear Profile Picture"; "Clear Profile Picture" = "Clear Profile Picture";
"Invalid QR Code" = "Invalid QR Code";
"Please make sure the QR code you scanned is correct and try again." = "Please make sure the QR code you scanned is correct and try again.";

Loading…
Cancel
Save