mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
40908ce9b4
commit
4316b417e5
BIN
Telegram/Telegram-iOS/Resources/IntroPassword.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/IntroPassword.tgs
Normal file
Binary file not shown.
@ -8040,3 +8040,9 @@ Sorry for the inconvenience.";
|
|||||||
"Login.CancelEmailVerification" = "Do you want to stop the email verification process?";
|
"Login.CancelEmailVerification" = "Do you want to stop the email verification process?";
|
||||||
"Login.CancelEmailVerificationStop" = "Stop";
|
"Login.CancelEmailVerificationStop" = "Stop";
|
||||||
"Login.CancelEmailVerificationContinue" = "Continue";
|
"Login.CancelEmailVerificationContinue" = "Continue";
|
||||||
|
|
||||||
|
"Premium.InfiniteReactions" = "Infinite Reactions";
|
||||||
|
"Premium.InfiniteReactionsInfo" = "React with thousands of emoji — with multiple reactions per message.";
|
||||||
|
|
||||||
|
"Premium.EmojiStatus" = "Emoji Status";
|
||||||
|
"Premium.EmojiStatusInfo" = "Add any of thousands emojis next to your name to display current activity.";
|
||||||
|
@ -10,6 +10,8 @@ final class AuthorizationSequencePasswordEntryController: ViewController {
|
|||||||
return self.displayNode as! AuthorizationSequencePasswordEntryControllerNode
|
return self.displayNode as! AuthorizationSequencePasswordEntryControllerNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var validLayout: ContainerViewLayout?
|
||||||
|
|
||||||
private let presentationData: PresentationData
|
private let presentationData: PresentationData
|
||||||
|
|
||||||
var loginWithPassword: ((String) -> Void)?
|
var loginWithPassword: ((String) -> Void)?
|
||||||
@ -33,12 +35,7 @@ final class AuthorizationSequencePasswordEntryController: ViewController {
|
|||||||
|
|
||||||
var inProgress: Bool = false {
|
var inProgress: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
if self.inProgress {
|
self.updateNavigationItems()
|
||||||
let item = UIBarButtonItem(customDisplayNode: ProgressNavigationButtonNode(color: self.presentationData.theme.rootController.navigationBar.accentTextColor))
|
|
||||||
self.navigationItem.rightBarButtonItem = item
|
|
||||||
} else {
|
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.nextPressed))
|
|
||||||
}
|
|
||||||
self.controllerNode.inProgress = self.inProgress
|
self.controllerNode.inProgress = self.inProgress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,8 +57,6 @@ final class AuthorizationSequencePasswordEntryController: ViewController {
|
|||||||
self.navigationBar?.backPressed = {
|
self.navigationBar?.backPressed = {
|
||||||
back()
|
back()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.nextPressed))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required init(coder aDecoder: NSCoder) {
|
required init(coder aDecoder: NSCoder) {
|
||||||
@ -97,6 +92,19 @@ final class AuthorizationSequencePasswordEntryController: ViewController {
|
|||||||
self.controllerNode.activateInput()
|
self.controllerNode.activateInput()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateNavigationItems() {
|
||||||
|
guard let layout = self.validLayout, layout.size.width < 360.0 else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.inProgress {
|
||||||
|
let item = UIBarButtonItem(customDisplayNode: ProgressNavigationButtonNode(color: self.presentationData.theme.rootController.navigationBar.accentTextColor))
|
||||||
|
self.navigationItem.rightBarButtonItem = item
|
||||||
|
} else {
|
||||||
|
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.nextPressed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func updateData(hint: String, suggestReset: Bool) {
|
func updateData(hint: String, suggestReset: Bool) {
|
||||||
if self.hint != hint || self.suggestReset != suggestReset {
|
if self.hint != hint || self.suggestReset != suggestReset {
|
||||||
self.hint = hint
|
self.hint = hint
|
||||||
@ -109,6 +117,7 @@ final class AuthorizationSequencePasswordEntryController: ViewController {
|
|||||||
|
|
||||||
func passwordIsInvalid() {
|
func passwordIsInvalid() {
|
||||||
if self.isNodeLoaded {
|
if self.isNodeLoaded {
|
||||||
|
self.hapticFeedback.error()
|
||||||
self.controllerNode.passwordIsInvalid()
|
self.controllerNode.passwordIsInvalid()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,6 +125,13 @@ final class AuthorizationSequencePasswordEntryController: ViewController {
|
|||||||
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
super.containerLayoutUpdated(layout, transition: transition)
|
super.containerLayoutUpdated(layout, transition: transition)
|
||||||
|
|
||||||
|
let hadLayout = self.validLayout != nil
|
||||||
|
self.validLayout = layout
|
||||||
|
|
||||||
|
if !hadLayout {
|
||||||
|
self.updateNavigationItems()
|
||||||
|
}
|
||||||
|
|
||||||
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
|
self.controllerNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,17 +2,23 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import Display
|
import Display
|
||||||
|
import SwiftSignalKit
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import AuthorizationUtils
|
import AuthorizationUtils
|
||||||
|
import AnimatedStickerNode
|
||||||
|
import TelegramAnimatedStickerNode
|
||||||
|
import SolidRoundedButtonNode
|
||||||
|
|
||||||
final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UITextFieldDelegate {
|
final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UITextFieldDelegate {
|
||||||
private let strings: PresentationStrings
|
private let strings: PresentationStrings
|
||||||
private let theme: PresentationTheme
|
private let theme: PresentationTheme
|
||||||
|
|
||||||
|
private let animationNode: AnimatedStickerNode
|
||||||
private let titleNode: ASTextNode
|
private let titleNode: ASTextNode
|
||||||
private let noticeNode: ASTextNode
|
private let noticeNode: ASTextNode
|
||||||
private let forgotNode: HighlightableButtonNode
|
private let forgotNode: HighlightableButtonNode
|
||||||
private let resetNode: HighlightableButtonNode
|
private let resetNode: HighlightableButtonNode
|
||||||
|
private let proceedNode: SolidRoundedButtonNode
|
||||||
|
|
||||||
private let codeField: TextFieldNode
|
private let codeField: TextFieldNode
|
||||||
private let codeSeparatorNode: ASDisplayNode
|
private let codeSeparatorNode: ASDisplayNode
|
||||||
@ -35,13 +41,26 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
var inProgress: Bool = false {
|
var inProgress: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
self.codeField.alpha = self.inProgress ? 0.6 : 1.0
|
self.codeField.alpha = self.inProgress ? 0.6 : 1.0
|
||||||
|
|
||||||
|
if self.inProgress != oldValue {
|
||||||
|
if self.inProgress {
|
||||||
|
self.proceedNode.transitionToProgress()
|
||||||
|
} else {
|
||||||
|
self.proceedNode.transitionFromProgress()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var timer: SwiftSignalKit.Timer?
|
||||||
|
|
||||||
init(strings: PresentationStrings, theme: PresentationTheme) {
|
init(strings: PresentationStrings, theme: PresentationTheme) {
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
|
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||||
|
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "IntroPassword"), width: 256, height: 256, playbackMode: .still(.start), mode: .direct(cachePathPrefix: nil))
|
||||||
|
|
||||||
self.titleNode = ASTextNode()
|
self.titleNode = ASTextNode()
|
||||||
self.titleNode.isUserInteractionEnabled = false
|
self.titleNode.isUserInteractionEnabled = false
|
||||||
self.titleNode.displaysAsynchronously = false
|
self.titleNode.displaysAsynchronously = false
|
||||||
@ -75,6 +94,10 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
self.codeField.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
||||||
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
self.codeField.textField.tintColor = self.theme.list.itemAccentColor
|
||||||
|
|
||||||
|
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
|
||||||
|
self.proceedNode.progressType = .embedded
|
||||||
|
self.proceedNode.isEnabled = false
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.setViewBlock({
|
self.setViewBlock({
|
||||||
@ -84,6 +107,7 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
self.backgroundColor = self.theme.list.plainBackgroundColor
|
self.backgroundColor = self.theme.list.plainBackgroundColor
|
||||||
|
|
||||||
self.codeField.textField.delegate = self
|
self.codeField.textField.delegate = self
|
||||||
|
self.codeField.textField.addTarget(self, action: #selector(self.textDidChange), for: .editingChanged)
|
||||||
|
|
||||||
self.addSubnode(self.codeSeparatorNode)
|
self.addSubnode(self.codeSeparatorNode)
|
||||||
self.addSubnode(self.codeField)
|
self.addSubnode(self.codeField)
|
||||||
@ -91,9 +115,26 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
self.addSubnode(self.forgotNode)
|
self.addSubnode(self.forgotNode)
|
||||||
self.addSubnode(self.resetNode)
|
self.addSubnode(self.resetNode)
|
||||||
self.addSubnode(self.noticeNode)
|
self.addSubnode(self.noticeNode)
|
||||||
|
self.addSubnode(self.animationNode)
|
||||||
|
self.addSubnode(self.proceedNode)
|
||||||
|
|
||||||
self.forgotNode.addTarget(self, action: #selector(self.forgotPressed), forControlEvents: .touchUpInside)
|
self.forgotNode.addTarget(self, action: #selector(self.forgotPressed), forControlEvents: .touchUpInside)
|
||||||
self.resetNode.addTarget(self, action: #selector(self.resetPressed), forControlEvents: .touchUpInside)
|
self.resetNode.addTarget(self, action: #selector(self.resetPressed), forControlEvents: .touchUpInside)
|
||||||
|
|
||||||
|
self.proceedNode.pressed = { [weak self] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.loginWithCode?(strongSelf.currentPassword)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.timer = SwiftSignalKit.Timer(timeout: 7.5, repeat: true, completion: { [weak self] in
|
||||||
|
self?.animationNode.playOnce()
|
||||||
|
}, queue: Queue.mainQueue())
|
||||||
|
self.timer?.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.timer?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateData(hint: String, didForgotWithNoRecovery: Bool, suggestReset: Bool) {
|
func updateData(hint: String, didForgotWithNoRecovery: Bool, suggestReset: Bool) {
|
||||||
@ -109,26 +150,33 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
self.layoutArguments = (layout, navigationBarHeight)
|
self.layoutArguments = (layout, navigationBarHeight)
|
||||||
|
|
||||||
var insets = layout.insets(options: [])
|
var insets = layout.insets(options: [])
|
||||||
insets.top = navigationBarHeight
|
insets.top = layout.statusBarHeight ?? 20.0
|
||||||
|
if let inputHeight = layout.inputHeight, !inputHeight.isZero {
|
||||||
if let inputHeight = layout.inputHeight {
|
insets.bottom = max(inputHeight, insets.bottom)
|
||||||
insets.bottom += max(inputHeight, layout.standardInputHeight)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let titleInset: CGFloat = layout.size.width > 320.0 ? 18.0 : 0.0
|
||||||
|
let additionalBottomInset: CGFloat = layout.size.width > 320.0 ? 110.0 : 20.0
|
||||||
|
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.LoginPassword_Title, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.strings.LoginPassword_Title, font: Font.semibold(28.0), textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
|
|
||||||
|
let inset: CGFloat = 24.0
|
||||||
|
|
||||||
|
let animationSize = CGSize(width: 100.0, height: 100.0)
|
||||||
let titleSize = self.titleNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
let titleSize = self.titleNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
||||||
|
|
||||||
let noticeSize = self.noticeNode.measure(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude))
|
let noticeSize = self.noticeNode.measure(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude))
|
||||||
let forgotSize = self.forgotNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
let forgotSize = self.forgotNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
||||||
let resetSize = self.resetNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
let resetSize = self.resetNode.measure(CGSize(width: layout.size.width, height: CGFloat.greatestFiniteMagnitude))
|
||||||
|
let proceedHeight = self.proceedNode.updateLayout(width: layout.size.width - inset * 2.0, transition: transition)
|
||||||
|
let proceedSize = CGSize(width: layout.size.width - inset * 2.0, height: proceedHeight)
|
||||||
|
|
||||||
var items: [AuthorizationLayoutItem] = []
|
var items: [AuthorizationLayoutItem] = []
|
||||||
items.append(AuthorizationLayoutItem(node: self.titleNode, size: titleSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.titleNode, size: titleSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: titleInset, maxValue: titleInset), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
items.append(AuthorizationLayoutItem(node: self.noticeNode, size: noticeSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 18.0, maxValue: 18.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.noticeNode, size: noticeSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 18.0, maxValue: 18.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
|
||||||
items.append(AuthorizationLayoutItem(node: self.codeField, size: CGSize(width: layout.size.width - 88.0, height: 44.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 32.0, maxValue: 60.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.codeField, size: CGSize(width: layout.size.width - 80.0, height: 44.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 32.0, maxValue: 60.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
items.append(AuthorizationLayoutItem(node: self.codeSeparatorNode, size: CGSize(width: layout.size.width - 88.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.codeSeparatorNode, size: CGSize(width: layout.size.width - 48.0, height: UIScreenPixel), spacingBefore: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
|
||||||
items.append(AuthorizationLayoutItem(node: self.forgotNode, size: forgotSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 48.0, maxValue: 100.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
items.append(AuthorizationLayoutItem(node: self.forgotNode, size: forgotSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 48.0, maxValue: 100.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
|
|
||||||
@ -139,7 +187,22 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
self.resetNode.isHidden = true
|
self.resetNode.isHidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - 20.0)), items: items, transition: transition, failIfDoesNotFit: false)
|
if layout.size.width > 320.0 {
|
||||||
|
items.insert(AuthorizationLayoutItem(node: self.animationNode, size: animationSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 10.0, maxValue: 10.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)), at: 0)
|
||||||
|
self.proceedNode.isHidden = false
|
||||||
|
self.animationNode.isHidden = false
|
||||||
|
self.animationNode.visibility = true
|
||||||
|
} else {
|
||||||
|
insets.top = navigationBarHeight
|
||||||
|
self.proceedNode.isHidden = true
|
||||||
|
self.animationNode.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
transition.updateFrame(node: self.proceedNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - proceedSize.width) / 2.0), y: layout.size.height - insets.bottom - proceedSize.height - inset), size: proceedSize))
|
||||||
|
|
||||||
|
self.animationNode.updateLayout(size: animationSize)
|
||||||
|
|
||||||
|
let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - additionalBottomInset)), items: items, transition: transition, failIfDoesNotFit: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func activateInput() {
|
func activateInput() {
|
||||||
@ -154,6 +217,10 @@ final class AuthorizationSequencePasswordEntryControllerNode: ASDisplayNode, UIT
|
|||||||
self.clearOnce = true
|
self.clearOnce = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func textDidChange() {
|
||||||
|
self.proceedNode.isEnabled = !(self.codeField.textField.text ?? "").isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
||||||
if self.clearOnce {
|
if self.clearOnce {
|
||||||
self.clearOnce = false
|
self.clearOnce = false
|
||||||
|
Binary file not shown.
@ -712,7 +712,7 @@ private final class DemoSheetContent: CombinedComponent {
|
|||||||
isStandalone = true
|
isStandalone = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if let reactions = state.reactions, let stickers = state.stickers, let appIcons = state.appIcons, let configuration = state.promoConfiguration {
|
if let stickers = state.stickers, let appIcons = state.appIcons, let configuration = state.promoConfiguration {
|
||||||
let textColor = theme.actionSheet.primaryTextColor
|
let textColor = theme.actionSheet.primaryTextColor
|
||||||
|
|
||||||
var availableItems: [PremiumPerk: DemoPagerComponent.Item] = [:]
|
var availableItems: [PremiumPerk: DemoPagerComponent.Item] = [:]
|
||||||
@ -794,15 +794,14 @@ private final class DemoSheetContent: CombinedComponent {
|
|||||||
id: PremiumDemoScreen.Subject.uniqueReactions,
|
id: PremiumDemoScreen.Subject.uniqueReactions,
|
||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
PageComponent(
|
PageComponent(
|
||||||
content: AnyComponent(
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
ReactionsCarouselComponent(
|
context: component.context,
|
||||||
context: component.context,
|
position: .top,
|
||||||
theme: environment.theme,
|
videoFile: configuration.videos["infinite_reactions"],
|
||||||
reactions: reactions
|
decoration: .badgeStars
|
||||||
)
|
)),
|
||||||
),
|
title: strings.Premium_InfiniteReactions,
|
||||||
title: isStandalone ? strings.Premium_ReactionsStandalone : strings.Premium_Reactions,
|
text: strings.Premium_InfiniteReactionsInfo,
|
||||||
text: isStandalone ? strings.Premium_ReactionsStandaloneInfo : strings.Premium_ReactionsInfo,
|
|
||||||
textColor: textColor
|
textColor: textColor
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -826,6 +825,24 @@ private final class DemoSheetContent: CombinedComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
availableItems[.emojiStatus] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.emojiStatus,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
|
context: component.context,
|
||||||
|
position: .top,
|
||||||
|
videoFile: configuration.videos["emoji_status"],
|
||||||
|
decoration: .swirlStars
|
||||||
|
)),
|
||||||
|
title: strings.Premium_EmojiStatus,
|
||||||
|
text: strings.Premium_EmojiStatusInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
availableItems[.advancedChatManagement] = DemoPagerComponent.Item(
|
availableItems[.advancedChatManagement] = DemoPagerComponent.Item(
|
||||||
AnyComponentWithIdentity(
|
AnyComponentWithIdentity(
|
||||||
id: PremiumDemoScreen.Subject.advancedChatManagement,
|
id: PremiumDemoScreen.Subject.advancedChatManagement,
|
||||||
@ -1171,6 +1188,7 @@ public class PremiumDemoScreen: ViewControllerComponentContainer {
|
|||||||
case animatedUserpics
|
case animatedUserpics
|
||||||
case appIcons
|
case appIcons
|
||||||
case animatedEmoji
|
case animatedEmoji
|
||||||
|
case emojiStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Source: Equatable {
|
public enum Source: Equatable {
|
||||||
|
@ -397,6 +397,8 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||||||
demoSubject = .appIcons
|
demoSubject = .appIcons
|
||||||
case .animatedEmoji:
|
case .animatedEmoji:
|
||||||
demoSubject = .animatedEmoji
|
demoSubject = .animatedEmoji
|
||||||
|
case .emojiStatus:
|
||||||
|
demoSubject = .emojiStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = PremiumDemoScreen(
|
let controller = PremiumDemoScreen(
|
||||||
|
@ -54,7 +54,7 @@ public enum PremiumSource: Equatable {
|
|||||||
case .stickers:
|
case .stickers:
|
||||||
return "premium_stickers"
|
return "premium_stickers"
|
||||||
case .reactions:
|
case .reactions:
|
||||||
return "unique_reactions"
|
return "infinite_reactions"
|
||||||
case .ads:
|
case .ads:
|
||||||
return "no_ads"
|
return "no_ads"
|
||||||
case .upload:
|
case .upload:
|
||||||
@ -110,6 +110,7 @@ enum PremiumPerk: CaseIterable {
|
|||||||
case animatedUserpics
|
case animatedUserpics
|
||||||
case appIcons
|
case appIcons
|
||||||
case animatedEmoji
|
case animatedEmoji
|
||||||
|
case emojiStatus
|
||||||
|
|
||||||
static var allCases: [PremiumPerk] {
|
static var allCases: [PremiumPerk] {
|
||||||
return [
|
return [
|
||||||
@ -124,7 +125,8 @@ enum PremiumPerk: CaseIterable {
|
|||||||
.profileBadge,
|
.profileBadge,
|
||||||
.animatedUserpics,
|
.animatedUserpics,
|
||||||
.appIcons,
|
.appIcons,
|
||||||
.animatedEmoji
|
.animatedEmoji,
|
||||||
|
.emojiStatus
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +153,7 @@ enum PremiumPerk: CaseIterable {
|
|||||||
case .noAds:
|
case .noAds:
|
||||||
return "no_ads"
|
return "no_ads"
|
||||||
case .uniqueReactions:
|
case .uniqueReactions:
|
||||||
return "unique_reactions"
|
return "infinite_reactions"
|
||||||
case .premiumStickers:
|
case .premiumStickers:
|
||||||
return "premium_stickers"
|
return "premium_stickers"
|
||||||
case .advancedChatManagement:
|
case .advancedChatManagement:
|
||||||
@ -164,6 +166,8 @@ enum PremiumPerk: CaseIterable {
|
|||||||
return "app_icons"
|
return "app_icons"
|
||||||
case .animatedEmoji:
|
case .animatedEmoji:
|
||||||
return "animated_emoji"
|
return "animated_emoji"
|
||||||
|
case .emojiStatus:
|
||||||
|
return "emoji_status"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +184,7 @@ enum PremiumPerk: CaseIterable {
|
|||||||
case .noAds:
|
case .noAds:
|
||||||
return strings.Premium_NoAds
|
return strings.Premium_NoAds
|
||||||
case .uniqueReactions:
|
case .uniqueReactions:
|
||||||
return strings.Premium_Reactions
|
return strings.Premium_InfiniteReactions
|
||||||
case .premiumStickers:
|
case .premiumStickers:
|
||||||
return strings.Premium_Stickers
|
return strings.Premium_Stickers
|
||||||
case .advancedChatManagement:
|
case .advancedChatManagement:
|
||||||
@ -193,6 +197,8 @@ enum PremiumPerk: CaseIterable {
|
|||||||
return strings.Premium_AppIcon
|
return strings.Premium_AppIcon
|
||||||
case .animatedEmoji:
|
case .animatedEmoji:
|
||||||
return strings.Premium_AnimatedEmoji
|
return strings.Premium_AnimatedEmoji
|
||||||
|
case .emojiStatus:
|
||||||
|
return strings.Premium_EmojiStatus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +215,7 @@ enum PremiumPerk: CaseIterable {
|
|||||||
case .noAds:
|
case .noAds:
|
||||||
return strings.Premium_NoAdsInfo
|
return strings.Premium_NoAdsInfo
|
||||||
case .uniqueReactions:
|
case .uniqueReactions:
|
||||||
return strings.Premium_ReactionsInfo
|
return strings.Premium_InfiniteReactionsInfo
|
||||||
case .premiumStickers:
|
case .premiumStickers:
|
||||||
return strings.Premium_StickersInfo
|
return strings.Premium_StickersInfo
|
||||||
case .advancedChatManagement:
|
case .advancedChatManagement:
|
||||||
@ -222,6 +228,8 @@ enum PremiumPerk: CaseIterable {
|
|||||||
return strings.Premium_AppIconInfo
|
return strings.Premium_AppIconInfo
|
||||||
case .animatedEmoji:
|
case .animatedEmoji:
|
||||||
return strings.Premium_AnimatedEmojiInfo
|
return strings.Premium_AnimatedEmojiInfo
|
||||||
|
case .emojiStatus:
|
||||||
|
return strings.Premium_EmojiStatusInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,6 +259,8 @@ enum PremiumPerk: CaseIterable {
|
|||||||
return "Premium/Perk/AppIcon"
|
return "Premium/Perk/AppIcon"
|
||||||
case .animatedEmoji:
|
case .animatedEmoji:
|
||||||
return "Premium/Perk/Emoji"
|
return "Premium/Perk/Emoji"
|
||||||
|
case .emojiStatus:
|
||||||
|
return "Premium/Perk/Emoji"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,6 +273,7 @@ struct PremiumIntroConfiguration {
|
|||||||
.fasterDownload,
|
.fasterDownload,
|
||||||
.voiceToText,
|
.voiceToText,
|
||||||
.noAds,
|
.noAds,
|
||||||
|
.emojiStatus,
|
||||||
.uniqueReactions,
|
.uniqueReactions,
|
||||||
.premiumStickers,
|
.premiumStickers,
|
||||||
.animatedEmoji,
|
.animatedEmoji,
|
||||||
@ -1445,6 +1456,8 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
demoSubject = .appIcons
|
demoSubject = .appIcons
|
||||||
case .animatedEmoji:
|
case .animatedEmoji:
|
||||||
demoSubject = .animatedEmoji
|
demoSubject = .animatedEmoji
|
||||||
|
case .emojiStatus:
|
||||||
|
demoSubject = .emojiStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = PremiumDemoScreen(
|
let controller = PremiumDemoScreen(
|
||||||
|
@ -1107,7 +1107,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
|||||||
}
|
}
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
|
|
||||||
Queue.mainQueue().after(0.1, {
|
Queue.mainQueue().after(0.5, {
|
||||||
navigationController.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .emoji(name: "IntroLetter", text: presentationData.strings.Login_EmailChanged), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
|
navigationController.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .emoji(name: "IntroLetter", text: presentationData.strings.Login_EmailChanged), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
|
||||||
return false
|
return false
|
||||||
}))
|
}))
|
||||||
|
@ -555,7 +555,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file
|
emojiFile = item.associatedData.animatedEmojiStickers[emoji.strippedEmoji]?.first?.file
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.message.text.count == 1, item.message.associatedMedia.isEmpty && emojiFile != nil {
|
if item.message.text.count == 1, (item.message.textEntitiesAttribute?.entities ?? []).isEmpty && emojiFile != nil {
|
||||||
emojiString = nil
|
emojiString = nil
|
||||||
} else if emojiString != nil {
|
} else if emojiString != nil {
|
||||||
emojiFile = nil
|
emojiFile = nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user