Refactoring

This commit is contained in:
Ali 2021-09-20 01:12:06 +03:00
parent ce36439bd2
commit f23d5ef97a
43 changed files with 484 additions and 349 deletions

View file

@ -1,14 +1,10 @@
import Foundation
public protocol OrderedItemListEntryContents: PostboxCoding {
}
public struct OrderedItemListEntry {
public let id: MemoryBuffer
public let contents: OrderedItemListEntryContents
public let contents: CodableEntry
public init(id: MemoryBuffer, contents: OrderedItemListEntryContents) {
public init(id: MemoryBuffer, contents: CodableEntry) {
self.id = id
self.contents = contents
}

View file

@ -12,9 +12,9 @@ final class OrderedItemListIndexTable: Table {
return key
}
func get(collectionId: Int32, id: MemoryBuffer) -> PostboxCoding? {
if let value = self.valueBox.get(self.table, key: self.key(collectionId: collectionId, id: id)), let content = PostboxDecoder(buffer: value).decodeRootObject() {
return content
func get(collectionId: Int32, id: MemoryBuffer) -> CodableEntry? {
if let value = self.valueBox.get(self.table, key: self.key(collectionId: collectionId, id: id)) {
return CodableEntry(data: value.makeData())
} else {
return nil
}
@ -24,12 +24,8 @@ final class OrderedItemListIndexTable: Table {
self.valueBox.remove(self.table, key: self.key(collectionId: collectionId, id: id), secure: false)
}
func set(collectionId: Int32, id: MemoryBuffer, content: PostboxCoding) {
let encoder = PostboxEncoder()
encoder.encodeRootObject(content)
withExtendedLifetime(encoder, {
self.valueBox.set(self.table, key: self.key(collectionId: collectionId, id: id), value: encoder.readBufferNoCopy())
})
func set(collectionId: Int32, id: MemoryBuffer, content: CodableEntry) {
self.valueBox.set(self.table, key: self.key(collectionId: collectionId, id: id), value: ReadBuffer(data: content.data))
}
func getAllItemIds(collectionId: Int32) -> [MemoryBuffer] {

View file

@ -4,7 +4,7 @@ enum OrderedItemListOperation {
case replace([OrderedItemListEntry])
case addOrMoveToFirstPosition(OrderedItemListEntry, Int?)
case remove(MemoryBuffer)
case update(MemoryBuffer, OrderedItemListEntryContents)
case update(MemoryBuffer, CodableEntry)
}
private enum OrderedItemListKeyNamespace: UInt8 {
@ -97,7 +97,7 @@ final class OrderedItemListTable: Table {
}, limit: 0)
var items: [OrderedItemListEntry] = []
for id in currentIds {
if let contents = self.indexTable.get(collectionId: collectionId, id: id) as? OrderedItemListEntryContents {
if let contents = self.indexTable.get(collectionId: collectionId, id: id) {
items.append(OrderedItemListEntry(id: id, contents: contents))
} else {
assertionFailure()
@ -107,15 +107,15 @@ final class OrderedItemListTable: Table {
}
func getItem(collectionId: Int32, itemId: MemoryBuffer) -> OrderedItemListEntry? {
if let contents = self.indexTable.get(collectionId: collectionId, id: itemId) as? OrderedItemListEntryContents {
if let contents = self.indexTable.get(collectionId: collectionId, id: itemId) {
return OrderedItemListEntry(id: itemId, contents: contents)
} else {
return nil
}
}
func updateItem(collectionId: Int32, itemId: MemoryBuffer, item: OrderedItemListEntryContents, operations: inout [Int32: [OrderedItemListOperation]]) {
if let _ = self.indexTable.get(collectionId: collectionId, id: itemId) as? OrderedItemListEntryContents {
func updateItem(collectionId: Int32, itemId: MemoryBuffer, item: CodableEntry, operations: inout [Int32: [OrderedItemListOperation]]) {
if let _ = self.indexTable.get(collectionId: collectionId, id: itemId) {
self.indexTable.set(collectionId: collectionId, id: itemId, content: item)
if operations[collectionId] == nil {
operations[collectionId] = []

View file

@ -2,6 +2,10 @@ import Foundation
import SwiftSignalKit
public protocol PostboxTypes {
associatedtype Media
}
public protocol PeerChatState: PostboxCoding {
func equals(_ other: PeerChatState) -> Bool
}
@ -649,7 +653,7 @@ public final class Transaction {
return self.postbox?.getOrderedItemListItem(collectionId: collectionId, itemId: itemId)
}
public func updateOrderedItemListItem(collectionId: Int32, itemId: MemoryBuffer, item: OrderedItemListEntryContents) {
public func updateOrderedItemListItem(collectionId: Int32, itemId: MemoryBuffer, item: CodableEntry) {
assert(!self.disposed)
self.postbox?.updateOrderedItemListItem(collectionId: collectionId, itemId: itemId, item: item)
}
@ -3400,7 +3404,7 @@ public final class Postbox {
return self.orderedItemListTable.getItem(collectionId: collectionId, itemId: itemId)
}
fileprivate func updateOrderedItemListItem(collectionId: Int32, itemId: MemoryBuffer, item: OrderedItemListEntryContents) {
fileprivate func updateOrderedItemListItem(collectionId: Int32, itemId: MemoryBuffer, item: CodableEntry) {
self.orderedItemListTable.updateItem(collectionId: collectionId, itemId: itemId, item: item, operations: &self.currentOrderedItemListOperations)
}

View file

@ -26,21 +26,23 @@ private struct SettingsSearchRecentQueryItemId {
}
}
public final class RecentSettingsSearchQueryItem: OrderedItemListEntryContents {
public final class RecentSettingsSearchQueryItem: Codable {
public init() {
}
public init(decoder: PostboxDecoder) {
public init(from decoder: Decoder) throws {
}
public func encode(_ encoder: PostboxEncoder) {
public func encode(to encoder: Encoder) throws {
}
}
func addRecentSettingsSearchItem(postbox: Postbox, item: SettingsSearchableItemId) {
let _ = (postbox.transaction { transaction in
let itemId = SettingsSearchRecentQueryItemId(item.index)
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: ApplicationSpecificOrderedItemListCollectionId.settingsSearchRecentItems, item: OrderedItemListEntry(id: itemId.rawValue, contents: RecentSettingsSearchQueryItem()), removeTailIfCountExceeds: 100)
if let entry = CodableEntry(RecentSettingsSearchQueryItem()) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: ApplicationSpecificOrderedItemListCollectionId.settingsSearchRecentItems, item: OrderedItemListEntry(id: itemId.rawValue, contents: entry), removeTailIfCountExceeds: 100)
}
}).start()
}

View file

@ -23,21 +23,23 @@ private struct WallpaperSearchRecentQueryItemId {
}
}
public final class RecentWallpaperSearchQueryItem: OrderedItemListEntryContents {
public final class RecentWallpaperSearchQueryItem: Codable {
public init() {
}
public init(decoder: PostboxDecoder) {
public init(from decoder: Decoder) throws {
}
public func encode(_ encoder: PostboxEncoder) {
public func encode(to encoder: Encoder) throws {
}
}
func addRecentWallpaperSearchQuery(postbox: Postbox, string: String) -> Signal<Void, NoError> {
return postbox.transaction { transaction in
if let itemId = WallpaperSearchRecentQueryItemId(string) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: ApplicationSpecificOrderedItemListCollectionId.wallpaperSearchRecentQueries, item: OrderedItemListEntry(id: itemId.rawValue, contents: RecentWallpaperSearchQueryItem()), removeTailIfCountExceeds: 100)
if let entry = CodableEntry(RecentWallpaperSearchQueryItem()) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: ApplicationSpecificOrderedItemListCollectionId.wallpaperSearchRecentQueries, item: OrderedItemListEntry(id: itemId.rawValue, contents: entry), removeTailIfCountExceeds: 100)
}
}
}
}

View file

@ -133,9 +133,6 @@ private var declaredEncodables: Void = {
declareEncodable(CloudChatRemoveChatOperation.self, f: { CloudChatRemoveChatOperation(decoder: $0) })
declareEncodable(SynchronizePinnedChatsOperation.self, f: { SynchronizePinnedChatsOperation(decoder: $0) })
declareEncodable(SynchronizeConsumeMessageContentsOperation.self, f: { SynchronizeConsumeMessageContentsOperation(decoder: $0) })
declareEncodable(RecentMediaItem.self, f: { RecentMediaItem(decoder: $0) })
declareEncodable(RecentPeerItem.self, f: { RecentPeerItem(decoder: $0) })
declareEncodable(RecentHashtagItem.self, f: { RecentHashtagItem(decoder: $0) })
declareEncodable(CloudChatClearHistoryOperation.self, f: { CloudChatClearHistoryOperation(decoder: $0) })
declareEncodable(OutgoingContentInfoMessageAttribute.self, f: { OutgoingContentInfoMessageAttribute(decoder: $0) })
declareEncodable(ConsumableContentMessageAttribute.self, f: { ConsumableContentMessageAttribute(decoder: $0) })
@ -143,9 +140,7 @@ private var declaredEncodables: Void = {
declareEncodable(TelegramMediaInvoice.self, f: { TelegramMediaInvoice(decoder: $0) })
declareEncodable(TelegramMediaWebFile.self, f: { TelegramMediaWebFile(decoder: $0) })
declareEncodable(SynchronizeInstalledStickerPacksOperation.self, f: { SynchronizeInstalledStickerPacksOperation(decoder: $0) })
declareEncodable(FeaturedStickerPackItem.self, f: { FeaturedStickerPackItem(decoder: $0) })
declareEncodable(SynchronizeMarkFeaturedStickerPacksAsSeenOperation.self, f: { SynchronizeMarkFeaturedStickerPacksAsSeenOperation(decoder: $0) })
declareEncodable(ArchivedStickerPacksInfo.self, f: { ArchivedStickerPacksInfo(decoder: $0) })
declareEncodable(SynchronizeChatInputStateOperation.self, f: { SynchronizeChatInputStateOperation(decoder: $0) })
declareEncodable(SynchronizeSavedGifsOperation.self, f: { SynchronizeSavedGifsOperation(decoder: $0) })
declareEncodable(SynchronizeSavedStickersOperation.self, f: { SynchronizeSavedStickersOperation(decoder: $0) })
@ -156,14 +151,11 @@ private var declaredEncodables: Void = {
declareEncodable(CachedSecretChatData.self, f: { CachedSecretChatData(decoder: $0) })
declareEncodable(AuthorSignatureMessageAttribute.self, f: { AuthorSignatureMessageAttribute(decoder: $0) })
declareEncodable(TelegramMediaExpiredContent.self, f: { TelegramMediaExpiredContent(decoder: $0) })
declareEncodable(SavedStickerItem.self, f: { SavedStickerItem(decoder: $0) })
declareEncodable(ConsumablePersonalMentionMessageAttribute.self, f: { ConsumablePersonalMentionMessageAttribute(decoder: $0) })
declareEncodable(ConsumePersonalMessageAction.self, f: { ConsumePersonalMessageAction(decoder: $0) })
declareEncodable(SynchronizeGroupedPeersOperation.self, f: { SynchronizeGroupedPeersOperation(decoder: $0) })
declareEncodable(TelegramDeviceContactImportedData.self, f: { TelegramDeviceContactImportedData(decoder: $0) })
declareEncodable(SecureFileMediaResource.self, f: { SecureFileMediaResource(decoder: $0) })
declareEncodable(TelegramWallpaper.self, f: { TelegramWallpaper(decoder: $0) })
declareEncodable(TelegramTheme.self, f: { TelegramTheme(decoder: $0) })
declareEncodable(SynchronizeMarkAllUnseenPersonalMessagesOperation.self, f: { SynchronizeMarkAllUnseenPersonalMessagesOperation(decoder: $0) })
declareEncodable(SynchronizeAppLogEventsOperation.self, f: { SynchronizeAppLogEventsOperation(decoder: $0) })
declareEncodable(TelegramMediaPoll.self, f: { TelegramMediaPoll(decoder: $0) })

View file

@ -350,7 +350,8 @@ final class MediaReferenceRevalidationContext {
return self.genericItem(key: .savedGifs, background: background, request: { next, error in
let loadRecentGifs: Signal<[TelegramMediaFile], NoError> = postbox.transaction { transaction -> [TelegramMediaFile] in
return transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentGifs).compactMap({ item -> TelegramMediaFile? in
if let contents = item.contents as? RecentMediaItem, let file = contents.media as? TelegramMediaFile {
if let contents = item.contents.get(RecentMediaItem.self) {
let file = contents.media
return file
}
return nil

View file

@ -3409,7 +3409,9 @@ func replayFinalState(
return $0.0 < $1.0
}).map({ $0.1 })
for file in stickerFiles {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: RecentMediaItem(file)), removeTailIfCountExceeds: 20)
if let entry = CodableEntry(RecentMediaItem(file)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 20)
}
}
}
@ -3448,7 +3450,9 @@ func replayFinalState(
}).map({ $0.1 })
for file in gifFiles {
if !file.hasLinkedStickers {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: RecentMediaItem(file)), removeTailIfCountExceeds: 200)
if let entry = CodableEntry(RecentMediaItem(file)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 200)
}
}
}
}
@ -3552,18 +3556,20 @@ func replayFinalState(
if !updatedThemes.isEmpty {
let entries = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
let themes = entries.map { entry -> TelegramTheme in
let theme = entry.contents as! TelegramTheme
if let updatedTheme = updatedThemes[theme.id] {
let theme = entry.contents.get(TelegramThemeNativeCodable.self)!
if let updatedTheme = updatedThemes[theme.value.id] {
return updatedTheme
} else {
return theme
return theme.value
}
}
var updatedEntries: [OrderedItemListEntry] = []
for theme in themes {
var intValue = Int32(updatedEntries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
updatedEntries.append(OrderedItemListEntry(id: id, contents: theme))
if let entry = CodableEntry(TelegramThemeNativeCodable(theme)) {
updatedEntries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudThemes, items: updatedEntries)
let _ = accountManager.transaction { transaction in

View file

@ -1581,7 +1581,7 @@ public final class AccountViewTracker {
if let account = self.account {
let view = account.postbox.combinedView(keys: [.orderedItemList(id: Namespaces.OrderedItemList.CloudFeaturedStickerPacks)]).start(next: { next in
if let view = next.views[.orderedItemList(id: Namespaces.OrderedItemList.CloudFeaturedStickerPacks)] as? OrderedItemListView {
subscriber.putNext(view.items.map { $0.contents as! FeaturedStickerPackItem })
subscriber.putNext(view.items.map { $0.contents.get(FeaturedStickerPackItem.self)! })
} else {
subscriber.putNext([])
}

View file

@ -244,11 +244,15 @@ func applyUpdateMessage(postbox: Postbox, stateManager: AccountStateManager, mes
}
}
for file in sentStickers {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: RecentMediaItem(file)), removeTailIfCountExceeds: 20)
if let entry = CodableEntry(RecentMediaItem(file)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 20)
}
}
for file in sentGifs {
if !file.hasLinkedStickers {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: RecentMediaItem(file)), removeTailIfCountExceeds: 200)
if let entry = CodableEntry(RecentMediaItem(file)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 200)
}
}
}
@ -385,11 +389,15 @@ func applyUpdateGroupMessages(postbox: Postbox, stateManager: AccountStateManage
}
for file in sentStickers {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: RecentMediaItem(file)), removeTailIfCountExceeds: 20)
if let entry = CodableEntry(RecentMediaItem(file)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 20)
}
}
for file in sentGifs {
if !file.hasLinkedStickers {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: RecentMediaItem(file)), removeTailIfCountExceeds: 200)
if let entry = CodableEntry(RecentMediaItem(file)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 200)
}
}
}
stateManager.addUpdates(result)

View file

@ -55,7 +55,9 @@ func managedRecentStickers(postbox: Postbox, network: Network) -> Signal<Void, N
var items: [OrderedItemListEntry] = []
for sticker in stickers {
if let file = telegramMediaFileFromApiDocument(sticker), let id = file.id {
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: RecentMediaItem(file)))
if let entry = CodableEntry(RecentMediaItem(file)) {
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: entry))
}
}
}
return .single(items)
@ -76,7 +78,9 @@ func managedRecentGifs(postbox: Postbox, network: Network, forceFetch: Bool = fa
var items: [OrderedItemListEntry] = []
for gif in gifs {
if let file = telegramMediaFileFromApiDocument(gif), let id = file.id {
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: RecentMediaItem(file)))
if let entry = CodableEntry(RecentMediaItem(file)) {
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: entry))
}
}
}
return .single(items)
@ -116,7 +120,9 @@ func managedSavedStickers(postbox: Postbox, network: Network) -> Signal<Void, No
if let representations = fileStringRepresentations[id] {
stringRepresentations = representations
}
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: SavedStickerItem(file: file, stringRepresentations: stringRepresentations)))
if let entry = CodableEntry(SavedStickerItem(file: file, stringRepresentations: stringRepresentations)) {
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: entry))
}
}
}
return .single(items)
@ -137,7 +143,9 @@ func managedGreetingStickers(postbox: Postbox, network: Network) -> Signal<Void,
var items: [OrderedItemListEntry] = []
for sticker in stickers {
if let file = telegramMediaFileFromApiDocument(sticker), let id = file.id {
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: RecentMediaItem(file)))
if let entry = CodableEntry(RecentMediaItem(file)) {
items.append(OrderedItemListEntry(id: RecentMediaItemId(id).rawValue, contents: entry))
}
}
}
return .single(items)

View file

@ -28,7 +28,7 @@ func updatedFeaturedStickerPacks(network: Network, postbox: Postbox) -> Signal<V
let initialPacks = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks)
var initialPackMap: [Int64: FeaturedStickerPackItem] = [:]
for entry in initialPacks {
let item = entry.contents as! FeaturedStickerPackItem
let item = entry.contents.get(FeaturedStickerPackItem.self)!
initialPackMap[FeaturedStickerPackItemId(entry.id).packId] = item
}
@ -55,7 +55,13 @@ func updatedFeaturedStickerPacks(network: Network, postbox: Postbox) -> Signal<V
}
updatedPacks.append(FeaturedStickerPackItem(info: info, topItems: items, unread: unreadIds.contains(info.id.id)))
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, items: updatedPacks.map { OrderedItemListEntry(id: FeaturedStickerPackItemId($0.info.id.id).rawValue, contents: $0) })
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, items: updatedPacks.compactMap { item -> OrderedItemListEntry? in
if let entry = CodableEntry(item) {
return OrderedItemListEntry(id: FeaturedStickerPackItemId(item.info.id.id).rawValue, contents: entry)
} else {
return nil
}
})
}
}
}
@ -83,7 +89,7 @@ public func requestOldFeaturedStickerPacks(network: Network, postbox: Postbox, o
public func preloadedFeaturedStickerSet(network: Network, postbox: Postbox, id: ItemCollectionId) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Signal<Void, NoError> in
if let pack = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, itemId: FeaturedStickerPackItemId(id.id).rawValue)?.contents as? FeaturedStickerPackItem {
if let pack = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, itemId: FeaturedStickerPackItemId(id.id).rawValue)?.contents.get(FeaturedStickerPackItem.self) {
if pack.topItems.count < 5 && pack.topItems.count < pack.info.count {
return _internal_requestStickerSet(postbox: postbox, network: network, reference: .id(id: pack.info.id.id, accessHash: pack.info.accessHash))
|> map(Optional.init)
@ -93,12 +99,14 @@ public func preloadedFeaturedStickerSet(network: Network, postbox: Postbox, id:
|> mapToSignal { result -> Signal<Void, NoError> in
if let result = result {
return postbox.transaction { transaction -> Void in
if let pack = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, itemId: FeaturedStickerPackItemId(id.id).rawValue)?.contents as? FeaturedStickerPackItem {
if let pack = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, itemId: FeaturedStickerPackItemId(id.id).rawValue)?.contents.get(FeaturedStickerPackItem.self) {
var items = result.items.map({ $0 as? StickerPackItem }).compactMap({ $0 })
if items.count > 5 {
items.removeSubrange(5 ..< items.count)
}
transaction.updateOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, itemId: FeaturedStickerPackItemId(id.id).rawValue, item: FeaturedStickerPackItem(info: pack.info, topItems: items, unread: pack.unread))
if let entry = CodableEntry(FeaturedStickerPackItem(info: pack.info, topItems: items, unread: pack.unread)) {
transaction.updateOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks, itemId: FeaturedStickerPackItemId(id.id).rawValue, item: entry)
}
}
}
} else {

View file

@ -33,7 +33,9 @@ func addSynchronizeRecentlyUsedMediaOperation(transaction: Transaction, category
func addRecentlyUsedSticker(transaction: Transaction, fileReference: FileMediaReference) {
if let resource = fileReference.media.resource as? CloudDocumentMediaResource {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(fileReference.media.fileId).rawValue, contents: RecentMediaItem(fileReference.media)), removeTailIfCountExceeds: 20)
if let entry = CodableEntry(RecentMediaItem(fileReference.media)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentStickers, item: OrderedItemListEntry(id: RecentMediaItemId(fileReference.media.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 20)
}
addSynchronizeRecentlyUsedMediaOperation(transaction: transaction, category: .stickers, operation: .add(id: resource.fileId, accessHash: resource.accessHash, fileReference: fileReference))
}
}

View file

@ -33,7 +33,9 @@ public func isGifSaved(transaction: Transaction, mediaId: MediaId) -> Bool {
public func addSavedGif(postbox: Postbox, fileReference: FileMediaReference) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
if let resource = fileReference.media.resource as? CloudDocumentMediaResource {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(fileReference.media.fileId).rawValue, contents: RecentMediaItem(fileReference.media)), removeTailIfCountExceeds: 200)
if let entry = CodableEntry(RecentMediaItem(fileReference.media)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, item: OrderedItemListEntry(id: RecentMediaItemId(fileReference.media.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 200)
}
addSynchronizeSavedGifsOperation(transaction: transaction, operation: .add(id: resource.fileId, accessHash: resource.accessHash, fileReference: fileReference))
}
}
@ -41,8 +43,9 @@ public func addSavedGif(postbox: Postbox, fileReference: FileMediaReference) ->
public func removeSavedGif(postbox: Postbox, mediaId: MediaId) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents as? RecentMediaItem {
if let file = item.media as? TelegramMediaFile, let resource = file.resource as? CloudDocumentMediaResource {
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents.get(RecentMediaItem.self) {
let file = item.media
if let resource = file.resource as? CloudDocumentMediaResource {
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentGifs, itemId: entry.id)
addSynchronizeSavedGifsOperation(transaction: transaction, operation: .remove(id: resource.fileId, accessHash: resource.accessHash))
}

View file

@ -107,13 +107,15 @@ public func addSavedSticker(postbox: Postbox, network: Network, file: TelegramMe
public func addSavedSticker(transaction: Transaction, file: TelegramMediaFile, stringRepresentations: [String]) {
if let resource = file.resource as? CloudDocumentMediaResource {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: SavedStickerItem(file: file, stringRepresentations: stringRepresentations)), removeTailIfCountExceeds: 5)
if let entry = CodableEntry(SavedStickerItem(file: file, stringRepresentations: stringRepresentations)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, item: OrderedItemListEntry(id: RecentMediaItemId(file.fileId).rawValue, contents: entry), removeTailIfCountExceeds: 5)
}
addSynchronizeSavedStickersOperation(transaction: transaction, operation: .add(id: resource.fileId, accessHash: resource.accessHash, fileReference: .standalone(media: file)))
}
}
public func removeSavedSticker(transaction: Transaction, mediaId: MediaId) {
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents as? SavedStickerItem {
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents.get(SavedStickerItem.self) {
if let resource = item.file.resource as? CloudDocumentMediaResource {
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: entry.id)
addSynchronizeSavedStickersOperation(transaction: transaction, operation: .remove(id: resource.fileId, accessHash: resource.accessHash))
@ -123,7 +125,7 @@ public func removeSavedSticker(transaction: Transaction, mediaId: MediaId) {
public func removeSavedSticker(postbox: Postbox, mediaId: MediaId) -> Signal<Void, NoError> {
return postbox.transaction { transaction in
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents as? SavedStickerItem {
if let entry = transaction.getOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: RecentMediaItemId(mediaId).rawValue), let item = entry.contents.get(SavedStickerItem.self) {
if let resource = item.file.resource as? CloudDocumentMediaResource {
transaction.removeOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudSavedStickers, itemId: entry.id)
addSynchronizeSavedStickersOperation(transaction: transaction, operation: .remove(id: resource.fileId, accessHash: resource.accessHash))

View file

@ -1,7 +1,6 @@
import Foundation
import Postbox
public struct ArchivedStickerPacksInfoId {
public let rawValue: MemoryBuffer
public let id: Int32
@ -22,18 +21,22 @@ public struct ArchivedStickerPacksInfoId {
}
}
public final class ArchivedStickerPacksInfo: OrderedItemListEntryContents {
public final class ArchivedStickerPacksInfo: Codable {
public let count: Int32
init(count: Int32) {
self.count = count
}
public init(decoder: PostboxDecoder) {
self.count = decoder.decodeInt32ForKey("c", orElse: 0)
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.count = try container.decode(Int32.self, forKey: "c")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.count, forKey: "c")
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.count, forKey: "c")
}
}

View file

@ -21,7 +21,7 @@ public struct FeaturedStickerPackItemId {
}
}
public final class FeaturedStickerPackItem: OrderedItemListEntryContents {
public final class FeaturedStickerPackItem: Codable {
public let info: StickerPackCollectionInfo
public let topItems: [StickerPackItem]
public let unread: Bool
@ -32,15 +32,27 @@ public final class FeaturedStickerPackItem: OrderedItemListEntryContents {
self.unread = unread
}
public init(decoder: PostboxDecoder) {
self.info = decoder.decodeObjectForKey("i") as! StickerPackCollectionInfo
self.topItems = decoder.decodeObjectArrayForKey("t")
self.unread = decoder.decodeInt32ForKey("u", orElse: 0) != 0
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
let infoData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "i")
self.info = StickerPackCollectionInfo(decoder: PostboxDecoder(buffer: MemoryBuffer(data: infoData.data)))
self.topItems = (try container.decode([AdaptedPostboxDecoder.RawObjectData].self, forKey: "t")).map { itemData in
return StickerPackItem(decoder: PostboxDecoder(buffer: MemoryBuffer(data: itemData.data)))
}
self.unread = try container.decode(Int32.self, forKey: "u") != 0
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.info, forKey: "i")
encoder.encodeObjectArray(self.topItems, forKey: "t")
encoder.encodeInt32(self.unread ? 1 : 0, forKey: "u")
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.info), forKey: "i")
try container.encode(self.topItems.map { item in
return PostboxEncoder().encodeObjectToRawData(item)
}, forKey: "t")
try container.encode((self.unread ? 1 : 0) as Int32, forKey: "u")
}
}

View file

@ -1,12 +1,12 @@
import Postbox
public final class RecentHashtagItem: OrderedItemListEntryContents {
public final class RecentHashtagItem: Codable {
public init() {
}
public init(decoder: PostboxDecoder) {
public init(from decoder: Decoder) throws {
}
public func encode(_ encoder: PostboxEncoder) {
public func encode(to encoder: Encoder) throws {
}
}

View file

@ -25,19 +25,24 @@ public struct RecentMediaItemId {
}
}
public final class RecentMediaItem: OrderedItemListEntryContents, Equatable {
public let media: Media
public final class RecentMediaItem: Codable, Equatable {
public let media: TelegramMediaFile
public init(_ media: Media) {
public init(_ media: TelegramMediaFile) {
self.media = media
}
public init(decoder: PostboxDecoder) {
self.media = decoder.decodeObjectForKey("m") as! Media
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
let mediaData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "m")
self.media = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: mediaData.data)))
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.media, forKey: "m")
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.media), forKey: "m")
}
public static func ==(lhs: RecentMediaItem, rhs: RecentMediaItem) -> Bool {

View file

@ -21,18 +21,22 @@ public struct RecentPeerItemId {
}
}
public final class RecentPeerItem: OrderedItemListEntryContents {
public final class RecentPeerItem: Codable {
public let rating: Double
public init(rating: Double) {
self.rating = rating
}
public init(decoder: PostboxDecoder) {
self.rating = decoder.decodeDoubleForKey("r", orElse: 0.0)
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.rating = try container.decode(Double.self, forKey: "r")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeDouble(self.rating, forKey: "r")
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.rating, forKey: "r")
}
}

View file

@ -1,7 +1,7 @@
import Foundation
import Postbox
public final class SavedStickerItem: OrderedItemListEntryContents, Equatable {
public final class SavedStickerItem: Codable, Equatable {
public let file: TelegramMediaFile
public let stringRepresentations: [String]
@ -10,14 +10,18 @@ public final class SavedStickerItem: OrderedItemListEntryContents, Equatable {
self.stringRepresentations = stringRepresentations
}
public init(decoder: PostboxDecoder) {
self.file = decoder.decodeObjectForKey("f") as! TelegramMediaFile
self.stringRepresentations = decoder.decodeStringArrayForKey("sr")
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.file = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: (try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "f")).data)))
self.stringRepresentations = try container.decode([String].self, forKey: "sr")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.file, forKey: "f")
encoder.encodeStringArray(self.stringRepresentations, forKey: "sr")
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.file), forKey: "f")
try container.encode(self.stringRepresentations, forKey: "sr")
}
public static func ==(lhs: SavedStickerItem, rhs: SavedStickerItem) -> Bool {

View file

@ -56,13 +56,13 @@ public final class TelegraMediaWebpageThemeAttribute: PostboxCoding, Equatable {
public init(decoder: PostboxDecoder) {
self.files = decoder.decodeObjectArrayForKey("files")
self.settings = decoder.decodeObjectForKey("settings", decoder: { TelegramThemeSettings(decoder: $0) }) as? TelegramThemeSettings
self.settings = decoder.decode(TelegramThemeSettings.self, forKey: "settings")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObjectArray(self.files, forKey: "files")
if let settings = self.settings {
encoder.encodeObject(settings, forKey: "settings")
encoder.encode(settings, forKey: "settings")
} else {
encoder.encodeNil(forKey: "settings")
}

View file

@ -14,7 +14,7 @@ public extension UInt32 {
}
}
public final class TelegramThemeSettings: PostboxCoding, Equatable {
public final class TelegramThemeSettings: Codable, Equatable {
public static func == (lhs: TelegramThemeSettings, rhs: TelegramThemeSettings) -> Bool {
if lhs.baseTheme != rhs.baseTheme {
return false
@ -53,43 +53,108 @@ public final class TelegramThemeSettings: PostboxCoding, Equatable {
self.wallpaper = wallpaper
}
public init(decoder: PostboxDecoder) {
self.baseTheme = TelegramBaseTheme(rawValue: decoder.decodeInt32ForKey("baseTheme", orElse: 0)) ?? .classic
self.accentColor = UInt32(bitPattern: decoder.decodeInt32ForKey("accent", orElse: 0))
self.outgoingAccentColor = decoder.decodeOptionalInt32ForKey("outgoingAccent").flatMap { UInt32(bitPattern: $0) }
let messageColors = decoder.decodeInt32ArrayForKey("messageColors")
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.baseTheme = TelegramBaseTheme(rawValue: try container.decode(Int32.self, forKey: "baseTheme")) ?? .classic
self.accentColor = UInt32(bitPattern: try container.decode(Int32.self, forKey: "accent"))
self.outgoingAccentColor = (try container.decodeIfPresent(Int32.self, forKey: "outgoingAccent")).flatMap { UInt32(bitPattern: $0) }
let messageColors = try container.decode([Int32].self, forKey: "messageColors")
if !messageColors.isEmpty {
self.messageColors = messageColors.map(UInt32.init(bitPattern:))
} else {
if let topMessageColor = decoder.decodeOptionalInt32ForKey("topMessage"), let bottomMessageColor = decoder.decodeOptionalInt32ForKey("bottomMessage") {
if let topMessageColor = try container.decodeIfPresent(Int32.self, forKey: "topMessage"), let bottomMessageColor = try container.decodeIfPresent(Int32.self, forKey: "bottomMessage") {
self.messageColors = [UInt32(bitPattern: topMessageColor), UInt32(bitPattern: bottomMessageColor)]
} else {
self.messageColors = []
}
}
self.animateMessageColors = decoder.decodeInt32ForKey("animateMessageColors", orElse: 0) != 0
self.wallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
self.animateMessageColors = try container.decode(Int32.self, forKey: "animateMessageColors") != 0
self.wallpaper = (try container.decodeIfPresent(TelegramWallpaperNativeCodable.self, forKey: "wallpaper"))?.value
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.baseTheme.rawValue, forKey: "baseTheme")
encoder.encodeInt32(Int32(bitPattern: self.accentColor), forKey: "accent")
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.baseTheme.rawValue, forKey: "baseTheme")
try container.encode(Int32(bitPattern: self.accentColor), forKey: "accent")
if let outgoingAccentColor = self.outgoingAccentColor {
encoder.encodeInt32(Int32(bitPattern: outgoingAccentColor), forKey: "outgoingAccent")
try container.encode(Int32(bitPattern: outgoingAccentColor), forKey: "outgoingAccent")
} else {
encoder.encodeNil(forKey: "outgoingAccent")
}
encoder.encodeInt32Array(self.messageColors.map(Int32.init(bitPattern:)), forKey: "messageColors")
encoder.encodeInt32(self.animateMessageColors ? 1 : 0, forKey: "animateMessageColors")
if let wallpaper = self.wallpaper {
encoder.encodeObject(wallpaper, forKey: "wallpaper")
} else {
encoder.encodeNil(forKey: "wallpaper")
try container.encodeNil(forKey: "outgoingAccent")
}
try container.encode(self.messageColors.map(Int32.init(bitPattern:)), forKey: "messageColors")
try container.encode((self.animateMessageColors ? 1 : 0) as Int32, forKey: "animateMessageColors")
try container.encodeIfPresent(self.wallpaper.flatMap(TelegramWallpaperNativeCodable.init), forKey: "wallpaper")
}
}
public final class TelegramTheme: OrderedItemListEntryContents, Equatable {
public struct TelegramThemeNativeCodable: Codable {
public let value: TelegramTheme
public init(_ value: TelegramTheme) {
self.value = value
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
let id = try container.decode(Int64.self, forKey: "id")
let accessHash = try container.decode(Int64.self, forKey: "accessHash")
let slug = try container.decode(String.self, forKey: "slug")
let title = try container.decode(String.self, forKey: "title")
let file: TelegramMediaFile?
if let fileData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "file") {
file = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: fileData.data)))
} else {
file = nil
}
let settings = try container.decodeIfPresent(TelegramThemeSettings.self, forKey: "settings")
let isCreator = try container.decode(Int32.self, forKey: "isCreator") != 0
let isDefault = try container.decode(Int32.self, forKey: "isDefault") != 0
let installCount = try container.decodeIfPresent(Int32.self, forKey: "installCount")
self.value = TelegramTheme(
id: id,
accessHash: accessHash,
slug: slug,
title: title,
file: file,
settings: settings,
isCreator: isCreator,
isDefault: isDefault,
installCount: installCount
)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.value.id, forKey: "id")
try container.encode(self.value.accessHash, forKey: "accessHash")
try container.encode(self.value.slug, forKey: "slug")
try container.encode(self.value.title, forKey: "title")
if let file = self.value.file {
try container.encode(PostboxEncoder().encodeObjectToRawData(file), forKey: "file")
} else {
try container.encodeNil(forKey: "file")
}
try container.encodeIfPresent(self.value.settings, forKey: "settings")
try container.encode((self.value.isCreator ? 1 : 0) as Int32, forKey: "isCreator")
try container.encode((self.value.isDefault ? 1 : 0) as Int32, forKey: "isDefault")
try container.encodeIfPresent(self.value.installCount, forKey: "installCount")
}
}
public final class TelegramTheme: Equatable {
public let id: Int64
public let accessHash: Int64
public let slug: String
@ -112,42 +177,6 @@ public final class TelegramTheme: OrderedItemListEntryContents, Equatable {
self.installCount = installCount
}
public init(decoder: PostboxDecoder) {
self.id = decoder.decodeInt64ForKey("id", orElse: 0)
self.accessHash = decoder.decodeInt64ForKey("accessHash", orElse: 0)
self.slug = decoder.decodeStringForKey("slug", orElse: "")
self.title = decoder.decodeStringForKey("title", orElse: "")
self.file = decoder.decodeObjectForKey("file", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile
self.settings = decoder.decodeObjectForKey("settings", decoder: { TelegramThemeSettings(decoder: $0) }) as? TelegramThemeSettings
self.isCreator = decoder.decodeInt32ForKey("isCreator", orElse: 0) != 0
self.isDefault = decoder.decodeInt32ForKey("isDefault", orElse: 0) != 0
self.installCount = decoder.decodeOptionalInt32ForKey("installCount")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt64(self.id, forKey: "id")
encoder.encodeInt64(self.accessHash, forKey: "accessHash")
encoder.encodeString(self.slug, forKey: "slug")
encoder.encodeString(self.title, forKey: "title")
if let file = self.file {
encoder.encodeObject(file, forKey: "file")
} else {
encoder.encodeNil(forKey: "file")
}
if let settings = self.settings {
encoder.encodeObject(settings, forKey: "settings")
} else {
encoder.encodeNil(forKey: "settings")
}
encoder.encodeInt32(self.isCreator ? 1 : 0, forKey: "isCreator")
encoder.encodeInt32(self.isDefault ? 1 : 0, forKey: "isDefault")
if let installCount = self.installCount {
encoder.encodeInt32(installCount, forKey: "installCount")
} else {
encoder.encodeNil(forKey: "installCount")
}
}
public static func ==(lhs: TelegramTheme, rhs: TelegramTheme) -> Bool {
if lhs.id != rhs.id {
return false

View file

@ -1,6 +1,6 @@
import Postbox
public struct WallpaperSettings: PostboxCoding, Equatable {
public struct WallpaperSettings: Codable, Equatable {
public var blur: Bool
public var motion: Bool
public var colors: [UInt32]
@ -15,37 +15,33 @@ public struct WallpaperSettings: PostboxCoding, Equatable {
self.rotation = rotation
}
public init(decoder: PostboxDecoder) {
self.blur = decoder.decodeInt32ForKey("b", orElse: 0) != 0
self.motion = decoder.decodeInt32ForKey("m", orElse: 0) != 0
if let topColor = decoder.decodeOptionalInt32ForKey("c").flatMap(UInt32.init(bitPattern:)) {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
self.blur = try container.decode(Int32.self, forKey: "b") != 0
self.motion = try container.decode(Int32.self, forKey: "m") != 0
if let topColor = (try container.decodeIfPresent(Int32.self, forKey: "c")).flatMap(UInt32.init(bitPattern:)) {
var colors: [UInt32] = [topColor]
if let bottomColor = decoder.decodeOptionalInt32ForKey("bc").flatMap(UInt32.init(bitPattern:)) {
if let bottomColor = (try container.decodeIfPresent(Int32.self, forKey: "bc")).flatMap(UInt32.init(bitPattern:)) {
colors.append(bottomColor)
}
self.colors = colors
} else {
self.colors = decoder.decodeInt32ArrayForKey("colors").map(UInt32.init(bitPattern:))
self.colors = (try container.decode([Int32].self, forKey: "colors")).map(UInt32.init(bitPattern:))
}
self.intensity = decoder.decodeOptionalInt32ForKey("i")
self.rotation = decoder.decodeOptionalInt32ForKey("r")
self.intensity = try container.decodeIfPresent(Int32.self, forKey: "i")
self.rotation = try container.decodeIfPresent(Int32.self, forKey: "r")
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeInt32(self.blur ? 1 : 0, forKey: "b")
encoder.encodeInt32(self.motion ? 1 : 0, forKey: "m")
encoder.encodeInt32Array(self.colors.map(Int32.init(bitPattern:)), forKey: "colors")
if let intensity = self.intensity {
encoder.encodeInt32(intensity, forKey: "i")
} else {
encoder.encodeNil(forKey: "i")
}
if let rotation = self.rotation {
encoder.encodeInt32(rotation, forKey: "r")
} else {
encoder.encodeNil(forKey: "r")
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode((self.blur ? 1 : 0) as Int32, forKey: "b")
try container.encode((self.motion ? 1 : 0) as Int32, forKey: "m")
try container.encode(self.colors.map(Int32.init(bitPattern:)), forKey: "colors")
try container.encodeIfPresent(self.intensity, forKey: "i")
try container.encodeIfPresent(self.rotation, forKey: "r")
}
public static func ==(lhs: WallpaperSettings, rhs: WallpaperSettings) -> Bool {
@ -68,7 +64,108 @@ public struct WallpaperSettings: PostboxCoding, Equatable {
}
}
public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
public struct TelegramWallpaperNativeCodable: Codable {
public let value: TelegramWallpaper
public init(_ value: TelegramWallpaper) {
self.value = value
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
switch try container.decode(Int32.self, forKey: "v") {
case 0:
let settings = try container.decode(WallpaperSettings.self, forKey: "settings")
self.value = .builtin(settings)
case 1:
self.value = .color(UInt32(bitPattern: try container.decode(Int32.self, forKey: "c")))
case 2:
let settings = try container.decode(WallpaperSettings.self, forKey: "settings")
let representations = (try container.decode([AdaptedPostboxDecoder.RawObjectData].self, forKey: "i")).map { itemData in
return TelegramMediaImageRepresentation(decoder: PostboxDecoder(buffer: MemoryBuffer(data: itemData.data)))
}
self.value = .image(representations, settings)
case 3:
let settings = try container.decode(WallpaperSettings.self, forKey: "settings")
if let fileData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "file") {
let file = TelegramMediaFile(decoder: PostboxDecoder(buffer: MemoryBuffer(data: fileData.data)))
self.value = .file(TelegramWallpaper.File(
id: try container.decode(Int64.self, forKey: "id"),
accessHash: try container.decode(Int64.self, forKey: "accessHash"),
isCreator: try container.decode(Int32.self, forKey: "isCreator") != 0,
isDefault: try container.decode(Int32.self, forKey: "isDefault") != 0,
isPattern: try container.decode(Int32.self, forKey: "isPattern") != 0,
isDark: try container.decode(Int32.self, forKey: "isDark") != 0,
slug: try container.decode(String.self, forKey: "slug"),
file: file,
settings: settings
))
} else {
self.value = .color(0xffffff)
}
case 4:
let settings = try container.decode(WallpaperSettings.self, forKey: "settings")
var colors: [UInt32] = []
if let topColor = (try container.decodeIfPresent(Int32.self, forKey: "c1")).flatMap(UInt32.init(bitPattern:)) {
colors.append(topColor)
if let bottomColor = (try container.decodeIfPresent(Int32.self, forKey: "c2")).flatMap(UInt32.init(bitPattern:)) {
colors.append(bottomColor)
}
} else {
colors = (try container.decode([Int32].self, forKey: "colors")).map(UInt32.init(bitPattern:))
}
self.value = .gradient(TelegramWallpaper.Gradient(
id: try container.decodeIfPresent(Int64.self, forKey: "id"),
colors: colors,
settings: settings
))
default:
assertionFailure()
self.value = .color(0xffffff)
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
switch self.value {
case let .builtin(settings):
try container.encode(0 as Int32, forKey: "v")
try container.encode(settings, forKey: "settings")
case let .color(color):
try container.encode(1 as Int32, forKey: "v")
try container.encode(Int32(bitPattern: color), forKey: "c")
case let .gradient(gradient):
try container.encode(4 as Int32, forKey: "v")
try container.encodeIfPresent(gradient.id, forKey: "id")
try container.encode(gradient.colors.map(Int32.init(bitPattern:)), forKey: "colors")
try container.encode(gradient.settings, forKey: "settings")
case let .image(representations, settings):
try container.encode(2 as Int32, forKey: "v")
try container.encode(representations.map { item in
return PostboxEncoder().encodeObjectToRawData(item)
}, forKey: "i")
try container.encode(settings, forKey: "settings")
case let .file(file):
try container.encode(3 as Int32, forKey: "v")
try container.encode(file.id, forKey: "id")
try container.encode(file.accessHash, forKey: "accessHash")
try container.encode((file.isCreator ? 1 : 0) as Int32, forKey: "isCreator")
try container.encode((file.isDefault ? 1 : 0) as Int32, forKey: "isDefault")
try container.encode((file.isPattern ? 1 : 0) as Int32, forKey: "isPattern")
try container.encode((file.isDark ? 1 : 0) as Int32, forKey: "isDark")
try container.encode(file.slug, forKey: "slug")
try container.encode(PostboxEncoder().encodeObjectToRawData(file.file), forKey: "file")
try container.encode(file.settings, forKey: "settings")
}
}
}
public enum TelegramWallpaper: Equatable {
public struct Gradient: Equatable {
public var id: Int64?
public var colors: [UInt32]
@ -125,44 +222,6 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
case image([TelegramMediaImageRepresentation], WallpaperSettings)
case file(File)
public init(decoder: PostboxDecoder) {
switch decoder.decodeInt32ForKey("v", orElse: 0) {
case 0:
let settings = decoder.decodeObjectForKey("settings", decoder: { WallpaperSettings(decoder: $0) }) as? WallpaperSettings ?? WallpaperSettings()
self = .builtin(settings)
case 1:
self = .color(UInt32(bitPattern: decoder.decodeInt32ForKey("c", orElse: 0)))
case 2:
let settings = decoder.decodeObjectForKey("settings", decoder: { WallpaperSettings(decoder: $0) }) as? WallpaperSettings ?? WallpaperSettings()
self = .image(decoder.decodeObjectArrayWithDecoderForKey("i"), settings)
case 3:
let settings = decoder.decodeObjectForKey("settings", decoder: { WallpaperSettings(decoder: $0) }) as? WallpaperSettings ?? WallpaperSettings()
if let file = decoder.decodeObjectForKey("file", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile {
self = .file(File(id: decoder.decodeInt64ForKey("id", orElse: 0), accessHash: decoder.decodeInt64ForKey("accessHash", orElse: 0), isCreator: decoder.decodeInt32ForKey("isCreator", orElse: 0) != 0, isDefault: decoder.decodeInt32ForKey("isDefault", orElse: 0) != 0, isPattern: decoder.decodeInt32ForKey("isPattern", orElse: 0) != 0, isDark: decoder.decodeInt32ForKey("isDark", orElse: 0) != 0, slug: decoder.decodeStringForKey("slug", orElse: ""), file: file, settings: settings))
} else {
self = .color(0xffffff)
}
case 4:
let settings = decoder.decodeObjectForKey("settings", decoder: { WallpaperSettings(decoder: $0) }) as? WallpaperSettings ?? WallpaperSettings()
var colors: [UInt32] = []
if let topColor = decoder.decodeOptionalInt32ForKey("c1").flatMap(UInt32.init(bitPattern:)) {
colors.append(topColor)
if let bottomColor = decoder.decodeOptionalInt32ForKey("c2").flatMap(UInt32.init(bitPattern:)) {
colors.append(bottomColor)
}
} else {
colors = decoder.decodeInt32ArrayForKey("colors").map(UInt32.init(bitPattern:))
}
self = .gradient(Gradient(id: decoder.decodeOptionalInt64ForKey("id"), colors: colors, settings: settings))
default:
assertionFailure()
self = .color(0xffffff)
}
}
public var hasWallpaper: Bool {
switch self {
case .color:
@ -172,41 +231,6 @@ public enum TelegramWallpaper: OrderedItemListEntryContents, Equatable {
}
}
public func encode(_ encoder: PostboxEncoder) {
switch self {
case let .builtin(settings):
encoder.encodeInt32(0, forKey: "v")
encoder.encodeObject(settings, forKey: "settings")
case let .color(color):
encoder.encodeInt32(1, forKey: "v")
encoder.encodeInt32(Int32(bitPattern: color), forKey: "c")
case let .gradient(gradient):
encoder.encodeInt32(4, forKey: "v")
if let id = gradient.id {
encoder.encodeInt64(id, forKey: "id")
} else {
encoder.encodeNil(forKey: "id")
}
encoder.encodeInt32Array(gradient.colors.map(Int32.init(bitPattern:)), forKey: "colors")
encoder.encodeObject(gradient.settings, forKey: "settings")
case let .image(representations, settings):
encoder.encodeInt32(2, forKey: "v")
encoder.encodeObjectArray(representations, forKey: "i")
encoder.encodeObject(settings, forKey: "settings")
case let .file(file):
encoder.encodeInt32(3, forKey: "v")
encoder.encodeInt64(file.id, forKey: "id")
encoder.encodeInt64(file.accessHash, forKey: "accessHash")
encoder.encodeInt32(file.isCreator ? 1 : 0, forKey: "isCreator")
encoder.encodeInt32(file.isDefault ? 1 : 0, forKey: "isDefault")
encoder.encodeInt32(file.isPattern ? 1 : 0, forKey: "isPattern")
encoder.encodeInt32(file.isDark ? 1 : 0, forKey: "isDark")
encoder.encodeString(file.slug, forKey: "slug")
encoder.encodeObject(file.file, forKey: "file")
encoder.encodeObject(file.settings, forKey: "settings")
}
}
public static func ==(lhs: TelegramWallpaper, rhs: TelegramWallpaper) -> Bool {
switch lhs {
case let .builtin(settings):

View file

@ -10,19 +10,14 @@ public final class ThemeSettings: Codable, Equatable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
if let currentThemeData = try container.decodeIfPresent(AdaptedPostboxDecoder.RawObjectData.self, forKey: "t") {
self.currentTheme = TelegramTheme(decoder: PostboxDecoder(buffer: MemoryBuffer(data: currentThemeData.data)))
} else {
self.currentTheme = nil
}
self.currentTheme = (try container.decodeIfPresent(TelegramThemeNativeCodable.self, forKey: "t"))?.value
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
if let currentTheme = self.currentTheme {
let currentThemeData = PostboxEncoder().encodeObjectToRawData(currentTheme)
try container.encode(currentThemeData, forKey: "t")
try container.encode(TelegramThemeNativeCodable(currentTheme), forKey: "t")
} else {
try container.encodeNil(forKey: "t")
}

View file

@ -18,7 +18,7 @@ public struct WallpapersState: Codable, Equatable {
let wallpapersData = try container.decode([Data].self, forKey: "wallpapers")
self.wallpapers = wallpapersData.map { data in
return TelegramWallpaper(decoder: PostboxDecoder(buffer: MemoryBuffer(data: data)))
return (try! AdaptedPostboxDecoder().decode(TelegramWallpaperNativeCodable.self, from: data)).value
}
}
@ -26,9 +26,7 @@ public struct WallpapersState: Codable, Equatable {
var container = encoder.container(keyedBy: StringCodingKey.self)
let wallpapersData: [Data] = self.wallpapers.map { wallpaper in
let innerEncoder = PostboxEncoder()
wallpaper.encode(innerEncoder)
return innerEncoder.makeData()
return try! AdaptedPostboxEncoder().encode(TelegramWallpaperNativeCodable(wallpaper))
}
try container.encode(wallpapersData, forKey: "wallpapers")

View file

@ -25,7 +25,9 @@ private struct RecentHashtagItemId {
func addRecentlyUsedHashtag(transaction: Transaction, string: String) {
if let itemId = RecentHashtagItemId(string) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlyUsedHashtags, item: OrderedItemListEntry(id: itemId.rawValue, contents: RecentHashtagItem()), removeTailIfCountExceeds: 100)
if let entry = CodableEntry(RecentHashtagItem()) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlyUsedHashtags, item: OrderedItemListEntry(id: itemId.rawValue, contents: entry), removeTailIfCountExceeds: 100)
}
}
}

View file

@ -204,8 +204,12 @@ func _internal_managedRecentlyUsedInlineBots(postbox: Postbox, network: Network,
let sortedPeersWithRating = peersWithRating.sorted(by: { $0.1 > $1.1 })
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots, items: sortedPeersWithRating.map { (peerId, rating) in
return OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: RecentPeerItem(rating: rating))
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots, items: sortedPeersWithRating.compactMap { (peerId, rating) in
if let entry = CodableEntry(RecentPeerItem(rating: rating)) {
return OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: entry)
} else {
return nil
}
})
}
} else {
@ -220,11 +224,13 @@ func _internal_addRecentlyUsedInlineBot(postbox: Postbox, peerId: PeerId) -> Sig
return postbox.transaction { transaction -> Void in
var maxRating = 1.0
for entry in transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots) {
if let contents = entry.contents as? RecentPeerItem {
if let contents = entry.contents.get(RecentPeerItem.self) {
maxRating = max(maxRating, contents.rating)
}
}
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots, item: OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: RecentPeerItem(rating: maxRating)), removeTailIfCountExceeds: 20)
if let entry = CodableEntry(RecentPeerItem(rating: maxRating)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.CloudRecentInlineBots, item: OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: entry), removeTailIfCountExceeds: 20)
}
}
}
@ -237,7 +243,7 @@ func _internal_recentlyUsedInlineBots(postbox: Postbox) -> Signal<[(Peer, Double
if let view = view.views[.orderedItemList(id: Namespaces.OrderedItemList.CloudRecentInlineBots)] as? OrderedItemListView {
for item in view.items {
let peerId = RecentPeerItemId(item.id).peerId
if let peer = transaction.getPeer(peerId), let contents = item.contents as? RecentPeerItem {
if let peer = transaction.getPeer(peerId), let contents = item.contents.get(RecentPeerItem.self) {
peers.append((peer, contents.rating))
}
}

View file

@ -5,7 +5,9 @@ import SwiftSignalKit
func _internal_addRecentlySearchedPeer(postbox: Postbox, peerId: PeerId) -> Signal<Void, NoError> {
return postbox.transaction { transaction -> Void in
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, item: OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: RecentPeerItem(rating: 0.0)), removeTailIfCountExceeds: 20)
if let entry = CodableEntry(RecentPeerItem(rating: 0.0)) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: Namespaces.OrderedItemList.RecentlySearchedPeerIds, item: OrderedItemListEntry(id: RecentPeerItemId(peerId).rawValue, contents: entry), removeTailIfCountExceeds: 20)
}
}
}

View file

@ -71,7 +71,8 @@ func _internal_randomGreetingSticker(account: Account) -> Signal<FoundStickerIte
}
|> take(1)
|> map { items -> FoundStickerItem? in
if let randomItem = items?.randomElement(), let item = randomItem.contents as? RecentMediaItem, let file = item.media as? TelegramMediaFile {
if let randomItem = items?.randomElement(), let item = randomItem.contents.get(RecentMediaItem.self) {
let file = item.media
return FoundStickerItem(file: file, stringRepresentations: [])
}
return nil
@ -90,7 +91,7 @@ func _internal_searchStickers(account: Account, query: String, scope: SearchStic
var result: [FoundStickerItem] = []
if scope.contains(.installed) {
for entry in transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudSavedStickers) {
if let item = entry.contents as? SavedStickerItem {
if let item = entry.contents.get(SavedStickerItem.self) {
for representation in item.stringRepresentations {
if representation.hasPrefix(query) {
result.append(FoundStickerItem(file: item.file, stringRepresentations: item.stringRepresentations))
@ -107,7 +108,9 @@ func _internal_searchStickers(account: Account, query: String, scope: SearchStic
var matchingRecentItemsIds = Set<MediaId>()
for entry in transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudRecentStickers) {
if let item = entry.contents as? RecentMediaItem, let file = item.media as? TelegramMediaFile {
if let item = entry.contents.get(RecentMediaItem.self) {
let file = item.media
if !currentItems.contains(file.fileId) {
for case let .Sticker(displayText, _, _) in file.attributes {
if displayText.hasPrefix(query) {

View file

@ -98,10 +98,12 @@ func _internal_markFeaturedStickerPacksAsSeenInteractively(postbox: Postbox, ids
var items = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudFeaturedStickerPacks)
var readIds = Set<ItemCollectionId>()
for i in 0 ..< items.count {
let item = (items[i].contents as! FeaturedStickerPackItem)
let item = items[i].contents.get(FeaturedStickerPackItem.self)!
if item.unread && idsSet.contains(item.info.id) {
readIds.insert(item.info.id)
items[i] = OrderedItemListEntry(id: items[i].id, contents: FeaturedStickerPackItem(info: item.info, topItems: item.topItems, unread: false))
if let entry = CodableEntry(FeaturedStickerPackItem(info: item.info, topItems: item.topItems, unread: false)) {
items[i] = OrderedItemListEntry(id: items[i].id, contents: entry)
}
}
}
if !readIds.isEmpty {

View file

@ -23,19 +23,16 @@ public struct ChatTheme: Codable, Equatable {
self.emoji = try container.decode(String.self, forKey: "e")
let themeData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "t")
self.theme = TelegramTheme(decoder: PostboxDecoder(buffer: MemoryBuffer(data: themeData.data)))
let darkThemeData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "dt")
self.darkTheme = TelegramTheme(decoder: PostboxDecoder(buffer: MemoryBuffer(data: darkThemeData.data)))
self.theme = (try container.decode(TelegramThemeNativeCodable.self, forKey: "t")).value
self.darkTheme = (try container.decode(TelegramThemeNativeCodable.self, forKey: "dt")).value
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(self.emoji, forKey: "e")
try container.encode(PostboxEncoder().encodeObjectToRawData(self.theme), forKey: "t")
try container.encode(PostboxEncoder().encodeObjectToRawData(self.darkTheme), forKey: "dt")
try container.encode(TelegramThemeNativeCodable(self.theme), forKey: "t")
try container.encode(TelegramThemeNativeCodable(self.darkTheme), forKey: "dt")
}
}

View file

@ -49,7 +49,9 @@ public func telegramThemes(postbox: Postbox, network: Network, accountManager: A
for item in items {
var intValue = Int32(entries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
entries.append(OrderedItemListEntry(id: id, contents: item))
if let entry = CodableEntry(TelegramThemeNativeCodable(item)) {
entries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudThemes, items: entries)
if let entry = CodableEntry(CachedThemesConfiguration(hash: hash)) {
@ -61,7 +63,7 @@ public func telegramThemes(postbox: Postbox, network: Network, accountManager: A
postbox.combinedView(keys: [PostboxViewKey.orderedItemList(id: Namespaces.OrderedItemList.CloudThemes)])
|> map { view -> [TelegramTheme] in
if let view = view.views[.orderedItemList(id: Namespaces.OrderedItemList.CloudThemes)] as? OrderedItemListView {
return view.items.compactMap { $0.contents as? TelegramTheme }
return view.items.compactMap { $0.contents.get(TelegramThemeNativeCodable.self)?.value }
} else {
return []
}
@ -75,7 +77,7 @@ public func telegramThemes(postbox: Postbox, network: Network, accountManager: A
return postbox.transaction { transaction -> ([TelegramTheme], Int64?) in
let configuration = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedThemesConfiguration, key: ValueBoxKey(length: 0)))?.get(CachedThemesConfiguration.self)
let items = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
return (items.map { $0.contents as! TelegramTheme }, configuration?.hash)
return (items.compactMap { $0.contents.get(TelegramThemeNativeCodable.self)?.value }, configuration?.hash)
}
|> mapToSignal { current, hash -> Signal<[TelegramTheme], NoError> in
return .single(current)
@ -126,7 +128,7 @@ private func checkThemeUpdated(network: Network, theme: TelegramTheme) -> Signal
private func saveUnsaveTheme(account: Account, accountManager: AccountManager<TelegramAccountManagerTypes>, theme: TelegramTheme, unsave: Bool) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
let entries = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
var items = entries.map { $0.contents as! TelegramTheme }
var items = entries.compactMap { $0.contents.get(TelegramThemeNativeCodable.self)?.value }
items = items.filter { $0.id != theme.id }
if !unsave {
items.insert(theme, at: 0)
@ -135,7 +137,9 @@ private func saveUnsaveTheme(account: Account, accountManager: AccountManager<Te
for item in items {
var intValue = Int32(updatedEntries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
updatedEntries.append(OrderedItemListEntry(id: id, contents: item))
if let entry = CodableEntry(TelegramThemeNativeCodable(item)) {
updatedEntries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudThemes, items: updatedEntries)
@ -306,13 +310,15 @@ public func createTheme(account: Account, title: String, resource: MediaResource
let theme = TelegramTheme(apiTheme: apiTheme)
return account.postbox.transaction { transaction -> CreateThemeResult in
let entries = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
var items = entries.map { $0.contents as! TelegramTheme }
var items = entries.compactMap { $0.contents.get(TelegramThemeNativeCodable.self)?.value }
items.insert(theme, at: 0)
var updatedEntries: [OrderedItemListEntry] = []
for item in items {
var intValue = Int32(updatedEntries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
updatedEntries.append(OrderedItemListEntry(id: id, contents: item))
if let entry = CodableEntry(TelegramThemeNativeCodable(item)) {
updatedEntries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudThemes, items: updatedEntries)
return .result(theme)
@ -343,13 +349,15 @@ public func createTheme(account: Account, title: String, resource: MediaResource
return account.postbox.transaction { transaction -> CreateThemeResult in
let entries = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
var items = entries.map { $0.contents as! TelegramTheme }
var items = entries.compactMap { $0.contents.get(TelegramThemeNativeCodable.self)?.value }
items.insert(theme, at: 0)
var updatedEntries: [OrderedItemListEntry] = []
for item in items {
var intValue = Int32(updatedEntries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
updatedEntries.append(OrderedItemListEntry(id: id, contents: item))
if let entry = CodableEntry(TelegramThemeNativeCodable(item)) {
updatedEntries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudThemes, items: updatedEntries)
return .result(theme)
@ -431,7 +439,7 @@ public func updateTheme(account: Account, accountManager: AccountManager<Telegra
return account.postbox.transaction { transaction -> CreateThemeResult in
let entries = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
let items = entries.map { entry -> TelegramTheme in
let theme = entry.contents as! TelegramTheme
let theme = entry.contents.get(TelegramThemeNativeCodable.self)!.value
if theme.id == updatedTheme.id {
return updatedTheme
} else {
@ -442,7 +450,9 @@ public func updateTheme(account: Account, accountManager: AccountManager<Telegra
for item in items {
var intValue = Int32(updatedEntries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
updatedEntries.append(OrderedItemListEntry(id: id, contents: item))
if let entry = CodableEntry(TelegramThemeNativeCodable(item)) {
updatedEntries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudThemes, items: updatedEntries)
return .result(updatedTheme)
@ -501,7 +511,7 @@ func managedThemesUpdates(accountManager: AccountManager<TelegramAccountManagerT
let _ = postbox.transaction { transaction in
let entries = transaction.getOrderedListItems(collectionId: Namespaces.OrderedItemList.CloudThemes)
let items = entries.map { entry -> TelegramTheme in
let theme = entry.contents as! TelegramTheme
let theme = entry.contents.get(TelegramThemeNativeCodable.self)!.value
if theme.id == updatedTheme.id {
return updatedTheme
} else {
@ -512,7 +522,9 @@ func managedThemesUpdates(accountManager: AccountManager<TelegramAccountManagerT
for item in items {
var intValue = Int32(updatedEntries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
updatedEntries.append(OrderedItemListEntry(id: id, contents: item))
if let entry = CodableEntry(TelegramThemeNativeCodable(item)) {
updatedEntries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudThemes, items: updatedEntries)
}.start()
@ -559,7 +571,7 @@ public func actualizedTheme(account: Account, accountManager: AccountManager<Tel
return account.postbox.combinedView(keys: [PostboxViewKey.orderedItemList(id: Namespaces.OrderedItemList.CloudThemes)])
|> map { view -> [TelegramTheme] in
if let view = view.views[.orderedItemList(id: Namespaces.OrderedItemList.CloudThemes)] as? OrderedItemListView {
return view.items.compactMap { $0.contents as? TelegramTheme }
return view.items.compactMap { $0.contents.get(TelegramThemeNativeCodable.self)?.value }
} else {
return []
}

View file

@ -43,7 +43,9 @@ public func telegramWallpapers(postbox: Postbox, network: Network, forceUpdate:
for item in items {
var intValue = Int32(entries.count)
let id = MemoryBuffer(data: Data(bytes: &intValue, count: 4))
entries.append(OrderedItemListEntry(id: id, contents: item))
if let entry = CodableEntry(TelegramWallpaperNativeCodable(item)) {
entries.append(OrderedItemListEntry(id: id, contents: entry))
}
}
transaction.replaceOrderedItemListItems(collectionId: Namespaces.OrderedItemList.CloudWallpapers, items: entries)
if let entry = CodableEntry(CachedWallpapersConfiguration(hash: hash)) {
@ -63,7 +65,7 @@ public func telegramWallpapers(postbox: Postbox, network: Network, forceUpdate:
if items.count == 0 {
return ([.builtin(WallpaperSettings())], 0)
} else {
return (items.map { $0.contents as! TelegramWallpaper }, configuration?.hash)
return (items.map { $0.contents.get(TelegramWallpaperNativeCodable.self)!.value }, configuration?.hash)
}
}
|> mapToSignal { current, hash -> Signal<[TelegramWallpaper], NoError> in

View file

@ -64,18 +64,24 @@ private func encodeColorList<Key>(_ values: inout KeyedEncodingContainer<Key>, _
try values.encode(stringList, forKey: key)
}
extension TelegramWallpaper: Codable {
public init(from decoder: Decoder) throws {
struct TelegramWallpaperStandardizedCodable: Codable {
let value: TelegramWallpaper
init(_ value: TelegramWallpaper) {
self.value = value
}
init(from decoder: Decoder) throws {
let values = try decoder.singleValueContainer()
if let value = try? values.decode(String.self) {
switch value.lowercased() {
case "builtin":
self = .builtin(WallpaperSettings())
self.value = .builtin(WallpaperSettings())
default:
let optionKeys = ["motion", "blur"]
if [6, 8].contains(value.count), let color = UIColor(hexString: value) {
self = .color(color.argb)
self.value = .color(color.argb)
} else {
let components = value.components(separatedBy: " ")
var blur = false
@ -117,9 +123,9 @@ extension TelegramWallpaper: Codable {
}
if let slug = slug {
self = .file(TelegramWallpaper.File(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: !colors.isEmpty, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: WallpaperDataResource(slug: slug), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, colors: colors.map { $0.argb }, intensity: intensity, rotation: rotation)))
self.value = .file(TelegramWallpaper.File(id: 0, accessHash: 0, isCreator: false, isDefault: false, isPattern: !colors.isEmpty, isDark: false, slug: slug, file: TelegramMediaFile(fileId: MediaId(namespace: 0, id: 0), partialReference: nil, resource: WallpaperDataResource(slug: slug), previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "", size: nil, attributes: []), settings: WallpaperSettings(blur: blur, motion: motion, colors: colors.map { $0.argb }, intensity: intensity, rotation: rotation)))
} else if colors.count > 1 {
self = .gradient(TelegramWallpaper.Gradient(id: nil, colors: colors.map { $0.argb }, settings: WallpaperSettings(blur: blur, motion: motion, rotation: rotation)))
self.value = .gradient(TelegramWallpaper.Gradient(id: nil, colors: colors.map { $0.argb }, settings: WallpaperSettings(blur: blur, motion: motion, rotation: rotation)))
} else {
throw PresentationThemeDecodingError.generic
}
@ -130,9 +136,9 @@ extension TelegramWallpaper: Codable {
}
}
public func encode(to encoder: Encoder) throws {
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
switch self.value {
case .builtin:
try container.encode("builtin")
case let .color(color):
@ -155,7 +161,7 @@ extension TelegramWallpaper: Codable {
case let .file(file):
var components: [String] = []
components.append(file.slug)
if self.isPattern {
if self.value.isPattern {
if file.settings.colors.count >= 1 {
components.append(String(format: "%06x", file.settings.colors[0]))
}
@ -1659,7 +1665,7 @@ extension PresentationThemeChat: Codable {
public convenience init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
var wallpaper = try values.decode(TelegramWallpaper.self, forKey: .defaultWallpaper)
var wallpaper = (try values.decode(TelegramWallpaperStandardizedCodable.self, forKey: .defaultWallpaper)).value
if let decoder = decoder as? PresentationThemeDecoding {
if case .file = wallpaper, let resolvedWallpaper = decoder.resolvedWallpaper {
wallpaper = resolvedWallpaper
@ -1678,7 +1684,7 @@ extension PresentationThemeChat: Codable {
public func encode(to encoder: Encoder) throws {
var values = encoder.container(keyedBy: CodingKeys.self)
try values.encode(self.defaultWallpaper, forKey: .defaultWallpaper)
try values.encode(TelegramWallpaperStandardizedCodable(self.defaultWallpaper), forKey: .defaultWallpaper)
try values.encode(self.animateMessageColors, forKey: .animateMessageColors)
try values.encode(self.message, forKey: .message)
try values.encode(self.serviceMessage, forKey: .serviceMessage)

View file

@ -300,7 +300,7 @@ final class ChatMediaInputGifPane: ChatMediaInputPane, UIScrollViewDelegate {
if let recentGifs = recentGifs {
saved = recentGifs.items.map { item in
let file = (item.contents as! RecentMediaItem).media as! TelegramMediaFile
let file = item.contents.get(RecentMediaItem.self)!.media
return MultiplexedVideoNodeFile(file: .savedGif(media: file), contextResult: nil)
}
} else {

View file

@ -176,7 +176,7 @@ func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: Ordere
var savedStickerIds = Set<Int64>()
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
for i in 0 ..< savedStickers.items.count {
if let item = savedStickers.items[i].contents as? SavedStickerItem {
if let item = savedStickers.items[i].contents.get(SavedStickerItem.self) {
savedStickerIds.insert(item.file.fileId.id)
}
}
@ -184,7 +184,7 @@ func chatMediaInputPanelEntries(view: ItemCollectionsView, savedStickers: Ordere
if let recentStickers = recentStickers, !recentStickers.items.isEmpty {
var found = false
for item in recentStickers.items {
if let item = item.contents as? RecentMediaItem, let _ = item.media as? TelegramMediaFile, let mediaId = item.media.id {
if let item = item.contents.get(RecentMediaItem.self), let mediaId = item.media.id {
if !savedStickerIds.contains(mediaId.id) {
found = true
break
@ -273,7 +273,7 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered
if let savedStickers = savedStickers, !savedStickers.items.isEmpty {
let packInfo = StickerPackCollectionInfo(id: ItemCollectionId(namespace: ChatMediaInputPanelAuxiliaryNamespace.savedStickers.rawValue, id: 0), flags: [], accessHash: 0, title: strings.Stickers_FavoriteStickers.uppercased(), shortName: "", thumbnail: nil, immediateThumbnailData: nil, hash: 0, count: 0)
for i in 0 ..< savedStickers.items.count {
if let item = savedStickers.items[i].contents as? SavedStickerItem {
if let item = savedStickers.items[i].contents.get(SavedStickerItem.self) {
savedStickerIds.insert(item.file.fileId.id)
let index = ItemCollectionItemIndex(index: Int32(i), id: item.file.fileId.id)
let stickerItem = StickerPackItem(index: index, file: item.file, indexKeys: [])
@ -294,7 +294,9 @@ func chatMediaInputGridEntries(view: ItemCollectionsView, savedStickers: Ordered
if addedCount >= 20 {
break
}
if let item = recentStickers.items[i].contents as? RecentMediaItem, let file = item.media as? TelegramMediaFile, let mediaId = item.media.id {
if let item = recentStickers.items[i].contents.get(RecentMediaItem.self), let mediaId = item.media.id {
let file = item.media
if !savedStickerIds.contains(mediaId.id) {
let index = ItemCollectionItemIndex(index: Int32(i), id: mediaId.id)
let stickerItem = StickerPackItem(index: index, file: file, indexKeys: [])

View file

@ -19,9 +19,6 @@ private var telegramUIDeclaredEncodables: Void = {
declareEncodable(LocalFileGifMediaResource.self, f: { LocalFileGifMediaResource(decoder: $0) })
declareEncodable(PhotoLibraryMediaResource.self, f: { PhotoLibraryMediaResource(decoder: $0) })
declareEncodable(ICloudFileResource.self, f: { ICloudFileResource(decoder: $0) })
declareEncodable(RecentWebSearchQueryItem.self, f: { RecentWebSearchQueryItem(decoder: $0) })
declareEncodable(RecentWallpaperSearchQueryItem.self, f: { RecentWallpaperSearchQueryItem(decoder: $0) })
declareEncodable(RecentSettingsSearchQueryItem.self, f: { RecentSettingsSearchQueryItem(decoder: $0) })
return
}()

View file

@ -67,14 +67,14 @@ public struct PresentationLocalTheme: PostboxCoding, Equatable {
public init(decoder: PostboxDecoder) {
self.title = decoder.decodeStringForKey("title", orElse: "")
self.resource = decoder.decodeObjectForKey("resource", decoder: { LocalFileMediaResource(decoder: $0) }) as! LocalFileMediaResource
self.resolvedWallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
self.resolvedWallpaper = decoder.decode(TelegramWallpaperNativeCodable.self, forKey: "wallpaper")?.value
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeString(self.title, forKey: "title")
encoder.encodeObject(self.resource, forKey: "resource")
if let resolvedWallpaper = self.resolvedWallpaper {
encoder.encodeObject(resolvedWallpaper, forKey: "wallpaper")
encoder.encode(TelegramWallpaperNativeCodable(resolvedWallpaper), forKey: "wallpaper")
} else {
encoder.encodeNil(forKey: "wallpaper")
}
@ -106,15 +106,15 @@ public struct PresentationCloudTheme: PostboxCoding, Equatable {
}
public init(decoder: PostboxDecoder) {
self.theme = decoder.decodeObjectForKey("theme", decoder: { TelegramTheme(decoder: $0) }) as! TelegramTheme
self.resolvedWallpaper = decoder.decodeObjectForKey("wallpaper", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
self.theme = decoder.decode(TelegramThemeNativeCodable.self, forKey: "theme")!.value
self.resolvedWallpaper = decoder.decode(TelegramWallpaperNativeCodable.self, forKey: "wallpaper")?.value
self.creatorAccountId = decoder.decodeOptionalInt64ForKey("account").flatMap { AccountRecordId(rawValue: $0) }
}
public func encode(_ encoder: PostboxEncoder) {
encoder.encodeObject(self.theme, forKey: "theme")
encoder.encode(TelegramThemeNativeCodable(self.theme), forKey: "theme")
if let resolvedWallpaper = self.resolvedWallpaper {
encoder.encodeObject(resolvedWallpaper, forKey: "wallpaper")
encoder.encode(TelegramWallpaperNativeCodable(resolvedWallpaper), forKey: "wallpaper")
} else {
encoder.encodeNil(forKey: "wallpaper")
}
@ -480,7 +480,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
}
}
self.wallpaper = decoder.decodeObjectForKey("w", decoder: { TelegramWallpaper(decoder: $0) }) as? TelegramWallpaper
self.wallpaper = decoder.decode(TelegramWallpaperNativeCodable.self, forKey: "w")?.value
self.themeIndex = decoder.decodeOptionalInt64ForKey("t")
}
@ -494,7 +494,7 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable {
}
encoder.encodeInt32Array(self.bubbleColors.map(Int32.init(bitPattern:)), forKey: "bubbleColors")
if let wallpaper = self.wallpaper {
encoder.encodeObject(wallpaper, forKey: "w")
encoder.encode(TelegramWallpaperNativeCodable(wallpaper), forKey: "w")
} else {
encoder.encodeNil(forKey: "w")
}
@ -649,11 +649,10 @@ public struct PresentationThemeSettings: Codable {
self.theme = .builtin(.dayClassic)
}
let themeSpecificChatWallpapersDict = try container.decode([DictionaryKey: AdaptedPostboxDecoder.RawObjectData].self, forKey: "themeSpecificChatWallpapers")
let themeSpecificChatWallpapersDict = try container.decode([DictionaryKey: TelegramWallpaperNativeCodable].self, forKey: "themeSpecificChatWallpapers")
var mappedThemeSpecificChatWallpapers: [Int64: TelegramWallpaper] = [:]
for (key, value) in themeSpecificChatWallpapersDict {
let innerDecoder = PostboxDecoder(buffer: MemoryBuffer(data: value.data))
mappedThemeSpecificChatWallpapers[key.key] = TelegramWallpaper(decoder: innerDecoder)
mappedThemeSpecificChatWallpapers[key.key] = value.value
}
self.themeSpecificChatWallpapers = mappedThemeSpecificChatWallpapers
@ -689,9 +688,9 @@ public struct PresentationThemeSettings: Codable {
}
try container.encode(mappedThemeSpecificAccentColors, forKey: "themeSpecificAccentColors")
var mappedThemeSpecificChatWallpapers: [DictionaryKey: AdaptedPostboxEncoder.RawObjectData] = [:]
var mappedThemeSpecificChatWallpapers: [DictionaryKey: TelegramWallpaperNativeCodable] = [:]
for (key, value) in self.themeSpecificChatWallpapers {
mappedThemeSpecificChatWallpapers[DictionaryKey(key)] = PostboxEncoder().encodeObjectToRawData(value)
mappedThemeSpecificChatWallpapers[DictionaryKey(key)] = TelegramWallpaperNativeCodable(value)
}
try container.encode(mappedThemeSpecificChatWallpapers, forKey: "themeSpecificChatWallpapers")

View file

@ -17,14 +17,13 @@ public final class CachedWallpaper: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: StringCodingKey.self)
let wallpaperData = try container.decode(AdaptedPostboxDecoder.RawObjectData.self, forKey: "wallpaper")
self.wallpaper = TelegramWallpaper(decoder: PostboxDecoder(buffer: MemoryBuffer(data: wallpaperData.data)))
self.wallpaper = (try container.decode(TelegramWallpaperNativeCodable.self, forKey: "wallpaper")).value
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: StringCodingKey.self)
try container.encode(PostboxEncoder().encodeObjectToRawData(self.wallpaper), forKey: "wallpaper")
try container.encode(TelegramWallpaperNativeCodable(self.wallpaper), forKey: "wallpaper")
}
}

View file

@ -313,11 +313,11 @@ private func mediaForSticker(documentId: Int64, account: Account) -> Signal<Tele
|> map { view -> TelegramMediaFile? in
for view in view.orderedItemListsViews {
for entry in view.items {
if let file = (entry.contents as? SavedStickerItem)?.file {
if let file = entry.contents.get(SavedStickerItem.self)?.file {
if file.id?.id == documentId {
return file
}
} else if let file = (entry.contents as? RecentMediaItem)?.media as? TelegramMediaFile {
} else if let file = entry.contents.get(RecentMediaItem.self)?.media {
if file.id?.id == documentId {
return file
}
@ -618,12 +618,12 @@ final class WatchStickersHandler: WatchRequestHandler {
var added: Set<Int64> = []
outer: for view in view.orderedItemListsViews {
for entry in view.items {
if let file = (entry.contents as? SavedStickerItem)?.file {
if let file = entry.contents.get(SavedStickerItem.self)?.file {
if let sticker = makeBridgeDocument(file), !added.contains(sticker.documentId) {
stickers.append(sticker)
added.insert(sticker.documentId)
}
} else if let file = (entry.contents as? RecentMediaItem)?.media as? TelegramMediaFile {
} else if let file = entry.contents.get(RecentMediaItem.self)?.media {
if let sticker = makeBridgeDocument(file), !added.contains(sticker.documentId) {
stickers.append(sticker)
added.insert(sticker.documentId)

View file

@ -24,21 +24,23 @@ private struct WebSearchRecentQueryItemId {
}
}
public final class RecentWebSearchQueryItem: OrderedItemListEntryContents {
public final class RecentWebSearchQueryItem: Codable {
init() {
}
public init(decoder: PostboxDecoder) {
public init(from decoder: Decoder) throws {
}
public func encode(_ encoder: PostboxEncoder) {
public func encode(to encoder: Encoder) throws {
}
}
func addRecentWebSearchQuery(postbox: Postbox, string: String) -> Signal<Void, NoError> {
return postbox.transaction { transaction in
if let itemId = WebSearchRecentQueryItemId(string) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: ApplicationSpecificOrderedItemListCollectionId.webSearchRecentQueries, item: OrderedItemListEntry(id: itemId.rawValue, contents: RecentWebSearchQueryItem()), removeTailIfCountExceeds: 100)
if let entry = CodableEntry(RecentWebSearchQueryItem()) {
transaction.addOrMoveToFirstPositionOrderedItemListItem(collectionId: ApplicationSpecificOrderedItemListCollectionId.webSearchRecentQueries, item: OrderedItemListEntry(id: itemId.rawValue, contents: entry), removeTailIfCountExceeds: 100)
}
}
}
}