Update API

This commit is contained in:
Ilya Laktyushin 2025-08-25 18:37:14 +04:00
parent f6e28fc44e
commit 618859a050
7 changed files with 182 additions and 27 deletions

View File

@ -14918,3 +14918,9 @@ Sorry for the inconvenience.";
"Conversation.StopVoiceMessagePauseAction" = "Pause";
"Gift.Options.GiftLocked.Title" = "Gift Locked";
"Gift.Unique.Value" = "Value";
"Gift.Unique.LearnMore" = "learn more";
"Gift.Upgrade.GiftUpgrade" = "Pay %@ for Upgrade";
"Gift.View.GiftUpgrade" = "Gift an Upgrade";

View File

@ -1231,7 +1231,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1674235686] = { return Api.account.AutoDownloadSettings.parse_autoDownloadSettings($0) }
dict[1279133341] = { return Api.account.AutoSaveSettings.parse_autoSaveSettings($0) }
dict[-331111727] = { return Api.account.BusinessChatLinks.parse_businessChatLinks($0) }
dict[-1642883515] = { return Api.account.ChatThemes.parse_chatThemes($0) }
dict[1271855483] = { return Api.account.ChatThemes.parse_chatThemes($0) }
dict[-535699004] = { return Api.account.ChatThemes.parse_chatThemesNotModified($0) }
dict[400029819] = { return Api.account.ConnectedBots.parse_connectedBots($0) }
dict[1474462241] = { return Api.account.ContentSettings.parse_contentSettings($0) }

View File

@ -570,21 +570,23 @@ public extension Api.account {
}
public extension Api.account {
enum ChatThemes: TypeConstructorDescription {
case chatThemes(hash: Int64, themes: [Api.ChatTheme])
case chatThemes(flags: Int32, hash: Int64, themes: [Api.ChatTheme], nextOffset: Int32?)
case chatThemesNotModified
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .chatThemes(let hash, let themes):
case .chatThemes(let flags, let hash, let themes, let nextOffset):
if boxed {
buffer.appendInt32(-1642883515)
buffer.appendInt32(1271855483)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(hash, buffer: buffer, boxed: false)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(themes.count))
for item in themes {
item.serialize(buffer, true)
}
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(nextOffset!, buffer: buffer, boxed: false)}
break
case .chatThemesNotModified:
if boxed {
@ -597,24 +599,30 @@ public extension Api.account {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .chatThemes(let hash, let themes):
return ("chatThemes", [("hash", hash as Any), ("themes", themes as Any)])
case .chatThemes(let flags, let hash, let themes, let nextOffset):
return ("chatThemes", [("flags", flags as Any), ("hash", hash as Any), ("themes", themes as Any), ("nextOffset", nextOffset as Any)])
case .chatThemesNotModified:
return ("chatThemesNotModified", [])
}
}
public static func parse_chatThemes(_ reader: BufferReader) -> ChatThemes? {
var _1: Int64?
_1 = reader.readInt64()
var _2: [Api.ChatTheme]?
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: [Api.ChatTheme]?
if let _ = reader.readInt32() {
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ChatTheme.self)
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.ChatTheme.self)
}
var _4: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_4 = reader.readInt32() }
let _c1 = _1 != nil
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.account.ChatThemes.chatThemes(hash: _1!, themes: _2!)
let _c3 = _3 != nil
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.account.ChatThemes.chatThemes(flags: _1!, hash: _2!, themes: _3!, nextOffset: _4)
}
else {
return nil

View File

@ -839,11 +839,13 @@ public extension Api.functions.account {
}
}
public extension Api.functions.account {
static func getUniqueGiftChatThemes(hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.ChatThemes>) {
static func getUniqueGiftChatThemes(offset: Int32, limit: Int32, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.account.ChatThemes>) {
let buffer = Buffer()
buffer.appendInt32(1036953191)
buffer.appendInt32(-25890913)
serializeInt32(offset, buffer: buffer, boxed: false)
serializeInt32(limit, buffer: buffer, boxed: false)
serializeInt64(hash, buffer: buffer, boxed: false)
return (FunctionDescription(name: "account.getUniqueGiftChatThemes", parameters: [("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.ChatThemes? in
return (FunctionDescription(name: "account.getUniqueGiftChatThemes", parameters: [("offset", String(describing: offset)), ("limit", String(describing: limit)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.account.ChatThemes? in
let reader = BufferReader(buffer)
var result: Api.account.ChatThemes?
if let signature = reader.readInt32() {

View File

@ -146,6 +146,7 @@ public struct Namespaces {
public static let groupCallPersistentSettings: Int8 = 47
public static let cachedProfileGiftsCollections: Int8 = 48
public static let cachedProfileSavedMusic: Int8 = 49
public static let cachedChatThemes: Int8 = 50
}
public struct UnorderedItemList {

View File

@ -131,10 +131,6 @@ extension ChatTheme {
}
}
//func _internal_getChatGiftThemes(accountManager: AccountManager<TelegramAccountManagerTypes>, network: Network, forceUpdate: Bool = false, onlyCached: Bool = false) -> Signal<[TelegramTheme], NoError> {
//
//}
func _internal_getChatThemes(accountManager: AccountManager<TelegramAccountManagerTypes>, network: Network, forceUpdate: Bool = false, onlyCached: Bool = false) -> Signal<[TelegramTheme], NoError> {
let fetch: ([TelegramTheme]?, Int64?) -> Signal<[TelegramTheme], NoError> = { current, hash in
return network.request(Api.functions.account.getChatThemes(hash: hash ?? 0))
@ -374,3 +370,148 @@ func _internal_setExistingChatWallpaper(account: Account, messageId: MessageId,
}
}
}
private final class CachedUniqueGiftChatThemes: Codable {
enum CodingKeys: String, CodingKey {
case themes
}
let themes: [ChatTheme]
init(themes: [ChatTheme]) {
self.themes = themes
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.themes = try container.decode([ChatTheme].self, forKey: .themes)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.themes, forKey: .themes)
}
}
private func entryId() -> ItemCacheEntryId {
let cacheKey = ValueBoxKey(length: 8)
cacheKey.setInt64(0, value: 0)
return ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedChatThemes, key: cacheKey)
}
public final class UniqueGiftChatThemesContext {
public struct State: Equatable {
public enum DataState: Equatable {
case loading
case ready(canLoadMore: Bool)
}
public var themes: [ChatTheme]
public var dataState: DataState
}
private let queue: Queue = .mainQueue()
private let account: Account
private let disposable = MetaDisposable()
private let cacheDisposable = MetaDisposable()
private var themes: [ChatTheme] = []
private var nextOffset: Int32?
private var dataState: UniqueGiftChatThemesContext.State.DataState = .ready(canLoadMore: true)
private let stateValue = Promise<State>()
public var state: Signal<State, NoError> {
return self.stateValue.get()
}
public init(account: Account) {
self.account = account
self.loadMore()
}
deinit {
self.disposable.dispose()
self.cacheDisposable.dispose()
}
public func reload() {
self.themes = []
self.nextOffset = nil
self.dataState = .ready(canLoadMore: true)
self.loadMore(reload: true)
}
public func loadMore(reload: Bool = false) {
let network = self.account.network
let postbox = self.account.postbox
let dataState = self.dataState
let offset = self.nextOffset
guard case .ready(true) = dataState else {
return
}
if self.themes.isEmpty, !reload {
self.cacheDisposable.set((postbox.transaction { transaction -> CachedUniqueGiftChatThemes? in
return transaction.retrieveItemCacheEntry(id: entryId())?.get(CachedUniqueGiftChatThemes.self)
} |> deliverOn(self.queue)).start(next: { [weak self] cachedUniqueGiftChatThemes in
guard let self, let cachedUniqueGiftChatThemes else {
return
}
self.themes = cachedUniqueGiftChatThemes.themes
if case .loading = self.dataState {
self.pushState()
}
}))
}
self.dataState = .loading
if !reload {
self.pushState()
}
let signal = network.request(Api.functions.account.getUniqueGiftChatThemes(offset: offset ?? 0, limit: 32, hash: 0))
|> map { result -> ([ChatTheme], Int32?) in
switch result {
case let .chatThemes(_, _, themes, nextOffset):
return (themes.compactMap { ChatTheme(apiChatTheme: $0) }, nextOffset)
case .chatThemesNotModified:
return ([], nil)
}
}
self.disposable.set((signal
|> deliverOn(self.queue)).start(next: { [weak self] themes, nextOffset in
guard let self else {
return
}
if offset == 0 || reload {
self.themes = themes
self.cacheDisposable.set(self.account.postbox.transaction { transaction in
if let entry = CodableEntry(CachedUniqueGiftChatThemes(themes: themes)) {
transaction.putItemCacheEntry(id: entryId(), entry: entry)
}
}.start())
} else {
self.themes.append(contentsOf: themes)
}
self.dataState = .ready(canLoadMore: nextOffset != nil)
self.pushState()
}))
}
private func pushState() {
let state = State(
themes: self.themes,
dataState: self.dataState
)
self.stateValue.set(.single(state))
}
}

View File

@ -2648,7 +2648,7 @@ private final class GiftViewSheetContent: CombinedComponent {
var descriptionSize = CGSize()
if state.justUpgraded {
var items: [AnyComponentWithIdentity<Empty>] = [
AnyComponentWithIdentity(id: "label", component: AnyComponent(Text(text: "Collectible #", font: textFont, color: .white, tintColor: textColor)))
AnyComponentWithIdentity(id: "label", component: AnyComponent(Text(text: "\(strings.Gift_Unique_Collectible) #", font: textFont, color: .white, tintColor: textColor)))
]
let numberFont = Font.with(size: 13.0, traits: .monospacedNumbers)
@ -3413,11 +3413,10 @@ private final class GiftViewSheetContent: CombinedComponent {
)
), at: hasOriginalInfo ? tableItems.count - 1 : tableItems.count)
//TODO:localize
if let valueAmount = uniqueGift.valueAmount, let valueCurrency = uniqueGift.valueCurrency {
tableItems.insert(.init(
id: "fiatValue",
title: "Value",
title: strings.Gift_Unique_Value,
component: AnyComponent(
HStack([
AnyComponentWithIdentity(
@ -3429,7 +3428,7 @@ private final class GiftViewSheetContent: CombinedComponent {
component: AnyComponent(Button(
content: AnyComponent(ButtonContentComponent(
context: component.context,
text: "learn more",
text: strings.Gift_Unique_LearnMore,
color: theme.list.itemAccentColor
)),
action: { [weak state] in
@ -3889,9 +3888,8 @@ private final class GiftViewSheetContent: CombinedComponent {
}
var upgradeString = strings.Gift_Upgrade_Upgrade
if !incoming {
//TODO:localize
if let gift = state.starGiftsMap[giftId], let upgradeStars = gift.upgradeStars {
upgradeString = "Pay # \(upgradeStars) for Upgrade"
upgradeString = strings.Gift_Upgrade_GiftUpgrade(" # \(upgradeStars)").string
}
} else if let upgradeForm = state.upgradeForm, let price = upgradeForm.invoice.prices.first?.amount {
upgradeString += " # \(presentationStringsFormattedNumber(Int32(price), environment.dateTimeFormat.groupingSeparator))"
@ -3945,8 +3943,7 @@ private final class GiftViewSheetContent: CombinedComponent {
} else if (incoming && !converted && !upgraded && canUpgrade) || canGiftUpgrade {
let buttonTitle: String
if canGiftUpgrade {
//TODO:localize
buttonTitle = "Gift an Upgrade"
buttonTitle = strings.Gift_View_GiftUpgrade
} else if let upgradeStars, upgradeStars > 0 {
buttonTitle = strings.Gift_View_UpgradeForFree
} else {