mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
2e666c5c2b
commit
21866185a8
@ -68,10 +68,10 @@ extension StickerPackReference {
|
||||
self = .emojiGenericAnimations
|
||||
case .inputStickerSetEmojiDefaultStatuses:
|
||||
self = .iconStatusEmoji
|
||||
case .inputStickerSetEmojiChannelDefaultStatuses:
|
||||
self = .iconChannelStatusEmoji
|
||||
case .inputStickerSetEmojiDefaultTopicIcons:
|
||||
self = .iconTopicEmoji
|
||||
case .inputStickerSetEmojiChannelDefaultStatuses:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -26,6 +26,8 @@ extension StickerPackReference {
|
||||
return .inputStickerSetEmojiGenericAnimations
|
||||
case .iconStatusEmoji:
|
||||
return .inputStickerSetEmojiDefaultStatuses
|
||||
case .iconChannelStatusEmoji:
|
||||
return .inputStickerSetEmojiChannelDefaultStatuses
|
||||
case .iconTopicEmoji:
|
||||
return .inputStickerSetEmojiDefaultTopicIcons
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
}))
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user