Various improvements

This commit is contained in:
Isaac 2023-12-21 23:36:38 +04:00
parent 2e666c5c2b
commit 21866185a8
13 changed files with 203 additions and 81 deletions

View File

@ -68,10 +68,10 @@ extension StickerPackReference {
self = .emojiGenericAnimations
case .inputStickerSetEmojiDefaultStatuses:
self = .iconStatusEmoji
case .inputStickerSetEmojiChannelDefaultStatuses:
self = .iconChannelStatusEmoji
case .inputStickerSetEmojiDefaultTopicIcons:
self = .iconTopicEmoji
case .inputStickerSetEmojiChannelDefaultStatuses:
return nil
}
}
}

View File

@ -98,6 +98,7 @@ func messageContentToUpload(accountPeerId: PeerId, network: Network, postbox: Po
} else if let media = media.first as? TelegramMediaWebpage, case let .Loaded(content) = media.content {
return .signal(postbox.transaction { transaction -> PendingMessageUploadedContentResult in
var flags: Int32 = 0
flags |= 1 << 2
if let attribute = attributes.first(where: { $0 is WebpagePreviewMessageAttribute }) as? WebpagePreviewMessageAttribute {
if let forceLargeMedia = attribute.forceLargeMedia {
if forceLargeMedia {
@ -241,6 +242,7 @@ func mediaContentToUpload(accountPeerId: PeerId, network: Network, postbox: Post
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(inputDice, text), reuploadInfo: nil, cacheReferenceKey: nil)))
} else if let media = media as? TelegramMediaWebpage, case let .Loaded(content) = media.content {
var flags: Int32 = 0
flags |= 1 << 2
if let attribute = attributes.first(where: { $0 is WebpagePreviewMessageAttribute }) as? WebpagePreviewMessageAttribute {
if let forceLargeMedia = attribute.forceLargeMedia {
if forceLargeMedia {

View File

@ -102,11 +102,14 @@ final class AccountTaskManager {
tasks.add(managedAllPremiumStickers(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedRecentStatusEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedFeaturedStatusEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedFeaturedChannelStatusEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedProfilePhotoEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedGroupPhotoEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedBackgroundIconEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(managedRecentReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconStatusEmoji, forceActualized: true).start())
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconChannelStatusEmoji, forceActualized: true).start())
tasks.add(managedDisabledChannelStatusIconEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconTopicEmoji, forceActualized: true).start())
tasks.add(managedPeerColorUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())

View File

@ -262,6 +262,36 @@ func managedFeaturedStatusEmoji(postbox: Postbox, network: Network) -> Signal<Vo
return (poll |> then(.complete() |> suspendAwareDelay(3.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
}
func managedFeaturedChannelStatusEmoji(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let poll = managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudFeaturedChannelStatusEmoji, extractItemId: { RecentMediaItemId($0).mediaId.id }, reverseHashOrder: false, forceFetch: false, fetch: { hash in
return network.request(Api.functions.account.getChannelDefaultEmojiStatuses(hash: hash))
|> retryRequest
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
switch result {
case .emojiStatusesNotModified:
return .single(nil)
case let .emojiStatuses(_, statuses):
let parsedStatuses = statuses.compactMap(PeerEmojiStatus.init(apiStatus:))
return _internal_resolveInlineStickers(postbox: postbox, network: network, fileIds: parsedStatuses.map(\.fileId))
|> map { files -> [OrderedItemListEntry] in
var items: [OrderedItemListEntry] = []
for status in parsedStatuses {
guard let file = files[status.fileId] else {
continue
}
if let entry = CodableEntry(RecentMediaItem(file)) {
items.append(OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry))
}
}
return items
}
}
}
})
return (poll |> then(.complete() |> suspendAwareDelay(3.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
}
func managedProfilePhotoEmoji(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let poll = managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudFeaturedProfilePhotoEmoji, extractItemId: { RecentMediaItemId($0).mediaId.id }, reverseHashOrder: false, forceFetch: false, fetch: { hash in
return network.request(Api.functions.account.getDefaultProfilePhotoEmojis(hash: hash))
@ -346,6 +376,34 @@ func managedBackgroundIconEmoji(postbox: Postbox, network: Network) -> Signal<Vo
return (poll |> then(.complete() |> suspendAwareDelay(3.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
}
func managedDisabledChannelStatusIconEmoji(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let poll = managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudDisabledChannelStatusEmoji, extractItemId: { RecentMediaItemId($0).mediaId.id }, reverseHashOrder: false, forceFetch: false, fetch: { hash in
return network.request(Api.functions.account.getChannelRestrictedStatusEmojis(hash: hash))
|> retryRequest
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
switch result {
case .emojiListNotModified:
return .single(nil)
case let .emojiList(_, documentIds):
return _internal_resolveInlineStickers(postbox: postbox, network: network, fileIds: documentIds)
|> map { files -> [OrderedItemListEntry] in
var items: [OrderedItemListEntry] = []
for fileId in documentIds {
guard let file = files[fileId] else {
continue
}
if let entry = CodableEntry(RecentMediaItem(file)) {
items.append(OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry))
}
}
return items
}
}
}
})
return (poll |> then(.complete() |> suspendAwareDelay(3.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
}
func managedRecentReactions(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
let poll = managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudRecentReactions, extractItemId: { rawId in
switch RecentReactionItemId(rawId).id {

View File

@ -61,7 +61,7 @@ public func addSavedSticker(postbox: Postbox, network: Network, file: TelegramMe
if !found {
fetchReference = packReference
}
case .animatedEmoji, .animatedEmojiAnimations, .dice, .premiumGifts, .emojiGenericAnimations, .iconStatusEmoji, .iconTopicEmoji:
case .animatedEmoji, .animatedEmojiAnimations, .dice, .premiumGifts, .emojiGenericAnimations, .iconStatusEmoji, .iconChannelStatusEmoji, .iconTopicEmoji:
break
}
if let fetchReference = fetchReference {

View File

@ -51,6 +51,7 @@ public struct Namespaces {
public static let CloudEmojiGenericAnimations: Int32 = 9
public static let CloudIconStatusEmoji: Int32 = 10
public static let CloudIconTopicEmoji: Int32 = 11
public static let CloudIconChannelStatusEmoji: Int32 = 12
}
public struct OrderedItemList {
@ -81,6 +82,8 @@ public struct Namespaces {
public static let CloudFeaturedGroupPhotoEmoji: Int32 = 24
public static let NewSessionReviews: Int32 = 25
public static let CloudFeaturedBackgroundIconEmoji: Int32 = 26
public static let CloudFeaturedChannelStatusEmoji: Int32 = 27
public static let CloudDisabledChannelStatusEmoji: Int32 = 28
}
public struct CachedItemCollection {

View File

@ -23,24 +23,27 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable, Codable {
case emojiGenericAnimations
case iconStatusEmoji
case iconTopicEmoji
case iconChannelStatusEmoji
public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("r", orElse: 0) {
case 0:
self = .id(id: decoder.decodeInt64ForKey("i", orElse: 0), accessHash: decoder.decodeInt64ForKey("h", orElse: 0))
case 1:
self = .name(decoder.decodeStringForKey("n", orElse: ""))
case 2:
self = .animatedEmoji
case 3:
self = .dice(decoder.decodeStringForKey("e", orElse: "🎲"))
case 4:
self = .animatedEmojiAnimations
case 5:
self = .premiumGifts
default:
self = .name("")
assertionFailure()
case 0:
self = .id(id: decoder.decodeInt64ForKey("i", orElse: 0), accessHash: decoder.decodeInt64ForKey("h", orElse: 0))
case 1:
self = .name(decoder.decodeStringForKey("n", orElse: ""))
case 2:
self = .animatedEmoji
case 3:
self = .dice(decoder.decodeStringForKey("e", orElse: "🎲"))
case 4:
self = .animatedEmojiAnimations
case 5:
self = .premiumGifts
case 6:
self = .iconChannelStatusEmoji
default:
self = .name("")
assertionFailure()
}
}
@ -61,6 +64,8 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable, Codable {
self = .animatedEmojiAnimations
case 5:
self = .premiumGifts
case 6:
self = .iconChannelStatusEmoji
default:
self = .name("")
assertionFailure()
@ -85,7 +90,7 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable, Codable {
encoder.encodeInt32(4, forKey: "r")
case .premiumGifts:
encoder.encodeInt32(5, forKey: "r")
case .emojiGenericAnimations, .iconStatusEmoji, .iconTopicEmoji:
case .emojiGenericAnimations, .iconStatusEmoji, .iconTopicEmoji, .iconChannelStatusEmoji:
preconditionFailure()
}
}
@ -110,7 +115,7 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable, Codable {
try container.encode(4 as Int32, forKey: "r")
case .premiumGifts:
try container.encode(5 as Int32, forKey: "r")
case .emojiGenericAnimations, .iconStatusEmoji, .iconTopicEmoji:
case .emojiGenericAnimations, .iconStatusEmoji, .iconTopicEmoji, .iconChannelStatusEmoji:
preconditionFailure()
}
}
@ -171,6 +176,12 @@ public enum StickerPackReference: PostboxCoding, Hashable, Equatable, Codable {
} else {
return false
}
case .iconChannelStatusEmoji:
if case .iconChannelStatusEmoji = rhs {
return true
} else {
return false
}
}
}
}

View File

@ -36,6 +36,9 @@ func cacheStickerPack(transaction: Transaction, info: StickerPackCollectionInfo,
case .iconStatusEmoji:
namespace = Namespaces.ItemCollection.CloudIconStatusEmoji
id = 0
case .iconChannelStatusEmoji:
namespace = Namespaces.ItemCollection.CloudIconChannelStatusEmoji
id = 0
case .iconTopicEmoji:
namespace = Namespaces.ItemCollection.CloudIconTopicEmoji
id = 0
@ -186,6 +189,20 @@ func _internal_cachedStickerPack(postbox: Postbox, network: Network, reference:
} else {
return (.fetching, true, nil)
}
case .iconChannelStatusEmoji:
let namespace = Namespaces.ItemCollection.CloudIconChannelStatusEmoji
let id: ItemCollectionId.Id = 0
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
previousHash = cached.hash
let current: CachedStickerPackResult = .result(info, cached.items, false)
if cached.hash != info.hash {
return (current, true, previousHash)
} else {
return (current, false, previousHash)
}
} else {
return (.fetching, true, nil)
}
case .iconTopicEmoji:
let namespace = Namespaces.ItemCollection.CloudIconTopicEmoji
let id: ItemCollectionId.Id = 0
@ -333,6 +350,18 @@ func cachedStickerPack(transaction: Transaction, reference: StickerPackReference
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
return (info, cached.items, false)
}
case .iconChannelStatusEmoji:
let namespace = Namespaces.ItemCollection.CloudIconChannelStatusEmoji
let id: ItemCollectionId.Id = 0
if let currentInfo = transaction.getItemCollectionInfo(collectionId: ItemCollectionId(namespace: namespace, id: id)) as? StickerPackCollectionInfo {
let items = transaction.getItemCollectionItems(collectionId: ItemCollectionId(namespace: namespace, id: id))
if !items.isEmpty {
return (currentInfo, items.compactMap { $0 as? StickerPackItem }, true)
}
}
if let cached = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedStickerPacks, key: CachedStickerPack.cacheKey(ItemCollectionId(namespace: namespace, id: id))))?.get(CachedStickerPack.self), let info = cached.info {
return (info, cached.items, false)
}
case .iconTopicEmoji:
let namespace = Namespaces.ItemCollection.CloudIconTopicEmoji
let id: ItemCollectionId.Id = 0

View File

@ -26,6 +26,8 @@ extension StickerPackReference {
return .inputStickerSetEmojiGenericAnimations
case .iconStatusEmoji:
return .inputStickerSetEmojiDefaultStatuses
case .iconChannelStatusEmoji:
return .inputStickerSetEmojiChannelDefaultStatuses
case .iconTopicEmoji:
return .inputStickerSetEmojiDefaultTopicIcons
}

View File

@ -52,6 +52,9 @@ func _internal_requestStickerSet(postbox: Postbox, network: Network, reference:
case .iconStatusEmoji:
collectionId = nil
input = .inputStickerSetEmojiDefaultStatuses
case .iconChannelStatusEmoji:
collectionId = nil
input = .inputStickerSetEmojiChannelDefaultStatuses
case .iconTopicEmoji:
collectionId = nil
input = .inputStickerSetEmojiDefaultTopicIcons

View File

@ -7251,9 +7251,10 @@ public final class EmojiPagerContentComponent: Component {
}
|> take(1)
} else if case .channelStatus = subject {
orderedItemListCollectionIds.append(Namespaces.OrderedItemList.CloudFeaturedStatusEmoji)
orderedItemListCollectionIds.append(Namespaces.OrderedItemList.CloudFeaturedChannelStatusEmoji)
orderedItemListCollectionIds.append(Namespaces.OrderedItemList.CloudDisabledChannelStatusEmoji)
iconStatusEmoji = context.engine.stickers.loadedStickerPack(reference: .iconStatusEmoji, forceActualized: false)
iconStatusEmoji = context.engine.stickers.loadedStickerPack(reference: .iconChannelStatusEmoji, forceActualized: false)
|> map { result -> [TelegramMediaFile] in
switch result {
case let .result(_, items, _):
@ -7298,7 +7299,7 @@ public final class EmojiPagerContentComponent: Component {
} else if case .status = subject {
searchCategories = context.engine.stickers.emojiSearchCategories(kind: .status)
} else if case .channelStatus = subject {
searchCategories = context.engine.stickers.emojiSearchCategories(kind: .status)
searchCategories = .single(nil)
} else if [.profilePhoto, .groupPhoto].contains(subject) {
searchCategories = context.engine.stickers.emojiSearchCategories(kind: .avatar)
} else {
@ -7436,6 +7437,8 @@ public final class EmojiPagerContentComponent: Component {
var recentEmoji: OrderedItemListView?
var featuredStatusEmoji: OrderedItemListView?
var featuredChannelStatusEmoji: OrderedItemListView?
var disabledChannelStatusEmoji: OrderedItemListView?
var recentStatusEmoji: OrderedItemListView?
var topReactions: OrderedItemListView?
var recentReactions: OrderedItemListView?
@ -7446,6 +7449,10 @@ public final class EmojiPagerContentComponent: Component {
recentEmoji = orderedView
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedStatusEmoji {
featuredStatusEmoji = orderedView
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedChannelStatusEmoji {
featuredChannelStatusEmoji = orderedView
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudDisabledChannelStatusEmoji {
disabledChannelStatusEmoji = orderedView
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudRecentStatusEmoji {
recentStatusEmoji = orderedView
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudRecentReactions {
@ -7700,7 +7707,17 @@ public final class EmojiPagerContentComponent: Component {
var existingIds = Set<MediaId>()
for file in iconStatusEmoji.prefix(7) {
if let disabledChannelStatusEmoji {
for item in disabledChannelStatusEmoji.items {
guard let item = item.contents.get(RecentMediaItem.self) else {
continue
}
let file = item.media
existingIds.insert(file.fileId)
}
}
for file in iconStatusEmoji {
if existingIds.contains(file.fileId) {
continue
}
@ -7740,58 +7757,8 @@ public final class EmojiPagerContentComponent: Component {
}
}
if let recentStatusEmoji = recentStatusEmoji {
for item in recentStatusEmoji.items {
guard let item = item.contents.get(RecentMediaItem.self) else {
continue
}
let file = item.media
if existingIds.contains(file.fileId) {
continue
}
existingIds.insert(file.fileId)
var tintMode: Item.TintMode = .none
if file.isCustomTemplateEmoji {
tintMode = .accent
}
for attribute in file.attributes {
if case let .CustomEmoji(_, _, _, packReference) = attribute {
switch packReference {
case let .id(id, _):
if id == 773947703670341676 || id == 2964141614563343 {
tintMode = .accent
}
default:
break
}
}
}
let resultItem: EmojiPagerContentComponent.Item
let animationData = EntityKeyboardAnimationData(file: file)
resultItem = EmojiPagerContentComponent.Item(
animationData: animationData,
content: .animation(animationData),
itemFile: file,
subgroupId: nil,
icon: .none,
tintMode: tintMode
)
if let groupIndex = itemGroupIndexById[groupId] {
if itemGroups[groupIndex].items.count >= (5 + 8) * 8 {
break
}
itemGroups[groupIndex].items.append(resultItem)
}
}
}
if let featuredStatusEmoji = featuredStatusEmoji {
for item in featuredStatusEmoji.items {
if let featuredChannelStatusEmoji {
for item in featuredChannelStatusEmoji.items {
guard let item = item.contents.get(RecentMediaItem.self) else {
continue
}
@ -7832,9 +7799,9 @@ public final class EmojiPagerContentComponent: Component {
)
if let groupIndex = itemGroupIndexById[groupId] {
if itemGroups[groupIndex].items.count >= (5 + 8) * 8 {
/*if itemGroups[groupIndex].items.count >= (5 + 8) * 8 {
break
}
}*/
itemGroups[groupIndex].items.append(resultItem)
}
@ -8296,6 +8263,13 @@ public final class EmojiPagerContentComponent: Component {
if !hasPremium {
maybeAppendUnicodeEmoji()
}
var itemCollectionMapping: [ItemCollectionId: StickerPackCollectionInfo] = [:]
for (id, info, _) in view.collectionInfos {
if let info = info as? StickerPackCollectionInfo {
itemCollectionMapping[id] = info
}
}
var skippedCollectionIds = Set<AnyHashable>()
if areCustomEmojiEnabled {
@ -8316,6 +8290,15 @@ public final class EmojiPagerContentComponent: Component {
continue
}
if case .channelStatus = subject {
guard let collection = itemCollectionMapping[entry.index.collectionId] else {
continue
}
if !collection.flags.contains(.isAvailableAsChannelStatus) {
continue
}
}
var isTemplate = false
var tintMode: Item.TintMode = .none
if item.file.isCustomTemplateEmoji {
@ -8402,6 +8385,12 @@ public final class EmojiPagerContentComponent: Component {
continue
}
if case .channelStatus = subject {
if !featuredEmojiPack.info.flags.contains(.isAvailableAsChannelStatus) {
continue
}
}
for item in featuredEmojiPack.topItems {
var tintMode: Item.TintMode = .none
if item.file.isCustomTemplateEmoji {

View File

@ -1673,13 +1673,28 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
let colorImage = generateSettingsMenuPeerColorsLabelIcon(colors: colors)
var boostIcon: UIImage?
var additionalBadge: String?
if let approximateBoostLevel = channel.approximateBoostLevel, approximateBoostLevel < 1 {
boostIcon = generateDisclosureActionBoostLevelBadgeImage(text: presentationData.strings.Channel_Info_BoostLevelPlusBadge("1").string)
} else {
additionalBadge = presentationData.strings.Settings_New
let labelText = NSAttributedString(string: presentationData.strings.Settings_New, font: Font.medium(11.0), textColor: presentationData.theme.list.itemCheckColors.foregroundColor)
let labelBounds = labelText.boundingRect(with: CGSize(width: 100.0, height: 100.0), options: [.usesLineFragmentOrigin], context: nil)
let labelSize = CGSize(width: ceil(labelBounds.width), height: ceil(labelBounds.height))
let badgeSize = CGSize(width: labelSize.width + 8.0, height: labelSize.height + 2.0 + 1.0)
boostIcon = generateImage(badgeSize, rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
let rect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height - UIScreenPixel * 2.0))
context.addPath(UIBezierPath(roundedRect: rect, cornerRadius: 5.0).cgPath)
context.setFillColor(presentationData.theme.list.itemCheckColors.fillColor.cgColor)
context.fillPath()
UIGraphicsPushContext(context)
labelText.draw(at: CGPoint(x: 4.0, y: 1.0 + UIScreenPixel))
UIGraphicsPopContext()
})
}
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), additionalBadgeLabel: additionalBadge, additionalBadgeIcon: boostIcon, text: presentationData.strings.Channel_Info_AppearanceItem, icon: UIImage(bundleImageName: "Chat/Info/NameColorIcon"), action: {
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), additionalBadgeIcon: boostIcon, text: presentationData.strings.Channel_Info_AppearanceItem, icon: UIImage(bundleImageName: "Chat/Info/NameColorIcon"), action: {
interaction.editingOpenNameColorSetup()
}))
}

View File

@ -333,6 +333,13 @@ final class ChannelAppearanceScreenComponent: Component {
}
if !resolvedState.changes.isEmpty {
if let premiumConfiguration = self.premiumConfiguration, let requiredBoostSubject = self.requiredBoostSubject{
let requiredLevel = requiredBoostSubject.requiredLevel(context: component.context, configuration: premiumConfiguration)
if let boostLevel = self.boostLevel, requiredLevel > boostLevel {
return true
}
}
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.Channel_Appearance_UnsavedChangesAlertTitle, text: presentationData.strings.Channel_Appearance_UnsavedChangesAlertText, actions: [
TextAlertAction(type: .genericAction, title: presentationData.strings.Channel_Appearance_UnsavedChangesAlertDiscard, action: { [weak self] in