mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Start implementing device linking UI
This commit is contained in:
parent
da2d18f0fc
commit
a604ba5646
1
Podfile
1
Podfile
|
@ -78,6 +78,7 @@ target 'Signal' do
|
|||
pod 'FirebaseCore', '~> 6.0', :inhibit_warnings => true
|
||||
pod 'Fabric', '~> 1.10', :inhibit_warnings => true
|
||||
pod 'Crashlytics', '~> 3.13', :inhibit_warnings => true
|
||||
pod 'NVActivityIndicatorView', '~> 4.7', :inhibit_warnings => true
|
||||
|
||||
target 'SignalTests' do
|
||||
inherit! :search_paths
|
||||
|
|
|
@ -62,6 +62,9 @@ PODS:
|
|||
- Mantle/extobjc (= 2.1.0)
|
||||
- Mantle/extobjc (2.1.0)
|
||||
- Mixpanel (3.4.7)
|
||||
- NVActivityIndicatorView (4.7.0):
|
||||
- NVActivityIndicatorView/Presenter (= 4.7.0)
|
||||
- NVActivityIndicatorView/Presenter (4.7.0)
|
||||
- PromiseKit (6.5.3):
|
||||
- PromiseKit/CorePromise (= 6.5.3)
|
||||
- PromiseKit/Foundation (= 6.5.3)
|
||||
|
@ -220,6 +223,7 @@ DEPENDENCIES:
|
|||
- IGIdenticon
|
||||
- Mantle (from `https://github.com/signalapp/Mantle`, branch `signal-master`)
|
||||
- Mixpanel (~> 3.4)
|
||||
- NVActivityIndicatorView (~> 4.7)
|
||||
- PromiseKit (= 6.5.3)
|
||||
- PureLayout
|
||||
- Reachability
|
||||
|
@ -249,6 +253,7 @@ SPEC REPOS:
|
|||
- IGIdenticon
|
||||
- libPhoneNumber-iOS
|
||||
- Mixpanel
|
||||
- NVActivityIndicatorView
|
||||
- PromiseKit
|
||||
- PureLayout
|
||||
- Reachability
|
||||
|
@ -331,6 +336,7 @@ SPEC CHECKSUMS:
|
|||
libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa
|
||||
Mantle: 2fa750afa478cd625a94230fbf1c13462f29395b
|
||||
Mixpanel: 696e0a1c7f2685aa06bb23829b7a58ab7203d6c7
|
||||
NVActivityIndicatorView: b19ddab2576f805cbe0fb2306cba3476e09a1dea
|
||||
PromiseKit: c609029bdd801f792551a504c695c7d3098b42cd
|
||||
PureLayout: f08c01b8dec00bb14a1fefa3de4c7d9c265df85e
|
||||
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
|
||||
|
@ -345,6 +351,6 @@ SPEC CHECKSUMS:
|
|||
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
|
||||
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
|
||||
|
||||
PODFILE CHECKSUM: 1240a47686acf0d2d7e61e6ec3a925fbded184fa
|
||||
PODFILE CHECKSUM: ff66104e65cc960ed08a74b71c27f5caf59f4239
|
||||
|
||||
COCOAPODS: 1.5.3
|
||||
|
|
|
@ -568,6 +568,7 @@
|
|||
B82584A02315024B001B41CB /* LokiRSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */; };
|
||||
B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; };
|
||||
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
|
||||
B885D5F4233491AB00EE0D8E /* DeviceLinkingModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */; };
|
||||
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 */; };
|
||||
B891105F2320872800F15FCC /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B891105B2320872800F15FCC /* GoogleService-Info.plist */; };
|
||||
|
@ -1371,6 +1372,7 @@
|
|||
B825849F2315024B001B41CB /* LokiRSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiRSSFeedPoller.swift; sourceTree = "<group>"; };
|
||||
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = "<group>"; };
|
||||
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
|
||||
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceLinkingModal.swift; sourceTree = "<group>"; };
|
||||
B891105B2320872800F15FCC /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = "<group>"; };
|
||||
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
|
||||
|
@ -2640,6 +2642,7 @@
|
|||
B8258491230FA5DA001B41CB /* ScanQRCodeViewController.h */,
|
||||
B8258492230FA5E9001B41CB /* ScanQRCodeViewController.m */,
|
||||
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */,
|
||||
B885D5F3233491AB00EE0D8E /* DeviceLinkingModal.swift */,
|
||||
);
|
||||
path = Loki;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3319,6 +3322,7 @@
|
|||
"${BUILT_PRODUCTS_DIR}/IGIdenticon/IGIdenticon.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Mixpanel/Mixpanel.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/NVActivityIndicatorView/NVActivityIndicatorView.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/PureLayout/PureLayout.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework",
|
||||
|
@ -3349,6 +3353,7 @@
|
|||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IGIdenticon.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mixpanel.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/NVActivityIndicatorView.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PureLayout.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework",
|
||||
|
@ -3706,6 +3711,7 @@
|
|||
450D19131F85236600970622 /* RemoteVideoView.m in Sources */,
|
||||
34129B8621EF877A005457A8 /* LinkPreviewView.swift in Sources */,
|
||||
34386A54207D271D009F5D9C /* NeverClearView.swift in Sources */,
|
||||
B885D5F4233491AB00EE0D8E /* DeviceLinkingModal.swift in Sources */,
|
||||
45DF5DF21DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */,
|
||||
451166C01FD86B98000739BA /* AccountManager.swift in Sources */,
|
||||
3430FE181F7751D4000EC51B /* GiphyAPI.swift in Sources */,
|
||||
|
|
|
@ -60,7 +60,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
|
||||
static NSTimeInterval launchStartedAt;
|
||||
|
||||
@interface AppDelegate () <UNUserNotificationCenterDelegate, LKDeviceLinkingSessionDelegate>
|
||||
@interface AppDelegate () <UNUserNotificationCenterDelegate>
|
||||
|
||||
@property (nonatomic) BOOL hasInitialRootViewController;
|
||||
@property (nonatomic) BOOL areVersionMigrationsComplete;
|
||||
|
@ -72,7 +72,6 @@ static NSTimeInterval launchStartedAt;
|
|||
@property (nonatomic) LKGroupChatPoller *lokiPublicChatPoller;
|
||||
@property (nonatomic) LKRSSFeedPoller *lokiNewsFeedPoller;
|
||||
@property (nonatomic) LKRSSFeedPoller *lokiMessengerUpdatesFeedPoller;
|
||||
@property (nonatomic) LKDeviceLinkingSession *lokiDeviceLinkingSession;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -1639,21 +1638,4 @@ static NSTimeInterval launchStartedAt;
|
|||
}
|
||||
}
|
||||
|
||||
- (void)startListeningForLinkingRequests
|
||||
{
|
||||
[self.lokiDeviceLinkingSession stopListeningForLinkingRequests];
|
||||
self.lokiDeviceLinkingSession = [[LKDeviceLinkingSession alloc] initWithDelegate:self];
|
||||
[self.lokiDeviceLinkingSession startListeningForLinkingRequests];
|
||||
}
|
||||
|
||||
- (void)requestUserAuthorizationFor:(LKDeviceLink *)deviceLink
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)handleDeviceLinkingSessionTimeout
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
131
Signal/src/Loki/DeviceLinkingModal.swift
Normal file
131
Signal/src/Loki/DeviceLinkingModal.swift
Normal file
|
@ -0,0 +1,131 @@
|
|||
import NVActivityIndicatorView
|
||||
|
||||
@objc(LKDeviceLinkingModal)
|
||||
final class DeviceLinkingModal : UIViewController, LokiDeviceLinkingSessionDelegate {
|
||||
|
||||
private lazy var deviceLinkingSession: LokiDeviceLinkingSession = {
|
||||
return LokiDeviceLinkingSession(delegate: self)
|
||||
}()
|
||||
|
||||
// MARK: Components
|
||||
private lazy var contentView: UIView = {
|
||||
let result = UIView()
|
||||
result.backgroundColor = .lokiDarkGray()
|
||||
result.layer.cornerRadius = 4
|
||||
result.layer.masksToBounds = false
|
||||
result.layer.shadowColor = UIColor.black.cgColor
|
||||
result.layer.shadowRadius = 8
|
||||
result.layer.shadowOpacity = 0.64
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var spinner = NVActivityIndicatorView(frame: CGRect.zero, type: .circleStrokeSpin, color: .white, padding: nil)
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let result = UILabel()
|
||||
result.textColor = Theme.primaryColor
|
||||
result.font = UIFont.ows_dynamicTypeHeadlineClamped
|
||||
result.text = NSLocalizedString("Waiting for Device", comment: "")
|
||||
result.numberOfLines = 0
|
||||
result.lineBreakMode = .byWordWrapping
|
||||
result.textAlignment = .center
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var subtitleLabel: UILabel = {
|
||||
let result = UILabel()
|
||||
result.textColor = Theme.primaryColor
|
||||
result.font = UIFont.ows_dynamicTypeCaption1Clamped
|
||||
result.text = NSLocalizedString("Click the \"Link Device\" button on your other device to start the linking process", comment: "")
|
||||
result.numberOfLines = 0
|
||||
result.lineBreakMode = .byWordWrapping
|
||||
result.textAlignment = .center
|
||||
return result
|
||||
}()
|
||||
|
||||
private lazy var cancelButton: OWSFlatButton = {
|
||||
let result = OWSFlatButton.button(title: NSLocalizedString("Cancel", comment: ""), font: .ows_dynamicTypeBodyClamped, titleColor: .white, backgroundColor: .clear, target: self, selector: #selector(cancel))
|
||||
result.setBackgroundColors(upColor: .clear, downColor: .clear)
|
||||
return result
|
||||
}()
|
||||
|
||||
// MARK: Lifecycle
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setUpViewHierarchy()
|
||||
deviceLinkingSession.startListeningForLinkingRequests()
|
||||
}
|
||||
|
||||
private func setUpViewHierarchy() {
|
||||
view.backgroundColor = .clear
|
||||
// Content view
|
||||
view.addSubview(contentView)
|
||||
contentView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32),
|
||||
view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: 32),
|
||||
contentView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
])
|
||||
// Spinner
|
||||
contentView.addSubview(spinner)
|
||||
spinner.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
spinner.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
|
||||
spinner.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 32),
|
||||
spinner.heightAnchor.constraint(equalToConstant: 64),
|
||||
spinner.widthAnchor.constraint(equalToConstant: 64)
|
||||
])
|
||||
spinner.startAnimating()
|
||||
// Title label
|
||||
contentView.addSubview(titleLabel)
|
||||
titleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
||||
titleLabel.topAnchor.constraint(equalTo: spinner.bottomAnchor, constant: 32),
|
||||
contentView.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 16)
|
||||
])
|
||||
// Subtitle label
|
||||
contentView.addSubview(subtitleLabel)
|
||||
subtitleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
subtitleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
||||
subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 16),
|
||||
contentView.trailingAnchor.constraint(equalTo: subtitleLabel.trailingAnchor, constant: 16)
|
||||
])
|
||||
// Cancel button
|
||||
contentView.addSubview(cancelButton)
|
||||
cancelButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
let cancelButtonHeight = cancelButton.button.titleLabel!.font.pointSize * 48 / 17
|
||||
NSLayoutConstraint.activate([
|
||||
cancelButton.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
||||
cancelButton.topAnchor.constraint(equalTo: subtitleLabel.bottomAnchor, constant: 16),
|
||||
contentView.trailingAnchor.constraint(equalTo: cancelButton.trailingAnchor, constant: 16),
|
||||
contentView.bottomAnchor.constraint(equalTo: cancelButton.bottomAnchor, constant: 16),
|
||||
cancelButton.heightAnchor.constraint(equalToConstant: cancelButtonHeight)
|
||||
])
|
||||
}
|
||||
|
||||
// MARK: Device Linking
|
||||
func requestUserAuthorization(for deviceLink: LokiDeviceLink) {
|
||||
|
||||
}
|
||||
|
||||
func handleDeviceLinkingSessionTimeout() {
|
||||
|
||||
}
|
||||
|
||||
// MARK: Interaction
|
||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
let touch = touches.first!
|
||||
let location = touch.location(in: view)
|
||||
if contentView.frame.contains(location) {
|
||||
super.touchesBegan(touches, with: event)
|
||||
} else {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func cancel() {
|
||||
dismiss(animated: true, completion: nil)
|
||||
}
|
||||
}
|
|
@ -514,7 +514,9 @@
|
|||
|
||||
- (void)linkDevice
|
||||
{
|
||||
|
||||
LKDeviceLinkingModal *deviceLinkingModal = [LKDeviceLinkingModal new];
|
||||
deviceLinkingModal.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||
[self presentViewController:deviceLinkingModal animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)showSeed
|
||||
|
|
|
@ -2622,3 +2622,5 @@
|
|||
"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.";
|
||||
"Copy Public Key" = "Copy Public Key";
|
||||
"Link Device" = "Link Device";
|
||||
"Waiting for Device" = "Waiting for Device";
|
||||
"Click the \"Link Device\" button on your other device to start the linking process" = "Click the \"Link Device\" button on your other device to start the linking process";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import PromiseKit
|
||||
|
||||
@objc (LKDeviceLinkingSession)
|
||||
final class LokiDeviceLinkingSession : NSObject {
|
||||
public final class LokiDeviceLinkingSession : NSObject {
|
||||
private let delegate: LokiDeviceLinkingSessionDelegate
|
||||
private var timer: Timer?
|
||||
@objc public var isListeningForLinkingRequests = false
|
||||
|
|
Loading…
Reference in a new issue