mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Passkeys
This commit is contained in:
parent
2e279e8fd3
commit
62d29ee551
6 changed files with 84 additions and 13 deletions
|
|
@ -1475,7 +1475,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||
func makeNewContactScreen(context: AccountContext, peer: EnginePeer?, phoneNumber: String?, shareViaException: Bool, completion: @escaping (EnginePeer?, DeviceContactStableId?, DeviceContactExtendedData?) -> Void) -> ViewController
|
||||
|
||||
func makeLoginEmailSetupController(context: AccountContext, blocking: Bool, emailPattern: String?, canAutoDismissIfNeeded: Bool, navigationController: NavigationController?, completion: @escaping () -> Void, dismiss: @escaping () -> Void) -> ViewController
|
||||
public func makePasskeySetupController(context: AccountContext, displaySkip: Bool, navigationController: NavigationController?, completion: @escaping () -> Void, dismiss: completion: @escaping () -> Void) -> ViewController
|
||||
func makePasskeySetupController(context: AccountContext, displaySkip: Bool, navigationController: NavigationController?, completion: @escaping () -> Void, dismiss: @escaping () -> Void) -> ViewController
|
||||
|
||||
func navigateToCurrentCall()
|
||||
var hasOngoingCall: ValuePromise<Bool> { get }
|
||||
|
|
|
|||
|
|
@ -2604,11 +2604,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
}, dismiss: {
|
||||
let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: ServerProvidedSuggestion.setupPasskey.id).startStandalone()
|
||||
})
|
||||
if let layout = strongSelf.validLayout, layout.metrics.isTablet {
|
||||
controller.navigationPresentation = .standaloneFlatModal
|
||||
} else {
|
||||
controller.navigationPresentation = .flatModal
|
||||
}
|
||||
navigationController.pushViewController(controller)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1268,9 +1268,9 @@ public func privacyAndSecurityController(
|
|||
}, openPasskeys: {
|
||||
Task { @MainActor in
|
||||
let initialPasskeysData = await (passkeysDataValue.get() |> take(1)).get()
|
||||
let passkeysScreen = await PasskeysScreen(context: context, initialPasskeysData: initialPasskeysData, passkeysDataUpdated: { passkeysData in
|
||||
let passkeysScreen = PasskeysScreen(context: context, displaySkip: false, initialPasskeysData: initialPasskeysData, passkeysDataUpdated: { passkeysData in
|
||||
passkeysDataValue.set(.single(passkeysData))
|
||||
})
|
||||
}, completion: {}, cancel: {})
|
||||
pushControllerImpl?(passkeysScreen, true)
|
||||
}
|
||||
}, openActiveSessions: {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ final class PasskeysScreenComponent: Component {
|
|||
class View: UIView, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
||||
private var intro: ComponentView<Empty>?
|
||||
private var list: ComponentView<Empty>?
|
||||
private var activityIndicator: UIActivityIndicatorView?
|
||||
|
||||
private var component: PasskeysScreenComponent?
|
||||
private var environment: EnvironmentType?
|
||||
|
|
@ -168,6 +169,8 @@ final class PasskeysScreenComponent: Component {
|
|||
authController.delegate = self
|
||||
authController.presentationContextProvider = self
|
||||
authController.performRequests()
|
||||
|
||||
component.completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -264,11 +267,19 @@ final class PasskeysScreenComponent: Component {
|
|||
context: component.context,
|
||||
theme: environment.theme,
|
||||
insets: UIEdgeInsets(top: environment.statusBarHeight + environment.navigationHeight, left: 0.0, bottom: environment.safeInsets.bottom, right: 0.0),
|
||||
displaySkip: component.displaySkip,
|
||||
createPasskeyAction: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.createPasskey()
|
||||
},
|
||||
skipAction: { [weak self] in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.cancel()
|
||||
self.environment?.controller()?.dismiss()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
|
|
@ -346,6 +357,27 @@ final class PasskeysScreenComponent: Component {
|
|||
}
|
||||
}
|
||||
|
||||
if self.passkeysData == nil {
|
||||
let activityIndicator: UIActivityIndicatorView
|
||||
if let current = self.activityIndicator {
|
||||
activityIndicator = current
|
||||
} else {
|
||||
activityIndicator = UIActivityIndicatorView(style: .large)
|
||||
self.activityIndicator = activityIndicator
|
||||
self.addSubview(activityIndicator)
|
||||
}
|
||||
activityIndicator.tintColor = environment.theme.list.itemPrimaryTextColor
|
||||
|
||||
let indicatorSize = activityIndicator.bounds.size
|
||||
activityIndicator.frame = CGRect(origin: CGPoint(x: floor((availableSize.width - indicatorSize.width) / 2.0), y: floor((availableSize.height - indicatorSize.height) / 2.0)), size: indicatorSize)
|
||||
if !activityIndicator.isAnimating {
|
||||
activityIndicator.startAnimating()
|
||||
}
|
||||
} else if let activityIndicator = self.activityIndicator {
|
||||
self.activityIndicator = nil
|
||||
activityIndicator.removeFromSuperview()
|
||||
}
|
||||
|
||||
return availableSize
|
||||
}
|
||||
}
|
||||
|
|
@ -362,10 +394,10 @@ final class PasskeysScreenComponent: Component {
|
|||
public final class PasskeysScreen: ViewControllerComponentContainer {
|
||||
private let context: AccountContext
|
||||
|
||||
public init(context: AccountContext, displaySkip: Bool, initialPasskeysData: [TelegramPasskey]?, passkeysDataUpdated: @escaping ([TelegramPasskey]) -> Void, completion: @escaping () -> Void, cancel: @escaping () -> Void) async {
|
||||
public init(context: AccountContext, displaySkip: Bool, initialPasskeysData: [TelegramPasskey]?, passkeysDataUpdated: @escaping ([TelegramPasskey]) -> Void, completion: @escaping () -> Void, cancel: @escaping () -> Void) {
|
||||
self.context = context
|
||||
|
||||
super.init(context: context, component: PasskeysScreenComponent(context: context, displaySkip: displaySkip, initialPasskeysData: initialPasskeysData, passkeysDataUpdated: passkeysDataUpdated), navigationBarAppearance: .transparent)
|
||||
super.init(context: context, component: PasskeysScreenComponent(context: context, displaySkip: displaySkip, initialPasskeysData: initialPasskeysData, passkeysDataUpdated: passkeysDataUpdated, completion: completion, cancel: cancel), navigationBarAppearance: .transparent)
|
||||
}
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
|
|
|
|||
|
|
@ -16,19 +16,22 @@ final class PasskeysScreenIntroComponent: Component {
|
|||
let insets: UIEdgeInsets
|
||||
let displaySkip: Bool
|
||||
let createPasskeyAction: () -> Void
|
||||
let skipAction: () -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
theme: PresentationTheme,
|
||||
insets: UIEdgeInsets,
|
||||
displaySkip: Bool,
|
||||
createPasskeyAction: @escaping () -> Void
|
||||
createPasskeyAction: @escaping () -> Void,
|
||||
skipAction: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
self.insets = insets
|
||||
self.displaySkip = displaySkip
|
||||
self.createPasskeyAction = createPasskeyAction
|
||||
self.skipAction = skipAction
|
||||
}
|
||||
|
||||
static func ==(lhs: PasskeysScreenIntroComponent, rhs: PasskeysScreenIntroComponent) -> Bool {
|
||||
|
|
@ -300,14 +303,55 @@ final class PasskeysScreenIntroComponent: Component {
|
|||
containerSize: CGSize(width: availableSize.width - buttonInsets.left - buttonInsets.right, height: 52.0)
|
||||
)
|
||||
|
||||
var skipButtonSize: CGSize?
|
||||
if component.displaySkip {
|
||||
let skipButton: ComponentView<Empty>
|
||||
if let current = self.skipButton {
|
||||
skipButton = current
|
||||
} else {
|
||||
skipButton = ComponentView()
|
||||
self.skipButton = skipButton
|
||||
}
|
||||
//TODO:localize
|
||||
skipButtonSize = skipButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ButtonComponent(
|
||||
background: ButtonComponent.Background(
|
||||
style: .glass,
|
||||
color: component.theme.chatList.unreadBadgeInactiveBackgroundColor,
|
||||
foreground: component.theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: component.theme.chatList.unreadBadgeInactiveBackgroundColor.withMultipliedAlpha(0.9),
|
||||
cornerRadius: 52.0 * 0.5
|
||||
),
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: "Skip", font: Font.semibold(17.0), textColor: component.theme.list.itemCheckColors.foregroundColor))))
|
||||
),
|
||||
action: { [weak self] in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.skipAction()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - buttonInsets.left - buttonInsets.right, height: 52.0)
|
||||
)
|
||||
} else if let skipButton = self.skipButton {
|
||||
self.skipButton = nil
|
||||
skipButton.view?.removeFromSuperview()
|
||||
}
|
||||
|
||||
let buttonFrame = CGRect(origin: CGPoint(x: buttonInsets.left, y: availableSize.height - buttonInsets.bottom - actionButtonSize.height), size: actionButtonSize)
|
||||
var buttonFrame = CGRect(origin: CGPoint(x: buttonInsets.left, y: availableSize.height - buttonInsets.bottom - actionButtonSize.height), size: actionButtonSize)
|
||||
if let skipButtonSize, let skipButtonView = self.skipButton?.view {
|
||||
let skipButtonFrame = buttonFrame
|
||||
buttonFrame = buttonFrame.offsetBy(dx: 0.0, dy: -8.0 - skipButtonSize.height)
|
||||
|
||||
if skipButtonView.superview == nil {
|
||||
self.addSubview(skipButtonView)
|
||||
}
|
||||
transition.setFrame(view: skipButtonView, frame: skipButtonFrame)
|
||||
}
|
||||
|
||||
if let actionButtonView = self.actionButton.view {
|
||||
if actionButtonView.superview == nil {
|
||||
|
|
|
|||
|
|
@ -4065,7 +4065,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
return loginEmailSetupController(context: context, blocking: blocking, emailPattern: emailPattern, canAutoDismissIfNeeded: canAutoDismissIfNeeded, navigationController: navigationController, completion: completion, dismiss: dismiss)
|
||||
}
|
||||
|
||||
public func makePasskeySetupController(context: AccountContext, displaySkip: Bool, navigationController: NavigationController?, completion: @escaping () -> Void, dismiss: completion: @escaping () -> Void) -> ViewController {
|
||||
public func makePasskeySetupController(context: AccountContext, displaySkip: Bool, navigationController: NavigationController?, completion: @escaping () -> Void, dismiss: @escaping () -> Void) -> ViewController {
|
||||
return PasskeysScreen(context: context, displaySkip: displaySkip, initialPasskeysData: nil, passkeysDataUpdated: { _ in }, completion: completion, cancel: dismiss)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue