Gift collections improvements

This commit is contained in:
Ilya Laktyushin 2025-07-16 17:29:01 +01:00
parent 9bb46769a3
commit 555518a41d
2 changed files with 88 additions and 13 deletions

View File

@ -1119,7 +1119,7 @@ func _internal_starGiftUpgradePreview(account: Account, giftId: Int64) -> Signal
} }
} }
private final class CachedProfileGifts: Codable { final class CachedProfileGifts: Codable {
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case gifts case gifts
case count case count
@ -1162,7 +1162,7 @@ private final class CachedProfileGifts: Codable {
} }
} }
private func entryId(peerId: EnginePeer.Id, collectionId: Int32?) -> ItemCacheEntryId { func giftsEntryId(peerId: EnginePeer.Id, collectionId: Int32?) -> ItemCacheEntryId {
let cacheKey: ValueBoxKey let cacheKey: ValueBoxKey
if let collectionId { if let collectionId {
cacheKey = ValueBoxKey(length: 8 + 4) cacheKey = ValueBoxKey(length: 8 + 4)
@ -1255,7 +1255,7 @@ private final class ProfileGiftsContextImpl {
if case let .ready(true, initialNextOffset) = dataState { if case let .ready(true, initialNextOffset) = dataState {
if !isFiltered || isUniqueOnlyFilter, self.gifts.isEmpty, initialNextOffset == nil, !reload { if !isFiltered || isUniqueOnlyFilter, self.gifts.isEmpty, initialNextOffset == nil, !reload {
self.cacheDisposable.set((self.account.postbox.transaction { transaction -> CachedProfileGifts? in self.cacheDisposable.set((self.account.postbox.transaction { transaction -> CachedProfileGifts? in
let cachedGifts = transaction.retrieveItemCacheEntry(id: entryId(peerId: peerId, collectionId: collectionId))?.get(CachedProfileGifts.self) let cachedGifts = transaction.retrieveItemCacheEntry(id: giftsEntryId(peerId: peerId, collectionId: collectionId))?.get(CachedProfileGifts.self)
cachedGifts?.render(transaction: transaction) cachedGifts?.render(transaction: transaction)
return cachedGifts return cachedGifts
} |> deliverOn(self.queue)).start(next: { [weak self] cachedGifts in } |> deliverOn(self.queue)).start(next: { [weak self] cachedGifts in
@ -1377,7 +1377,7 @@ private final class ProfileGiftsContextImpl {
self.gifts = gifts self.gifts = gifts
self.cacheDisposable.set(self.account.postbox.transaction { transaction in self.cacheDisposable.set(self.account.postbox.transaction { transaction in
if let entry = CodableEntry(CachedProfileGifts(gifts: gifts, count: count, notificationsEnabled: notificationsEnabled)) { if let entry = CodableEntry(CachedProfileGifts(gifts: gifts, count: count, notificationsEnabled: notificationsEnabled)) {
transaction.putItemCacheEntry(id: entryId(peerId: peerId, collectionId: collectionId), entry: entry) transaction.putItemCacheEntry(id: giftsEntryId(peerId: peerId, collectionId: collectionId), entry: entry)
} }
}.start()) }.start())
} else { } else {
@ -1651,6 +1651,24 @@ private final class ProfileGiftsContextImpl {
func insertStarGifts(gifts: [ProfileGiftsContext.State.StarGift]) { func insertStarGifts(gifts: [ProfileGiftsContext.State.StarGift]) {
self.gifts.insert(contentsOf: gifts, at: 0) self.gifts.insert(contentsOf: gifts, at: 0)
self.pushState() self.pushState()
let peerId = self.peerId
let collectionId = self.collectionId
self.cacheDisposable.set(self.account.postbox.transaction { transaction in
var updatedGifts: [ProfileGiftsContext.State.StarGift] = []
var updatedCount: Int32 = 0
if let cachedGifts = transaction.retrieveItemCacheEntry(id: giftsEntryId(peerId: peerId, collectionId: collectionId))?.get(CachedProfileGifts.self) {
updatedGifts = cachedGifts.gifts
updatedCount = cachedGifts.count
} else {
updatedGifts = []
}
updatedGifts.insert(contentsOf: gifts, at: 0)
updatedCount += Int32(gifts.count)
if let entry = CodableEntry(CachedProfileGifts(gifts: updatedGifts, count: updatedCount, notificationsEnabled: nil)) {
transaction.putItemCacheEntry(id: giftsEntryId(peerId: peerId, collectionId: collectionId), entry: entry)
}
}.start())
} }
func removeStarGifts(references: [StarGiftReference]) { func removeStarGifts(references: [StarGiftReference]) {
@ -1662,6 +1680,54 @@ private final class ProfileGiftsContextImpl {
} }
}) })
self.pushState() self.pushState()
let peerId = self.peerId
let collectionId = self.collectionId
self.cacheDisposable.set(self.account.postbox.transaction { transaction in
var updatedGifts: [ProfileGiftsContext.State.StarGift] = []
var updatedCount: Int32 = 0
if let cachedGifts = transaction.retrieveItemCacheEntry(id: giftsEntryId(peerId: peerId, collectionId: collectionId))?.get(CachedProfileGifts.self) {
updatedGifts = cachedGifts.gifts
updatedCount = cachedGifts.count
} else {
updatedGifts = []
}
updatedGifts = updatedGifts.filter { gift in
if let reference = gift.reference {
return !references.contains(reference)
} else {
return true
}
}
updatedCount -= Int32(references.count)
if let entry = CodableEntry(CachedProfileGifts(gifts: updatedGifts, count: updatedCount, notificationsEnabled: nil)) {
transaction.putItemCacheEntry(id: giftsEntryId(peerId: peerId, collectionId: collectionId), entry: entry)
}
}.start())
}
func reorderStarGifts(references: [StarGiftReference]) {
let giftsSet = Set(references)
var giftsMap: [StarGiftReference: ProfileGiftsContext.State.StarGift] = [:]
for gift in self.gifts {
if let reference = gift.reference {
giftsMap[reference] = gift
}
}
var updatedGifts: [ProfileGiftsContext.State.StarGift] = []
for reference in references {
if let gift = giftsMap[reference] {
updatedGifts.append(gift)
}
}
for gift in self.gifts {
if let reference = gift.reference, giftsSet.contains(reference) {
continue
}
updatedGifts.append(gift)
}
self.gifts = updatedGifts
self.pushState()
} }
func upgradeStarGift(formId: Int64?, reference: StarGiftReference, keepOriginalInfo: Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError> { func upgradeStarGift(formId: Int64?, reference: StarGiftReference, keepOriginalInfo: Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError> {
@ -2177,6 +2243,12 @@ public final class ProfileGiftsContext {
} }
} }
public func reorderStarGifts(references: [StarGiftReference]) {
self.impl.with { impl in
impl.reorderStarGifts(references: references)
}
}
public func transferStarGift(prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) -> Signal<Never, TransferStarGiftError> { public func transferStarGift(prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) -> Signal<Never, TransferStarGiftError> {
return Signal { subscriber in return Signal { subscriber in
let disposable = MetaDisposable() let disposable = MetaDisposable()

View File

@ -133,12 +133,12 @@ private func _internal_getStarGiftCollections(postbox: Postbox, network: Network
} }
} }
private func _internal_createStarGiftCollection(account: Account, peerId: EnginePeer.Id, title: String, starGifts: [StarGiftReference]) -> Signal<StarGiftCollection?, NoError> { private func _internal_createStarGiftCollection(account: Account, peerId: EnginePeer.Id, title: String, starGifts: [ProfileGiftsContext.State.StarGift]) -> Signal<StarGiftCollection?, NoError> {
return account.postbox.transaction { transaction -> (Api.InputPeer, [Api.InputSavedStarGift])? in return account.postbox.transaction { transaction -> (Api.InputPeer, [Api.InputSavedStarGift])? in
guard let inputPeer = transaction.getPeer(peerId).flatMap(apiInputPeer) else { guard let inputPeer = transaction.getPeer(peerId).flatMap(apiInputPeer) else {
return nil return nil
} }
let inputStarGifts = starGifts.compactMap { $0.apiStarGiftReference(transaction: transaction) } let inputStarGifts = starGifts.compactMap { $0.reference }.compactMap { $0.apiStarGiftReference(transaction: transaction) }
return (inputPeer, inputStarGifts) return (inputPeer, inputStarGifts)
} }
|> mapToSignal { inputPeerAndGifts -> Signal<StarGiftCollection?, NoError> in |> mapToSignal { inputPeerAndGifts -> Signal<StarGiftCollection?, NoError> in
@ -157,6 +157,13 @@ private func _internal_createStarGiftCollection(account: Account, peerId: Engine
} }
return StarGiftCollection(apiStarGiftCollection: result) return StarGiftCollection(apiStarGiftCollection: result)
} }
|> beforeNext { collection in
let _ = account.postbox.transaction { transaction in
if let collection, let entry = CodableEntry(CachedProfileGifts(gifts: starGifts.map { $0.withPinnedToTop(false) }, count: Int32(starGifts.count), notificationsEnabled: nil)) {
transaction.putItemCacheEntry(id: giftsEntryId(peerId: peerId, collectionId: collection.id), entry: entry)
}
}.start()
}
} }
} }
@ -191,7 +198,7 @@ private func _internal_updateStarGiftCollection(account: Account, peerId: Engine
case let .removeGifts(gifts): case let .removeGifts(gifts):
giftsContext?.removeStarGifts(references: gifts) giftsContext?.removeStarGifts(references: gifts)
case let .reorderGifts(gifts): case let .reorderGifts(gifts):
let _ = gifts giftsContext?.reorderStarGifts(references: gifts)
default: default:
break break
} }
@ -337,10 +344,10 @@ public final class ProfileGiftsCollectionsContext {
})) }))
} }
public func createCollection(title: String, starGifts: [StarGiftReference]) -> Signal<StarGiftCollection?, NoError> { public func createCollection(title: String, starGifts: [ProfileGiftsContext.State.StarGift]) -> Signal<StarGiftCollection?, NoError> {
return _internal_createStarGiftCollection(account: self.account, peerId: self.peerId, title: title, starGifts: starGifts) return _internal_createStarGiftCollection(account: self.account, peerId: self.peerId, title: title, starGifts: starGifts)
|> deliverOn(self.queue) |> deliverOn(self.queue)
|> afterNext { [weak self] collection in |> beforeNext { [weak self] collection in
guard let self else { guard let self else {
return return
} }
@ -348,7 +355,6 @@ public final class ProfileGiftsCollectionsContext {
self.collections.append(collection) self.collections.append(collection)
self.pushState() self.pushState()
} }
self.reload()
} }
} }
@ -366,7 +372,6 @@ public final class ProfileGiftsCollectionsContext {
self.pushState() self.pushState()
} }
} }
self.reload()
} }
} }
@ -405,7 +410,6 @@ public final class ProfileGiftsCollectionsContext {
} }
self.collections = collections self.collections = collections
self.pushState() self.pushState()
self.reload()
} }
} }
@ -419,7 +423,6 @@ public final class ProfileGiftsCollectionsContext {
self.giftsContexts.removeValue(forKey: id) self.giftsContexts.removeValue(forKey: id)
self.collections.removeAll(where: { $0.id == id }) self.collections.removeAll(where: { $0.id == id })
self.pushState() self.pushState()
self.reload()
} }
} }