mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-05 05:51:42 +00:00
Merge commit 'df07c2a5bb8bf2d10a023d9accba5e1144115bc7'
This commit is contained in:
commit
8f2a7327d7
@ -7441,6 +7441,7 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"WebApp.AddToAttachmentUnavailableError" = "This bot can't be added to the attachment menu.";
|
"WebApp.AddToAttachmentUnavailableError" = "This bot can't be added to the attachment menu.";
|
||||||
"WebApp.AddToAttachmentAlreadyAddedError" = "This bot is already added to your attachment menu.";
|
"WebApp.AddToAttachmentAlreadyAddedError" = "This bot is already added to your attachment menu.";
|
||||||
|
"WebApp.AddToAttachmentSucceeded" = "**%@** has been added to your attachment menu.";
|
||||||
|
|
||||||
"WebApp.OpenWebViewAlertTitle" = "Open Web App";
|
"WebApp.OpenWebViewAlertTitle" = "Open Web App";
|
||||||
"WebApp.OpenWebViewAlertText" = "**%@** would like to open its web app to proceed.\n\nIt will be able to access your **IP address** and basic device info.";
|
"WebApp.OpenWebViewAlertText" = "**%@** would like to open its web app to proceed.\n\nIt will be able to access your **IP address** and basic device info.";
|
||||||
@ -7968,4 +7969,6 @@ Sorry for the inconvenience.";
|
|||||||
"Login.Edit" = "Edit";
|
"Login.Edit" = "Edit";
|
||||||
"Login.Yes" = "Yes";
|
"Login.Yes" = "Yes";
|
||||||
|
|
||||||
|
"Checkout.PaymentLiabilityBothAlert" = "Telegram will not have access to your credit card information. Credit card details will be handled only by the payment system, {target}.\n\nPayments will go directly to the developer of {target}. Telegram cannot provide any guarantees, so proceed at your own risk. In case of problems, please contact the developer of {target} or your bank.";
|
||||||
|
|
||||||
"Settings.ChangeProfilePhoto" = "Change Profile Photo";
|
"Settings.ChangeProfilePhoto" = "Change Profile Photo";
|
||||||
|
|||||||
@ -151,10 +151,12 @@ public struct ChatControllerInitialBotStart {
|
|||||||
public struct ChatControllerInitialAttachBotStart {
|
public struct ChatControllerInitialAttachBotStart {
|
||||||
public let botId: PeerId
|
public let botId: PeerId
|
||||||
public let payload: String?
|
public let payload: String?
|
||||||
|
public let justInstalled: Bool
|
||||||
|
|
||||||
public init(botId: PeerId, payload: String?) {
|
public init(botId: PeerId, payload: String?, justInstalled: Bool) {
|
||||||
self.botId = botId
|
self.botId = botId
|
||||||
self.payload = payload
|
self.payload = payload
|
||||||
|
self.justInstalled = justInstalled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,8 @@ public struct AuthorizationLayoutItemSpacing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct AuthorizationLayoutItem {
|
public struct AuthorizationLayoutItem {
|
||||||
public var node: ASDisplayNode
|
public var node: ASDisplayNode?
|
||||||
|
public var view: UIView?
|
||||||
public var size: CGSize
|
public var size: CGSize
|
||||||
public var spacingBefore: AuthorizationLayoutItemSpacing
|
public var spacingBefore: AuthorizationLayoutItemSpacing
|
||||||
public var spacingAfter: AuthorizationLayoutItemSpacing
|
public var spacingAfter: AuthorizationLayoutItemSpacing
|
||||||
@ -25,6 +26,14 @@ public struct AuthorizationLayoutItem {
|
|||||||
self.spacingBefore = spacingBefore
|
self.spacingBefore = spacingBefore
|
||||||
self.spacingAfter = spacingAfter
|
self.spacingAfter = spacingAfter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public init(view: UIView, size: CGSize, spacingBefore: AuthorizationLayoutItemSpacing, spacingAfter: AuthorizationLayoutItemSpacing) {
|
||||||
|
self.view = view
|
||||||
|
self.size = size
|
||||||
|
self.spacingBefore = spacingBefore
|
||||||
|
self.spacingAfter = spacingAfter
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class SolvedAuthorizationLayoutItem {
|
public final class SolvedAuthorizationLayoutItem {
|
||||||
@ -147,7 +156,12 @@ public func layoutAuthorizationItems(bounds: CGRect, items: [AuthorizationLayout
|
|||||||
for i in 0 ..< solvedItems.count {
|
for i in 0 ..< solvedItems.count {
|
||||||
let item = solvedItems[i]
|
let item = solvedItems[i]
|
||||||
verticalOrigin += item.spacingBefore!
|
verticalOrigin += item.spacingBefore!
|
||||||
transition.updateFrame(node: item.item.node, frame: CGRect(origin: CGPoint(x: floor((bounds.size.width - item.item.size.width) / 2.0), y: verticalOrigin), size: item.item.size))
|
let itemFrame = CGRect(origin: CGPoint(x: floor((bounds.size.width - item.item.size.width) / 2.0), y: verticalOrigin), size: item.item.size)
|
||||||
|
if let view = item.item.view {
|
||||||
|
transition.updateFrame(view: view, frame: itemFrame)
|
||||||
|
} else if let node = item.item.node {
|
||||||
|
transition.updateFrame(node: node, frame: itemFrame)
|
||||||
|
}
|
||||||
verticalOrigin += item.item.size.height
|
verticalOrigin += item.item.size.height
|
||||||
verticalOrigin += item.spacingAfter!
|
verticalOrigin += item.spacingAfter!
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1464,9 +1464,15 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||||||
if value {
|
if value {
|
||||||
strongSelf.pay(savedCredentialsToken: savedCredentialsToken, liabilityNoticeAccepted: true)
|
strongSelf.pay(savedCredentialsToken: savedCredentialsToken, liabilityNoticeAccepted: true)
|
||||||
} else {
|
} else {
|
||||||
let paymentText = strongSelf.presentationData.strings.Checkout_PaymentLiabilityAlert
|
let paymentText: String
|
||||||
|
if botPeer.id == providerPeer?.id {
|
||||||
|
paymentText = strongSelf.presentationData.strings.Checkout_PaymentLiabilityBothAlert
|
||||||
|
.replacingOccurrences(of: "{target}", with: botPeer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder))
|
||||||
|
} else {
|
||||||
|
paymentText = strongSelf.presentationData.strings.Checkout_PaymentLiabilityAlert
|
||||||
.replacingOccurrences(of: "{target}", with: botPeer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder))
|
.replacingOccurrences(of: "{target}", with: botPeer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder))
|
||||||
.replacingOccurrences(of: "{payment_system}", with: providerPeer?.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder) ?? "")
|
.replacingOccurrences(of: "{payment_system}", with: providerPeer?.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder) ?? "")
|
||||||
|
}
|
||||||
|
|
||||||
strongSelf.present(textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Checkout_LiabilityAlertTitle, text: paymentText, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
strongSelf.present(textAlertController(context: strongSelf.context, title: strongSelf.presentationData.strings.Checkout_LiabilityAlertTitle, text: paymentText, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: { }), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
|||||||
@ -1,57 +0,0 @@
|
|||||||
//import Foundation
|
|
||||||
//import UIKit
|
|
||||||
//import SwiftSignalKit
|
|
||||||
//import Postbox
|
|
||||||
//import TelegramCore
|
|
||||||
//import TelegramUIPreferences
|
|
||||||
//
|
|
||||||
//final class StoredTransactionState: Codable {
|
|
||||||
// let timestamp: Double
|
|
||||||
// let playbackRate: AudioPlaybackRate
|
|
||||||
//
|
|
||||||
// init(timestamp: Double, playbackRate: AudioPlaybackRate) {
|
|
||||||
// self.timestamp = timestamp
|
|
||||||
// self.playbackRate = playbackRate
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public init(from decoder: Decoder) throws {
|
|
||||||
// let container = try decoder.container(keyedBy: StringCodingKey.self)
|
|
||||||
//
|
|
||||||
// self.timestamp = try container.decode(Double.self, forKey: "timestamp")
|
|
||||||
// self.playbackRate = AudioPlaybackRate(rawValue: try container.decode(Int32.self, forKey: "playbackRate")) ?? .x1
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public func encode(to encoder: Encoder) throws {
|
|
||||||
// var container = encoder.container(keyedBy: StringCodingKey.self)
|
|
||||||
//
|
|
||||||
// try container.encode(self.timestamp, forKey: "timestamp")
|
|
||||||
// try container.encode(self.playbackRate.rawValue, forKey: "playbackRate")
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//public func storedState(engine: TelegramEngine, : MessageId) -> Signal<MediaPlaybackStoredState?, NoError> {
|
|
||||||
// let key = ValueBoxKey(length: 20)
|
|
||||||
// key.setInt32(0, value: messageId.namespace)
|
|
||||||
// key.setInt32(4, value: messageId.peerId.namespace._internalGetInt32Value())
|
|
||||||
// key.setInt64(8, value: messageId.peerId.id._internalGetInt64Value())
|
|
||||||
// key.setInt32(16, value: messageId.id)
|
|
||||||
//
|
|
||||||
// return engine.data.get(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.mediaPlaybackStoredState, id: key))
|
|
||||||
// |> map { entry -> MediaPlaybackStoredState? in
|
|
||||||
// return entry?.get(MediaPlaybackStoredState.self)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//public func updateMediaPlaybackStoredStateInteractively(engine: TelegramEngine, messageId: MessageId, state: MediaPlaybackStoredState?) -> Signal<Never, NoError> {
|
|
||||||
// let key = ValueBoxKey(length: 20)
|
|
||||||
// key.setInt32(0, value: messageId.namespace)
|
|
||||||
// key.setInt32(4, value: messageId.peerId.namespace._internalGetInt32Value())
|
|
||||||
// key.setInt64(8, value: messageId.peerId.id._internalGetInt64Value())
|
|
||||||
// key.setInt32(16, value: messageId.id)
|
|
||||||
//
|
|
||||||
// if let state = state {
|
|
||||||
// return engine.itemCache.put(collectionId: ApplicationSpecificItemCacheCollectionId.mediaPlaybackStoredState, id: key, item: state)
|
|
||||||
// } else {
|
|
||||||
// return engine.itemCache.remove(collectionId: ApplicationSpecificItemCacheCollectionId.mediaPlaybackStoredState, id: key)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 9.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 9.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 6.7 KiB |
@ -364,7 +364,7 @@ public func sendLoginEmailCode(account: UnauthorizedAccount, email: String) -> S
|
|||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
}
|
}
|
||||||
|
|
||||||
public func verifyLoginEmail(account: UnauthorizedAccount, code: AuthorizationCode.EmailVerification) -> Signal<Never, AuthorizationEmailVerificationError> {
|
public func verifyLoginEmailSetup(account: UnauthorizedAccount, code: AuthorizationCode.EmailVerification) -> Signal<Never, AuthorizationEmailVerificationError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Never, AuthorizationEmailVerificationError> in
|
return account.postbox.transaction { transaction -> Signal<Never, AuthorizationEmailVerificationError> in
|
||||||
if let state = transaction.getState() as? UnauthorizedAccountState {
|
if let state = transaction.getState() as? UnauthorizedAccountState {
|
||||||
switch state.contents {
|
switch state.contents {
|
||||||
|
|||||||
@ -16,6 +16,8 @@ final class AuthorizationSequenceCodeEntryController: ViewController {
|
|||||||
private let openUrl: (String) -> Void
|
private let openUrl: (String) -> Void
|
||||||
|
|
||||||
var loginWithCode: ((String) -> Void)?
|
var loginWithCode: ((String) -> Void)?
|
||||||
|
var signInWithApple: (() -> Void)?
|
||||||
|
|
||||||
var reset: (() -> Void)?
|
var reset: (() -> Void)?
|
||||||
var requestNextOption: (() -> Void)?
|
var requestNextOption: (() -> Void)?
|
||||||
|
|
||||||
@ -24,6 +26,8 @@ final class AuthorizationSequenceCodeEntryController: ViewController {
|
|||||||
|
|
||||||
private let hapticFeedback = HapticFeedback()
|
private let hapticFeedback = HapticFeedback()
|
||||||
|
|
||||||
|
private var appleSignInAllowed = false
|
||||||
|
|
||||||
var inProgress: Bool = false {
|
var inProgress: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
if self.inProgress {
|
if self.inProgress {
|
||||||
@ -76,6 +80,10 @@ final class AuthorizationSequenceCodeEntryController: ViewController {
|
|||||||
self?.continueWithCode(code)
|
self?.continueWithCode(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.controllerNode.signInWithApple = { [weak self] in
|
||||||
|
self?.signInWithApple?()
|
||||||
|
}
|
||||||
|
|
||||||
self.controllerNode.requestNextOption = { [weak self] in
|
self.controllerNode.requestNextOption = { [weak self] in
|
||||||
self?.requestNextOption?()
|
self?.requestNextOption?()
|
||||||
}
|
}
|
||||||
@ -89,7 +97,11 @@ final class AuthorizationSequenceCodeEntryController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let (number, codeType, nextType, timeout) = self.data {
|
if let (number, codeType, nextType, timeout) = self.data {
|
||||||
self.controllerNode.updateData(number: number, codeType: codeType, nextType: nextType, timeout: timeout)
|
var appleSignInAllowed = false
|
||||||
|
if case let .email(_, _, _, appleSignInAllowedValue, _) = codeType {
|
||||||
|
appleSignInAllowed = appleSignInAllowedValue
|
||||||
|
}
|
||||||
|
self.controllerNode.updateData(number: number, codeType: codeType, nextType: nextType, timeout: timeout, appleSignInAllowed: appleSignInAllowed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,8 +125,14 @@ final class AuthorizationSequenceCodeEntryController: ViewController {
|
|||||||
self.title = nil
|
self.title = nil
|
||||||
}
|
}
|
||||||
self.data = (number, codeType, nextType, timeout)
|
self.data = (number, codeType, nextType, timeout)
|
||||||
|
|
||||||
|
var appleSignInAllowed = false
|
||||||
|
if case let .email(_, _, _, appleSignInAllowedValue, _) = codeType {
|
||||||
|
appleSignInAllowed = appleSignInAllowedValue
|
||||||
|
}
|
||||||
|
|
||||||
if self.isNodeLoaded {
|
if self.isNodeLoaded {
|
||||||
self.controllerNode.updateData(number: number, codeType: codeType, nextType: nextType, timeout: timeout)
|
self.controllerNode.updateData(number: number, codeType: codeType, nextType: nextType, timeout: timeout, appleSignInAllowed: appleSignInAllowed)
|
||||||
self.requestLayout(transition: .immediate)
|
self.requestLayout(transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import SwiftSignalKit
|
|||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import TextFormat
|
import TextFormat
|
||||||
import AuthorizationUI
|
import AuthorizationUI
|
||||||
|
import AuthenticationServices
|
||||||
import CodeInputView
|
import CodeInputView
|
||||||
import PhoneNumberFormat
|
import PhoneNumberFormat
|
||||||
import AnimatedStickerNode
|
import AnimatedStickerNode
|
||||||
@ -25,6 +26,9 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
private let nextOptionTitleNode: ImmediateTextNode
|
private let nextOptionTitleNode: ImmediateTextNode
|
||||||
private let nextOptionButtonNode: HighlightableButtonNode
|
private let nextOptionButtonNode: HighlightableButtonNode
|
||||||
|
|
||||||
|
private let dividerNode: AuthorizationDividerNode
|
||||||
|
private var signInWithAppleButton: UIControl?
|
||||||
|
|
||||||
private let codeInputView: CodeInputView
|
private let codeInputView: CodeInputView
|
||||||
|
|
||||||
private var codeType: SentAuthorizationCodeType?
|
private var codeType: SentAuthorizationCodeType?
|
||||||
@ -34,6 +38,8 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
|
|
||||||
private var layoutArguments: (ContainerViewLayout, CGFloat)?
|
private var layoutArguments: (ContainerViewLayout, CGFloat)?
|
||||||
|
|
||||||
|
private var appleSignInAllowed = false
|
||||||
|
|
||||||
var phoneNumber: String = "" {
|
var phoneNumber: String = "" {
|
||||||
didSet {
|
didSet {
|
||||||
if self.phoneNumber != oldValue {
|
if self.phoneNumber != oldValue {
|
||||||
@ -49,6 +55,8 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
}
|
}
|
||||||
|
|
||||||
var loginWithCode: ((String) -> Void)?
|
var loginWithCode: ((String) -> Void)?
|
||||||
|
var signInWithApple: (() -> Void)?
|
||||||
|
|
||||||
var requestNextOption: (() -> Void)?
|
var requestNextOption: (() -> Void)?
|
||||||
var requestAnotherOption: (() -> Void)?
|
var requestAnotherOption: (() -> Void)?
|
||||||
var updateNextEnabled: ((Bool) -> Void)?
|
var updateNextEnabled: ((Bool) -> Void)?
|
||||||
@ -106,6 +114,13 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
self.codeInputView.textField.keyboardType = .numberPad
|
self.codeInputView.textField.keyboardType = .numberPad
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.dividerNode = AuthorizationDividerNode(theme: self.theme, strings: self.strings)
|
||||||
|
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
self.signInWithAppleButton = ASAuthorizationAppleIDButton(authorizationButtonType: .signIn, authorizationButtonStyle: theme.overallDarkAppearance ? .white : .black)
|
||||||
|
(self.signInWithAppleButton as? ASAuthorizationAppleIDButton)?.cornerRadius = 11
|
||||||
|
}
|
||||||
|
|
||||||
/*self.codeField = TextFieldNode()
|
/*self.codeField = TextFieldNode()
|
||||||
self.codeField.textField.font = Font.regular(24.0)
|
self.codeField.textField.font = Font.regular(24.0)
|
||||||
self.codeField.textField.textAlignment = .center
|
self.codeField.textField.textAlignment = .center
|
||||||
@ -140,6 +155,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
self.addSubnode(self.currentOptionInfoNode)
|
self.addSubnode(self.currentOptionInfoNode)
|
||||||
self.addSubnode(self.nextOptionButtonNode)
|
self.addSubnode(self.nextOptionButtonNode)
|
||||||
self.addSubnode(self.animationNode)
|
self.addSubnode(self.animationNode)
|
||||||
|
self.addSubnode(self.dividerNode)
|
||||||
|
|
||||||
self.codeInputView.updated = { [weak self] in
|
self.codeInputView.updated = { [weak self] in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
@ -154,12 +170,21 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
//self.codeField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_Code, font: Font.regular(24.0), textColor: self.theme.list.itemPlaceholderTextColor)
|
//self.codeField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_Code, font: Font.regular(24.0), textColor: self.theme.list.itemPlaceholderTextColor)
|
||||||
|
|
||||||
self.nextOptionButtonNode.addTarget(self, action: #selector(self.nextOptionNodePressed), forControlEvents: .touchUpInside)
|
self.nextOptionButtonNode.addTarget(self, action: #selector(self.nextOptionNodePressed), forControlEvents: .touchUpInside)
|
||||||
|
self.signInWithAppleButton?.addTarget(self, action: #selector(self.signInWithApplePressed), for: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.countdownDisposable.dispose()
|
self.countdownDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
|
||||||
|
if let signInWithAppleButton = self.signInWithAppleButton {
|
||||||
|
self.view.addSubview(signInWithAppleButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updateCode(_ code: String) {
|
func updateCode(_ code: String) {
|
||||||
self.codeInputView.text = code
|
self.codeInputView.text = code
|
||||||
self.textChanged(text: code)
|
self.textChanged(text: code)
|
||||||
@ -189,10 +214,17 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
self.codeInputView.text = ""
|
self.codeInputView.text = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateData(number: String, codeType: SentAuthorizationCodeType, nextType: AuthorizationCodeNextType?, timeout: Int32?) {
|
func updateData(number: String, codeType: SentAuthorizationCodeType, nextType: AuthorizationCodeNextType?, timeout: Int32?, appleSignInAllowed: Bool) {
|
||||||
self.codeType = codeType
|
self.codeType = codeType
|
||||||
self.phoneNumber = number
|
self.phoneNumber = number
|
||||||
|
|
||||||
|
var appleSignInAllowed = appleSignInAllowed
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
} else {
|
||||||
|
appleSignInAllowed = false
|
||||||
|
}
|
||||||
|
self.appleSignInAllowed = appleSignInAllowed
|
||||||
|
|
||||||
self.currentOptionNode.attributedText = authorizationCurrentOptionText(codeType, strings: self.strings, primaryColor: self.theme.list.itemPrimaryTextColor, accentColor: self.theme.list.itemAccentColor)
|
self.currentOptionNode.attributedText = authorizationCurrentOptionText(codeType, strings: self.strings, primaryColor: self.theme.list.itemPrimaryTextColor, accentColor: self.theme.list.itemAccentColor)
|
||||||
if case .missedCall = codeType {
|
if case .missedCall = codeType {
|
||||||
self.currentOptionInfoNode.attributedText = NSAttributedString(string: self.strings.Login_CodePhonePatternInfoText, font: Font.regular(16.0), textColor: self.theme.list.itemPrimaryTextColor, paragraphAlignment: .center)
|
self.currentOptionInfoNode.attributedText = NSAttributedString(string: self.strings.Login_CodePhonePatternInfoText, font: Font.regular(16.0), textColor: self.theme.list.itemPrimaryTextColor, paragraphAlignment: .center)
|
||||||
@ -395,8 +427,22 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
/*items.append(AuthorizationLayoutItem(node: self.codeField, size: CGSize(width: layout.size.width - 88.0, height: 44.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 40.0, maxValue: 100.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
/*items.append(AuthorizationLayoutItem(node: self.codeField, size: CGSize(width: layout.size.width - 88.0, height: 44.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 40.0, maxValue: 100.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
items.append(AuthorizationLayoutItem(node: self.codeSeparatorNode, size: CGSize(width: layout.size.width - 88.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))*/
|
items.append(AuthorizationLayoutItem(node: self.codeSeparatorNode, size: CGSize(width: layout.size.width - 88.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))*/
|
||||||
|
|
||||||
|
if self.appleSignInAllowed, let signInWithAppleButton = self.signInWithAppleButton {
|
||||||
|
self.nextOptionButtonNode.isHidden = true
|
||||||
|
signInWithAppleButton.isHidden = false
|
||||||
|
|
||||||
|
let dividerSize = self.dividerNode.updateLayout(width: layout.size.width)
|
||||||
|
items.append(AuthorizationLayoutItem(node: self.dividerNode, size: dividerSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 50.0, maxValue: 120.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
|
||||||
|
let buttonSize = CGSize(width: layout.size.width - 48.0, height: 50.0)
|
||||||
|
items.append(AuthorizationLayoutItem(view: signInWithAppleButton, size: buttonSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 10.0, maxValue: 10.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
} else {
|
||||||
|
self.signInWithAppleButton?.isHidden = true
|
||||||
|
self.dividerNode.isHidden = true
|
||||||
|
self.nextOptionButtonNode.isHidden = false
|
||||||
items.append(AuthorizationLayoutItem(node: self.nextOptionButtonNode, size: nextOptionSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 50.0, maxValue: 120.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.nextOptionButtonNode, size: nextOptionSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 50.0, maxValue: 120.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.titleIconNode.isHidden = true
|
self.titleIconNode.isHidden = true
|
||||||
items.append(AuthorizationLayoutItem(node: self.titleNode, size: titleSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.titleNode, size: titleSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
@ -476,4 +522,8 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
@objc func nextOptionNodePressed() {
|
@objc func nextOptionNodePressed() {
|
||||||
self.requestAnotherOption?()
|
self.requestAnotherOption?()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func signInWithApplePressed() {
|
||||||
|
self.signInWithApple?()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -294,7 +294,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
}
|
}
|
||||||
|
|
||||||
if case let .email(_, _, _, _, setup) = type, setup, case let .emailVerification(emailCode) = authorizationCode {
|
if case let .email(_, _, _, _, setup) = type, setup, case let .emailVerification(emailCode) = authorizationCode {
|
||||||
strongSelf.actionDisposable.set(((verifyLoginEmail(account: strongSelf.account, code: emailCode))
|
strongSelf.actionDisposable.set(((verifyLoginEmailSetup(account: strongSelf.account, code: emailCode))
|
||||||
|> deliverOnMainQueue).start(error: { error in
|
|> deliverOnMainQueue).start(error: { error in
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
if let strongSelf = self, let controller = controller {
|
if let strongSelf = self, let controller = controller {
|
||||||
@ -475,10 +475,28 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
controller.signInWithApple = { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
strongSelf.signInWithAppleSetup = false
|
||||||
|
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
let appleIdProvider = ASAuthorizationAppleIDProvider()
|
||||||
|
let request = appleIdProvider.createRequest()
|
||||||
|
|
||||||
|
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
|
||||||
|
authorizationController.delegate = strongSelf
|
||||||
|
authorizationController.presentationContextProvider = strongSelf
|
||||||
|
authorizationController.performRequests()
|
||||||
|
}
|
||||||
|
}
|
||||||
controller.updateData(number: formatPhoneNumber(number), codeType: type, nextType: nextType, timeout: timeout, termsOfService: termsOfService)
|
controller.updateData(number: formatPhoneNumber(number), codeType: type, nextType: nextType, timeout: timeout, termsOfService: termsOfService)
|
||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var signInWithAppleSetup = false
|
||||||
private func emailSetupController(appleSignInAllowed: Bool) -> AuthorizationSequenceEmailEntryController {
|
private func emailSetupController(appleSignInAllowed: Bool) -> AuthorizationSequenceEmailEntryController {
|
||||||
var currentController: AuthorizationSequenceEmailEntryController?
|
var currentController: AuthorizationSequenceEmailEntryController?
|
||||||
for c in self.viewControllers {
|
for c in self.viewControllers {
|
||||||
@ -533,6 +551,8 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strongSelf.signInWithAppleSetup = true
|
||||||
|
|
||||||
if #available(iOS 13.0, *) {
|
if #available(iOS 13.0, *) {
|
||||||
let appleIdProvider = ASAuthorizationAppleIDProvider()
|
let appleIdProvider = ASAuthorizationAppleIDProvider()
|
||||||
let request = appleIdProvider.createRequest()
|
let request = appleIdProvider.createRequest()
|
||||||
@ -559,8 +579,9 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.actionDisposable.set((verifyLoginEmail(account: self.account, code: .appleToken(token))
|
if self.signInWithAppleSetup {
|
||||||
|> deliverOnMainQueue).start(error: { [weak self] error in
|
self.actionDisposable.set((verifyLoginEmailSetup(account: self.account, code: .appleToken(token))
|
||||||
|
|> deliverOnMainQueue).start(error: { [weak self, weak lastController] error in
|
||||||
if let strongSelf = self, let lastController = lastController {
|
if let strongSelf = self, let lastController = lastController {
|
||||||
let text: String
|
let text: String
|
||||||
switch error {
|
switch error {
|
||||||
@ -576,6 +597,49 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
lastController.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
lastController.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
} else {
|
||||||
|
self.actionDisposable.set(
|
||||||
|
authorizeWithCode(accountManager: self.sharedContext.accountManager, account: self.account, code: .emailVerification(.appleToken(token)), termsOfService: nil, forcedPasswordSetupNotice: { value in
|
||||||
|
guard let entry = CodableEntry(ApplicationSpecificCounterNotice(value: value)) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||||
|
}).start(next: { [weak self] result in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// lastController?.inProgress = false
|
||||||
|
switch result {
|
||||||
|
case let .signUp(data):
|
||||||
|
let _ = beginSignUp(account: strongSelf.account, data: data).start()
|
||||||
|
case .loggedIn:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}, error: { [weak self, weak lastController] error in
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
if let strongSelf = self, let lastController = lastController {
|
||||||
|
// controller.inProgress = false
|
||||||
|
|
||||||
|
let text: String
|
||||||
|
switch error {
|
||||||
|
case .limitExceeded:
|
||||||
|
text = strongSelf.presentationData.strings.Login_CodeFloodError
|
||||||
|
case .invalidCode:
|
||||||
|
text = strongSelf.presentationData.strings.Login_InvalidCodeError
|
||||||
|
case .generic:
|
||||||
|
text = strongSelf.presentationData.strings.Login_UnknownError
|
||||||
|
case .codeExpired:
|
||||||
|
text = strongSelf.presentationData.strings.Login_CodeExpired
|
||||||
|
let account = strongSelf.account
|
||||||
|
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .empty)).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
lastController.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,44 @@ import AnimatedStickerNode
|
|||||||
import TelegramAnimatedStickerNode
|
import TelegramAnimatedStickerNode
|
||||||
import SolidRoundedButtonNode
|
import SolidRoundedButtonNode
|
||||||
|
|
||||||
|
final class AuthorizationDividerNode: ASDisplayNode {
|
||||||
|
private let titleNode: ImmediateTextNode
|
||||||
|
private let leftLineNode: ASDisplayNode
|
||||||
|
private let rightLineNode: ASDisplayNode
|
||||||
|
|
||||||
|
init(theme: PresentationTheme, strings: PresentationStrings) {
|
||||||
|
self.titleNode = ImmediateTextNode()
|
||||||
|
self.titleNode.maximumNumberOfLines = 1
|
||||||
|
self.titleNode.attributedText = NSAttributedString(string: "or", font: Font.regular(17.0), textColor: theme.list.itemSecondaryTextColor)
|
||||||
|
|
||||||
|
self.leftLineNode = ASDisplayNode()
|
||||||
|
self.leftLineNode.backgroundColor = theme.list.itemSecondaryTextColor
|
||||||
|
|
||||||
|
self.rightLineNode = ASDisplayNode()
|
||||||
|
self.rightLineNode.backgroundColor = theme.list.itemSecondaryTextColor
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.addSubnode(self.titleNode)
|
||||||
|
self.addSubnode(self.leftLineNode)
|
||||||
|
self.addSubnode(self.rightLineNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateLayout(width: CGFloat) -> CGSize {
|
||||||
|
let lineSize = CGSize(width: 33.0, height: UIScreenPixel)
|
||||||
|
let spacing: CGFloat = 7.0
|
||||||
|
|
||||||
|
let titleSize = self.titleNode.updateLayout(CGSize(width: width - (lineSize.width + spacing) * 2.0, height: .greatestFiniteMagnitude))
|
||||||
|
|
||||||
|
let height: CGFloat = 40.0
|
||||||
|
let titleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((width - lineSize.width) / 2.0), y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||||
|
self.titleNode.frame = titleFrame
|
||||||
|
self.leftLineNode.frame = CGRect(origin: CGPoint(x: titleFrame.minX - spacing - lineSize.width, y: floorToScreenPixels(height / 2.0)), size: lineSize)
|
||||||
|
self.rightLineNode.frame = CGRect(origin: CGPoint(x: titleFrame.maxX + spacing, y: floorToScreenPixels(height / 2.0)), size: lineSize)
|
||||||
|
return CGSize(width: width, height: height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final class AuthorizationSequenceEmailEntryControllerNode: ASDisplayNode, UITextFieldDelegate {
|
final class AuthorizationSequenceEmailEntryControllerNode: ASDisplayNode, UITextFieldDelegate {
|
||||||
private let strings: PresentationStrings
|
private let strings: PresentationStrings
|
||||||
private let theme: PresentationTheme
|
private let theme: PresentationTheme
|
||||||
@ -17,6 +55,7 @@ final class AuthorizationSequenceEmailEntryControllerNode: ASDisplayNode, UIText
|
|||||||
private let titleNode: ASTextNode
|
private let titleNode: ASTextNode
|
||||||
private let noticeNode: ASTextNode
|
private let noticeNode: ASTextNode
|
||||||
|
|
||||||
|
private let dividerNode: AuthorizationDividerNode
|
||||||
private var signInWithAppleButton: UIControl?
|
private var signInWithAppleButton: UIControl?
|
||||||
private let proceedNode: SolidRoundedButtonNode
|
private let proceedNode: SolidRoundedButtonNode
|
||||||
|
|
||||||
@ -82,6 +121,8 @@ final class AuthorizationSequenceEmailEntryControllerNode: ASDisplayNode, UIText
|
|||||||
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
||||||
self.codeField.textField.placeholder = "Enter Your Email"
|
self.codeField.textField.placeholder = "Enter Your Email"
|
||||||
|
|
||||||
|
self.dividerNode = AuthorizationDividerNode(theme: self.theme, strings: self.strings)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.setViewBlock({
|
self.setViewBlock({
|
||||||
@ -98,6 +139,7 @@ final class AuthorizationSequenceEmailEntryControllerNode: ASDisplayNode, UIText
|
|||||||
self.addSubnode(self.proceedNode)
|
self.addSubnode(self.proceedNode)
|
||||||
self.addSubnode(self.noticeNode)
|
self.addSubnode(self.noticeNode)
|
||||||
self.addSubnode(self.animationNode)
|
self.addSubnode(self.animationNode)
|
||||||
|
self.addSubnode(self.dividerNode)
|
||||||
|
|
||||||
self.codeField.textField.addTarget(self, action: #selector(self.textDidChange), for: .editingChanged)
|
self.codeField.textField.addTarget(self, action: #selector(self.textDidChange), for: .editingChanged)
|
||||||
self.proceedNode.pressed = { [weak self] in
|
self.proceedNode.pressed = { [weak self] in
|
||||||
@ -169,17 +211,23 @@ final class AuthorizationSequenceEmailEntryControllerNode: ASDisplayNode, UIText
|
|||||||
items.append(AuthorizationLayoutItem(node: self.codeField, size: CGSize(width: layout.size.width - 88.0, height: 44.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 32.0, maxValue: 60.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.codeField, size: CGSize(width: layout.size.width - 88.0, height: 44.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 32.0, maxValue: 60.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
items.append(AuthorizationLayoutItem(node: self.codeSeparatorNode, size: CGSize(width: layout.size.width - 48.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.codeSeparatorNode, size: CGSize(width: layout.size.width - 48.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
|
||||||
items.append(AuthorizationLayoutItem(node: self.proceedNode, size: proceedSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 48.0, maxValue: 100.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
if let _ = self.signInWithAppleButton, self.appleSignInAllowed {
|
||||||
|
self.dividerNode.isHidden = false
|
||||||
|
let dividerSize = self.dividerNode.updateLayout(width: layout.size.width)
|
||||||
|
items.append(AuthorizationLayoutItem(node: self.dividerNode, size: dividerSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 48.0, maxValue: 100.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
} else {
|
||||||
|
self.dividerNode.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(AuthorizationLayoutItem(node: self.proceedNode, size: proceedSize, spacingBefore: self.dividerNode.isHidden ? AuthorizationLayoutItemSpacing(weight: 48.0, maxValue: 100.0) : AuthorizationLayoutItemSpacing(weight: 10.0, maxValue: 10.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
|
||||||
let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - 20.0)), items: items, transition: transition, failIfDoesNotFit: false)
|
let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - 20.0)), items: items, transition: transition, failIfDoesNotFit: false)
|
||||||
|
|
||||||
if let signInWithAppleButton = self.signInWithAppleButton {
|
if let signInWithAppleButton = self.signInWithAppleButton, self.appleSignInAllowed {
|
||||||
if self.appleSignInAllowed {
|
|
||||||
signInWithAppleButton.isHidden = false
|
signInWithAppleButton.isHidden = false
|
||||||
transition.updateFrame(view: signInWithAppleButton, frame: self.proceedNode.frame)
|
transition.updateFrame(view: signInWithAppleButton, frame: self.proceedNode.frame)
|
||||||
} else {
|
} else {
|
||||||
signInWithAppleButton.isHidden = true
|
self.signInWithAppleButton?.isHidden = true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -235,8 +235,6 @@ private final class ContactSyncNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||||
private let sharedContext: SharedAccountContext
|
private let sharedContext: SharedAccountContext
|
||||||
private var account: UnauthorizedAccount
|
private var account: UnauthorizedAccount
|
||||||
|
|||||||
@ -50,7 +50,7 @@ final class AuthorizationSequenceSignUpController: ViewController {
|
|||||||
|
|
||||||
self.statusBar.statusBarStyle = presentationData.theme.intro.statusBarStyle.style
|
self.statusBar.statusBarStyle = presentationData.theme.intro.statusBarStyle.style
|
||||||
|
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.nextPressed))
|
// self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.nextPressed))
|
||||||
|
|
||||||
self.attemptNavigation = { _ in
|
self.attemptNavigation = { _ in
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import Display
|
|||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import TextFormat
|
import TextFormat
|
||||||
import Markdown
|
import Markdown
|
||||||
|
import AuthorizationUI
|
||||||
|
import SolidRoundedButtonNode
|
||||||
|
|
||||||
private func roundCorners(diameter: CGFloat) -> UIImage {
|
private func roundCorners(diameter: CGFloat) -> UIImage {
|
||||||
UIGraphicsBeginImageContextWithOptions(CGSize(width: diameter, height: diameter), false, 0.0)
|
UIGraphicsBeginImageContextWithOptions(CGSize(width: diameter, height: diameter), false, 0.0)
|
||||||
@ -34,6 +36,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
private let lastSeparatorNode: ASDisplayNode
|
private let lastSeparatorNode: ASDisplayNode
|
||||||
private let currentPhotoNode: ASImageNode
|
private let currentPhotoNode: ASImageNode
|
||||||
private let addPhotoButton: HighlightableButtonNode
|
private let addPhotoButton: HighlightableButtonNode
|
||||||
|
private let proceedNode: SolidRoundedButtonNode
|
||||||
|
|
||||||
private var layoutArguments: (ContainerViewLayout, CGFloat)?
|
private var layoutArguments: (ContainerViewLayout, CGFloat)?
|
||||||
|
|
||||||
@ -75,20 +78,20 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
self.titleNode = ASTextNode()
|
self.titleNode = ASTextNode()
|
||||||
self.titleNode.isUserInteractionEnabled = false
|
self.titleNode.isUserInteractionEnabled = false
|
||||||
self.titleNode.displaysAsynchronously = false
|
self.titleNode.displaysAsynchronously = false
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_InfoTitle, font: Font.light(30.0), textColor: theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_InfoTitle, font: Font.semibold(28.0), textColor: theme.list.itemPrimaryTextColor)
|
||||||
|
|
||||||
self.currentOptionNode = ASTextNode()
|
self.currentOptionNode = ASTextNode()
|
||||||
self.currentOptionNode.isUserInteractionEnabled = false
|
self.currentOptionNode.isUserInteractionEnabled = false
|
||||||
self.currentOptionNode.displaysAsynchronously = false
|
self.currentOptionNode.displaysAsynchronously = false
|
||||||
self.currentOptionNode.attributedText = NSAttributedString(string: self.strings.Login_InfoHelp, font: Font.regular(16.0), textColor: theme.list.itemPlaceholderTextColor, paragraphAlignment: .center)
|
self.currentOptionNode.attributedText = NSAttributedString(string: self.strings.Login_InfoHelp, font: Font.regular(16.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .center)
|
||||||
|
|
||||||
self.termsNode = ImmediateTextNode()
|
self.termsNode = ImmediateTextNode()
|
||||||
self.termsNode.textAlignment = .center
|
self.termsNode.textAlignment = .center
|
||||||
self.termsNode.maximumNumberOfLines = 0
|
self.termsNode.maximumNumberOfLines = 0
|
||||||
self.termsNode.displaysAsynchronously = false
|
self.termsNode.displaysAsynchronously = false
|
||||||
let body = MarkdownAttributeSet(font: Font.regular(16.0), textColor: theme.list.itemPrimaryTextColor)
|
let body = MarkdownAttributeSet(font: Font.regular(13.0), textColor: theme.list.itemSecondaryTextColor)
|
||||||
let link = MarkdownAttributeSet(font: Font.regular(16.0), textColor: theme.list.itemAccentColor, additionalAttributes: [TelegramTextAttributes.URL: ""])
|
let link = MarkdownAttributeSet(font: Font.regular(13.0), textColor: theme.list.itemAccentColor, additionalAttributes: [TelegramTextAttributes.URL: ""])
|
||||||
self.termsNode.attributedText = parseMarkdownIntoAttributedString(strings.Login_TermsOfServiceLabel.replacingOccurrences(of: "]", with: "]()"), attributes: MarkdownAttributes(body: body, bold: body, link: link, linkAttribute: { _ in nil }), textAlignment: .center)
|
self.termsNode.attributedText = parseMarkdownIntoAttributedString(strings.Login_TermsOfServiceLabel.replacingOccurrences(of: "\n", with: " ").replacingOccurrences(of: "]", with: "]()"), attributes: MarkdownAttributes(body: body, bold: body, link: link, linkAttribute: { _ in nil }), textAlignment: .center)
|
||||||
|
|
||||||
self.firstSeparatorNode = ASDisplayNode()
|
self.firstSeparatorNode = ASDisplayNode()
|
||||||
self.firstSeparatorNode.isLayerBacked = true
|
self.firstSeparatorNode.isLayerBacked = true
|
||||||
@ -132,12 +135,14 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
self.currentPhotoNode.displayWithoutProcessing = true
|
self.currentPhotoNode.displayWithoutProcessing = true
|
||||||
|
|
||||||
self.addPhotoButton = HighlightableButtonNode()
|
self.addPhotoButton = HighlightableButtonNode()
|
||||||
self.addPhotoButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Avatar/EditAvatarIconLarge"), color: self.theme.list.itemPlaceholderTextColor), for: .normal)
|
self.addPhotoButton.setImage(generateTintedImage(image: UIImage(bundleImageName: "Avatar/EditAvatarIconLarge"), color: self.theme.list.itemAccentColor), for: .normal)
|
||||||
self.addPhotoButton.setBackgroundImage(generateCircleImage(diameter: 110.0, lineWidth: 1.0, color: self.theme.list.itemPlaceholderTextColor), for: .normal)
|
self.addPhotoButton.setBackgroundImage(generateFilledCircleImage(diameter: 110.0, color: self.theme.list.itemAccentColor.withAlphaComponent(0.1), strokeColor: nil, strokeWidth: nil, backgroundColor: nil), for: .normal)
|
||||||
|
|
||||||
self.addPhotoButton.addSubnode(self.currentPhotoNode)
|
self.addPhotoButton.addSubnode(self.currentPhotoNode)
|
||||||
self.addPhotoButton.allowsGroupOpacity = true
|
self.addPhotoButton.allowsGroupOpacity = true
|
||||||
|
|
||||||
|
self.proceedNode = SolidRoundedButtonNode(title: "Continue", theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.setViewBlock({
|
self.setViewBlock({
|
||||||
@ -158,6 +163,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
self.addSubnode(self.termsNode)
|
self.addSubnode(self.termsNode)
|
||||||
self.termsNode.isHidden = true
|
self.termsNode.isHidden = true
|
||||||
self.addSubnode(self.addPhotoButton)
|
self.addSubnode(self.addPhotoButton)
|
||||||
|
self.addSubnode(self.proceedNode)
|
||||||
|
|
||||||
self.addPhotoButton.addTarget(self, action: #selector(self.addPhotoPressed), forControlEvents: .touchUpInside)
|
self.addPhotoButton.addTarget(self, action: #selector(self.addPhotoPressed), forControlEvents: .touchUpInside)
|
||||||
|
|
||||||
@ -174,6 +180,13 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
self?.openTermsOfService?()
|
self?.openTermsOfService?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.proceedNode.pressed = { [weak self] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
let name = strongSelf.currentName
|
||||||
|
strongSelf.signUpWithName?(name.0, name.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateData(firstName: String, lastName: String, hasTermsOfService: Bool) {
|
func updateData(firstName: String, lastName: String, hasTermsOfService: Bool) {
|
||||||
@ -194,90 +207,109 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
|||||||
insets.bottom += max(inputHeight, layout.standardInputHeight)
|
insets.bottom += max(inputHeight, layout.standardInputHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
let availableHeight = max(1.0, layout.size.height - insets.top - insets.bottom)
|
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_InfoTitle, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
|
|
||||||
if max(layout.size.width, layout.size.height) > 1023.0 {
|
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_InfoTitle, font: Font.light(40.0), textColor: self.theme.list.itemPrimaryTextColor)
|
|
||||||
} else {
|
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_InfoTitle, font: Font.light(30.0), textColor: self.theme.list.itemPrimaryTextColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
let titleSize = self.titleNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
let titleSize = self.titleNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
||||||
let additionalTitleSpacing: CGFloat
|
|
||||||
if titleSize.width > layout.size.width - 160.0 {
|
|
||||||
additionalTitleSpacing = 44.0
|
|
||||||
} else {
|
|
||||||
additionalTitleSpacing = 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
let minimalTitleSpacing: CGFloat = 10.0
|
// let additionalTitleSpacing: CGFloat
|
||||||
let maxTitleSpacing: CGFloat = 22.0
|
// if titleSize.width > layout.size.width - 160.0 {
|
||||||
let fieldHeight: CGFloat = 57.0
|
// additionalTitleSpacing = 44.0
|
||||||
let inputFieldsHeight: CGFloat = fieldHeight * 2.0
|
// } else {
|
||||||
let leftInset: CGFloat = 130.0
|
// additionalTitleSpacing = 0.0
|
||||||
|
// }
|
||||||
|
|
||||||
let minimalNoticeSpacing: CGFloat = 11.0
|
let fieldHeight: CGFloat = 54.0
|
||||||
let maxNoticeSpacing: CGFloat = 35.0
|
|
||||||
|
let sideInset: CGFloat = 24.0
|
||||||
|
let innerInset: CGFloat = 16.0
|
||||||
|
|
||||||
|
// let minimalNoticeSpacing: CGFloat = 11.0
|
||||||
|
// let maxNoticeSpacing: CGFloat = 35.0
|
||||||
let noticeSize = self.currentOptionNode.measure(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude))
|
let noticeSize = self.currentOptionNode.measure(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude))
|
||||||
let termsSize = self.termsNode.updateLayout(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude))
|
let termsSize = self.termsNode.updateLayout(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude))
|
||||||
|
//
|
||||||
|
// let noticeHeight: CGFloat = noticeSize.height + (self.termsNode.isHidden ? 0.0 : (termsSize.height + 4.0))
|
||||||
|
//
|
||||||
|
// let minimalTermsOfServiceSpacing: CGFloat = 6.0
|
||||||
|
// let maxTermsOfServiceSpacing: CGFloat = 20.0
|
||||||
|
// let minTrailingSpacing: CGFloat = 10.0
|
||||||
|
//
|
||||||
|
// let inputHeight = inputFieldsHeight
|
||||||
|
// let essentialHeight = additionalTitleSpacing + titleSize.height + minimalTitleSpacing + inputHeight + minimalNoticeSpacing + noticeHeight
|
||||||
|
// let additionalHeight = minimalTermsOfServiceSpacing + minTrailingSpacing
|
||||||
|
//
|
||||||
|
// let navigationHeight: CGFloat
|
||||||
|
// if essentialHeight + additionalHeight > availableHeight || availableHeight * 0.66 - inputHeight < additionalHeight {
|
||||||
|
// navigationHeight = min(floor(availableHeight * 0.3), availableHeight - inputFieldsHeight)
|
||||||
|
// } else {
|
||||||
|
// navigationHeight = floor(availableHeight * 0.3)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let titleOffset: CGFloat
|
||||||
|
// if navigationHeight * 0.5 < titleSize.height + minimalTitleSpacing {
|
||||||
|
// titleOffset = max(navigationBarHeight, floor((navigationHeight - titleSize.height) / 2.0))
|
||||||
|
// } else {
|
||||||
|
// titleOffset = max(navigationBarHeight, max(navigationHeight * 0.5, navigationHeight - maxTitleSpacing - titleSize.height))
|
||||||
|
// }
|
||||||
|
// transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - titleSize.width) / 2.0), y: titleOffset), size: titleSize))
|
||||||
|
//
|
||||||
|
// let avatarSize: CGSize = CGSize(width: 110.0, height: 110.0)
|
||||||
|
// let addPhotoButtonFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - avatarSize.width) / 2.0), y: navigationHeight + 10.0), size: avatarSize)
|
||||||
|
// transition.updateFrame(node: self.addPhotoButton, frame: addPhotoButtonFrame)
|
||||||
|
// self.currentPhotoNode.frame = CGRect(origin: CGPoint(), size: addPhotoButtonFrame.size)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// let firstFieldFrame = CGRect(origin: CGPoint(x: sideInset + innerInset, y: navigationHeight + 3.0), size: CGSize(width: layout.size.width - (sideInset + innerInset) * 2.0, height: fieldHeight))
|
||||||
|
// transition.updateFrame(node: self.firstNameField, frame: firstFieldFrame)
|
||||||
|
//
|
||||||
|
// let lastFieldFrame = CGRect(origin: CGPoint(x: firstFieldFrame.minX, y: firstFieldFrame.maxY), size: CGSize(width: firstFieldFrame.size.width, height: fieldHeight))
|
||||||
|
// transition.updateFrame(node: self.lastNameField, frame: lastFieldFrame)
|
||||||
|
//
|
||||||
|
// transition.updateFrame(node: self.firstSeparatorNode, frame: CGRect(origin: CGPoint(x: sideInset, y: firstFieldFrame.maxY), size: CGSize(width: layout.size.width - sideInset * 2.0, height: UIScreenPixel)))
|
||||||
|
// transition.updateFrame(node: self.lastSeparatorNode, frame: CGRect(origin: CGPoint(x: sideInset, y: lastFieldFrame.maxY), size: CGSize(width: layout.size.width - sideInset * 2.0, height: UIScreenPixel)))
|
||||||
|
//
|
||||||
|
// let additionalAvailableHeight = max(1.0, availableHeight - lastFieldFrame.maxY)
|
||||||
|
// let additionalAvailableSpacing = max(1.0, additionalAvailableHeight - noticeHeight)
|
||||||
|
// let noticeSpacingFactor = maxNoticeSpacing / (maxNoticeSpacing + maxTermsOfServiceSpacing + minTrailingSpacing)
|
||||||
|
// let termsOfServiceSpacingFactor = maxTermsOfServiceSpacing / (maxNoticeSpacing + maxTermsOfServiceSpacing + minTrailingSpacing)
|
||||||
|
//
|
||||||
|
// let noticeSpacing: CGFloat
|
||||||
|
// let termsOfServiceSpacing: CGFloat
|
||||||
|
// if additionalAvailableHeight <= maxNoticeSpacing + noticeHeight + maxTermsOfServiceSpacing + minTrailingSpacing {
|
||||||
|
// termsOfServiceSpacing = min(floor(termsOfServiceSpacingFactor * additionalAvailableSpacing), maxTermsOfServiceSpacing)
|
||||||
|
// noticeSpacing = floor((additionalAvailableHeight - termsOfServiceSpacing - noticeHeight) / 2.0)
|
||||||
|
// } else {
|
||||||
|
// noticeSpacing = min(floor(noticeSpacingFactor * additionalAvailableSpacing), maxNoticeSpacing)
|
||||||
|
// termsOfServiceSpacing = min(floor(termsOfServiceSpacingFactor * additionalAvailableSpacing), maxTermsOfServiceSpacing)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// let currentOptionFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - noticeSize.width) / 2.0), y: lastFieldFrame.maxY + max(0.0, noticeSpacing)), size: noticeSize)
|
||||||
|
// transition.updateFrame(node: self.currentOptionNode, frame: currentOptionFrame)
|
||||||
|
// let termsFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - termsSize.width) / 2.0), y: layout.size.height - insets.bottom - termsSize.height - 4.0), size: termsSize)
|
||||||
|
// transition.updateFrame(node: self.termsNode, frame: termsFrame)
|
||||||
|
//
|
||||||
|
|
||||||
let noticeHeight: CGFloat = noticeSize.height + (self.termsNode.isHidden ? 0.0 : (termsSize.height + 4.0))
|
let avatarSize: CGSize = CGSize(width: 110.0, height: 110.0)
|
||||||
|
var items: [AuthorizationLayoutItem] = []
|
||||||
|
items.append(AuthorizationLayoutItem(node: self.addPhotoButton, size: avatarSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 16.0, maxValue: 16.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
self.currentPhotoNode.frame = CGRect(origin: CGPoint(), size: avatarSize)
|
||||||
|
|
||||||
let minimalTermsOfServiceSpacing: CGFloat = 6.0
|
items.append(AuthorizationLayoutItem(node: self.titleNode, size: titleSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 18.0, maxValue: 18.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
let maxTermsOfServiceSpacing: CGFloat = 20.0
|
items.append(AuthorizationLayoutItem(node: self.currentOptionNode, size: noticeSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 20.0, maxValue: 20.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
let minTrailingSpacing: CGFloat = 10.0
|
|
||||||
|
|
||||||
let inputHeight = inputFieldsHeight
|
items.append(AuthorizationLayoutItem(node: self.firstNameField, size: CGSize(width: layout.size.width - (sideInset + innerInset) * 2.0, height: fieldHeight), spacingBefore: AuthorizationLayoutItemSpacing(weight: 32.0, maxValue: 60.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
let essentialHeight = additionalTitleSpacing + titleSize.height + minimalTitleSpacing + inputHeight + minimalNoticeSpacing + noticeHeight
|
items.append(AuthorizationLayoutItem(node: self.firstSeparatorNode, size: CGSize(width: layout.size.width - sideInset * 2.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
let additionalHeight = minimalTermsOfServiceSpacing + minTrailingSpacing
|
|
||||||
|
|
||||||
let navigationHeight: CGFloat
|
items.append(AuthorizationLayoutItem(node: self.lastNameField, size: CGSize(width: layout.size.width - (sideInset + innerInset) * 2.0, height: fieldHeight), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
if essentialHeight + additionalHeight > availableHeight || availableHeight * 0.66 - inputHeight < additionalHeight {
|
items.append(AuthorizationLayoutItem(node: self.lastSeparatorNode, size: CGSize(width: layout.size.width - sideInset * 2.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
navigationHeight = min(floor(availableHeight * 0.3), availableHeight - inputFieldsHeight)
|
|
||||||
} else {
|
|
||||||
navigationHeight = floor(availableHeight * 0.3)
|
|
||||||
}
|
|
||||||
|
|
||||||
let titleOffset: CGFloat
|
items.append(AuthorizationLayoutItem(node: self.termsNode, size: termsSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 48.0, maxValue: 100.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
if navigationHeight * 0.5 < titleSize.height + minimalTitleSpacing {
|
|
||||||
titleOffset = max(navigationBarHeight, floor((navigationHeight - titleSize.height) / 2.0))
|
|
||||||
} else {
|
|
||||||
titleOffset = max(navigationBarHeight, max(navigationHeight * 0.5, navigationHeight - maxTitleSpacing - titleSize.height))
|
|
||||||
}
|
|
||||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - titleSize.width) / 2.0), y: titleOffset), size: titleSize))
|
|
||||||
|
|
||||||
let addPhotoButtonFrame = CGRect(origin: CGPoint(x: 10.0, y: navigationHeight + 10.0), size: CGSize(width: 110.0, height: 110.0))
|
let proceedHeight = self.proceedNode.updateLayout(width: layout.size.width - 48.0, transition: transition)
|
||||||
transition.updateFrame(node: self.addPhotoButton, frame: addPhotoButtonFrame)
|
let proceedSize = CGSize(width: layout.size.width - 48.0, height: proceedHeight)
|
||||||
self.currentPhotoNode.frame = CGRect(origin: CGPoint(), size: addPhotoButtonFrame.size)
|
items.append(AuthorizationLayoutItem(node: self.proceedNode, size: proceedSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 20.0, maxValue: 20.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
|
||||||
let firstFieldFrame = CGRect(origin: CGPoint(x: leftInset, y: navigationHeight + 3.0), size: CGSize(width: layout.size.width - leftInset, height: fieldHeight))
|
let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - 20.0)), items: items, transition: transition, failIfDoesNotFit: false)
|
||||||
transition.updateFrame(node: self.firstNameField, frame: firstFieldFrame)
|
|
||||||
|
|
||||||
let lastFieldFrame = CGRect(origin: CGPoint(x: firstFieldFrame.minX, y: firstFieldFrame.maxY), size: CGSize(width: firstFieldFrame.size.width, height: fieldHeight))
|
|
||||||
transition.updateFrame(node: self.lastNameField, frame: lastFieldFrame)
|
|
||||||
|
|
||||||
transition.updateFrame(node: self.firstSeparatorNode, frame: CGRect(origin: CGPoint(x: leftInset, y: firstFieldFrame.maxY), size: CGSize(width: layout.size.width - leftInset, height: UIScreenPixel)))
|
|
||||||
transition.updateFrame(node: self.lastSeparatorNode, frame: CGRect(origin: CGPoint(x: leftInset, y: lastFieldFrame.maxY), size: CGSize(width: layout.size.width - leftInset, height: UIScreenPixel)))
|
|
||||||
|
|
||||||
let additionalAvailableHeight = max(1.0, availableHeight - lastFieldFrame.maxY)
|
|
||||||
let additionalAvailableSpacing = max(1.0, additionalAvailableHeight - noticeHeight)
|
|
||||||
let noticeSpacingFactor = maxNoticeSpacing / (maxNoticeSpacing + maxTermsOfServiceSpacing + minTrailingSpacing)
|
|
||||||
let termsOfServiceSpacingFactor = maxTermsOfServiceSpacing / (maxNoticeSpacing + maxTermsOfServiceSpacing + minTrailingSpacing)
|
|
||||||
|
|
||||||
let noticeSpacing: CGFloat
|
|
||||||
let termsOfServiceSpacing: CGFloat
|
|
||||||
if additionalAvailableHeight <= maxNoticeSpacing + noticeHeight + maxTermsOfServiceSpacing + minTrailingSpacing {
|
|
||||||
termsOfServiceSpacing = min(floor(termsOfServiceSpacingFactor * additionalAvailableSpacing), maxTermsOfServiceSpacing)
|
|
||||||
noticeSpacing = floor((additionalAvailableHeight - termsOfServiceSpacing - noticeHeight) / 2.0)
|
|
||||||
} else {
|
|
||||||
noticeSpacing = min(floor(noticeSpacingFactor * additionalAvailableSpacing), maxNoticeSpacing)
|
|
||||||
termsOfServiceSpacing = min(floor(termsOfServiceSpacingFactor * additionalAvailableSpacing), maxTermsOfServiceSpacing)
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentOptionFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - noticeSize.width) / 2.0), y: lastFieldFrame.maxY + max(0.0, noticeSpacing)), size: noticeSize)
|
|
||||||
transition.updateFrame(node: self.currentOptionNode, frame: currentOptionFrame)
|
|
||||||
let termsFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - termsSize.width) / 2.0), y: layout.size.height - insets.bottom - termsSize.height - 4.0), size: termsSize)
|
|
||||||
transition.updateFrame(node: self.termsNode, frame: termsFrame)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func activateInput() {
|
func activateInput() {
|
||||||
|
|||||||
@ -9835,7 +9835,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
if let attachBotStart = self.attachBotStart {
|
if let attachBotStart = self.attachBotStart {
|
||||||
self.attachBotStart = nil
|
self.attachBotStart = nil
|
||||||
self.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload)
|
self.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11235,12 +11235,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public func presentAttachmentBot(botId: PeerId, payload: String?) {
|
public func presentAttachmentBot(botId: PeerId, payload: String?, justInstalled: Bool) {
|
||||||
self.attachmentController?.dismiss(animated: true, completion: nil)
|
self.attachmentController?.dismiss(animated: true, completion: nil)
|
||||||
self.presentAttachmentMenu(editMediaOptions: nil, editMediaReference: nil, botId: botId, botPayload: payload)
|
self.presentAttachmentMenu(editMediaOptions: nil, editMediaReference: nil, botId: botId, botPayload: payload, botJustInstalled: justInstalled)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func presentAttachmentMenu(editMediaOptions: MessageMediaEditingOptions?, editMediaReference: AnyMediaReference?, botId: PeerId? = nil, botPayload: String? = nil) {
|
private func presentAttachmentMenu(editMediaOptions: MessageMediaEditingOptions?, editMediaReference: AnyMediaReference?, botId: PeerId? = nil, botPayload: String? = nil, botJustInstalled: Bool = false) {
|
||||||
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
|
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -11285,16 +11285,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
isScheduledMessages = true
|
isScheduledMessages = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttons: Signal<([AttachmentButtonType], AttachmentButtonType?), NoError>
|
|
||||||
if !isScheduledMessages {
|
|
||||||
buttons = self.context.engine.messages.attachMenuBots()
|
|
||||||
|> map { attachMenuBots in
|
|
||||||
var buttons = availableButtons
|
|
||||||
var initialButton: AttachmentButtonType?
|
|
||||||
if botId == nil {
|
|
||||||
initialButton = .gallery
|
|
||||||
}
|
|
||||||
|
|
||||||
var peerType: AttachMenuBots.Bot.PeerFlags = []
|
var peerType: AttachMenuBots.Bot.PeerFlags = []
|
||||||
if let user = peer as? TelegramUser {
|
if let user = peer as? TelegramUser {
|
||||||
if let _ = user.botInfo {
|
if let _ = user.botInfo {
|
||||||
@ -11312,6 +11302,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let buttons: Signal<([AttachmentButtonType], [AttachmentButtonType], AttachmentButtonType?), NoError>
|
||||||
|
if !isScheduledMessages {
|
||||||
|
buttons = self.context.engine.messages.attachMenuBots()
|
||||||
|
|> map { attachMenuBots in
|
||||||
|
var buttons = availableButtons
|
||||||
|
var allButtons = availableButtons
|
||||||
|
|
||||||
|
var initialButton: AttachmentButtonType?
|
||||||
|
if botId == nil {
|
||||||
|
initialButton = .gallery
|
||||||
|
}
|
||||||
|
|
||||||
for bot in attachMenuBots.reversed() {
|
for bot in attachMenuBots.reversed() {
|
||||||
var peerType = peerType
|
var peerType = peerType
|
||||||
if bot.peer.id == peer.id {
|
if bot.peer.id == peer.id {
|
||||||
@ -11319,19 +11321,20 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
peerType.remove(.bot)
|
peerType.remove(.bot)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bot.peerTypes.intersection(peerType).isEmpty {
|
|
||||||
let button: AttachmentButtonType = .app(bot.peer, bot.shortName, bot.icons)
|
let button: AttachmentButtonType = .app(bot.peer, bot.shortName, bot.icons)
|
||||||
|
if !bot.peerTypes.intersection(peerType).isEmpty {
|
||||||
buttons.insert(button, at: 1)
|
buttons.insert(button, at: 1)
|
||||||
|
|
||||||
if initialButton == nil && bot.peer.id == botId {
|
if initialButton == nil && bot.peer.id == botId {
|
||||||
initialButton = button
|
initialButton = button
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
allButtons.insert(button, at: 1)
|
||||||
}
|
}
|
||||||
return (buttons, initialButton)
|
return (buttons, allButtons, initialButton)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buttons = .single((availableButtons, .gallery))
|
buttons = .single((availableButtons, availableButtons, .gallery))
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataSettings = self.context.sharedContext.accountManager.transaction { transaction -> GeneratedMediaStoreSettings in
|
let dataSettings = self.context.sharedContext.accountManager.transaction { transaction -> GeneratedMediaStoreSettings in
|
||||||
@ -11344,10 +11347,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let (buttons, initialButton) = buttonsAndInitialButton
|
let (buttons, allButtons, initialButton) = buttonsAndInitialButton
|
||||||
|
|
||||||
guard let initialButton = initialButton else {
|
guard let initialButton = initialButton else {
|
||||||
if let botId = botId {
|
if let botId = botId {
|
||||||
|
if let button = allButtons.first(where: { button in
|
||||||
|
if case let .app(botPeer, _, _) = button, botPeer.id == botId {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}), case let .app(_, botName, _) = button {
|
||||||
|
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: botJustInstalled ? strongSelf.presentationData.strings.WebApp_AddToAttachmentSucceeded(botName).string : strongSelf.presentationData.strings.WebApp_AddToAttachmentAlreadyAddedError), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||||
|
} else {
|
||||||
let _ = (context.engine.messages.getAttachMenuBot(botId: botId)
|
let _ = (context.engine.messages.getAttachMenuBot(botId: botId)
|
||||||
|> deliverOnMainQueue).start(next: { bot in
|
|> deliverOnMainQueue).start(next: { bot in
|
||||||
let peer = EnginePeer(bot.peer)
|
let peer = EnginePeer(bot.peer)
|
||||||
@ -11356,7 +11368,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|> deliverOnMainQueue).start(error: { _ in
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
|
|
||||||
}, completed: {
|
}, completed: {
|
||||||
strongSelf.presentAttachmentBot(botId: botId, payload: botPayload)
|
strongSelf.presentAttachmentBot(botId: botId, payload: botPayload, justInstalled: true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
strongSelf.present(controller, in: .window(.root))
|
strongSelf.present(controller, in: .window(.root))
|
||||||
@ -11364,6 +11376,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
strongSelf.present(textAlertController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
strongSelf.present(textAlertController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if let attachBotStart = params.attachBotStart {
|
if let attachBotStart = params.attachBotStart {
|
||||||
controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload)
|
controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled)
|
||||||
}
|
}
|
||||||
params.setupController(controller)
|
params.setupController(controller)
|
||||||
found = true
|
found = true
|
||||||
@ -85,7 +85,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if let attachBotStart = params.attachBotStart {
|
if let attachBotStart = params.attachBotStart {
|
||||||
controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload)
|
controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, attachBotStart: params.attachBotStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter, chatNavigationStack: params.chatNavigationStack)
|
controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, attachBotStart: params.attachBotStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter, chatNavigationStack: params.chatNavigationStack)
|
||||||
|
|||||||
@ -579,13 +579,13 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
||||||
controller.peerSelected = { peer in
|
controller.peerSelected = { peer in
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: bot.peer.id, payload: payload), useExisting: true))
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: bot.peer.id, payload: payload, justInstalled: false), useExisting: true))
|
||||||
}
|
}
|
||||||
navigationController.pushViewController(controller)
|
navigationController.pushViewController(controller)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext {
|
if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext {
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: peerId, payload: payload), useExisting: true))
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: peerId, payload: payload, justInstalled: false), useExisting: true))
|
||||||
} else {
|
} else {
|
||||||
presentError(presentationData.strings.WebApp_AddToAttachmentAlreadyAddedError)
|
presentError(presentationData.strings.WebApp_AddToAttachmentAlreadyAddedError)
|
||||||
}
|
}
|
||||||
@ -622,13 +622,13 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
|||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat))
|
||||||
controller.peerSelected = { peer in
|
controller.peerSelected = { peer in
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload), useExisting: true))
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true))
|
||||||
}
|
}
|
||||||
navigationController.pushViewController(controller)
|
navigationController.pushViewController(controller)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext {
|
if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext {
|
||||||
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload), useExisting: true))
|
let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -647,6 +647,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||||||
var domain: String?
|
var domain: String?
|
||||||
var start: String?
|
var start: String?
|
||||||
var startGroup: String?
|
var startGroup: String?
|
||||||
|
var startChannel: String?
|
||||||
var admin: String?
|
var admin: String?
|
||||||
var game: String?
|
var game: String?
|
||||||
var post: String?
|
var post: String?
|
||||||
@ -684,6 +685,10 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||||||
voiceChat = ""
|
voiceChat = ""
|
||||||
} else if queryItem.name == "startattach" {
|
} else if queryItem.name == "startattach" {
|
||||||
startAttach = ""
|
startAttach = ""
|
||||||
|
} else if queryItem.name == "startgroup" {
|
||||||
|
startGroup = ""
|
||||||
|
} else if queryItem.name == "startchannel" {
|
||||||
|
startChannel = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -698,7 +703,20 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||||||
if let start = start {
|
if let start = start {
|
||||||
result += "?start=\(start)"
|
result += "?start=\(start)"
|
||||||
} else if let startGroup = startGroup {
|
} else if let startGroup = startGroup {
|
||||||
|
if !startGroup.isEmpty {
|
||||||
result += "?startgroup=\(startGroup)"
|
result += "?startgroup=\(startGroup)"
|
||||||
|
} else {
|
||||||
|
result += "?startgroup"
|
||||||
|
}
|
||||||
|
if let admin = admin {
|
||||||
|
result += "&admin=\(admin)"
|
||||||
|
}
|
||||||
|
} else if let startChannel = startChannel {
|
||||||
|
if !startChannel.isEmpty {
|
||||||
|
result += "?startchannel=\(startChannel)"
|
||||||
|
} else {
|
||||||
|
result += "?startchannel"
|
||||||
|
}
|
||||||
if let admin = admin {
|
if let admin = admin {
|
||||||
result += "&admin=\(admin)"
|
result += "&admin=\(admin)"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -230,6 +230,15 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return .startAttach(peerName, nil, choose)
|
return .startAttach(peerName, nil, choose)
|
||||||
|
} else if queryItem.name == "startgroup" || queryItem.name == "startchannel" {
|
||||||
|
var botAdminRights: ResolvedBotAdminRights?
|
||||||
|
for queryItem in queryItems {
|
||||||
|
if queryItem.name == "admin", let value = queryItem.value {
|
||||||
|
botAdminRights = ResolvedBotAdminRights(value)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return .peerName(peerName, .groupBotStart("", botAdminRights))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,7 +477,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
|||||||
|> take(1)
|
|> take(1)
|
||||||
|> map { botPeer -> ResolvedUrl? in
|
|> map { botPeer -> ResolvedUrl? in
|
||||||
if let botPeer = botPeer?._asPeer() {
|
if let botPeer = botPeer?._asPeer() {
|
||||||
return .peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: startAttach)))
|
return .peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: startAttach, justInstalled: false)))
|
||||||
} else {
|
} else {
|
||||||
return .peer(peer.id, .chat(textInputState: nil, subject: nil, peekData: nil))
|
return .peer(peer.id, .chat(textInputState: nil, subject: nil, peekData: nil))
|
||||||
}
|
}
|
||||||
@ -502,7 +511,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl)
|
|||||||
}
|
}
|
||||||
|> mapToSignal { botPeer -> Signal<ResolvedUrl?, NoError> in
|
|> mapToSignal { botPeer -> Signal<ResolvedUrl?, NoError> in
|
||||||
if let botPeer = botPeer {
|
if let botPeer = botPeer {
|
||||||
return .single(.peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload))))
|
return .single(.peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: false))))
|
||||||
} else {
|
} else {
|
||||||
return .single(.peer(peer.id, .chat(textInputState: nil, subject: nil, peekData: nil)))
|
return .single(.peer(peer.id, .chat(textInputState: nil, subject: nil, peekData: nil)))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user