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 {
case gifts
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
if let collectionId {
cacheKey = ValueBoxKey(length: 8 + 4)
@ -1255,7 +1255,7 @@ private final class ProfileGiftsContextImpl {
if case let .ready(true, initialNextOffset) = dataState {
if !isFiltered || isUniqueOnlyFilter, self.gifts.isEmpty, initialNextOffset == nil, !reload {
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)
return cachedGifts
} |> deliverOn(self.queue)).start(next: { [weak self] cachedGifts in
@ -1377,7 +1377,7 @@ private final class ProfileGiftsContextImpl {
self.gifts = gifts
self.cacheDisposable.set(self.account.postbox.transaction { transaction in
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())
} else {
@ -1651,6 +1651,24 @@ private final class ProfileGiftsContextImpl {
func insertStarGifts(gifts: [ProfileGiftsContext.State.StarGift]) {
self.gifts.insert(contentsOf: gifts, at: 0)
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]) {
@ -1662,6 +1680,54 @@ private final class ProfileGiftsContextImpl {
}
})
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> {
@ -2176,6 +2242,12 @@ public final class ProfileGiftsContext {
impl.removeStarGifts(references: references)
}
}
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> {
return Signal { subscriber in

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
guard let inputPeer = transaction.getPeer(peerId).flatMap(apiInputPeer) else {
return nil
}
let inputStarGifts = starGifts.compactMap { $0.apiStarGiftReference(transaction: transaction) }
let inputStarGifts = starGifts.compactMap { $0.reference }.compactMap { $0.apiStarGiftReference(transaction: transaction) }
return (inputPeer, inputStarGifts)
}
|> mapToSignal { inputPeerAndGifts -> Signal<StarGiftCollection?, NoError> in
@ -157,6 +157,13 @@ private func _internal_createStarGiftCollection(account: Account, peerId: Engine
}
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):
giftsContext?.removeStarGifts(references: gifts)
case let .reorderGifts(gifts):
let _ = gifts
giftsContext?.reorderStarGifts(references: gifts)
default:
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)
|> deliverOn(self.queue)
|> afterNext { [weak self] collection in
|> beforeNext { [weak self] collection in
guard let self else {
return
}
@ -348,7 +355,6 @@ public final class ProfileGiftsCollectionsContext {
self.collections.append(collection)
self.pushState()
}
self.reload()
}
}
@ -366,7 +372,6 @@ public final class ProfileGiftsCollectionsContext {
self.pushState()
}
}
self.reload()
}
}
@ -405,7 +410,6 @@ public final class ProfileGiftsCollectionsContext {
}
self.collections = collections
self.pushState()
self.reload()
}
}
@ -419,7 +423,6 @@ public final class ProfileGiftsCollectionsContext {
self.giftsContexts.removeValue(forKey: id)
self.collections.removeAll(where: { $0.id == id })
self.pushState()
self.reload()
}
}