Tags and stories quality premium info

This commit is contained in:
Ilya Laktyushin 2024-01-30 03:13:43 +04:00
parent 4ffc6367bb
commit c7f6595e8e
21 changed files with 588 additions and 34 deletions

View File

@ -10983,3 +10983,10 @@ Sorry for the inconvenience.";
"Login.Announce.Info" = "Notify people on Telegram who know my phone number that I signed up."; "Login.Announce.Info" = "Notify people on Telegram who know my phone number that I signed up.";
"Login.Announce.Notify" = "Notify"; "Login.Announce.Notify" = "Notify";
"Login.Announce.DontNotify" = "Do Not Notify"; "Login.Announce.DontNotify" = "Do Not Notify";
"Premium.Stories.Quality.Title" = "Higher Quality";
"Premium.Stories.Quality.Text" = "View video stories in double the resolution.";
"Premium.MessageTags" = "Tags for Messages";
"Premium.MessageTagsInfo" = "Organize your Saved Messages with tags for quicker access.";
"Premium.MessageTags.Proceed" = "About Telegram Premium";

View File

@ -30,12 +30,14 @@ public enum PremiumIntroSource {
case storiesFormatting case storiesFormatting
case storiesExpirationDurations case storiesExpirationDurations
case storiesSuggestedReactions case storiesSuggestedReactions
case storiesHigherQuality
case channelBoost(EnginePeer.Id) case channelBoost(EnginePeer.Id)
case nameColor case nameColor
case similarChannels case similarChannels
case wallpapers case wallpapers
case presence case presence
case readTime case readTime
case messageTags
} }
public enum PremiumGiftSource: Equatable { public enum PremiumGiftSource: Equatable {
@ -65,6 +67,7 @@ public enum PremiumDemoSubject {
case stories case stories
case colors case colors
case wallpapers case wallpapers
case messageTags
} }
public enum PremiumLimitSubject { public enum PremiumLimitSubject {

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

View File

@ -111,3 +111,57 @@ final class EmojiStarsView: UIView, PhoneDemoDecorationView {
self.sceneView.frame = CGRect(origin: .zero, size: frame.size) self.sceneView.frame = CGRect(origin: .zero, size: frame.size)
} }
} }
final class TagStarsView: UIView, PhoneDemoDecorationView {
private let sceneView: SCNView
private var leftParticles: SCNNode?
private var rightParticles: SCNNode?
override init(frame: CGRect) {
self.sceneView = SCNView(frame: CGRect(origin: .zero, size: frame.size))
self.sceneView.backgroundColor = .clear
if let url = getAppBundle().url(forResource: "tag", withExtension: "scn") {
self.sceneView.scene = try? SCNScene(url: url, options: nil)
}
self.sceneView.isUserInteractionEnabled = false
self.sceneView.preferredFramesPerSecond = 60
super.init(frame: frame)
self.alpha = 0.0
self.addSubview(self.sceneView)
self.leftParticles = self.sceneView.scene?.rootNode.childNode(withName: "leftParticles", recursively: false)
self.rightParticles = self.sceneView.scene?.rootNode.childNode(withName: "rightParticles", recursively: false)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setVisible(_ visible: Bool) {
if visible, let leftParticles = self.leftParticles, let rightParticles = self.rightParticles, leftParticles.parent == nil {
self.sceneView.scene?.rootNode.addChildNode(leftParticles)
self.sceneView.scene?.rootNode.addChildNode(rightParticles)
}
let transition = ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear)
transition.updateAlpha(layer: self.layer, alpha: visible ? 0.5 : 0.0, completion: { [weak self] finished in
if let strongSelf = self, finished && !visible && strongSelf.leftParticles?.parent != nil {
strongSelf.leftParticles?.removeFromParentNode()
strongSelf.rightParticles?.removeFromParentNode()
}
})
}
func resetAnimation() {
}
override func layoutSubviews() {
super.layoutSubviews()
self.sceneView.frame = CGRect(origin: .zero, size: frame.size)
}
}

View File

@ -370,6 +370,7 @@ final class PhoneDemoComponent: Component {
case badgeStars case badgeStars
case emoji case emoji
case hello case hello
case tag
} }
enum Model { enum Model {
@ -539,6 +540,13 @@ final class PhoneDemoComponent: Component {
self.decorationView = starsView self.decorationView = starsView
self.decorationContainerView.addSubview(starsView) self.decorationContainerView.addSubview(starsView)
} }
case .tag:
if let _ = self.decorationView as? TagStarsView {
} else {
let starsView = TagStarsView(frame: self.decorationContainerView.bounds)
self.decorationView = starsView
self.decorationContainerView.addSubview(starsView)
}
} }
self.phoneView.setup(context: component.context, videoFile: component.videoFile, position: component.position) self.phoneView.setup(context: component.context, videoFile: component.videoFile, position: component.position)

View File

@ -981,6 +981,25 @@ private final class DemoSheetContent: CombinedComponent {
) )
) )
) )
availableItems[.messageTags] = DemoPagerComponent.Item(
AnyComponentWithIdentity(
id: PremiumDemoScreen.Subject.messageTags,
component: AnyComponent(
PageComponent(
content: AnyComponent(PhoneDemoComponent(
context: component.context,
position: .top,
model: .island,
videoFile: configuration.videos["saved_tags"],
decoration: .tag
)),
title: strings.Premium_MessageTags,
text: strings.Premium_MessageTagsInfo,
textColor: textColor
)
)
)
)
var items: [DemoPagerComponent.Item] = component.order.compactMap { availableItems[$0] } var items: [DemoPagerComponent.Item] = component.order.compactMap { availableItems[$0] }
let index: Int let index: Int
@ -1083,6 +1102,8 @@ private final class DemoSheetContent: CombinedComponent {
buttonText = strings.Premium_Wallpaper_Proceed buttonText = strings.Premium_Wallpaper_Proceed
case .colors: case .colors:
buttonText = strings.Premium_Colors_Proceed buttonText = strings.Premium_Colors_Proceed
case .messageTags:
buttonText = strings.Premium_MessageTags_Proceed
default: default:
buttonText = strings.Common_OK buttonText = strings.Common_OK
} }
@ -1118,9 +1139,9 @@ private final class DemoSheetContent: CombinedComponent {
text = strings.Premium_ColorsInfo text = strings.Premium_ColorsInfo
case .wallpapers: case .wallpapers:
text = strings.Premium_WallpapersInfo text = strings.Premium_WallpapersInfo
case .doubleLimits: case .messageTags:
text = "" text = strings.Premium_MessageTagsInfo
case .stories: case .doubleLimits, .stories:
text = "" text = ""
} }
@ -1338,6 +1359,7 @@ public class PremiumDemoScreen: ViewControllerComponentContainer {
case stories case stories
case colors case colors
case wallpapers case wallpapers
case messageTags
} }
public enum Source: Equatable { public enum Source: Equatable {

View File

@ -429,6 +429,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
UIColor(rgb: 0xcb3e6d), UIColor(rgb: 0xcb3e6d),
UIColor(rgb: 0xbc4395), UIColor(rgb: 0xbc4395),
UIColor(rgb: 0xab4ac4), UIColor(rgb: 0xab4ac4),
UIColor(rgb: 0xa34cd7),
UIColor(rgb: 0x9b4fed), UIColor(rgb: 0x9b4fed),
UIColor(rgb: 0x8958ff), UIColor(rgb: 0x8958ff),
UIColor(rgb: 0x676bff), UIColor(rgb: 0x676bff),
@ -521,6 +522,8 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
demoSubject = .colors demoSubject = .colors
case .wallpapers: case .wallpapers:
demoSubject = .wallpapers demoSubject = .wallpapers
case .messageTags:
demoSubject = .messageTags
} }
let buttonText: String let buttonText: String

View File

@ -229,6 +229,12 @@ public enum PremiumSource: Equatable {
} else { } else {
return false return false
} }
case .storiesHigherQuality:
if case .storiesHigherQuality = rhs {
return true
} else {
return false
}
case let .channelBoost(peerId): case let .channelBoost(peerId):
if case .channelBoost(peerId) = rhs { if case .channelBoost(peerId) = rhs {
return true return true
@ -265,6 +271,12 @@ public enum PremiumSource: Equatable {
} else { } else {
return false return false
} }
case .messageTags:
if case .messageTags = rhs {
return true
} else {
return false
}
} }
} }
@ -301,12 +313,14 @@ public enum PremiumSource: Equatable {
case storiesFormatting case storiesFormatting
case storiesExpirationDurations case storiesExpirationDurations
case storiesSuggestedReactions case storiesSuggestedReactions
case storiesHigherQuality
case channelBoost(EnginePeer.Id) case channelBoost(EnginePeer.Id)
case nameColor case nameColor
case similarChannels case similarChannels
case wallpapers case wallpapers
case presence case presence
case readTime case readTime
case messageTags
var identifier: String? { var identifier: String? {
switch self { switch self {
@ -378,6 +392,8 @@ public enum PremiumSource: Equatable {
return "stories__expiration_durations" return "stories__expiration_durations"
case .storiesSuggestedReactions: case .storiesSuggestedReactions:
return "stories__suggested_reactions" return "stories__suggested_reactions"
case .storiesHigherQuality:
return "stories__quality"
case let .channelBoost(peerId): case let .channelBoost(peerId):
return "channel_boost__\(peerId.id._internalGetInt64Value())" return "channel_boost__\(peerId.id._internalGetInt64Value())"
case .nameColor: case .nameColor:
@ -390,6 +406,8 @@ public enum PremiumSource: Equatable {
return "presence" return "presence"
case .readTime: case .readTime:
return "read_time" return "read_time"
case .messageTags:
return "saved_tags"
} }
} }
} }
@ -412,6 +430,7 @@ public enum PremiumPerk: CaseIterable {
case stories case stories
case colors case colors
case wallpapers case wallpapers
case messageTags
public static var allCases: [PremiumPerk] { public static var allCases: [PremiumPerk] {
return [ return [
@ -431,7 +450,8 @@ public enum PremiumPerk: CaseIterable {
.translation, .translation,
.stories, .stories,
.colors, .colors,
.wallpapers .wallpapers,
.messageTags
] ]
} }
@ -481,6 +501,8 @@ public enum PremiumPerk: CaseIterable {
return "peer_colors" return "peer_colors"
case .wallpapers: case .wallpapers:
return "wallpapers" return "wallpapers"
case .messageTags:
return "saved_tags"
} }
} }
@ -520,6 +542,8 @@ public enum PremiumPerk: CaseIterable {
return strings.Premium_Colors return strings.Premium_Colors
case .wallpapers: case .wallpapers:
return strings.Premium_Wallpapers return strings.Premium_Wallpapers
case .messageTags:
return strings.Premium_MessageTags
} }
} }
@ -559,6 +583,8 @@ public enum PremiumPerk: CaseIterable {
return strings.Premium_ColorsInfo return strings.Premium_ColorsInfo
case .wallpapers: case .wallpapers:
return strings.Premium_WallpapersInfo return strings.Premium_WallpapersInfo
case .messageTags:
return strings.Premium_MessageTagsInfo
} }
} }
@ -598,6 +624,8 @@ public enum PremiumPerk: CaseIterable {
return "Premium/Perk/Colors" return "Premium/Perk/Colors"
case .wallpapers: case .wallpapers:
return "Premium/Perk/Wallpapers" return "Premium/Perk/Wallpapers"
case .messageTags:
return "Premium/Perk/MessageTags"
} }
} }
} }
@ -606,22 +634,23 @@ struct PremiumIntroConfiguration {
static var defaultValue: PremiumIntroConfiguration { static var defaultValue: PremiumIntroConfiguration {
return PremiumIntroConfiguration(perks: [ return PremiumIntroConfiguration(perks: [
.stories, .stories,
.doubleLimits,
.moreUpload, .moreUpload,
.doubleLimits,
.voiceToText,
.fasterDownload, .fasterDownload,
.translation, .translation,
.voiceToText, .animatedEmoji,
.noAds,
.emojiStatus, .emojiStatus,
.messageTags,
.colors, .colors,
.wallpapers, .wallpapers,
.uniqueReactions,
.premiumStickers,
.animatedEmoji,
.advancedChatManagement,
.profileBadge, .profileBadge,
.advancedChatManagement,
.noAds,
.appIcons,
.uniqueReactions,
.animatedUserpics, .animatedUserpics,
.appIcons .premiumStickers
]) ])
} }
@ -657,6 +686,9 @@ struct PremiumIntroConfiguration {
if !perks.contains(.colors) { if !perks.contains(.colors) {
perks.append(.colors) perks.append(.colors)
} }
if !perks.contains(.messageTags) {
perks.append(.messageTags)
}
#endif #endif
return PremiumIntroConfiguration(perks: perks) return PremiumIntroConfiguration(perks: perks)
} else { } else {
@ -1617,8 +1649,9 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
self.newPerksDisposable = combineLatest(queue: Queue.mainQueue(), self.newPerksDisposable = combineLatest(queue: Queue.mainQueue(),
ApplicationSpecificNotice.dismissedPremiumAppIconsBadge(accountManager: context.sharedContext.accountManager), ApplicationSpecificNotice.dismissedPremiumAppIconsBadge(accountManager: context.sharedContext.accountManager),
ApplicationSpecificNotice.dismissedPremiumWallpapersBadge(accountManager: context.sharedContext.accountManager), ApplicationSpecificNotice.dismissedPremiumWallpapersBadge(accountManager: context.sharedContext.accountManager),
ApplicationSpecificNotice.dismissedPremiumColorsBadge(accountManager: context.sharedContext.accountManager) ApplicationSpecificNotice.dismissedPremiumColorsBadge(accountManager: context.sharedContext.accountManager),
).startStrict(next: { [weak self] dismissedPremiumAppIconsBadge, dismissedPremiumWallpapersBadge, dismissedPremiumColorsBadge in ApplicationSpecificNotice.dismissedMessageTagsBadge(accountManager: context.sharedContext.accountManager)
).startStrict(next: { [weak self] dismissedPremiumAppIconsBadge, dismissedPremiumWallpapersBadge, dismissedPremiumColorsBadge, dismissedMessageTagsBadge in
guard let self else { guard let self else {
return return
} }
@ -1629,6 +1662,9 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
if !dismissedPremiumColorsBadge { if !dismissedPremiumColorsBadge {
newPerks.append(PremiumPerk.colors.identifier) newPerks.append(PremiumPerk.colors.identifier)
} }
if !dismissedMessageTagsBadge {
newPerks.append(PremiumPerk.messageTags.identifier)
}
self.newPerks = newPerks self.newPerks = newPerks
self.updated() self.updated()
}) })
@ -1808,6 +1844,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
UIColor(rgb: 0xcb3e6d), UIColor(rgb: 0xcb3e6d),
UIColor(rgb: 0xbc4395), UIColor(rgb: 0xbc4395),
UIColor(rgb: 0xab4ac4), UIColor(rgb: 0xab4ac4),
UIColor(rgb: 0xa34cd7),
UIColor(rgb: 0x9b4fed), UIColor(rgb: 0x9b4fed),
UIColor(rgb: 0x8958ff), UIColor(rgb: 0x8958ff),
UIColor(rgb: 0x676bff), UIColor(rgb: 0x676bff),
@ -2031,6 +2068,9 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
case .wallpapers: case .wallpapers:
demoSubject = .wallpapers demoSubject = .wallpapers
let _ = ApplicationSpecificNotice.setDismissedPremiumWallpapersBadge(accountManager: accountContext.sharedContext.accountManager).startStandalone() let _ = ApplicationSpecificNotice.setDismissedPremiumWallpapersBadge(accountManager: accountContext.sharedContext.accountManager).startStandalone()
case .messageTags:
demoSubject = .messageTags
let _ = ApplicationSpecificNotice.setDismissedMessageTagsBadge(accountManager: accountContext.sharedContext.accountManager).startStandalone()
} }
let isPremium = state?.isPremium == true let isPremium = state?.isPremium == true

View File

@ -742,6 +742,25 @@ public class PremiumLimitsListScreen: ViewController {
) )
) )
) )
availableItems[.messageTags] = DemoPagerComponent.Item(
AnyComponentWithIdentity(
id: PremiumDemoScreen.Subject.messageTags,
component: AnyComponent(
PageComponent(
content: AnyComponent(PhoneDemoComponent(
context: context,
position: .top,
model: .island,
videoFile: configuration.videos["saved_tags"],
decoration: .tag
)),
title: strings.Premium_MessageTags,
text: strings.Premium_MessageTagsInfo,
textColor: textColor
)
)
)
)
if let order = controller.order { if let order = controller.order {
var items: [DemoPagerComponent.Item] = order.compactMap { availableItems[$0] } var items: [DemoPagerComponent.Item] = order.compactMap { availableItems[$0] }

View File

@ -312,13 +312,14 @@ private final class StoriesListComponent: CombinedComponent {
let strings = context.component.context.sharedContext.currentPresentationData.with { $0 }.strings let strings = context.component.context.sharedContext.currentPresentationData.with { $0 }.strings
let colors = [ let colors = [
UIColor(rgb: 0x0275f3), UIColor(rgb: 0x007aff),
UIColor(rgb: 0x8698ff), UIColor(rgb: 0x798aff),
UIColor(rgb: 0xc871ff), UIColor(rgb: 0xac64f3),
UIColor(rgb: 0xc356ad), UIColor(rgb: 0xc456ae),
UIColor(rgb: 0xe85c44), UIColor(rgb: 0xe95d44),
UIColor(rgb: 0xff932b), UIColor(rgb: 0xf2822a),
UIColor(rgb: 0xe9af18) UIColor(rgb: 0xe79519),
UIColor(rgb: 0xe7ad19)
] ]
let titleColor = theme.list.itemPrimaryTextColor let titleColor = theme.list.itemPrimaryTextColor
@ -367,6 +368,20 @@ private final class StoriesListComponent: CombinedComponent {
) )
) )
items.append(
AnyComponentWithIdentity(
id: "quality",
component: AnyComponent(ParagraphComponent(
title: strings.Premium_Stories_Quality_Title,
titleColor: titleColor,
text: strings.Premium_Stories_Quality_Text,
textColor: textColor,
iconName: "Premium/Stories/Quality",
iconColor: colors[2]
))
)
)
items.append( items.append(
AnyComponentWithIdentity( AnyComponentWithIdentity(
id: "views", id: "views",
@ -376,7 +391,7 @@ private final class StoriesListComponent: CombinedComponent {
text: strings.Premium_Stories_Views_Text, text: strings.Premium_Stories_Views_Text,
textColor: textColor, textColor: textColor,
iconName: "Premium/Stories/Views", iconName: "Premium/Stories/Views",
iconColor: colors[2] iconColor: colors[3]
)) ))
) )
) )
@ -390,7 +405,7 @@ private final class StoriesListComponent: CombinedComponent {
text: strings.Premium_Stories_Expiration_Text, text: strings.Premium_Stories_Expiration_Text,
textColor: textColor, textColor: textColor,
iconName: "Premium/Stories/Expire", iconName: "Premium/Stories/Expire",
iconColor: colors[3] iconColor: colors[4]
)) ))
) )
) )
@ -404,7 +419,7 @@ private final class StoriesListComponent: CombinedComponent {
text: strings.Premium_Stories_Save_Text, text: strings.Premium_Stories_Save_Text,
textColor: textColor, textColor: textColor,
iconName: "Premium/Stories/Save", iconName: "Premium/Stories/Save",
iconColor: colors[4] iconColor: colors[5]
)) ))
) )
) )
@ -418,7 +433,7 @@ private final class StoriesListComponent: CombinedComponent {
text: strings.Premium_Stories_Captions_Text, text: strings.Premium_Stories_Captions_Text,
textColor: textColor, textColor: textColor,
iconName: "Premium/Stories/Caption", iconName: "Premium/Stories/Caption",
iconColor: colors[5] iconColor: colors[6]
)) ))
) )
) )
@ -432,7 +447,7 @@ private final class StoriesListComponent: CombinedComponent {
text: strings.Premium_Stories_Format_Text, text: strings.Premium_Stories_Format_Text,
textColor: textColor, textColor: textColor,
iconName: "Premium/Stories/Format", iconName: "Premium/Stories/Format",
iconColor: colors[6] iconColor: colors[7]
)) ))
) )
) )

View File

@ -195,6 +195,7 @@ private enum ApplicationSpecificGlobalNotice: Int32 {
case videoMessagesPlayOnceSuggestion = 61 case videoMessagesPlayOnceSuggestion = 61
case incomingVideoMessagePlayOnceTip = 62 case incomingVideoMessagePlayOnceTip = 62
case outgoingVideoMessagePlayOnceTip = 63 case outgoingVideoMessagePlayOnceTip = 63
case dismissedMessageTagsBadge = 64
var key: ValueBoxKey { var key: ValueBoxKey {
let v = ValueBoxKey(length: 4) let v = ValueBoxKey(length: 4)
@ -504,6 +505,10 @@ private struct ApplicationSpecificNoticeKeys {
static func outgoingVideoMessagePlayOnceTip() -> NoticeEntryKey { static func outgoingVideoMessagePlayOnceTip() -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.outgoingVideoMessagePlayOnceTip.key) return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.outgoingVideoMessagePlayOnceTip.key)
} }
static func dismissedMessageTagsBadge() -> NoticeEntryKey {
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.dismissedMessageTagsBadge.key)
}
} }
public struct ApplicationSpecificNotice { public struct ApplicationSpecificNotice {
@ -2080,4 +2085,25 @@ public struct ApplicationSpecificNotice {
return Int(previousValue) return Int(previousValue)
} }
} }
public static func setDismissedMessageTagsBadge(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Never, NoError> {
return accountManager.transaction { transaction -> Void in
if let entry = CodableEntry(ApplicationSpecificBoolNotice()) {
transaction.setNotice(ApplicationSpecificNoticeKeys.dismissedMessageTagsBadge(), entry)
}
}
|> ignoreValues
}
public static func dismissedMessageTagsBadge(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Bool, NoError> {
return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.dismissedMessageTagsBadge())
|> map { view -> Bool in
if let _ = view.value?.get(ApplicationSpecificBoolNotice.self) {
return true
} else {
return false
}
}
|> take(1)
}
} }

View File

@ -27,7 +27,7 @@ public final class SliderContextItem: ContextMenuCustomItem {
private let textFont = Font.with(size: 17.0, design: .regular, traits: .monospacedNumbers) private let textFont = Font.with(size: 17.0, design: .regular, traits: .monospacedNumbers)
private final class SliderContextItemNode: ASDisplayNode, ContextMenuCustomNode { private final class SliderContextItemNode: ASDisplayNode, ContextMenuCustomNode, UIGestureRecognizerDelegate {
private var presentationData: PresentationData private var presentationData: PresentationData
private(set) var vibrancyEffectView: UIVisualEffectView? private(set) var vibrancyEffectView: UIVisualEffectView?
@ -122,6 +122,8 @@ private final class SliderContextItemNode: ASDisplayNode, ContextMenuCustomNode
override func didLoad() { override func didLoad() {
super.didLoad() super.didLoad()
self.view.disablesInteractiveTransitionGestureRecognizer = true
if let vibrancyEffectView = self.vibrancyEffectView { if let vibrancyEffectView = self.vibrancyEffectView {
Queue.mainQueue().after(0.05) { Queue.mainQueue().after(0.05) {
if let effectNode = findEffectNode(node: self.supernode) { if let effectNode = findEffectNode(node: self.supernode) {
@ -132,6 +134,7 @@ private final class SliderContextItemNode: ASDisplayNode, ContextMenuCustomNode
} }
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.panGesture(_:))) let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.panGesture(_:)))
panGestureRecognizer.delegate = self
self.view.addGestureRecognizer(panGestureRecognizer) self.view.addGestureRecognizer(panGestureRecognizer)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))) let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))

View File

@ -5620,8 +5620,7 @@ public final class StoryItemSetContainerComponent: Component {
guard let self else { guard let self else {
return return
} }
//TODO:localize self.presentStoriesUpgradeScreen(source: .storiesHigherQuality)
self.presentStoriesUpgradeScreen(source: .storiesStealthMode)
}) })
} }

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "tag_30 (2).pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,164 @@
%PDF-1.7
1 0 obj
<< /Type /XObject
/Length 2 0 R
/Group << /Type /Group
/S /Transparency
>>
/Subtype /Form
/Resources << >>
/BBox [ 0.000000 0.000000 30.000000 30.000000 ]
>>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 5.406738 8.000000 cm
0.000000 0.000000 0.000000 scn
16.973253 11.854660 m
19.015503 9.069774 l
19.918947 7.837805 19.918947 6.162195 19.015503 4.930227 c
16.973253 2.145341 l
15.984283 0.796747 14.411980 0.000000 12.739626 0.000000 c
3.500002 0.000000 l
1.567005 0.000000 0.000000 1.567004 0.000000 3.500001 c
0.000000 10.500000 l
0.000000 12.432997 1.567003 14.000000 3.500000 14.000000 c
12.739625 14.000000 l
14.411979 14.000000 15.984283 13.203254 16.973253 11.854660 c
h
14.350163 5.250000 m
15.316662 5.250000 16.100163 6.033502 16.100163 7.000000 c
16.100163 7.966498 15.316662 8.750000 14.350163 8.750000 c
13.383665 8.750000 12.600163 7.966498 12.600163 7.000000 c
12.600163 6.033502 13.383665 5.250000 14.350163 5.250000 c
h
f*
n
Q
endstream
endobj
2 0 obj
809
endobj
3 0 obj
<< /Type /XObject
/Length 4 0 R
/Group << /Type /Group
/S /Transparency
>>
/Subtype /Form
/Resources << >>
/BBox [ 0.000000 0.000000 30.000000 30.000000 ]
>>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm
0.000000 0.000000 0.000000 scn
0.000000 18.799999 m
0.000000 22.720367 0.000000 24.680552 0.762954 26.177933 c
1.434068 27.495068 2.504932 28.565931 3.822066 29.237045 c
5.319448 30.000000 7.279633 30.000000 11.200000 30.000000 c
18.799999 30.000000 l
22.720367 30.000000 24.680552 30.000000 26.177933 29.237045 c
27.495068 28.565931 28.565931 27.495068 29.237045 26.177933 c
30.000000 24.680552 30.000000 22.720367 30.000000 18.799999 c
30.000000 11.200001 l
30.000000 7.279633 30.000000 5.319448 29.237045 3.822067 c
28.565931 2.504932 27.495068 1.434069 26.177933 0.762955 c
24.680552 0.000000 22.720367 0.000000 18.799999 0.000000 c
11.200000 0.000000 l
7.279633 0.000000 5.319448 0.000000 3.822066 0.762955 c
2.504932 1.434069 1.434068 2.504932 0.762954 3.822067 c
0.000000 5.319448 0.000000 7.279633 0.000000 11.200001 c
0.000000 18.799999 l
h
f
n
Q
endstream
endobj
4 0 obj
944
endobj
5 0 obj
<< /XObject << /X1 1 0 R >>
/ExtGState << /E1 << /SMask << /Type /Mask
/G 3 0 R
/S /Alpha
>>
/Type /ExtGState
>> >>
>>
endobj
6 0 obj
<< /Length 7 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
/E1 gs
/X1 Do
Q
endstream
endobj
7 0 obj
46
endobj
8 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
/Resources 5 0 R
/Contents 6 0 R
/Parent 9 0 R
>>
endobj
9 0 obj
<< /Kids [ 8 0 R ]
/Count 1
/Type /Pages
>>
endobj
10 0 obj
<< /Pages 9 0 R
/Type /Catalog
>>
endobj
xref
0 11
0000000000 65535 f
0000000010 00000 n
0000001067 00000 n
0000001089 00000 n
0000002281 00000 n
0000002303 00000 n
0000002601 00000 n
0000002703 00000 n
0000002724 00000 n
0000002897 00000 n
0000002971 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 10 0 R
/Size 11
>>
startxref
3031
%%EOF

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "hd_30.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,161 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 3.084961 4.960083 cm
0.000000 0.000000 0.000000 scn
6.665000 20.079956 m
6.635606 20.079956 l
6.635600 20.079956 l
5.610404 20.079960 4.800312 20.079964 4.147855 20.026657 c
3.481411 19.972206 2.921088 19.858839 2.410632 19.598749 c
1.579897 19.175468 0.904487 18.500059 0.481207 17.669323 c
0.221116 17.158869 0.107750 16.598545 0.053300 15.932100 c
-0.000008 15.279644 -0.000005 14.469551 0.000000 13.444355 c
0.000000 13.444349 l
0.000000 13.414955 l
0.000000 6.664956 l
0.000000 6.635563 l
-0.000005 5.610363 -0.000008 4.800270 0.053300 4.147811 c
0.107750 3.481365 0.221116 2.921043 0.481207 2.410587 c
0.904487 1.579851 1.579897 0.904442 2.410632 0.481161 c
2.921088 0.221071 3.481411 0.107704 4.147856 0.053255 c
4.800318 -0.000055 5.610417 -0.000051 6.635624 -0.000046 c
6.665001 -0.000046 l
17.165001 -0.000046 l
17.194378 -0.000046 l
18.219585 -0.000051 19.029684 -0.000055 19.682146 0.053255 c
20.348591 0.107704 20.908913 0.221071 21.419369 0.481161 c
22.250105 0.904442 22.925514 1.579851 23.348795 2.410587 c
23.608885 2.921043 23.722252 3.481365 23.776701 4.147811 c
23.830011 4.800273 23.830008 5.610373 23.830002 6.635580 c
23.830002 6.664956 l
23.830002 13.414955 l
23.830002 13.444332 l
23.830008 14.469540 23.830011 15.279638 23.776701 15.932100 c
23.722252 16.598545 23.608885 17.158869 23.348795 17.669323 c
22.925514 18.500059 22.250105 19.175468 21.419369 19.598749 c
20.908913 19.858839 20.348591 19.972206 19.682146 20.026657 c
19.029688 20.079964 18.219595 20.079960 17.194395 20.079956 c
17.165001 20.079956 l
6.665000 20.079956 l
h
3.014440 18.413712 m
3.306153 18.562346 3.671964 18.653343 4.256160 18.701073 c
4.848119 18.749439 5.603929 18.749956 6.665000 18.749956 c
17.165001 18.749956 l
18.226072 18.749956 18.981882 18.749439 19.573841 18.701073 c
20.158037 18.653343 20.523848 18.562346 20.815561 18.413712 c
21.396042 18.117941 21.867987 17.645996 22.163755 17.065517 c
22.312391 16.773804 22.403387 16.407993 22.451118 15.823796 c
22.499483 15.231836 22.500000 14.476027 22.500000 13.414955 c
22.500000 6.664956 l
22.500000 5.603885 22.499483 4.848075 22.451118 4.256116 c
22.403387 3.671919 22.312391 3.306108 22.163755 3.014395 c
21.867987 2.433914 21.396042 1.961969 20.815561 1.666201 c
20.523848 1.517565 20.158037 1.426569 19.573841 1.378838 c
18.981882 1.330473 18.226072 1.329956 17.165001 1.329956 c
6.665001 1.329956 l
5.603929 1.329956 4.848119 1.330473 4.256160 1.378838 c
3.671964 1.426569 3.306153 1.517565 3.014440 1.666201 c
2.433959 1.961969 1.962015 2.433914 1.666245 3.014395 c
1.517610 3.306108 1.426613 3.671919 1.378883 4.256116 c
1.330518 4.848075 1.330000 5.603885 1.330000 6.664956 c
1.330000 13.414955 l
1.330000 14.476027 1.330518 15.231836 1.378883 15.823796 c
1.426613 16.407993 1.517610 16.773804 1.666245 17.065517 c
1.962015 17.645996 2.433959 18.117941 3.014440 18.413712 c
h
3.975623 6.325036 m
3.975623 5.885583 4.231971 5.617028 4.659217 5.617028 c
5.080359 5.617028 5.342811 5.885583 5.342811 6.325036 c
5.342811 9.614831 l
9.865516 9.614831 l
9.865516 6.325036 l
9.865516 5.885583 10.121863 5.617028 10.549109 5.617028 c
10.970252 5.617028 11.232703 5.885583 11.232703 6.325036 c
11.232703 13.911706 l
11.232703 14.351159 10.970252 14.619714 10.549109 14.619714 c
10.121863 14.619714 9.865516 14.351159 9.865516 13.911706 c
9.865516 10.798913 l
5.342811 10.798913 l
5.342811 13.911706 l
5.342811 14.351159 5.080359 14.619714 4.659217 14.619714 c
4.231971 14.619714 3.975623 14.351159 3.975623 13.911706 c
3.975623 6.325036 l
h
12.752635 6.422692 m
12.752635 5.983239 13.008983 5.714684 13.436229 5.714684 c
15.859324 5.714684 l
18.483837 5.714684 20.028027 7.350427 20.028027 10.133630 c
20.028027 12.910729 18.477734 14.522058 15.859324 14.522058 c
13.436229 14.522058 l
13.008983 14.522058 12.752635 14.253503 12.752635 13.814050 c
12.752635 6.422692 l
h
15.731151 6.898767 m
14.119823 6.898767 l
14.119823 13.344079 l
15.731151 13.344079 l
17.592724 13.344079 18.630322 12.196618 18.630322 10.121423 c
18.630322 8.040124 17.598827 6.898767 15.731151 6.898767 c
h
f*
n
Q
endstream
endobj
3 0 obj
4117
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000004207 00000 n
0000004230 00000 n
0000004403 00000 n
0000004477 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
4536
%%EOF

View File

@ -317,8 +317,8 @@ extension ChatControllerImpl {
let context = self.context let context = self.context
var replaceImpl: ((ViewController) -> Void)? var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumDemoScreen(context: context, subject: .uniqueReactions, action: { let controller = PremiumDemoScreen(context: context, subject: .messageTags, action: {
let controller = PremiumIntroScreen(context: context, source: .reactions) let controller = PremiumIntroScreen(context: context, source: .messageTags)
replaceImpl?(controller) replaceImpl?(controller)
}) })
replaceImpl = { [weak controller] c in replaceImpl = { [weak controller] c in

View File

@ -21,8 +21,8 @@ extension ChatControllerImpl {
//TODO:localize //TODO:localize
let context = self.context let context = self.context
var replaceImpl: ((ViewController) -> Void)? var replaceImpl: ((ViewController) -> Void)?
let controller = PremiumDemoScreen(context: context, subject: .uniqueReactions, action: { let controller = PremiumDemoScreen(context: context, subject: .messageTags, action: {
let controller = PremiumIntroScreen(context: context, source: .reactions) let controller = PremiumIntroScreen(context: context, source: .messageTags)
replaceImpl?(controller) replaceImpl?(controller)
}) })
replaceImpl = { [weak controller] c in replaceImpl = { [weak controller] c in

View File

@ -1938,6 +1938,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
mappedSource = .storiesExpirationDurations mappedSource = .storiesExpirationDurations
case .storiesSuggestedReactions: case .storiesSuggestedReactions:
mappedSource = .storiesSuggestedReactions mappedSource = .storiesSuggestedReactions
case .storiesHigherQuality:
mappedSource = .storiesHigherQuality
case let .channelBoost(peerId): case let .channelBoost(peerId):
mappedSource = .channelBoost(peerId) mappedSource = .channelBoost(peerId)
case .nameColor: case .nameColor:
@ -1950,6 +1952,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
mappedSource = .presence mappedSource = .presence
case .readTime: case .readTime:
mappedSource = .readTime mappedSource = .readTime
case .messageTags:
mappedSource = .messageTags
} }
let controller = PremiumIntroScreen(context: context, modal: modal, source: mappedSource, forceDark: forceDark) let controller = PremiumIntroScreen(context: context, modal: modal, source: mappedSource, forceDark: forceDark)
controller.wasDismissed = dismissed controller.wasDismissed = dismissed
@ -1993,6 +1997,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
mappedSubject = .colors mappedSubject = .colors
case .wallpapers: case .wallpapers:
mappedSubject = .wallpapers mappedSubject = .wallpapers
case .messageTags:
mappedSubject = .messageTags
} }
return PremiumDemoScreen(context: context, subject: mappedSubject, action: action) return PremiumDemoScreen(context: context, subject: mappedSubject, action: action)
} }