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.";
|
||||
"Login.CheckOtherSessionMessages" = "Check your Telegram messages";
|
||||
"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.CancelPhoneVerificationStop" = "Stop";
|
||||
"Login.CancelPhoneVerificationContinue" = "Continue";
|
||||
@ -7101,3 +7102,24 @@ Sorry for the inconvenience.";
|
||||
"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?";
|
||||
|
||||
"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 {
|
||||
switch currentType {
|
||||
case .otherSession:
|
||||
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:
|
||||
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/DirectMediaImageCache:DirectMediaImageCache",
|
||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||
"//submodules/TooltipUI:TooltipUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -11,6 +11,7 @@ import ComponentFlow
|
||||
import PhotoResources
|
||||
import DirectMediaImageCache
|
||||
import TelegramStringFormatting
|
||||
import TooltipUI
|
||||
|
||||
private final class NullActionClass: NSObject, CAAction {
|
||||
@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 dayItemSize = updatedDays[0].size
|
||||
let deltaWidth = floor((weekdayWidth - dayItemSize.width) / 2.0)
|
||||
let deltaHeight = floor((weekdaySize - dayItemSize.width) / 2.0)
|
||||
let selectionRadius: CGFloat = min(dayItemSize.width, dayItemSize.height)
|
||||
|
||||
let deltaWidth = floor((weekdayWidth - selectionRadius) / 2.0)
|
||||
let deltaHeight = floor((weekdaySize - selectionRadius) / 2.0)
|
||||
let minX = sideInset + CGFloat(selection.range.lowerBound) * weekdayWidth + deltaWidth
|
||||
let maxX = sideInset + CGFloat(selection.range.upperBound + 1) * weekdayWidth - deltaWidth
|
||||
let minY = baseDayY + CGFloat(lineIndex) * (weekdaySize + weekdaySpacing) + deltaHeight
|
||||
let maxY = minY + dayItemSize.width
|
||||
|
||||
let leftRadius: CGFloat = dayItemSize.width
|
||||
let rightRadius: CGFloat = dayItemSize.width
|
||||
let maxY = minY + selectionRadius
|
||||
|
||||
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 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,
|
||||
transition: .immediate
|
||||
)
|
||||
@ -923,7 +923,7 @@ private final class MonthComponent: CombinedComponent {
|
||||
}
|
||||
let delay = Double(min(delayIndex, 6)) * 0.1
|
||||
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
|
||||
if case .none = transition.animation {
|
||||
@ -1314,8 +1314,7 @@ public final class CalendarMessageScreen: ViewController {
|
||||
|
||||
if let selectionState = self.selectionState {
|
||||
let selectionToolbarNode: ToolbarNode
|
||||
if let currrent = self.selectionToolbarNode {
|
||||
selectionToolbarNode = currrent
|
||||
let toolbarText: String
|
||||
|
||||
var selectedCount = 0
|
||||
if let dayRange = selectionState.dayRange {
|
||||
@ -1332,19 +1331,19 @@ public final class CalendarMessageScreen: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
let toolbarText: String
|
||||
if selectedCount == 0 {
|
||||
toolbarText = self.presentationData.strings.DialogList_ClearHistoryConfirmation
|
||||
} else if selectedCount == 1 {
|
||||
//TODO:localize
|
||||
toolbarText = "Clear History For This Day"
|
||||
toolbarText = self.presentationData.strings.MessageCalendar_ClearHistoryForThisDay
|
||||
} else {
|
||||
//TODO:localize
|
||||
toolbarText = "Clear History For These Days"
|
||||
toolbarText = self.presentationData.strings.MessageCalendar_ClearHistoryForTheseDays
|
||||
}
|
||||
|
||||
if let currrent = self.selectionToolbarNode {
|
||||
selectionToolbarNode = currrent
|
||||
|
||||
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 {
|
||||
selectionToolbarNode = ToolbarNode(
|
||||
theme: TabBarControllerTheme(
|
||||
@ -1359,7 +1358,7 @@ public final class CalendarMessageScreen: ViewController {
|
||||
}
|
||||
)
|
||||
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.selectionToolbarNode = selectionToolbarNode
|
||||
transition.animatePositionAdditive(node: selectionToolbarNode, offset: CGPoint(x: 0.0, y: tabBarFrame.height))
|
||||
@ -1425,6 +1424,16 @@ public final class CalendarMessageScreen: ViewController {
|
||||
}
|
||||
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import TelegramIntents
|
||||
import TooltipUI
|
||||
import TelegramCallsUI
|
||||
import StickerResources
|
||||
import PasswordSetupUI
|
||||
|
||||
private func fixListNodeScrolling(_ listNode: ListView, searchNode: NavigationBarSearchContentNode) -> Bool {
|
||||
if listNode.scroller.isDragging {
|
||||
@ -1264,6 +1265,53 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
})
|
||||
], 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
|
||||
|
@ -101,9 +101,9 @@ public final class ConstantDisplayLinkAnimator {
|
||||
self.displayLink = CADisplayLink(target: DisplayLinkTarget({ [weak self] in
|
||||
self?.tick()
|
||||
}), 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.isPaused = true
|
||||
self.displayLink.add(to: RunLoop.main, forMode: .common)
|
||||
}
|
||||
|
@ -35,14 +35,14 @@ public enum TwoFactorDataInputMode {
|
||||
case authorized
|
||||
}
|
||||
|
||||
case password
|
||||
case passwordRecoveryEmail(emailPattern: String, mode: PasswordRecoveryEmailMode)
|
||||
case passwordRecovery(Recovery)
|
||||
case emailAddress(password: String, hint: String)
|
||||
case updateEmailAddress(password: String)
|
||||
case emailConfirmation(passwordAndHint: (String, String)?, emailPattern: String, codeLength: Int?)
|
||||
case passwordHint(recovery: Recovery?, password: String)
|
||||
case rememberPassword
|
||||
case password(doneText: String)
|
||||
case passwordRecoveryEmail(emailPattern: String, mode: PasswordRecoveryEmailMode, doneText: String)
|
||||
case passwordRecovery(recovery: Recovery, doneText: String)
|
||||
case emailAddress(password: String, hint: String, doneText: String)
|
||||
case updateEmailAddress(password: String, doneText: String)
|
||||
case emailConfirmation(passwordAndHint: (String, String)?, emailPattern: String, codeLength: Int?, doneText: String)
|
||||
case passwordHint(recovery: Recovery?, password: String, doneText: String)
|
||||
case rememberPassword(doneText: String)
|
||||
}
|
||||
|
||||
public final class TwoFactorDataInputScreen: ViewController {
|
||||
@ -110,7 +110,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
return
|
||||
}
|
||||
switch strongSelf.mode {
|
||||
case .password:
|
||||
case let .password(doneText):
|
||||
let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText
|
||||
if values.count != 2 {
|
||||
return
|
||||
@ -136,9 +136,9 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
case let .passwordRecoveryEmail(_, mode):
|
||||
case let .passwordRecoveryEmail(_, mode, doneText):
|
||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||
return
|
||||
}
|
||||
@ -180,14 +180,14 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
navigationController.replaceController(strongSelf, with: setupController, animated: true)
|
||||
}))
|
||||
case let .passwordRecovery(recovery):
|
||||
case let .passwordRecovery(recovery, doneText):
|
||||
let values = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText
|
||||
if values.count != 2 {
|
||||
return
|
||||
@ -204,8 +204,8 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||
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)
|
||||
case let .emailAddress(password, hint):
|
||||
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, doneText):
|
||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||
return
|
||||
}
|
||||
@ -237,7 +237,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
} else {
|
||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||
@ -252,7 +252,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -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))
|
||||
})
|
||||
case let .updateEmailAddress(password):
|
||||
case let .updateEmailAddress(password, doneText):
|
||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||
return
|
||||
}
|
||||
@ -307,7 +307,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
} else {
|
||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||
@ -322,7 +322,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -346,7 +346,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
case .unauthorized:
|
||||
break
|
||||
}
|
||||
case .emailConfirmation:
|
||||
case let .emailConfirmation(_, _, _, doneText):
|
||||
guard let text = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !text.isEmpty else {
|
||||
return
|
||||
}
|
||||
@ -397,13 +397,13 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
})
|
||||
case .unauthorized:
|
||||
break
|
||||
}
|
||||
case let .passwordHint(recovery, password):
|
||||
case let .passwordHint(recovery, password, doneText):
|
||||
guard let value = (strongSelf.displayNode as! TwoFactorDataInputScreenNode).inputText.first, !value.isEmpty else {
|
||||
return
|
||||
}
|
||||
@ -411,7 +411,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
if let recovery = recovery {
|
||||
strongSelf.performRecovery(recovery: recovery, password: password, hint: value)
|
||||
} 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:
|
||||
guard case let .authorized(engine) = strongSelf.engine else {
|
||||
@ -476,7 +476,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
return
|
||||
}
|
||||
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: [
|
||||
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.TwoFactorSetup_Email_SkipConfirmationSkip, action: {
|
||||
guard let strongSelf = self else {
|
||||
@ -509,7 +509,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
}
|
||||
}, error: { [weak statusController] error in
|
||||
@ -532,13 +532,13 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})
|
||||
]), in: .window(.root))
|
||||
case let .passwordHint(recovery, password):
|
||||
case let .passwordHint(recovery, password, doneText):
|
||||
if let recovery = recovery {
|
||||
strongSelf.performRecovery(recovery: recovery, password: password, hint: "")
|
||||
} 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: [
|
||||
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.TwoFactorSetup_PasswordRecovery_SkipAlertAction, action: {
|
||||
guard let strongSelf = self else {
|
||||
@ -548,7 +548,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})
|
||||
]), in: .window(.root))
|
||||
case .rememberPassword:
|
||||
case let .rememberPassword(doneText):
|
||||
guard case let .authorized(engine) = strongSelf.engine else {
|
||||
return
|
||||
}
|
||||
@ -575,7 +575,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
disposable.set((engine.auth.requestTwoStepVerificationPasswordRecoveryCode()
|
||||
|> deliverOnMainQueue).start(next: { emailPattern in
|
||||
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 = { [weak controller] state in
|
||||
@ -706,7 +706,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
return
|
||||
}
|
||||
switch strongSelf.mode {
|
||||
case let .emailConfirmation(passwordAndHint, _, _):
|
||||
case let .emailConfirmation(passwordAndHint, _, _, doneText):
|
||||
if let (password, hint) = passwordAndHint {
|
||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||
return
|
||||
@ -720,7 +720,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
||||
}
|
||||
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)
|
||||
} else {
|
||||
}
|
||||
@ -1371,7 +1371,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
toggleTextHidden?(node)
|
||||
}),
|
||||
]
|
||||
case let .passwordRecoveryEmail(emailPattern, _):
|
||||
case let .passwordRecoveryEmail(emailPattern, _, _):
|
||||
title = presentationData.strings.TwoFactorSetup_EmailVerification_Title
|
||||
let formattedString = presentationData.strings.TwoFactorSetup_EmailVerification_Text(emailPattern)
|
||||
|
||||
@ -1398,7 +1398,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
toggleTextHidden?(node)
|
||||
}),
|
||||
]
|
||||
case let .emailConfirmation(_, emailPattern, _):
|
||||
case let .emailConfirmation(_, emailPattern, _, _):
|
||||
title = presentationData.strings.TwoFactorSetup_EmailVerification_Title
|
||||
let formattedString = presentationData.strings.TwoFactorSetup_EmailVerification_Text(emailPattern)
|
||||
|
||||
@ -1654,7 +1654,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
||||
strongSelf.buttonNode.isHidden = !hasText
|
||||
strongSelf.skipActionTitleNode.isHidden = hasText
|
||||
strongSelf.skipActionButtonNode.isHidden = hasText
|
||||
case let .emailConfirmation(_, _, codeLength):
|
||||
case let .emailConfirmation(_, _, codeLength, _):
|
||||
let text = strongSelf.inputNodes[0].text
|
||||
let hasText = !text.isEmpty
|
||||
strongSelf.buttonNode.isHidden = !hasText
|
||||
|
@ -13,8 +13,27 @@ import PresentationDataUtils
|
||||
import TelegramCore
|
||||
|
||||
public enum TwoFactorAuthSplashMode {
|
||||
case intro
|
||||
case done
|
||||
public struct Intro {
|
||||
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 remember
|
||||
}
|
||||
@ -25,6 +44,8 @@ public final class TwoFactorAuthSplashScreen: ViewController {
|
||||
private var presentationData: PresentationData
|
||||
private var mode: TwoFactorAuthSplashMode
|
||||
|
||||
public var dismissConfirmation: ((@escaping () -> Void) -> Bool)?
|
||||
|
||||
public init(sharedContext: SharedAccountContext, engine: SomeTelegramEngine, mode: TwoFactorAuthSplashMode, presentation: ViewControllerNavigationPresentation = .modalInLargeLayout) {
|
||||
self.sharedContext = sharedContext
|
||||
self.engine = engine
|
||||
@ -55,6 +76,14 @@ public final class TwoFactorAuthSplashScreen: ViewController {
|
||||
} else {
|
||||
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) {
|
||||
@ -70,8 +99,8 @@ public final class TwoFactorAuthSplashScreen: ViewController {
|
||||
return
|
||||
}
|
||||
switch strongSelf.mode {
|
||||
case .intro:
|
||||
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .password, stateUpdated: { _ in
|
||||
case let .intro(intro):
|
||||
strongSelf.push(TwoFactorDataInputScreen(sharedContext: strongSelf.sharedContext, engine: strongSelf.engine, mode: .password(doneText: intro.doneText), stateUpdated: { _ in
|
||||
}, presentation: strongSelf.navigationPresentation))
|
||||
case .done, .remember:
|
||||
guard let navigationController = strongSelf.navigationController as? NavigationController else {
|
||||
@ -136,18 +165,18 @@ private final class TwoFactorAuthSplashScreenNode: ViewControllerTracingNode {
|
||||
let textColor = self.presentationData.theme.list.itemPrimaryTextColor
|
||||
|
||||
switch mode {
|
||||
case .intro:
|
||||
title = self.presentationData.strings.TwoFactorSetup_Intro_Title
|
||||
texts = [NSAttributedString(string: self.presentationData.strings.TwoFactorSetup_Intro_Text, font: textFont, textColor: textColor)]
|
||||
buttonText = self.presentationData.strings.TwoFactorSetup_Intro_Action
|
||||
case let .intro(intro):
|
||||
title = intro.title
|
||||
texts = [NSAttributedString(string: intro.text, font: textFont, textColor: textColor)]
|
||||
buttonText = intro.actionText
|
||||
|
||||
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.animationNode.visibility = true
|
||||
case .done:
|
||||
case let .done(doneText):
|
||||
title = self.presentationData.strings.TwoFactorSetup_Done_Title
|
||||
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.animationSize = CGSize(width: 124.0, height: 124.0)
|
||||
|
@ -732,7 +732,13 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
||||
break
|
||||
case let .notSet(pendingEmail):
|
||||
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)
|
||||
return
|
||||
|
@ -509,7 +509,7 @@ public func twoStepVerificationUnlockSettingsController(context: AccountContext,
|
||||
}
|
||||
|
||||
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 = { [weak controller] state in
|
||||
|
@ -105,11 +105,11 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
|
||||
}
|
||||
|> `catch` { error -> Signal<(SendCodeResult, UnauthorizedAccount), MTRpcError> in
|
||||
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
|
||||
switch result {
|
||||
case let .password(_, _, _, _, hint, _, _, _, _, _):
|
||||
return .single((.password(hint: hint), account))
|
||||
return .single((.password(hint: hint), updatedAccount))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -252,7 +252,7 @@ public enum AuthorizeWithCodeResult {
|
||||
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
|
||||
if let state = transaction.getState() as? UnauthorizedAccountState {
|
||||
switch state.contents {
|
||||
@ -302,11 +302,14 @@ public func authorizeWithCode(accountManager: AccountManager<TelegramAccountMana
|
||||
return .single(.loggedIn)
|
||||
case let .authorization(authorization):
|
||||
switch authorization {
|
||||
case let .authorization(_, _, _, user):
|
||||
case let .authorization(_, otherwiseReloginDays, _, user):
|
||||
let user = TelegramUser(user: user)
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
||||
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
|
||||
switchToAuthorizedAccount(transaction: transaction, account: account)
|
||||
return .loggedIn
|
||||
@ -542,7 +545,7 @@ public enum SignUpError {
|
||||
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
|
||||
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))
|
||||
@ -561,7 +564,7 @@ public func signUpWithName(accountManager: AccountManager<TelegramAccountManager
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, SignUpError> in
|
||||
switch result {
|
||||
case let .authorization(_, _, _, user):
|
||||
case let .authorization(_, otherwiseReloginDays, _, user):
|
||||
let user = TelegramUser(user: user)
|
||||
let appliedState = account.postbox.transaction { transaction -> Void in
|
||||
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
|
||||
@ -570,6 +573,9 @@ public func signUpWithName(accountManager: AccountManager<TelegramAccountManager
|
||||
}
|
||||
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
|
||||
transaction.setState(state)
|
||||
if let otherwiseReloginDays = otherwiseReloginDays, let value = forcedPasswordSetupNotice(otherwiseReloginDays) {
|
||||
transaction.setNoticeEntry(key: value.0, value: value.1)
|
||||
}
|
||||
}
|
||||
|> castError(SignUpError.self)
|
||||
|
||||
|
@ -162,6 +162,7 @@ private enum ApplicationSpecificGlobalNotice: Int32 {
|
||||
case interactiveEmojiSyncTip = 28
|
||||
case sharedMediaScrollingTooltip = 29
|
||||
case sharedMediaFastScrollingTooltip = 30
|
||||
case forcedPasswordSetup = 31
|
||||
|
||||
var key: ValueBoxKey {
|
||||
let v = ValueBoxKey(length: 4)
|
||||
@ -211,6 +212,10 @@ private struct ApplicationSpecificNoticeKeys {
|
||||
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 {
|
||||
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> {
|
||||
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)
|
||||
if case .missedCall = codeType {
|
||||
//TODO:localize
|
||||
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)
|
||||
self.currentOptionInfoNode.attributedText = NSAttributedString(string: self.strings.Login_CodePhonePatternInfoText, font: Font.regular(16.0), textColor: self.theme.list.itemPrimaryTextColor, paragraphAlignment: .center)
|
||||
} else {
|
||||
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:
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_CheckOtherSessionMessages, font: Font.medium(32.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
case .missedCall:
|
||||
//TODO:localize
|
||||
self.titleNode.attributedText = NSAttributedString(string: "Enter the missing digits", font: Font.medium(32.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterMissingDigits, font: Font.medium(32.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
default:
|
||||
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 {
|
||||
fontSize = 18.0
|
||||
}
|
||||
//TODO:localize
|
||||
self.titleNode.attributedText = NSAttributedString(string: "Enter the missing digits", font: Font.semibold(fontSize), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_EnterMissingDigits, font: Font.semibold(fontSize), textColor: self.theme.list.itemPrimaryTextColor)
|
||||
default:
|
||||
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 LegacyMediaPickerUI
|
||||
import PasswordSetupUI
|
||||
import TelegramNotices
|
||||
|
||||
private enum InnerState: Equatable {
|
||||
case state(UnauthorizedAccountStateContents)
|
||||
@ -289,7 +290,12 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if let strongSelf = self {
|
||||
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
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
@ -553,7 +559,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if let currentController = currentController {
|
||||
controller = currentController
|
||||
} 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)
|
||||
}
|
||||
controller.passwordRecoveryFailed = { [weak self] in
|
||||
@ -713,7 +719,12 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
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
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self, let controller = controller {
|
||||
|
@ -11864,16 +11864,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
var statusText: String
|
||||
statusText = "Messages for \(dayCount) \(dayCount == 1 ? "day" : "days") deleted"
|
||||
let statusText: String
|
||||
switch type {
|
||||
case .forEveryone:
|
||||
statusText += " for both sides"
|
||||
statusText = strongSelf.presentationData.strings.Chat_MessageRangeDeleted_ForBothSides(Int32(dayCount))
|
||||
default:
|
||||
break
|
||||
statusText = strongSelf.presentationData.strings.Chat_MessageRangeDeleted_ForMe(Int32(dayCount))
|
||||
}
|
||||
statusText += "."
|
||||
|
||||
strongSelf.chatDisplayNode.historyNode.ignoreMessagesInTimestampRange = range
|
||||
|
||||
|
@ -5496,7 +5496,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
case .rememberPassword:
|
||||
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)
|
||||
controller.twoStepAuthSettingsController = { configuration in
|
||||
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