mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
d8c16d872d
commit
5004405e0b
@ -3765,6 +3765,7 @@ Unused sets are archived when you add more.";
|
|||||||
"AuthCode.Alert" = "Your login code is %@. Enter it in the Telegram app where you are trying to log in.\n\nDo not give this code to anyone.";
|
"AuthCode.Alert" = "Your login code is %@. Enter it in the Telegram app where you are trying to log in.\n\nDo not give this code to anyone.";
|
||||||
"Login.CheckOtherSessionMessages" = "Check your Telegram messages";
|
"Login.CheckOtherSessionMessages" = "Check your Telegram messages";
|
||||||
"Login.SendCodeViaSms" = "Send the code as an SMS";
|
"Login.SendCodeViaSms" = "Send the code as an SMS";
|
||||||
|
"Login.SendCodeViaCall" = "Get code on my phone";
|
||||||
"Login.CancelPhoneVerification" = "Do you want to stop the phone number verification process?";
|
"Login.CancelPhoneVerification" = "Do you want to stop the phone number verification process?";
|
||||||
"Login.CancelPhoneVerificationStop" = "Stop";
|
"Login.CancelPhoneVerificationStop" = "Stop";
|
||||||
"Login.CancelPhoneVerificationContinue" = "Continue";
|
"Login.CancelPhoneVerificationContinue" = "Continue";
|
||||||
@ -7101,3 +7102,24 @@ Sorry for the inconvenience.";
|
|||||||
"AuthSessions.TerminateOtherSessionsText" = "Are you sure you want to terminate all other sessions?";
|
"AuthSessions.TerminateOtherSessionsText" = "Are you sure you want to terminate all other sessions?";
|
||||||
|
|
||||||
"Notifications.ResetAllNotificationsText" = "Are you sure you want to reset all notification settings to default?";
|
"Notifications.ResetAllNotificationsText" = "Are you sure you want to reset all notification settings to default?";
|
||||||
|
|
||||||
|
"MessageCalendar.ClearHistoryForThisDay" = "Clear History For This Day";
|
||||||
|
"MessageCalendar.ClearHistoryForTheseDays" = "Clear History For These Days";
|
||||||
|
"MessageCalendar.EmptySelectionTooltip" = "Please select one or more days first.";
|
||||||
|
"Chat.MessageRangeDeleted.ForMe_1" = "Messages for 1 day deleted.";
|
||||||
|
"Chat.MessageRangeDeleted.ForMe_any" = "Messages for %@ days deleted.";
|
||||||
|
"Chat.MessageRangeDeleted.ForBothSides_1" = "Messages for 1 day deleted for both sides.";
|
||||||
|
"Chat.MessageRangeDeleted.ForBothSides_any" = "Messages for %@ days deleted for both sides.";
|
||||||
|
|
||||||
|
"ForcedPasswordSetup.Intro.Title" = "Set a Password";
|
||||||
|
"ForcedPasswordSetup.Intro.Text" = "If you want to log into your account frequently, please choose a password.";
|
||||||
|
"ForcedPasswordSetup.Intro.Action" = "Set a Password";
|
||||||
|
"ForcedPasswordSetup.Intro.DoneAction" = "Done";
|
||||||
|
"ForcedPasswordSetup.Intro.DismissTitle" = "Warning";
|
||||||
|
"ForcedPasswordSetup.Intro.DismissText_1" = "Proceed without a password? If you do not set a password, you will only be able to log into your account via SMS once every **day**.";
|
||||||
|
"ForcedPasswordSetup.Intro.DismissText_any" = "Proceed without a password? If you do not set a password, you will only be able to log into your account via SMS once every **%@ days**.";
|
||||||
|
"ForcedPasswordSetup.Intro.DismissActionCancel" = "No, let me set a password";
|
||||||
|
"ForcedPasswordSetup.Intro.DismissActionOK" = "Yes, I’m sure";
|
||||||
|
|
||||||
|
"Login.CodePhonePatternInfoText" = "Please enter the last digits\nof the missed call number.";
|
||||||
|
"Login.EnterMissingDigits" = "Enter the missing digits";
|
||||||
|
@ -45,7 +45,14 @@ public func authorizationNextOptionText(currentType: SentAuthorizationCodeType,
|
|||||||
} else {
|
} else {
|
||||||
switch currentType {
|
switch currentType {
|
||||||
case .otherSession:
|
case .otherSession:
|
||||||
return (NSAttributedString(string: strings.Login_SendCodeViaSms, font: Font.regular(16.0), textColor: accentColor, paragraphAlignment: .center), true)
|
switch nextType {
|
||||||
|
case .sms:
|
||||||
|
return (NSAttributedString(string: strings.Login_SendCodeViaSms, font: Font.regular(16.0), textColor: accentColor, paragraphAlignment: .center), true)
|
||||||
|
case .call, .flashCall, .missedCall:
|
||||||
|
return (NSAttributedString(string: strings.Login_SendCodeViaCall, font: Font.regular(16.0), textColor: accentColor, paragraphAlignment: .center), true)
|
||||||
|
case .none:
|
||||||
|
return (NSAttributedString(string: strings.Login_HaveNotReceivedCodeInternal, font: Font.regular(16.0), textColor: accentColor, paragraphAlignment: .center), true)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return (NSAttributedString(string: strings.Login_HaveNotReceivedCodeInternal, font: Font.regular(16.0), textColor: accentColor, paragraphAlignment: .center), true)
|
return (NSAttributedString(string: strings.Login_HaveNotReceivedCodeInternal, font: Font.regular(16.0), textColor: accentColor, paragraphAlignment: .center), true)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ swift_library(
|
|||||||
"//submodules/PhotoResources:PhotoResources",
|
"//submodules/PhotoResources:PhotoResources",
|
||||||
"//submodules/DirectMediaImageCache:DirectMediaImageCache",
|
"//submodules/DirectMediaImageCache:DirectMediaImageCache",
|
||||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||||
|
"//submodules/TooltipUI:TooltipUI",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -11,6 +11,7 @@ import ComponentFlow
|
|||||||
import PhotoResources
|
import PhotoResources
|
||||||
import DirectMediaImageCache
|
import DirectMediaImageCache
|
||||||
import TelegramStringFormatting
|
import TelegramStringFormatting
|
||||||
|
import TooltipUI
|
||||||
|
|
||||||
private final class NullActionClass: NSObject, CAAction {
|
private final class NullActionClass: NSObject, CAAction {
|
||||||
@objc func run(forKey event: String, object anObject: Any, arguments dict: [AnyHashable : Any]?) {
|
@objc func run(forKey event: String, object anObject: Any, arguments dict: [AnyHashable : Any]?) {
|
||||||
@ -896,21 +897,20 @@ private final class MonthComponent: CombinedComponent {
|
|||||||
let dayEnvironment = context.environment[DayEnvironment.self].value
|
let dayEnvironment = context.environment[DayEnvironment.self].value
|
||||||
|
|
||||||
let dayItemSize = updatedDays[0].size
|
let dayItemSize = updatedDays[0].size
|
||||||
let deltaWidth = floor((weekdayWidth - dayItemSize.width) / 2.0)
|
let selectionRadius: CGFloat = min(dayItemSize.width, dayItemSize.height)
|
||||||
let deltaHeight = floor((weekdaySize - dayItemSize.width) / 2.0)
|
|
||||||
|
let deltaWidth = floor((weekdayWidth - selectionRadius) / 2.0)
|
||||||
|
let deltaHeight = floor((weekdaySize - selectionRadius) / 2.0)
|
||||||
let minX = sideInset + CGFloat(selection.range.lowerBound) * weekdayWidth + deltaWidth
|
let minX = sideInset + CGFloat(selection.range.lowerBound) * weekdayWidth + deltaWidth
|
||||||
let maxX = sideInset + CGFloat(selection.range.upperBound + 1) * weekdayWidth - deltaWidth
|
let maxX = sideInset + CGFloat(selection.range.upperBound + 1) * weekdayWidth - deltaWidth
|
||||||
let minY = baseDayY + CGFloat(lineIndex) * (weekdaySize + weekdaySpacing) + deltaHeight
|
let minY = baseDayY + CGFloat(lineIndex) * (weekdaySize + weekdaySpacing) + deltaHeight
|
||||||
let maxY = minY + dayItemSize.width
|
let maxY = minY + selectionRadius
|
||||||
|
|
||||||
let leftRadius: CGFloat = dayItemSize.width
|
|
||||||
let rightRadius: CGFloat = dayItemSize.width
|
|
||||||
|
|
||||||
let monthSelectionColor = context.component.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.1)
|
let monthSelectionColor = context.component.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.1)
|
||||||
|
|
||||||
let selectionRect = CGRect(origin: CGPoint(x: minX, y: minY), size: CGSize(width: maxX - minX, height: maxY - minY))
|
let selectionRect = CGRect(origin: CGPoint(x: minX, y: minY), size: CGSize(width: maxX - minX, height: maxY - minY))
|
||||||
let selection = selections[lineIndex].update(
|
let selection = selections[lineIndex].update(
|
||||||
component: AnyComponent(ImageComponent(image: dayEnvironment.imageCache.monthSelection(leftRadius: leftRadius, rightRadius: rightRadius, maxRadius: dayItemSize.width, color: monthSelectionColor))),
|
component: AnyComponent(ImageComponent(image: dayEnvironment.imageCache.monthSelection(leftRadius: selectionRadius, rightRadius: selectionRadius, maxRadius: selectionRadius, color: monthSelectionColor))),
|
||||||
availableSize: selectionRect.size,
|
availableSize: selectionRect.size,
|
||||||
transition: .immediate
|
transition: .immediate
|
||||||
)
|
)
|
||||||
@ -923,7 +923,7 @@ private final class MonthComponent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
let delay = Double(min(delayIndex, 6)) * 0.1
|
let delay = Double(min(delayIndex, 6)) * 0.1
|
||||||
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.05, delay: delay)
|
view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.05, delay: delay)
|
||||||
view.layer.animateFrame(from: CGRect(origin: view.frame.origin, size: CGSize(width: leftRadius, height: view.frame.height)), to: view.frame, duration: 0.25, delay: delay, timingFunction: kCAMediaTimingFunctionSpring)
|
view.layer.animateFrame(from: CGRect(origin: view.frame.origin, size: CGSize(width: selectionRadius, height: view.frame.height)), to: view.frame, duration: 0.25, delay: delay, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
})
|
})
|
||||||
.disappear(Transition.Disappear { view, transition, completion in
|
.disappear(Transition.Disappear { view, transition, completion in
|
||||||
if case .none = transition.animation {
|
if case .none = transition.animation {
|
||||||
@ -1314,37 +1314,36 @@ public final class CalendarMessageScreen: ViewController {
|
|||||||
|
|
||||||
if let selectionState = self.selectionState {
|
if let selectionState = self.selectionState {
|
||||||
let selectionToolbarNode: ToolbarNode
|
let selectionToolbarNode: ToolbarNode
|
||||||
if let currrent = self.selectionToolbarNode {
|
let toolbarText: String
|
||||||
selectionToolbarNode = currrent
|
|
||||||
|
var selectedCount = 0
|
||||||
|
if let dayRange = selectionState.dayRange {
|
||||||
|
for i in 0 ..< self.months.count {
|
||||||
|
let firstDayTimestamp = Int32(self.months[i].firstDay.timeIntervalSince1970)
|
||||||
|
|
||||||
var selectedCount = 0
|
for day in 0 ..< self.months[i].numberOfDays {
|
||||||
if let dayRange = selectionState.dayRange {
|
let dayTimestamp = firstDayTimestamp + 24 * 60 * 60 * Int32(day)
|
||||||
for i in 0 ..< self.months.count {
|
|
||||||
let firstDayTimestamp = Int32(self.months[i].firstDay.timeIntervalSince1970)
|
|
||||||
|
|
||||||
for day in 0 ..< self.months[i].numberOfDays {
|
if dayRange.contains(dayTimestamp) {
|
||||||
let dayTimestamp = firstDayTimestamp + 24 * 60 * 60 * Int32(day)
|
selectedCount += 1
|
||||||
|
|
||||||
if dayRange.contains(dayTimestamp) {
|
|
||||||
selectedCount += 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let toolbarText: String
|
|
||||||
if selectedCount == 0 {
|
if selectedCount == 0 {
|
||||||
toolbarText = self.presentationData.strings.DialogList_ClearHistoryConfirmation
|
toolbarText = self.presentationData.strings.DialogList_ClearHistoryConfirmation
|
||||||
} else if selectedCount == 1 {
|
} else if selectedCount == 1 {
|
||||||
//TODO:localize
|
toolbarText = self.presentationData.strings.MessageCalendar_ClearHistoryForThisDay
|
||||||
toolbarText = "Clear History For This Day"
|
} else {
|
||||||
} else {
|
toolbarText = self.presentationData.strings.MessageCalendar_ClearHistoryForTheseDays
|
||||||
//TODO:localize
|
}
|
||||||
toolbarText = "Clear History For These Days"
|
|
||||||
}
|
if let currrent = self.selectionToolbarNode {
|
||||||
|
selectionToolbarNode = currrent
|
||||||
|
|
||||||
transition.updateFrame(node: selectionToolbarNode, frame: tabBarFrame)
|
transition.updateFrame(node: selectionToolbarNode, frame: tabBarFrame)
|
||||||
selectionToolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, additionalSideInsets: layout.additionalInsets, bottomInset: bottomInset, toolbar: Toolbar(leftAction: nil, rightAction: nil, middleAction: ToolbarAction(title: toolbarText, isEnabled: self.selectionState?.dayRange != nil, color: .custom(self.presentationData.theme.list.itemDestructiveColor))), transition: transition)
|
selectionToolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, additionalSideInsets: layout.additionalInsets, bottomInset: bottomInset, toolbar: Toolbar(leftAction: nil, rightAction: nil, middleAction: ToolbarAction(title: toolbarText, isEnabled: true, color: .custom(self.selectionState?.dayRange != nil ? self.presentationData.theme.list.itemDestructiveColor : self.presentationData.theme.list.itemDisabledTextColor))), transition: transition)
|
||||||
} else {
|
} else {
|
||||||
selectionToolbarNode = ToolbarNode(
|
selectionToolbarNode = ToolbarNode(
|
||||||
theme: TabBarControllerTheme(
|
theme: TabBarControllerTheme(
|
||||||
@ -1359,7 +1358,7 @@ public final class CalendarMessageScreen: ViewController {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
selectionToolbarNode.frame = tabBarFrame
|
selectionToolbarNode.frame = tabBarFrame
|
||||||
selectionToolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, additionalSideInsets: layout.additionalInsets, bottomInset: bottomInset, toolbar: Toolbar(leftAction: nil, rightAction: nil, middleAction: ToolbarAction(title: self.presentationData.strings.DialogList_ClearHistoryConfirmation, isEnabled: self.selectionState?.dayRange != nil, color: .custom(self.presentationData.theme.list.itemDestructiveColor))), transition: .immediate)
|
selectionToolbarNode.updateLayout(size: tabBarFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, additionalSideInsets: layout.additionalInsets, bottomInset: bottomInset, toolbar: Toolbar(leftAction: nil, rightAction: nil, middleAction: ToolbarAction(title: toolbarText, isEnabled: true, color: .custom(self.selectionState?.dayRange != nil ? self.presentationData.theme.list.itemDestructiveColor : self.presentationData.theme.list.itemDisabledTextColor))), transition: .immediate)
|
||||||
self.addSubnode(selectionToolbarNode)
|
self.addSubnode(selectionToolbarNode)
|
||||||
self.selectionToolbarNode = selectionToolbarNode
|
self.selectionToolbarNode = selectionToolbarNode
|
||||||
transition.animatePositionAdditive(node: selectionToolbarNode, offset: CGPoint(x: 0.0, y: tabBarFrame.height))
|
transition.animatePositionAdditive(node: selectionToolbarNode, offset: CGPoint(x: 0.0, y: tabBarFrame.height))
|
||||||
@ -1425,6 +1424,16 @@ public final class CalendarMessageScreen: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func selectionToolbarActionSelected() {
|
private func selectionToolbarActionSelected() {
|
||||||
|
if self.selectionState?.dayRange == nil {
|
||||||
|
if let selectionToolbarNode = self.selectionToolbarNode {
|
||||||
|
let toolbarFrame = selectionToolbarNode.view.convert(selectionToolbarNode.bounds, to: self.view)
|
||||||
|
self.controller?.present(TooltipScreen(account: self.context.account, text: self.presentationData.strings.MessageCalendar_EmptySelectionTooltip, style: .default, icon: .none, location: .point(toolbarFrame.insetBy(dx: 0.0, dy: 10.0), .bottom), shouldDismissOnTouch: { point in
|
||||||
|
return .dismiss(consume: false)
|
||||||
|
}), in: .current)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
guard let selectionState = self.selectionState, let dayRange = selectionState.dayRange else {
|
guard let selectionState = self.selectionState, let dayRange = selectionState.dayRange else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import TelegramIntents
|
|||||||
import TooltipUI
|
import TooltipUI
|
||||||
import TelegramCallsUI
|
import TelegramCallsUI
|
||||||
import StickerResources
|
import StickerResources
|
||||||
|
import PasswordSetupUI
|
||||||
|
|
||||||
private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool {
|
private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool {
|
||||||
if listNode.scroller.isDragging {
|
if listNode.scroller.isDragging {
|
||||||
@ -1264,6 +1265,53 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
})
|
})
|
||||||
], actionLayout: .vertical, parseMarkdown: true), in: .window(.root))
|
], actionLayout: .vertical, parseMarkdown: true), in: .window(.root))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
Queue.mainQueue().after(1.0, {
|
||||||
|
let _ = (self.context.account.postbox.transaction { transaction -> Int32? in
|
||||||
|
if let value = transaction.getNoticeEntry(key: ApplicationSpecificNotice.forcedPasswordSetupKey())?.get(ApplicationSpecificCounterNotice.self) {
|
||||||
|
return value.value
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let value = value else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = TwoFactorAuthSplashScreen(sharedContext: context.sharedContext, engine: .authorized(strongSelf.context.engine), mode: .intro(.init(
|
||||||
|
title: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_Title,
|
||||||
|
text: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_Text,
|
||||||
|
actionText: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_Action,
|
||||||
|
doneText: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DoneAction
|
||||||
|
)))
|
||||||
|
controller.dismissConfirmation = { [weak controller] f in
|
||||||
|
guard let strongSelf = self, let controller = controller else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DismissTitle, text: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DismissText(value), actions: [
|
||||||
|
TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DismissActionCancel, action: {
|
||||||
|
}),
|
||||||
|
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.ForcedPasswordSetup_Intro_DismissActionOK, action: { [weak controller] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
let _ = ApplicationSpecificNotice.setForcedPasswordSetup(postbox: strongSelf.context.account.postbox, reloginDaysTimeout: nil).start()
|
||||||
|
}
|
||||||
|
controller?.dismiss()
|
||||||
|
})
|
||||||
|
], parseMarkdown: true), in: .window(.root))
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
strongSelf.push(controller)
|
||||||
|
|
||||||
|
let _ = value
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.chatListDisplayNode.containerNode.addedVisibleChatsWithPeerIds = { [weak self] peerIds in
|
self.chatListDisplayNode.containerNode.addedVisibleChatsWithPeerIds = { [weak self] peerIds in
|
||||||
|
@ -101,9 +101,9 @@ public final class ConstantDisplayLinkAnimator {
|
|||||||
self.displayLink = CADisplayLink(target: DisplayLinkTarget({ [weak self] in
|
self.displayLink = CADisplayLink(target: DisplayLinkTarget({ [weak self] in
|
||||||
self?.tick()
|
self?.tick()
|
||||||
}), selector: #selector(DisplayLinkTarget.event))
|
}), selector: #selector(DisplayLinkTarget.event))
|
||||||
if #available(iOS 15.0, *) {
|
/*if #available(iOS 15.0, *) {
|
||||||
self.displayLink?.preferredFrameRateRange = CAFrameRateRange(minimum: 60.0, maximum: 120.0, preferred: 120.0)
|
self.displayLink?.preferredFrameRateRange = CAFrameRateRange(minimum: 60.0, maximum: 120.0, preferred: 120.0)
|
||||||
}
|
}*/
|
||||||
self.displayLink.isPaused = true
|
self.displayLink.isPaused = true
|
||||||
self.displayLink.add(to: RunLoop.main, forMode: .common)
|
self.displayLink.add(to: RunLoop.main, forMode: .common)
|
||||||
}
|
}
|
||||||
|
@ -35,14 +35,14 @@ public enum TwoFactorDataInputMode {
|
|||||||
case authorized
|
case authorized
|
||||||
}
|
}
|
||||||
|
|
||||||
case password
|
case password(doneText: String)
|
||||||
case passwordRecoveryEmail(emailPattern: String, mode: PasswordRecoveryEmailMode)
|
case passwordRecoveryEmail(emailPattern: String, mode: PasswordRecoveryEmailMode, doneText: String)
|
||||||
case passwordRecovery(Recovery)
|
case passwordRecovery(recovery: Recovery, doneText: String)
|
||||||
case emailAddress(password: String, hint: String)
|
case emailAddress(password: String, hint: String, doneText: String)
|
||||||
case updateEmailAddress(password: String)
|
case updateEmailAddress(password: String, doneText: String)
|
||||||
case emailConfirmation(passwordAndHint: (String, String)?, emailPattern: String, codeLength: Int?)
|
case emailConfirmation(passwordAndHint: (String, String)?, emailPattern: String, codeLength: Int?, doneText: String)
|
||||||
case passwordHint(recovery: Recovery?, password: String)
|
case passwordHint(recovery: Recovery?, password: String, doneText: String)
|
||||||
case rememberPassword
|
case rememberPassword(doneText: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class TwoFactorDataInputScreen: ViewController {
|
public final class TwoFactorDataInputScreen: ViewController {
|
||||||
@ -110,7 +110,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch strongSelf.mode {
|
switch strongSelf.mode {
|
||||||
case .password:
|
case let .password(doneText):
|
||||||
let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText
|
let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText
|
||||||
if values.count != 2 {
|
if values.count != 2 {
|
||||||
return
|
return
|
||||||
@ -136,9 +136,9 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordHint(recovery: nil, password: values[0]), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordHint(recovery: nil, password: values[0], doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
case let .passwordRecoveryEmail(_, mode):
|
case let .passwordRecoveryEmail(_, mode, doneText):
|
||||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -180,14 +180,14 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
mappedMode = .notAuthorized(syncContacts: syncContacts)
|
mappedMode = .notAuthorized(syncContacts: syncContacts)
|
||||||
}
|
}
|
||||||
|
|
||||||
let setupController = TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordRecovery(TwoFactorDataInputMode.Recovery(code: text, mode: mappedMode)), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation)
|
let setupController = TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordRecovery(recovery: TwoFactorDataInputMode.Recovery(code: text, mode: mappedMode), doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation)
|
||||||
|
|
||||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
navigationController.replaceController(strongSelf, with: setupController, animated: true)
|
navigationController.replaceController(strongSelf, with: setupController, animated: true)
|
||||||
}))
|
}))
|
||||||
case let .passwordRecovery(recovery):
|
case let .passwordRecovery(recovery, doneText):
|
||||||
let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText
|
let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText
|
||||||
if values.count != 2 {
|
if values.count != 2 {
|
||||||
return
|
return
|
||||||
@ -204,8 +204,8 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
navigationController.replaceController(strongSelf, with: TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordHint(recovery: recovery, password: values[0]), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation), animated: true)
|
navigationController.replaceController(strongSelf, with: TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .passwordHint(recovery: recovery, password: values[0], doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation), animated: true)
|
||||||
case let .emailAddress(password, hint):
|
case let .emailAddress(password, hint, doneText):
|
||||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailConfirmation(passwordAndHint: (password, hint), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init)), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailConfirmation(passwordAndHint: (password, hint), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init), doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
} else {
|
} else {
|
||||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||||
@ -252,7 +252,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done))
|
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done(doneText: doneText)))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: alertText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
strongSelf.present(textAlertController(sharedContext: strongSelf.sharedContext, title: nil, text: alertText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
})
|
})
|
||||||
case let .updateEmailAddress(password):
|
case let .updateEmailAddress(password, doneText):
|
||||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailConfirmation(passwordAndHint: (password, ""), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init)), stateUpdated: strongSelf.stateUpdated))
|
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailConfirmation(passwordAndHint: (password, ""), emailPattern: text, codeLength: pendingEmail.codeLength.flatMap(Int.init), doneText: doneText), stateUpdated: strongSelf.stateUpdated))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
} else {
|
} else {
|
||||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||||
@ -322,7 +322,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done))
|
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done(doneText: doneText)))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,7 +346,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
case .unauthorized:
|
case .unauthorized:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case .emailConfirmation:
|
case let .emailConfirmation(_, _, _, doneText):
|
||||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -397,13 +397,13 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done))
|
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done(doneText: doneText)))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
})
|
})
|
||||||
case .unauthorized:
|
case .unauthorized:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case let .passwordHint(recovery, password):
|
case let .passwordHint(recovery, password, doneText):
|
||||||
guard let value = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !value.isEmpty else {
|
guard let value = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !value.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -411,7 +411,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
if let recovery = recovery {
|
if let recovery = recovery {
|
||||||
strongSelf.performRecovery(recovery: recovery, password: password, hint: value)
|
strongSelf.performRecovery(recovery: recovery, password: password, hint: value)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: value), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: value, doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
||||||
}
|
}
|
||||||
case .rememberPassword:
|
case .rememberPassword:
|
||||||
guard case let .authorized(engine) = strongSelf.engine else {
|
guard case let .authorized(engine) = strongSelf.engine else {
|
||||||
@ -476,7 +476,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch strongSelf.mode {
|
switch strongSelf.mode {
|
||||||
case let .emailAddress(password, hint):
|
case let .emailAddress(password, hint, doneText):
|
||||||
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.TwoFactorSetup_Email_SkipConfirmationTitle, text: strongSelf.presentationData.strings.TwoFactorSetup_Email_SkipConfirmationText, actions: [
|
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.TwoFactorSetup_Email_SkipConfirmationTitle, text: strongSelf.presentationData.strings.TwoFactorSetup_Email_SkipConfirmationText, actions: [
|
||||||
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.TwoFactorSetup_Email_SkipConfirmationSkip, action: {
|
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.TwoFactorSetup_Email_SkipConfirmationSkip, action: {
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
@ -509,7 +509,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done))
|
controllers.append(TwoFactorAuthSplashScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .done(doneText: doneText)))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
}
|
}
|
||||||
}, error: { [weak statusController] error in
|
}, error: { [weak statusController] error in
|
||||||
@ -532,13 +532,13 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}),
|
}),
|
||||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})
|
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})
|
||||||
]), in: .window(.root))
|
]), in: .window(.root))
|
||||||
case let .passwordHint(recovery, password):
|
case let .passwordHint(recovery, password, doneText):
|
||||||
if let recovery = recovery {
|
if let recovery = recovery {
|
||||||
strongSelf.performRecovery(recovery: recovery, password: password, hint: "")
|
strongSelf.performRecovery(recovery: recovery, password: password, hint: "")
|
||||||
} else {
|
} else {
|
||||||
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: ""), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: "", doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
||||||
}
|
}
|
||||||
case let .passwordRecovery(recovery):
|
case let .passwordRecovery(recovery, _):
|
||||||
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertTitle, text: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertText, actions: [
|
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertTitle, text: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertText, actions: [
|
||||||
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertAction, action: {
|
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertAction, action: {
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
@ -548,7 +548,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}),
|
}),
|
||||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})
|
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})
|
||||||
]), in: .window(.root))
|
]), in: .window(.root))
|
||||||
case .rememberPassword:
|
case let .rememberPassword(doneText):
|
||||||
guard case let .authorized(engine) = strongSelf.engine else {
|
guard case let .authorized(engine) = strongSelf.engine else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -575,7 +575,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
disposable.set((engine.auth.requestTwoStepVerificationPasswordRecoveryCode()
|
disposable.set((engine.auth.requestTwoStepVerificationPasswordRecoveryCode()
|
||||||
|> deliverOnMainQueue).start(next: { emailPattern in
|
|> deliverOnMainQueue).start(next: { emailPattern in
|
||||||
var stateUpdated: ((SetupTwoStepVerificationStateUpdate) -> Void)?
|
var stateUpdated: ((SetupTwoStepVerificationStateUpdate) -> Void)?
|
||||||
let controller = TwoFactorDataInputScreen(sharedContext: sharedContext, engine: .authorized(engine), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .authorized), stateUpdated: { state in
|
let controller = TwoFactorDataInputScreen(sharedContext: sharedContext, engine: .authorized(engine), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .authorized, doneText: doneText), stateUpdated: { state in
|
||||||
stateUpdated?(state)
|
stateUpdated?(state)
|
||||||
})
|
})
|
||||||
stateUpdated = { [weak controller] state in
|
stateUpdated = { [weak controller] state in
|
||||||
@ -706,7 +706,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch strongSelf.mode {
|
switch strongSelf.mode {
|
||||||
case let .emailConfirmation(passwordAndHint, _, _):
|
case let .emailConfirmation(passwordAndHint, _, _, doneText):
|
||||||
if let (password, hint) = passwordAndHint {
|
if let (password, hint) = passwordAndHint {
|
||||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
@ -720,7 +720,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: hint), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
controllers.append(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .emailAddress(password: password, hint: hint, doneText: doneText), stateUpdated: strongSelf.stateUpdated, presentation: strongSelf.navigationPresentation))
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
@ -1371,7 +1371,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
toggleTextHidden?(node)
|
toggleTextHidden?(node)
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
case let .passwordRecoveryEmail(emailPattern, _):
|
case let .passwordRecoveryEmail(emailPattern, _, _):
|
||||||
title = presentationData.strings.TwoFactorSetup_EmailVerification_Title
|
title = presentationData.strings.TwoFactorSetup_EmailVerification_Title
|
||||||
let formattedString = presentationData.strings.TwoFactorSetup_EmailVerification_Text(emailPattern)
|
let formattedString = presentationData.strings.TwoFactorSetup_EmailVerification_Text(emailPattern)
|
||||||
|
|
||||||
@ -1398,7 +1398,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
toggleTextHidden?(node)
|
toggleTextHidden?(node)
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
case let .emailConfirmation(_, emailPattern, _):
|
case let .emailConfirmation(_, emailPattern, _, _):
|
||||||
title = presentationData.strings.TwoFactorSetup_EmailVerification_Title
|
title = presentationData.strings.TwoFactorSetup_EmailVerification_Title
|
||||||
let formattedString = presentationData.strings.TwoFactorSetup_EmailVerification_Text(emailPattern)
|
let formattedString = presentationData.strings.TwoFactorSetup_EmailVerification_Text(emailPattern)
|
||||||
|
|
||||||
@ -1654,7 +1654,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
strongSelf.buttonNode.isHidden = !hasText
|
strongSelf.buttonNode.isHidden = !hasText
|
||||||
strongSelf.skipActionTitleNode.isHidden = hasText
|
strongSelf.skipActionTitleNode.isHidden = hasText
|
||||||
strongSelf.skipActionButtonNode.isHidden = hasText
|
strongSelf.skipActionButtonNode.isHidden = hasText
|
||||||
case let .emailConfirmation(_, _, codeLength):
|
case let .emailConfirmation(_, _, codeLength, _):
|
||||||
let text = strongSelf.inputNodes[0].text
|
let text = strongSelf.inputNodes[0].text
|
||||||
let hasText = !text.isEmpty
|
let hasText = !text.isEmpty
|
||||||
strongSelf.buttonNode.isHidden = !hasText
|
strongSelf.buttonNode.isHidden = !hasText
|
||||||
|
@ -13,8 +13,27 @@ import PresentationDataUtils
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
|
||||||
public enum TwoFactorAuthSplashMode {
|
public enum TwoFactorAuthSplashMode {
|
||||||
case intro
|
public struct Intro {
|
||||||
case done
|
public var title: String
|
||||||
|
public var text: String
|
||||||
|
public var actionText: String
|
||||||
|
public var doneText: String
|
||||||
|
|
||||||
|
public init(
|
||||||
|
title: String,
|
||||||
|
text: String,
|
||||||
|
actionText: String,
|
||||||
|
doneText: String
|
||||||
|
) {
|
||||||
|
self.title = title
|
||||||
|
self.text = text
|
||||||
|
self.actionText = actionText
|
||||||
|
self.doneText = doneText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case intro(Intro)
|
||||||
|
case done(doneText: String)
|
||||||
case recoveryDone(recoveredAccountData: RecoveredAccountData?, syncContacts: Bool, isPasswordSet: Bool)
|
case recoveryDone(recoveredAccountData: RecoveredAccountData?, syncContacts: Bool, isPasswordSet: Bool)
|
||||||
case remember
|
case remember
|
||||||
}
|
}
|
||||||
@ -25,6 +44,8 @@ public final class TwoFactorAuthSplashScreen: ViewController {
|
|||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
private var mode: TwoFactorAuthSplashMode
|
private var mode: TwoFactorAuthSplashMode
|
||||||
|
|
||||||
|
public var dismissConfirmation: ((@escaping () -> Void) -> Bool)?
|
||||||
|
|
||||||
public init(sharedContext: SharedAccountContext, engine: SomeTelegramEngine, mode: TwoFactorAuthSplashMode, presentation: ViewControllerNavigationPresentation = .modalInLargeLayout) {
|
public init(sharedContext: SharedAccountContext, engine: SomeTelegramEngine, mode: TwoFactorAuthSplashMode, presentation: ViewControllerNavigationPresentation = .modalInLargeLayout) {
|
||||||
self.sharedContext = sharedContext
|
self.sharedContext = sharedContext
|
||||||
self.engine = engine
|
self.engine = engine
|
||||||
@ -55,6 +76,14 @@ public final class TwoFactorAuthSplashScreen: ViewController {
|
|||||||
} else {
|
} else {
|
||||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customDisplayNode: ASDisplayNode())
|
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customDisplayNode: ASDisplayNode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.attemptNavigation = { [weak self] f in
|
||||||
|
guard let strongSelf = self, let dismissConfirmation = strongSelf.dismissConfirmation else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return dismissConfirmation(f)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
required init(coder aDecoder: NSCoder) {
|
required init(coder aDecoder: NSCoder) {
|
||||||
@ -70,8 +99,8 @@ public final class TwoFactorAuthSplashScreen: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch strongSelf.mode {
|
switch strongSelf.mode {
|
||||||
case .intro:
|
case let .intro(intro):
|
||||||
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .password, stateUpdated: { _ in
|
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .password(doneText: intro.doneText), stateUpdated: { _ in
|
||||||
}, presentation: strongSelf.navigationPresentation))
|
}, presentation: strongSelf.navigationPresentation))
|
||||||
case .done, .remember:
|
case .done, .remember:
|
||||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||||
@ -136,18 +165,18 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
|
|||||||
let textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
let textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
case .intro:
|
case let .intro(intro):
|
||||||
title = self.presentationData.strings.TwoFactorSetup_Intro_Title
|
title = intro.title
|
||||||
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Intro_Text, font: textFont, textColor: textColor)]
|
texts = [NSAttributedString(string: intro.text, font: textFont, textColor: textColor)]
|
||||||
buttonText = self.presentationData.strings.TwoFactorSetup_Intro_Action
|
buttonText = intro.actionText
|
||||||
|
|
||||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupIntro"), width: 248, height: 248, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupIntro"), width: 248, height: 248, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||||
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
||||||
self.animationNode.visibility = true
|
self.animationNode.visibility = true
|
||||||
case .done:
|
case let .done(doneText):
|
||||||
title = self.presentationData.strings.TwoFactorSetup_Done_Title
|
title = self.presentationData.strings.TwoFactorSetup_Done_Title
|
||||||
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Done_Text, font: textFont, textColor: textColor)]
|
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Done_Text, font: textFont, textColor: textColor)]
|
||||||
buttonText = self.presentationData.strings.TwoFactorSetup_Done_Action
|
buttonText = doneText
|
||||||
|
|
||||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupDone"), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
|
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "TwoFactorSetupDone"), width: 248, height: 248, mode: .direct(cachePathPrefix: nil))
|
||||||
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
self.animationSize = CGSize(width: 124.0, height: 124.0)
|
||||||
|
@ -732,7 +732,13 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
|||||||
break
|
break
|
||||||
case let .notSet(pendingEmail):
|
case let .notSet(pendingEmail):
|
||||||
if pendingEmail == nil {
|
if pendingEmail == nil {
|
||||||
let controller = TwoFactorAuthSplashScreen(sharedContext: context.sharedContext, engine: .authorized(context.engine), mode: .intro)
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = TwoFactorAuthSplashScreen(sharedContext: context.sharedContext, engine: .authorized(context.engine), mode: .intro(.init(
|
||||||
|
title: presentationData.strings.TwoFactorSetup_Intro_Title,
|
||||||
|
text: presentationData.strings.TwoFactorSetup_Intro_Text,
|
||||||
|
actionText: presentationData.strings.TwoFactorSetup_Intro_Action,
|
||||||
|
doneText: presentationData.strings.TwoFactorSetup_Done_Action
|
||||||
|
)))
|
||||||
|
|
||||||
pushControllerImpl?(controller, true)
|
pushControllerImpl?(controller, true)
|
||||||
return
|
return
|
||||||
|
@ -509,7 +509,7 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var stateUpdated: ((SetupTwoStepVerificationStateUpdate) -> Void)?
|
var stateUpdated: ((SetupTwoStepVerificationStateUpdate) -> Void)?
|
||||||
let controller = TwoFactorDataInputScreen(sharedContext: context.sharedContext, engine: .authorized(context.engine), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .authorized), stateUpdated: { state in
|
let controller = TwoFactorDataInputScreen(sharedContext: context.sharedContext, engine: .authorized(context.engine), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .authorized, doneText: presentationData.strings.TwoFactorSetup_Done_Action), stateUpdated: { state in
|
||||||
stateUpdated?(state)
|
stateUpdated?(state)
|
||||||
})
|
})
|
||||||
stateUpdated = { [weak controller] state in
|
stateUpdated = { [weak controller] state in
|
||||||
|
@ -105,11 +105,11 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
|
|||||||
}
|
}
|
||||||
|> `catch` { error -> Signal<(SendCodeResult, UnauthorizedAccount), MTRpcError> in
|
|> `catch` { error -> Signal<(SendCodeResult, UnauthorizedAccount), MTRpcError> in
|
||||||
if error.errorDescription == "SESSION_PASSWORD_NEEDED" {
|
if error.errorDescription == "SESSION_PASSWORD_NEEDED" {
|
||||||
return account.network.request(Api.functions.account.getPassword(), automaticFloodWait: false)
|
return updatedAccount.network.request(Api.functions.account.getPassword(), automaticFloodWait: false)
|
||||||
|> mapToSignal { result -> Signal<(SendCodeResult, UnauthorizedAccount), MTRpcError> in
|
|> mapToSignal { result -> Signal<(SendCodeResult, UnauthorizedAccount), MTRpcError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .password(_, _, _, _, hint, _, _, _, _, _):
|
case let .password(_, _, _, _, hint, _, _, _, _, _):
|
||||||
return .single((.password(hint: hint), account))
|
return .single((.password(hint: hint), updatedAccount))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -252,7 +252,7 @@ public enum AuthorizeWithCodeResult {
|
|||||||
case loggedIn
|
case loggedIn
|
||||||
}
|
}
|
||||||
|
|
||||||
public func authorizeWithCode(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, code: String, termsOfService: UnauthorizedAccountTermsOfService?) -> Signal<AuthorizeWithCodeResult, AuthorizationCodeVerificationError> {
|
public func authorizeWithCode(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, code: String, termsOfService: UnauthorizedAccountTermsOfService?, forcedPasswordSetupNotice: @escaping (Int32) -> (NoticeEntryKey, CodableEntry)?) -> Signal<AuthorizeWithCodeResult, AuthorizationCodeVerificationError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<AuthorizeWithCodeResult, AuthorizationCodeVerificationError> in
|
return account.postbox.transaction { transaction -> Signal<AuthorizeWithCodeResult, AuthorizationCodeVerificationError> in
|
||||||
if let state = transaction.getState() as? UnauthorizedAccountState {
|
if let state = transaction.getState() as? UnauthorizedAccountState {
|
||||||
switch state.contents {
|
switch state.contents {
|
||||||
@ -302,11 +302,14 @@ public func authorizeWithCode(accountManager: AccountManager<TelegramAccountMana
|
|||||||
return .single(.loggedIn)
|
return .single(.loggedIn)
|
||||||
case let .authorization(authorization):
|
case let .authorization(authorization):
|
||||||
switch authorization {
|
switch authorization {
|
||||||
case let .authorization(_, _, _, user):
|
case let .authorization(_, otherwiseReloginDays, _, user):
|
||||||
let user = TelegramUser(user: user)
|
let user = TelegramUser(user: user)
|
||||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||||
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
||||||
transaction.setState(state)
|
transaction.setState(state)
|
||||||
|
if let otherwiseReloginDays = otherwiseReloginDays, let value = forcedPasswordSetupNotice(otherwiseReloginDays) {
|
||||||
|
transaction.setNoticeEntry(key: value.0, value: value.1)
|
||||||
|
}
|
||||||
return accountManager.transaction { transaction -> AuthorizeWithCodeResult in
|
return accountManager.transaction { transaction -> AuthorizeWithCodeResult in
|
||||||
switchToAuthorizedAccount(transaction: transaction, account: account)
|
switchToAuthorizedAccount(transaction: transaction, account: account)
|
||||||
return .loggedIn
|
return .loggedIn
|
||||||
@ -542,7 +545,7 @@ public enum SignUpError {
|
|||||||
case invalidLastName
|
case invalidLastName
|
||||||
}
|
}
|
||||||
|
|
||||||
public func signUpWithName(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, firstName: String, lastName: String, avatarData: Data?, avatarVideo: Signal<UploadedPeerPhotoData?, NoError>?, videoStartTimestamp: Double?) -> Signal<Void, SignUpError> {
|
public func signUpWithName(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, firstName: String, lastName: String, avatarData: Data?, avatarVideo: Signal<UploadedPeerPhotoData?, NoError>?, videoStartTimestamp: Double?, forcedPasswordSetupNotice: @escaping (Int32) -> (NoticeEntryKey, CodableEntry)?) -> Signal<Void, SignUpError> {
|
||||||
return account.postbox.transaction { transaction -> Signal<Void, SignUpError> in
|
return account.postbox.transaction { transaction -> Signal<Void, SignUpError> in
|
||||||
if let state = transaction.getState() as? UnauthorizedAccountState, case let .signUp(number, codeHash, _, _, _, syncContacts) = state.contents {
|
if let state = transaction.getState() as? UnauthorizedAccountState, case let .signUp(number, codeHash, _, _, _, syncContacts) = state.contents {
|
||||||
return account.network.request(Api.functions.auth.signUp(phoneNumber: number, phoneCodeHash: codeHash, firstName: firstName, lastName: lastName))
|
return account.network.request(Api.functions.auth.signUp(phoneNumber: number, phoneCodeHash: codeHash, firstName: firstName, lastName: lastName))
|
||||||
@ -561,7 +564,7 @@ public func signUpWithName(accountManager: AccountManager<TelegramAccountManager
|
|||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<Void, SignUpError> in
|
|> mapToSignal { result -> Signal<Void, SignUpError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .authorization(_, _, _, user):
|
case let .authorization(_, otherwiseReloginDays, _, user):
|
||||||
let user = TelegramUser(user: user)
|
let user = TelegramUser(user: user)
|
||||||
let appliedState = account.postbox.transaction { transaction -> Void in
|
let appliedState = account.postbox.transaction { transaction -> Void in
|
||||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||||
@ -570,8 +573,11 @@ public func signUpWithName(accountManager: AccountManager<TelegramAccountManager
|
|||||||
}
|
}
|
||||||
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
||||||
transaction.setState(state)
|
transaction.setState(state)
|
||||||
|
if let otherwiseReloginDays = otherwiseReloginDays, let value = forcedPasswordSetupNotice(otherwiseReloginDays) {
|
||||||
|
transaction.setNoticeEntry(key: value.0, value: value.1)
|
||||||
}
|
}
|
||||||
|> castError(SignUpError.self)
|
}
|
||||||
|
|> castError(SignUpError.self)
|
||||||
|
|
||||||
let switchedAccounts = accountManager.transaction { transaction -> Void in
|
let switchedAccounts = accountManager.transaction { transaction -> Void in
|
||||||
switchToAuthorizedAccount(transaction: transaction, account: account)
|
switchToAuthorizedAccount(transaction: transaction, account: account)
|
||||||
|
@ -162,6 +162,7 @@ private enum ApplicationSpecificGlobalNotice: Int32 {
|
|||||||
case interactiveEmojiSyncTip = 28
|
case interactiveEmojiSyncTip = 28
|
||||||
case sharedMediaScrollingTooltip = 29
|
case sharedMediaScrollingTooltip = 29
|
||||||
case sharedMediaFastScrollingTooltip = 30
|
case sharedMediaFastScrollingTooltip = 30
|
||||||
|
case forcedPasswordSetup = 31
|
||||||
|
|
||||||
var key: ValueBoxKey {
|
var key: ValueBoxKey {
|
||||||
let v = ValueBoxKey(length: 4)
|
let v = ValueBoxKey(length: 4)
|
||||||
@ -211,6 +212,10 @@ private struct ApplicationSpecificNoticeKeys {
|
|||||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: peerReportNamespace), key: noticeKey(peerId: peerId, key: 0))
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: peerReportNamespace), key: noticeKey(peerId: peerId, key: 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func forcedPasswordSetup() -> NoticeEntryKey {
|
||||||
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.secretChatInlineBotUsage.key)
|
||||||
|
}
|
||||||
|
|
||||||
static func secretChatInlineBotUsage() -> NoticeEntryKey {
|
static func secretChatInlineBotUsage() -> NoticeEntryKey {
|
||||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.secretChatInlineBotUsage.key)
|
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.secretChatInlineBotUsage.key)
|
||||||
}
|
}
|
||||||
@ -1098,6 +1103,23 @@ public struct ApplicationSpecificNotice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func forcedPasswordSetupKey() -> NoticeEntryKey {
|
||||||
|
return ApplicationSpecificNoticeKeys.forcedPasswordSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func setForcedPasswordSetup(postbox: Postbox, reloginDaysTimeout: Int32?) -> Signal<Never, NoError> {
|
||||||
|
return postbox.transaction { transaction -> Void in
|
||||||
|
if let reloginDaysTimeout = reloginDaysTimeout {
|
||||||
|
if let entry = CodableEntry(ApplicationSpecificCounterNotice(value: reloginDaysTimeout)) {
|
||||||
|
transaction.setNoticeEntry(key: ApplicationSpecificNoticeKeys.forcedPasswordSetup(), value: entry)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
transaction.setNoticeEntry(key: ApplicationSpecificNoticeKeys.forcedPasswordSetup(), value: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
}
|
||||||
|
|
||||||
public static func reset(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Void, NoError> {
|
public static func reset(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Void, NoError> {
|
||||||
return accountManager.transaction { transaction -> Void in
|
return accountManager.transaction { transaction -> Void in
|
||||||
}
|
}
|
||||||
|
@ -177,8 +177,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
|
|
||||||
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 {
|
||||||
//TODO:localize
|
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: "Please enter the last five digits\nof the missed call number.", font: Font.regular(16.0), textColor: self.theme.list.itemPrimaryTextColor, paragraphAlignment: .center)
|
|
||||||
} else {
|
} else {
|
||||||
self.currentOptionInfoNode.attributedText = NSAttributedString(string: "", font: Font.regular(15.0), textColor: self.theme.list.itemPrimaryTextColor)
|
self.currentOptionInfoNode.attributedText = NSAttributedString(string: "", font: Font.regular(15.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
}
|
}
|
||||||
@ -227,8 +226,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
case .otherSession:
|
case .otherSession:
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_CheckOtherSessionMessages, font: Font.medium(32.0), textColor: self.theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_CheckOtherSessionMessages, font: Font.medium(32.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
case .missedCall:
|
case .missedCall:
|
||||||
//TODO:localize
|
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterMissingDigits, font: Font.medium(32.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
self.titleNode.attributedText = NSAttributedString(string: "Enter the missing digits", font: Font.medium(32.0), textColor: self.theme.list.itemPrimaryTextColor)
|
|
||||||
default:
|
default:
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.phoneNumber, font: Font.light(40.0), textColor: self.theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.phoneNumber, font: Font.light(40.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
}
|
}
|
||||||
@ -253,8 +251,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
|||||||
} else {
|
} else {
|
||||||
fontSize = 18.0
|
fontSize = 18.0
|
||||||
}
|
}
|
||||||
//TODO:localize
|
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterMissingDigits, font: Font.semibold(fontSize), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
self.titleNode.attributedText = NSAttributedString(string: "Enter the missing digits", font: Font.semibold(fontSize), textColor: self.theme.list.itemPrimaryTextColor)
|
|
||||||
default:
|
default:
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.phoneNumber, font: Font.light(30.0), textColor: self.theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.phoneNumber, font: Font.light(30.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import PhoneNumberFormat
|
|||||||
import LegacyComponents
|
import LegacyComponents
|
||||||
import LegacyMediaPickerUI
|
import LegacyMediaPickerUI
|
||||||
import PasswordSetupUI
|
import PasswordSetupUI
|
||||||
|
import TelegramNotices
|
||||||
|
|
||||||
private enum InnerState: Equatable {
|
private enum InnerState: Equatable {
|
||||||
case state(UnauthorizedAccountStateContents)
|
case state(UnauthorizedAccountStateContents)
|
||||||
@ -289,7 +290,12 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
controller?.inProgress = true
|
controller?.inProgress = true
|
||||||
|
|
||||||
strongSelf.actionDisposable.set((authorizeWithCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, code: code, termsOfService: termsOfService?.0)
|
strongSelf.actionDisposable.set((authorizeWithCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, code: code, termsOfService: termsOfService?.0, forcedPasswordSetupNotice: { value in
|
||||||
|
guard let entry = CodableEntry(ApplicationSpecificCounterNotice(value: value)) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||||
|
})
|
||||||
|> deliverOnMainQueue).start(next: { result in
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
@ -553,7 +559,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
if let currentController = currentController {
|
if let currentController = currentController {
|
||||||
controller = currentController
|
controller = currentController
|
||||||
} else {
|
} else {
|
||||||
controller = TwoFactorDataInputScreen(sharedContext: self.sharedContext, engine: .unauthorized(TelegramEngineUnauthorized(account: self.account)), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .notAuthorized(syncContacts: syncContacts)), stateUpdated: { _ in
|
controller = TwoFactorDataInputScreen(sharedContext: self.sharedContext, engine: .unauthorized(TelegramEngineUnauthorized(account: self.account)), mode: .passwordRecoveryEmail(emailPattern: emailPattern, mode: .notAuthorized(syncContacts: syncContacts), doneText: self.presentationData.strings.TwoFactorSetup_Done_Action), stateUpdated: { _ in
|
||||||
}, presentation: .default)
|
}, presentation: .default)
|
||||||
}
|
}
|
||||||
controller.passwordRecoveryFailed = { [weak self] in
|
controller.passwordRecoveryFailed = { [weak self] in
|
||||||
@ -713,7 +719,12 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
avatarVideo = nil
|
avatarVideo = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.actionDisposable.set((signUpWithName(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, firstName: firstName, lastName: lastName, avatarData: avatarData, avatarVideo: avatarVideo, videoStartTimestamp: videoStartTimestamp)
|
strongSelf.actionDisposable.set((signUpWithName(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, firstName: firstName, lastName: lastName, avatarData: avatarData, avatarVideo: avatarVideo, videoStartTimestamp: videoStartTimestamp, forcedPasswordSetupNotice: { value in
|
||||||
|
guard let entry = CodableEntry(ApplicationSpecificCounterNotice(value: value)) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (ApplicationSpecificNotice.forcedPasswordSetupKey(), entry)
|
||||||
|
})
|
||||||
|> 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 {
|
||||||
|
@ -11864,16 +11864,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:localize
|
let statusText: String
|
||||||
var statusText: String
|
|
||||||
statusText = "Messages for \(dayCount) \(dayCount == 1 ? "day" : "days") deleted"
|
|
||||||
switch type {
|
switch type {
|
||||||
case .forEveryone:
|
case .forEveryone:
|
||||||
statusText += " for both sides"
|
statusText = strongSelf.presentationData.strings.Chat_MessageRangeDeleted_ForBothSides(Int32(dayCount))
|
||||||
default:
|
default:
|
||||||
break
|
statusText = strongSelf.presentationData.strings.Chat_MessageRangeDeleted_ForMe(Int32(dayCount))
|
||||||
}
|
}
|
||||||
statusText += "."
|
|
||||||
|
|
||||||
strongSelf.chatDisplayNode.historyNode.ignoreMessagesInTimestampRange = range
|
strongSelf.chatDisplayNode.historyNode.ignoreMessagesInTimestampRange = range
|
||||||
|
|
||||||
|
@ -5496,7 +5496,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
case .rememberPassword:
|
case .rememberPassword:
|
||||||
let context = self.context
|
let context = self.context
|
||||||
let controller = TwoFactorDataInputScreen(sharedContext: self.context.sharedContext, engine: .authorized(self.context.engine), mode: .rememberPassword, stateUpdated: { _ in
|
let controller = TwoFactorDataInputScreen(sharedContext: self.context.sharedContext, engine: .authorized(self.context.engine), mode: .rememberPassword(doneText: self.presentationData.strings.TwoFactorSetup_Done_Action), stateUpdated: { _ in
|
||||||
}, presentation: .modalInLargeLayout)
|
}, presentation: .modalInLargeLayout)
|
||||||
controller.twoStepAuthSettingsController = { configuration in
|
controller.twoStepAuthSettingsController = { configuration in
|
||||||
return twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: .single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: configuration, password: nil)))))
|
return twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: .single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: configuration, password: nil)))))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user