mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '35f21a6cb6b77a4b3f2d7235a77fbf39bb05f3f3'
This commit is contained in:
commit
8380e87571
@ -9051,9 +9051,9 @@ Sorry for the inconvenience.";
|
||||
"Login.Email.ResetText" = "You can change your login email if you are logged into Telegram from another device. Otherwise, if you don't have access to email %1$@, you can reset this email with an **SMS** code **%2$@**.";
|
||||
"Login.Email.Reset" = "Reset";
|
||||
"Login.Email.ResetNowViaSMS" = "Reset now via SMS";
|
||||
"Login.Email.WillBeResetIn" = "Email will be reset in %@";
|
||||
"Login.Email.WillBeResetIn" = "Email will be reset %@";
|
||||
"Login.Email.PremiumRequiredTitle" = "Telegram Premium Required";
|
||||
"Login.Email.PremiumRequiredText" = "Due to high cost of SMS in your country, you need to have a **Telegram Premium** account to reset this email via an SMS code. You can ask a friend to a gift a Premium subscription for your account %@";
|
||||
"Login.Email.PremiumRequiredText" = "Due to high cost of SMS in your country, you need to have a **Telegram Premium** account to reset this email via an SMS code.\n\nYou can ask a friend to gift a Premium subscription for your account\n**%@**";
|
||||
|
||||
"ChatList.StartMessaging" = "Select a chat to start messaging";
|
||||
|
||||
|
@ -136,15 +136,16 @@ final class AttachmentContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer, otherGestureRecognizer is UIPanGestureRecognizer {
|
||||
if let _ = gestureRecognizer as? UIPanGestureRecognizer, otherGestureRecognizer is UIPanGestureRecognizer {
|
||||
if let _ = otherGestureRecognizer.view?.superview as? MKMapView {
|
||||
return false
|
||||
}
|
||||
if let view = otherGestureRecognizer.view, view.description.contains("WKChildScroll") {
|
||||
let velocity = panGestureRecognizer.velocity(in: nil)
|
||||
if abs(velocity.x) > abs(velocity.y) * 2.0 {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
// let velocity = panGestureRecognizer.velocity(in: nil)
|
||||
// if abs(velocity.x) > abs(velocity.y) * 2.0 {
|
||||
// return false
|
||||
// }
|
||||
}
|
||||
if let _ = otherGestureRecognizer.view?.asyncdisplaykit_node as? CollectionIndexNode {
|
||||
return false
|
||||
@ -547,7 +548,11 @@ final class AttachmentContainer: ASDisplayNode, UIGestureRecognizerDelegate {
|
||||
private func findScrollView(view: UIView?) -> (UIScrollView, ListView?)? {
|
||||
if let view = view {
|
||||
if let view = view as? UIScrollView {
|
||||
return (view, nil)
|
||||
if view.description.contains("WKChildScroll") {
|
||||
return nil
|
||||
} else {
|
||||
return (view, nil)
|
||||
}
|
||||
}
|
||||
if let node = view.asyncdisplaykit_node as? ListView {
|
||||
return (node.scroller, node)
|
||||
|
@ -940,8 +940,11 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
return
|
||||
}
|
||||
var sendWhenOnlineAvailable = false
|
||||
if let presence = peerView.peerPresences[peer.id] as? TelegramUserPresence, case .present = presence.status {
|
||||
sendWhenOnlineAvailable = true
|
||||
if let presence = peerView.peerPresences[peer.id] as? TelegramUserPresence, case let .present(until) = presence.status {
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
if currentTime > until {
|
||||
sendWhenOnlineAvailable = true
|
||||
}
|
||||
}
|
||||
if peer.id.namespace == Namespaces.Peer.CloudUser && peer.id.id._internalGetInt64Value() == 777000 {
|
||||
sendWhenOnlineAvailable = false
|
||||
|
@ -24,6 +24,7 @@ public final class AuthorizationSequenceCodeEntryController: ViewController {
|
||||
var reset: (() -> Void)?
|
||||
var requestNextOption: (() -> Void)?
|
||||
var resetEmail: (() -> Void)?
|
||||
var retryResetEmail: (() -> Void)?
|
||||
|
||||
var data: (String, String?, SentAuthorizationCodeType, AuthorizationCodeNextType?, Int32?)?
|
||||
var termsOfService: (UnauthorizedAccountTermsOfService, Bool)?
|
||||
@ -114,6 +115,10 @@ public final class AuthorizationSequenceCodeEntryController: ViewController {
|
||||
self?.resetEmail?()
|
||||
}
|
||||
|
||||
self.controllerNode.retryReset = { [weak self] in
|
||||
self?.retryResetEmail?()
|
||||
}
|
||||
|
||||
self.controllerNode.present = { [weak self] c, a in
|
||||
self?.present(c, in: .window(.root), with: a)
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
private let nextOptionTitleNode: ImmediateTextNode
|
||||
private let nextOptionButtonNode: HighlightableButtonNode
|
||||
|
||||
private let resetTextNode: ImmediateTextNode
|
||||
private let resetNode: HighlightableButtonNode
|
||||
|
||||
private let dividerNode: AuthorizationDividerNode
|
||||
@ -75,6 +76,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
var requestAnotherOption: (() -> Void)?
|
||||
var updateNextEnabled: ((Bool) -> Void)?
|
||||
var reset: (() -> Void)?
|
||||
var retryReset: (() -> Void)?
|
||||
|
||||
var inProgress: Bool = false {
|
||||
didSet {
|
||||
@ -159,6 +161,13 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
self.resetNode.setAttributedTitle(NSAttributedString(string: self.strings.Login_Email_CantAccess, font: Font.regular(17.0), textColor: self.theme.list.itemAccentColor, paragraphAlignment: .center), for: [])
|
||||
self.resetNode.isHidden = true
|
||||
|
||||
self.resetTextNode = ImmediateTextNode()
|
||||
self.resetTextNode.maximumNumberOfLines = 1
|
||||
self.resetTextNode.textAlignment = .center
|
||||
self.resetTextNode.isUserInteractionEnabled = false
|
||||
self.resetTextNode.displaysAsynchronously = false
|
||||
self.resetTextNode.isHidden = true
|
||||
|
||||
self.dividerNode = AuthorizationDividerNode(theme: self.theme, strings: self.strings)
|
||||
|
||||
if #available(iOS 13.0, *) {
|
||||
@ -190,6 +199,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
self.addSubnode(self.nextOptionButtonNode)
|
||||
self.addSubnode(self.animationNode)
|
||||
self.addSubnode(self.resetNode)
|
||||
self.addSubnode(self.resetTextNode)
|
||||
self.addSubnode(self.dividerNode)
|
||||
self.addSubnode(self.errorTextNode)
|
||||
self.addSubnode(self.proceedNode)
|
||||
@ -337,6 +347,23 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
}
|
||||
})
|
||||
self.countdownDisposable.set(disposable)
|
||||
} else if case let .email(_, _, _, pendingDate, _, _) = codeType, let pendingDate {
|
||||
let disposable = ((Signal<Int, NoError>.single(1) |> delay(1.0, queue: Queue.mainQueue())) |> restart).start(next: { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
let interval = pendingDate - currentTime
|
||||
if interval <= 0 {
|
||||
strongSelf.countdownDisposable.set(nil)
|
||||
Queue.mainQueue().after(2.0) {
|
||||
strongSelf.retryReset?()
|
||||
}
|
||||
}
|
||||
if let layoutArguments = strongSelf.layoutArguments {
|
||||
strongSelf.containerLayoutUpdated(layoutArguments.0, navigationBarHeight: layoutArguments.1, transition: .immediate)
|
||||
}
|
||||
}
|
||||
})
|
||||
self.countdownDisposable.set(disposable)
|
||||
} else {
|
||||
self.currentTimeoutTime = nil
|
||||
self.countdownDisposable.set(nil)
|
||||
@ -418,8 +445,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
let currentOptionSize = self.currentOptionNode.updateLayout(CGSize(width: maximumWidth - 48.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
let currentOptionInfoSize = self.currentOptionInfoNode.measure(CGSize(width: maximumWidth - 48.0, height: CGFloat.greatestFiniteMagnitude))
|
||||
let nextOptionSize = self.nextOptionTitleNode.updateLayout(CGSize(width: maximumWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
let resetSize = self.resetNode.measure(CGSize(width: maximumWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
|
||||
let proceedHeight = self.proceedNode.updateLayout(width: maximumWidth - inset * 2.0, transition: transition)
|
||||
let proceedSize = CGSize(width: maximumWidth - inset * 2.0, height: proceedHeight)
|
||||
|
||||
@ -515,16 +541,56 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||
items.append(AuthorizationLayoutItem(node: self.currentOptionNode, size: currentOptionSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 18.0, maxValue: 18.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||
|
||||
var canReset = false
|
||||
if case let .email(_, _, resetPeriod, _, _, setup) = codeType, !setup && resetPeriod != nil {
|
||||
canReset = true
|
||||
var pendingDate: Int32?
|
||||
if case let .email(_, _, resetPeriod, pendingDateValue, _, setup) = codeType, !setup {
|
||||
if resetPeriod != nil {
|
||||
canReset = true
|
||||
} else if pendingDateValue != nil {
|
||||
pendingDate = pendingDateValue
|
||||
}
|
||||
}
|
||||
|
||||
items.append(AuthorizationLayoutItem(node: self.codeInputView, size: codeFieldSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 30.0, maxValue: 30.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: canReset ? 0.0 : 104.0, maxValue: canReset ? 0.0 : 104.0)))
|
||||
items.append(AuthorizationLayoutItem(node: self.codeInputView, size: codeFieldSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 30.0, maxValue: 30.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: canReset || pendingDate != nil ? 0.0 : 104.0, maxValue: canReset ? 0.0 : 104.0)))
|
||||
|
||||
if canReset {
|
||||
self.resetNode.setAttributedTitle(NSAttributedString(string: self.strings.Login_Email_CantAccess, font: Font.regular(17.0), textColor: self.theme.list.itemAccentColor, paragraphAlignment: .center), for: [])
|
||||
let resetSize = self.resetNode.measure(CGSize(width: maximumWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
self.resetTextNode.isHidden = true
|
||||
self.resetNode.isHidden = false
|
||||
items.append(AuthorizationLayoutItem(node: self.resetNode, size: resetSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 36.0, maxValue: 36.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 104.0, maxValue: 104.0)))
|
||||
} else if let pendingDate {
|
||||
self.resetNode.setAttributedTitle(NSAttributedString(string: self.strings.Login_Email_ResetNowViaSMS, font: Font.regular(17.0), textColor: self.theme.list.itemAccentColor, paragraphAlignment: .center), for: [])
|
||||
let resetSize = self.resetNode.measure(CGSize(width: maximumWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
let resetText: String
|
||||
let interval = pendingDate - currentTime
|
||||
if interval <= 0 {
|
||||
resetText = "Please wait..."
|
||||
} else if interval < 60 * 60 * 24 {
|
||||
let minutes = interval / 60
|
||||
let seconds = interval % 60
|
||||
let timeString = NSString(format: "%d:%.02d", Int(minutes), Int(seconds))
|
||||
resetText = "in \(timeString)"
|
||||
} else {
|
||||
resetText = unmuteIntervalString(strings: self.strings, value: interval)
|
||||
}
|
||||
|
||||
self.resetTextNode.attributedText = NSAttributedString(string: self.strings.Login_Email_WillBeResetIn(resetText).string, font: Font.regular(16.0), textColor: self.theme.list.itemSecondaryTextColor, paragraphAlignment: .center)
|
||||
let resetTextSize = self.resetTextNode.updateLayout(CGSize(width: maximumWidth, height: CGFloat.greatestFiniteMagnitude))
|
||||
|
||||
if !self.resetNode.isHidden && self.resetTextNode.isHidden {
|
||||
self.resetTextNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
|
||||
self.resetTextNode.isHidden = false
|
||||
items.append(AuthorizationLayoutItem(node: self.resetTextNode, size: resetTextSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 36.0, maxValue: 36.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||
|
||||
self.resetNode.isHidden = false
|
||||
items.append(AuthorizationLayoutItem(node: self.resetNode, size: resetSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 20.0, maxValue: 20.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 104.0, maxValue: 104.0)))
|
||||
} else {
|
||||
self.resetTextNode.isHidden = true
|
||||
self.resetNode.isHidden = true
|
||||
}
|
||||
|
||||
|
@ -289,6 +289,9 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
if c.data?.2 == type {
|
||||
currentController = c
|
||||
}
|
||||
// else if case let .email(_, _, _, newPendingDate, _, _) = type, let previousType = c.data?.2, case let .email(_, _, _, previousPendingDate, _, _) = previousType, newPendingDate != nil && previousPendingDate == nil {
|
||||
// currentController = c
|
||||
// }
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -304,16 +307,28 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
||||
|
||||
let _ = TelegramEngineUnauthorized(account: strongSelf.account).auth.setState(state: UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .phoneEntry(countryCode: countryCode, number: ""))).start()
|
||||
})
|
||||
controller.retryResetEmail = { [weak self] in
|
||||
if let self {
|
||||
self.actionDisposable.set(
|
||||
resetLoginEmail(account: self.account, phoneNumber: number, phoneCodeHash: phoneCodeHash).start()
|
||||
)
|
||||
}
|
||||
}
|
||||
controller.resetEmail = { [weak self, weak controller] in
|
||||
if let self, case let .email(pattern, _, resetAvailablePeriod, resetPendingDate, _, setup) = type, !setup {
|
||||
let body = MarkdownAttributeSet(font: Font.regular(self.presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(self.presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
if let _ = resetPendingDate {
|
||||
let formattedNumber = formatPhoneNumber(number)
|
||||
let title = NSAttributedString(string: self.presentationData.strings.Login_Email_PremiumRequiredTitle, font: Font.semibold(self.presentationData.listsFontSize.baseDisplaySize), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let text = parseMarkdownIntoAttributedString(self.presentationData.strings.Login_Email_PremiumRequiredText(formattedNumber).string, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in nil }), textAlignment: .center).mutableCopy() as! NSMutableAttributedString
|
||||
|
||||
let alertController = textWithEntitiesAlertController(theme: AlertControllerTheme(presentationData: self.presentationData), title: title, text: text, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.Common_OK, action: { })])
|
||||
controller?.present(alertController, in: .window(.root))
|
||||
} else if let resetAvailablePeriod {
|
||||
let pattern = pattern.replacingOccurrences(of: "*", with: "#")
|
||||
let title = NSAttributedString(string: self.presentationData.strings.Login_Email_ResetTitle, font: Font.semibold(self.presentationData.listsFontSize.baseDisplaySize), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let availableIn = unmuteIntervalString(strings: self.presentationData.strings, value: resetAvailablePeriod)
|
||||
let body = MarkdownAttributeSet(font: Font.regular(self.presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(self.presentationData.listsFontSize.baseDisplaySize * 13.0 / 17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let text = parseMarkdownIntoAttributedString(self.presentationData.strings.Login_Email_ResetText(pattern, availableIn).string, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in nil }), textAlignment: .center).mutableCopy() as! NSMutableAttributedString
|
||||
if let regex = try? NSRegularExpression(pattern: "\\#", options: []) {
|
||||
let matches = regex.matches(in: text.string, options: [], range: NSMakeRange(0, text.length))
|
||||
|
@ -246,8 +246,11 @@ func presentLegacyMediaPickerGallery(context: AccountContext, peer: EnginePeer?,
|
||||
return false
|
||||
}
|
||||
var sendWhenOnlineAvailable = false
|
||||
if let presence = peerView.peerPresences[peer.id] as? TelegramUserPresence, case .present = presence.status {
|
||||
sendWhenOnlineAvailable = true
|
||||
if let presence = peerView.peerPresences[peer.id] as? TelegramUserPresence, case let .present(until) = presence.status {
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
if currentTime > until {
|
||||
sendWhenOnlineAvailable = true
|
||||
}
|
||||
}
|
||||
if peer.id.namespace == Namespaces.Peer.CloudUser && peer.id.id._internalGetInt64Value() == 777000 {
|
||||
sendWhenOnlineAvailable = false
|
||||
|
@ -1537,7 +1537,7 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
|
||||
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.01)
|
||||
self.containerContainingNode.cornerRadius = 10.0
|
||||
|
||||
let size = CGSize(width: 390.0, height: min(620.0, layout.size.height - 60.0))
|
||||
let size = CGSize(width: 390.0, height: min(560.0, layout.size.height - 60.0))
|
||||
var contentRect: CGRect
|
||||
if let sourceRect = self.controller?.getSourceRect?() {
|
||||
let sideSpacing: CGFloat = 10.0
|
||||
|
@ -9868,8 +9868,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
var sendWhenOnlineAvailable = false
|
||||
if let presence = peerView.peerPresences[peer.id] as? TelegramUserPresence, case .present = presence.status {
|
||||
sendWhenOnlineAvailable = true
|
||||
if let presence = peerView.peerPresences[peer.id] as? TelegramUserPresence, case let .present(until) = presence.status {
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
if currentTime > until {
|
||||
sendWhenOnlineAvailable = true
|
||||
}
|
||||
}
|
||||
if peer.id.namespace == Namespaces.Peer.CloudUser && peer.id.id._internalGetInt64Value() == 777000 {
|
||||
sendWhenOnlineAvailable = false
|
||||
|
Loading…
x
Reference in New Issue
Block a user