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
e59a6a9238
commit
03a13c0305
@ -746,6 +746,7 @@ public enum PremiumIntroSource {
|
|||||||
case folders
|
case folders
|
||||||
case chatsPerFolder
|
case chatsPerFolder
|
||||||
case accounts
|
case accounts
|
||||||
|
case about
|
||||||
case deeplink(String?)
|
case deeplink(String?)
|
||||||
case profile(PeerId)
|
case profile(PeerId)
|
||||||
}
|
}
|
||||||
|
@ -460,13 +460,15 @@ private final class DemoSheetContent: CombinedComponent {
|
|||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let subject: PremiumDemoScreen.Subject
|
let subject: PremiumDemoScreen.Subject
|
||||||
let source: PremiumDemoScreen.Source
|
let source: PremiumDemoScreen.Source
|
||||||
|
let order: [PremiumPerk]
|
||||||
let action: () -> Void
|
let action: () -> Void
|
||||||
let dismiss: () -> Void
|
let dismiss: () -> Void
|
||||||
|
|
||||||
init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source, action: @escaping () -> Void, dismiss: @escaping () -> Void) {
|
init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source, order: [PremiumPerk]?, action: @escaping () -> Void, dismiss: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.subject = subject
|
self.subject = subject
|
||||||
self.source = source
|
self.source = source
|
||||||
|
self.order = order ?? [.moreUpload, .fasterDownload, .voiceToText, .noAds, .uniqueReactions, .premiumStickers, .advancedChatManagement, .profileBadge, .animatedUserpics]
|
||||||
self.action = action
|
self.action = action
|
||||||
self.dismiss = dismiss
|
self.dismiss = dismiss
|
||||||
}
|
}
|
||||||
@ -481,6 +483,9 @@ private final class DemoSheetContent: CombinedComponent {
|
|||||||
if lhs.source != rhs.source {
|
if lhs.source != rhs.source {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.order != rhs.order {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,164 +603,166 @@ private final class DemoSheetContent: CombinedComponent {
|
|||||||
if let reactions = state.reactions, let stickers = state.stickers {
|
if let reactions = state.reactions, let stickers = state.stickers {
|
||||||
let textColor = theme.actionSheet.primaryTextColor
|
let textColor = theme.actionSheet.primaryTextColor
|
||||||
|
|
||||||
var items: [DemoPagerComponent.Item] = [
|
var availableItems: [PremiumPerk: DemoPagerComponent.Item] = [:]
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
availableItems[.moreUpload] = DemoPagerComponent.Item(
|
||||||
id: PremiumDemoScreen.Subject.moreUpload,
|
AnyComponentWithIdentity(
|
||||||
component: AnyComponent(
|
id: PremiumDemoScreen.Subject.moreUpload,
|
||||||
PageComponent(
|
component: AnyComponent(
|
||||||
content: AnyComponent(PhoneDemoComponent(
|
PageComponent(
|
||||||
context: component.context,
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
position: .bottom,
|
context: component.context,
|
||||||
videoName: "4gb"
|
position: .bottom,
|
||||||
)),
|
videoName: "4gb"
|
||||||
title: strings.Premium_UploadSize,
|
)),
|
||||||
text: strings.Premium_UploadSizeInfo,
|
title: strings.Premium_UploadSize,
|
||||||
textColor: textColor
|
text: strings.Premium_UploadSizeInfo,
|
||||||
)
|
textColor: textColor
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.fasterDownload,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(PhoneDemoComponent(
|
|
||||||
context: component.context,
|
|
||||||
position: .top,
|
|
||||||
videoName: "fastdownload"
|
|
||||||
)),
|
|
||||||
title: strings.Premium_FasterSpeed,
|
|
||||||
text: strings.Premium_FasterSpeedInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.voiceToText,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(PhoneDemoComponent(
|
|
||||||
context: component.context,
|
|
||||||
position: .top,
|
|
||||||
videoName: "voice"
|
|
||||||
)),
|
|
||||||
title: strings.Premium_VoiceToText,
|
|
||||||
text: strings.Premium_VoiceToTextInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.noAds,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(PhoneDemoComponent(
|
|
||||||
context: component.context,
|
|
||||||
position: .bottom,
|
|
||||||
videoName: "noads"
|
|
||||||
)),
|
|
||||||
title: strings.Premium_NoAds,
|
|
||||||
text: strings.Premium_NoAdsInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.uniqueReactions,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(
|
|
||||||
ReactionsCarouselComponent(
|
|
||||||
context: component.context,
|
|
||||||
theme: environment.theme,
|
|
||||||
reactions: reactions
|
|
||||||
)
|
|
||||||
),
|
|
||||||
title: isStandalone ? strings.Premium_ReactionsStandalone : strings.Premium_Reactions,
|
|
||||||
text: isStandalone ? strings.Premium_ReactionsStandaloneInfo : strings.Premium_ReactionsInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.premiumStickers,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(
|
|
||||||
StickersCarouselComponent(
|
|
||||||
context: component.context,
|
|
||||||
stickers: stickers
|
|
||||||
)
|
|
||||||
),
|
|
||||||
title: strings.Premium_Stickers,
|
|
||||||
text: strings.Premium_StickersInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.advancedChatManagement,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(PhoneDemoComponent(
|
|
||||||
context: component.context,
|
|
||||||
position: .top,
|
|
||||||
videoName: "fastdownload"
|
|
||||||
)),
|
|
||||||
title: strings.Premium_ChatManagement,
|
|
||||||
text: strings.Premium_ChatManagementInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.profileBadge,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(PhoneDemoComponent(
|
|
||||||
context: component.context,
|
|
||||||
position: .top,
|
|
||||||
videoName: "badge"
|
|
||||||
)),
|
|
||||||
title: strings.Premium_Badge,
|
|
||||||
text: strings.Premium_BadgeInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
DemoPagerComponent.Item(
|
|
||||||
AnyComponentWithIdentity(
|
|
||||||
id: PremiumDemoScreen.Subject.animatedUserpics,
|
|
||||||
component: AnyComponent(
|
|
||||||
PageComponent(
|
|
||||||
content: AnyComponent(PhoneDemoComponent(
|
|
||||||
context: component.context,
|
|
||||||
position: .top,
|
|
||||||
videoName: "badge"
|
|
||||||
)),
|
|
||||||
title: strings.Premium_Avatar,
|
|
||||||
text: strings.Premium_AvatarInfo,
|
|
||||||
textColor: textColor
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
)
|
||||||
|
availableItems[.fasterDownload] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.fasterDownload,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
|
context: component.context,
|
||||||
|
position: .top,
|
||||||
|
videoName: "fastdownload"
|
||||||
|
)),
|
||||||
|
title: strings.Premium_FasterSpeed,
|
||||||
|
text: strings.Premium_FasterSpeedInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
availableItems[.voiceToText] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.voiceToText,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
|
context: component.context,
|
||||||
|
position: .top,
|
||||||
|
videoName: "voice"
|
||||||
|
)),
|
||||||
|
title: strings.Premium_VoiceToText,
|
||||||
|
text: strings.Premium_VoiceToTextInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
availableItems[.noAds] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.noAds,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
|
context: component.context,
|
||||||
|
position: .bottom,
|
||||||
|
videoName: "noads"
|
||||||
|
)),
|
||||||
|
title: strings.Premium_NoAds,
|
||||||
|
text: strings.Premium_NoAdsInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
availableItems[.uniqueReactions] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.uniqueReactions,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(
|
||||||
|
ReactionsCarouselComponent(
|
||||||
|
context: component.context,
|
||||||
|
theme: environment.theme,
|
||||||
|
reactions: reactions
|
||||||
|
)
|
||||||
|
),
|
||||||
|
title: isStandalone ? strings.Premium_ReactionsStandalone : strings.Premium_Reactions,
|
||||||
|
text: isStandalone ? strings.Premium_ReactionsStandaloneInfo : strings.Premium_ReactionsInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
availableItems[.premiumStickers] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.premiumStickers,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(
|
||||||
|
StickersCarouselComponent(
|
||||||
|
context: component.context,
|
||||||
|
stickers: stickers
|
||||||
|
)
|
||||||
|
),
|
||||||
|
title: strings.Premium_Stickers,
|
||||||
|
text: strings.Premium_StickersInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
availableItems[.advancedChatManagement] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.advancedChatManagement,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
|
context: component.context,
|
||||||
|
position: .top,
|
||||||
|
videoName: "fastdownload"
|
||||||
|
)),
|
||||||
|
title: strings.Premium_ChatManagement,
|
||||||
|
text: strings.Premium_ChatManagementInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
availableItems[.profileBadge] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.profileBadge,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
|
context: component.context,
|
||||||
|
position: .top,
|
||||||
|
videoName: "badge"
|
||||||
|
)),
|
||||||
|
title: strings.Premium_Badge,
|
||||||
|
text: strings.Premium_BadgeInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
availableItems[.animatedUserpics] = DemoPagerComponent.Item(
|
||||||
|
AnyComponentWithIdentity(
|
||||||
|
id: PremiumDemoScreen.Subject.animatedUserpics,
|
||||||
|
component: AnyComponent(
|
||||||
|
PageComponent(
|
||||||
|
content: AnyComponent(PhoneDemoComponent(
|
||||||
|
context: component.context,
|
||||||
|
position: .top,
|
||||||
|
videoName: "badge"
|
||||||
|
)),
|
||||||
|
title: strings.Premium_Avatar,
|
||||||
|
text: strings.Premium_AvatarInfo,
|
||||||
|
textColor: textColor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
var items: [DemoPagerComponent.Item] = component.order.compactMap { availableItems[$0] }
|
||||||
let index: Int
|
let index: Int
|
||||||
switch component.source {
|
switch component.source {
|
||||||
case .intro:
|
case .intro:
|
||||||
@ -881,12 +888,14 @@ private final class DemoSheetComponent: CombinedComponent {
|
|||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let subject: PremiumDemoScreen.Subject
|
let subject: PremiumDemoScreen.Subject
|
||||||
let source: PremiumDemoScreen.Source
|
let source: PremiumDemoScreen.Source
|
||||||
|
let order: [PremiumPerk]?
|
||||||
let action: () -> Void
|
let action: () -> Void
|
||||||
|
|
||||||
init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source, action: @escaping () -> Void) {
|
init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source, order: [PremiumPerk]?, action: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.subject = subject
|
self.subject = subject
|
||||||
self.source = source
|
self.source = source
|
||||||
|
self.order = order
|
||||||
self.action = action
|
self.action = action
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -900,6 +909,9 @@ private final class DemoSheetComponent: CombinedComponent {
|
|||||||
if lhs.source != rhs.source {
|
if lhs.source != rhs.source {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.order != rhs.order {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -919,6 +931,7 @@ private final class DemoSheetComponent: CombinedComponent {
|
|||||||
context: context.component.context,
|
context: context.component.context,
|
||||||
subject: context.component.subject,
|
subject: context.component.subject,
|
||||||
source: context.component.source,
|
source: context.component.source,
|
||||||
|
order: context.component.order,
|
||||||
action: context.component.action,
|
action: context.component.action,
|
||||||
dismiss: {
|
dismiss: {
|
||||||
animateOut.invoke(Action { _ in
|
animateOut.invoke(Action { _ in
|
||||||
@ -989,8 +1002,12 @@ public class PremiumDemoScreen: ViewControllerComponentContainer {
|
|||||||
return self._ready
|
return self._ready
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source = .other, action: @escaping () -> Void) {
|
public convenience init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source = .other, action: @escaping () -> Void) {
|
||||||
super.init(context: context, component: DemoSheetComponent(context: context, subject: subject, source: source, action: action), navigationBarAppearance: .none)
|
self.init(context: context, subject: subject, source: source, order: nil, action: action)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(context: AccountContext, subject: PremiumDemoScreen.Subject, source: PremiumDemoScreen.Source = .other, order: [PremiumPerk]?, action: @escaping () -> Void) {
|
||||||
|
super.init(context: context, component: DemoSheetComponent(context: context, subject: subject, source: source, order: order, action: action), navigationBarAppearance: .none)
|
||||||
|
|
||||||
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ public enum PremiumSource: Equatable {
|
|||||||
case folders
|
case folders
|
||||||
case chatsPerFolder
|
case chatsPerFolder
|
||||||
case accounts
|
case accounts
|
||||||
|
case about
|
||||||
case deeplink(String?)
|
case deeplink(String?)
|
||||||
case profile(PeerId)
|
case profile(PeerId)
|
||||||
|
|
||||||
@ -65,6 +66,8 @@ public enum PremiumSource: Equatable {
|
|||||||
return "double_limits__dialog_filters_chats"
|
return "double_limits__dialog_filters_chats"
|
||||||
case .accounts:
|
case .accounts:
|
||||||
return "double_limits__accounts"
|
return "double_limits__accounts"
|
||||||
|
case .about:
|
||||||
|
return "double_limits__about"
|
||||||
case let .profile(id):
|
case let .profile(id):
|
||||||
return "profile__\(id.id._internalGetInt64Value())"
|
return "profile__\(id.id._internalGetInt64Value())"
|
||||||
case let .deeplink(reference):
|
case let .deeplink(reference):
|
||||||
@ -77,7 +80,7 @@ public enum PremiumSource: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum PremiumPerk: CaseIterable {
|
enum PremiumPerk: CaseIterable {
|
||||||
case doubleLimits
|
case doubleLimits
|
||||||
case moreUpload
|
case moreUpload
|
||||||
case fasterDownload
|
case fasterDownload
|
||||||
@ -990,6 +993,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
context: accountContext,
|
context: accountContext,
|
||||||
subject: demoSubject,
|
subject: demoSubject,
|
||||||
source: .intro(state?.price),
|
source: .intro(state?.price),
|
||||||
|
order: state?.configuration.perks,
|
||||||
action: {
|
action: {
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
if !isPremium {
|
if !isPremium {
|
||||||
|
@ -1150,6 +1150,7 @@ public class Account {
|
|||||||
self.managedOperationsDisposable.add(managedConfigurationUpdates(accountManager: accountManager, postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedConfigurationUpdates(accountManager: accountManager, postbox: self.postbox, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedVoipConfigurationUpdates(postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedVoipConfigurationUpdates(postbox: self.postbox, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedAppConfigurationUpdates(postbox: self.postbox, network: self.network).start())
|
self.managedOperationsDisposable.add(managedAppConfigurationUpdates(postbox: self.postbox, network: self.network).start())
|
||||||
|
self.managedOperationsDisposable.add(managedPremiumPromoConfigurationUpdates(postbox: self.postbox, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedAutodownloadSettingsUpdates(accountManager: accountManager, network: self.network).start())
|
self.managedOperationsDisposable.add(managedAutodownloadSettingsUpdates(accountManager: accountManager, network: self.network).start())
|
||||||
self.managedOperationsDisposable.add(managedTermsOfServiceUpdates(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
self.managedOperationsDisposable.add(managedTermsOfServiceUpdates(postbox: self.postbox, network: self.network, stateManager: self.stateManager).start())
|
||||||
self.managedOperationsDisposable.add(managedAppUpdateInfo(network: self.network, stateManager: self.stateManager).start())
|
self.managedOperationsDisposable.add(managedAppUpdateInfo(network: self.network, stateManager: self.stateManager).start())
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
import Foundation
|
||||||
|
import Postbox
|
||||||
|
import SwiftSignalKit
|
||||||
|
import TelegramApi
|
||||||
|
import MtProtoKit
|
||||||
|
|
||||||
|
|
||||||
|
func updatePremiumPromoConfigurationOnce(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
|
return network.request(Api.functions.help.getPremiumPromo())
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { _ -> Signal<Api.help.PremiumPromo?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
|> mapToSignal { result -> Signal<Void, NoError> in
|
||||||
|
guard let result = result else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
return postbox.transaction { transaction -> Void in
|
||||||
|
updatePremiumPromoConfiguration(transaction: transaction, { configuration -> PremiumPromoConfiguration in
|
||||||
|
return PremiumPromoConfiguration(apiPremiumPromo: result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func managedPremiumPromoConfigurationUpdates(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||||
|
let poll = Signal<Void, NoError> { subscriber in
|
||||||
|
return updatePremiumPromoConfigurationOnce(postbox: postbox, network: network).start(completed: {
|
||||||
|
subscriber.putCompletion()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return (poll |> then(.complete() |> suspendAwareDelay(10.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||||
|
}
|
||||||
|
|
||||||
|
private func currentPremiumPromoConfiguration(transaction: Transaction) -> PremiumPromoConfiguration {
|
||||||
|
if let entry = transaction.getPreferencesEntry(key: PreferencesKeys.premiumPromo)?.get(PremiumPromoConfiguration.self) {
|
||||||
|
return entry
|
||||||
|
} else {
|
||||||
|
return PremiumPromoConfiguration.defaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updatePremiumPromoConfiguration(transaction: Transaction, _ f: (PremiumPromoConfiguration) -> PremiumPromoConfiguration) {
|
||||||
|
let current = currentPremiumPromoConfiguration(transaction: transaction)
|
||||||
|
let updated = f(current)
|
||||||
|
if updated != current {
|
||||||
|
transaction.setPreferencesEntry(key: PreferencesKeys.premiumPromo, value: PreferencesEntry(updated))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension PremiumPromoConfiguration {
|
||||||
|
init(apiPremiumPromo: Api.help.PremiumPromo) {
|
||||||
|
switch apiPremiumPromo {
|
||||||
|
case let .premiumPromo(statusText, statusEntities, videoSections, videoFiles):
|
||||||
|
self.status = statusText
|
||||||
|
self.statusEntities = messageTextEntitiesFromApiEntities(statusEntities)
|
||||||
|
|
||||||
|
var videos: [String: TelegramMediaFile] = [:]
|
||||||
|
for (key, document) in zip(videoSections, videoFiles) {
|
||||||
|
if let file = telegramMediaFileFromApiDocument(document) {
|
||||||
|
videos[key] = file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.videos = videos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -232,6 +232,7 @@ private enum PreferencesKeyValues: Int32 {
|
|||||||
case chatListFiltersFeaturedState = 22
|
case chatListFiltersFeaturedState = 22
|
||||||
case secretChatSettings = 23
|
case secretChatSettings = 23
|
||||||
case reactionSettings = 24
|
case reactionSettings = 24
|
||||||
|
case premiumPromo = 25
|
||||||
}
|
}
|
||||||
|
|
||||||
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
|
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
|
||||||
@ -360,6 +361,12 @@ public struct PreferencesKeys {
|
|||||||
key.setInt32(0, value: PreferencesKeyValues.reactionSettings.rawValue)
|
key.setInt32(0, value: PreferencesKeyValues.reactionSettings.rawValue)
|
||||||
return key
|
return key
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
public static let premiumPromo: ValueBoxKey = {
|
||||||
|
let key = ValueBoxKey(length: 4)
|
||||||
|
key.setInt32(0, value: PreferencesKeyValues.premiumPromo.rawValue)
|
||||||
|
return key
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum SharedDataKeyValues: Int32 {
|
private enum SharedDataKeyValues: Int32 {
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
import Foundation
|
||||||
|
import Postbox
|
||||||
|
|
||||||
|
public struct PremiumPromoConfiguration: Codable, Equatable {
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case status
|
||||||
|
case statusEntities
|
||||||
|
case videos
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct DictionaryPair: Codable {
|
||||||
|
var key: String
|
||||||
|
var value: TelegramMediaFile
|
||||||
|
|
||||||
|
init(_ key: String, value: TelegramMediaFile) {
|
||||||
|
self.key = key
|
||||||
|
self.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
|
self.key = try container.decode(String.self, forKey: "k")
|
||||||
|
self.value = try container.decode(TelegramMediaFile.self, forKey: "v")
|
||||||
|
}
|
||||||
|
|
||||||
|
func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: StringCodingKey.self)
|
||||||
|
|
||||||
|
try container.encode(self.key, forKey: "k")
|
||||||
|
try container.encode(self.value, forKey: "v")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var status: String
|
||||||
|
public var statusEntities: [MessageTextEntity]
|
||||||
|
public var videos: [String: TelegramMediaFile]
|
||||||
|
|
||||||
|
public static var defaultValue: PremiumPromoConfiguration {
|
||||||
|
return PremiumPromoConfiguration(status: "", statusEntities: [], videos: [:])
|
||||||
|
}
|
||||||
|
|
||||||
|
init(status: String, statusEntities: [MessageTextEntity], videos: [String: TelegramMediaFile]) {
|
||||||
|
self.status = status
|
||||||
|
self.statusEntities = statusEntities
|
||||||
|
self.videos = videos
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
|
self.status = try container.decode(String.self, forKey: .status)
|
||||||
|
self.statusEntities = try container.decode([MessageTextEntity].self, forKey: .statusEntities)
|
||||||
|
|
||||||
|
var videos: [String: TelegramMediaFile] = [:]
|
||||||
|
let pairs = try container.decode([DictionaryPair].self, forKey: .videos)
|
||||||
|
for pair in pairs {
|
||||||
|
videos[pair.key] = pair.value
|
||||||
|
}
|
||||||
|
self.videos = videos
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
|
try container.encode(self.status, forKey: .status)
|
||||||
|
try container.encode(self.statusEntities, forKey: .statusEntities)
|
||||||
|
|
||||||
|
var pairs: [DictionaryPair] = []
|
||||||
|
for (key, file) in self.videos {
|
||||||
|
pairs.append(DictionaryPair(key, value: file))
|
||||||
|
}
|
||||||
|
try container.encode(pairs, forKey: .videos)
|
||||||
|
}
|
||||||
|
}
|
@ -354,5 +354,26 @@ public extension TelegramEngine.EngineData.Item {
|
|||||||
return localizationListState
|
return localizationListState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct PremiumPromo: TelegramEngineDataItem, PostboxViewDataItem {
|
||||||
|
public typealias Result = PremiumPromoConfiguration
|
||||||
|
|
||||||
|
public init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
var key: PostboxViewKey {
|
||||||
|
return .preferences(keys: Set([PreferencesKeys.premiumPromo]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func extract(view: PostboxView) -> Result {
|
||||||
|
guard let view = view as? PreferencesView else {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
guard let premiumPromoConfiguration = view.values[PreferencesKeys.premiumPromo]?.get(PremiumPromoConfiguration.self) else {
|
||||||
|
return PremiumPromoConfiguration.defaultValue
|
||||||
|
}
|
||||||
|
return premiumPromoConfiguration
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1491,6 +1491,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
mappedSource = .chatsPerFolder
|
mappedSource = .chatsPerFolder
|
||||||
case .accounts:
|
case .accounts:
|
||||||
mappedSource = .accounts
|
mappedSource = .accounts
|
||||||
|
case .about:
|
||||||
|
mappedSource = .about
|
||||||
case let .deeplink(reference):
|
case let .deeplink(reference):
|
||||||
mappedSource = .deeplink(reference)
|
mappedSource = .deeplink(reference)
|
||||||
case let .profile(peerId):
|
case let .profile(peerId):
|
||||||
|
@ -526,8 +526,8 @@ class StickerPaneTrendingListGridItemNode: GridItemNode {
|
|||||||
self.dismissButtonNode.setImage(PresentationResourcesChat.chatInputMediaPanelGridDismissImage(item.theme), for: [])
|
self.dismissButtonNode.setImage(PresentationResourcesChat.chatInputMediaPanelGridDismissImage(item.theme), for: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
let leftInset: CGFloat = 12.0
|
let leftInset: CGFloat = 9.0
|
||||||
let rightInset: CGFloat = 16.0
|
let rightInset: CGFloat = 18.0 + UIScreenPixel
|
||||||
let topOffset: CGFloat = 9.0
|
let topOffset: CGFloat = 9.0
|
||||||
|
|
||||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.strings.StickerPacksSettings_FeaturedPacks.uppercased(), font: titleFont, textColor: item.theme.chat.inputMediaPanel.stickersSectionTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.leftInset - params.rightInset - leftInset - rightInset - 20.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.strings.StickerPacksSettings_FeaturedPacks.uppercased(), font: titleFont, textColor: item.theme.chat.inputMediaPanel.stickersSectionTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.leftInset - params.rightInset - leftInset - rightInset - 20.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user