Various improvements

This commit is contained in:
Ilya Laktyushin 2025-07-27 03:04:03 +02:00
parent 5a5892b3a7
commit f3a27124d7
23 changed files with 231 additions and 127 deletions

View File

@ -14760,3 +14760,5 @@ Sorry for the inconvenience.";
"FaceScan.Instruction.Position" = "Position your face\nwithin the frame";
"FaceScan.Instruction.Rotate" = "Move your head slowly to\ncomplete the circle";
"Gift.Buy.Confirm.BuyForTon" = "Buy for %@ TON";

View File

@ -881,6 +881,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1115174036] = { return Api.SavedDialog.parse_savedDialog($0) }
dict[-881854424] = { return Api.SavedReactionTag.parse_savedReactionTag($0) }
dict[514213599] = { return Api.SavedStarGift.parse_savedStarGift($0) }
dict[-1810993028] = { return Api.SearchPostsFlood.parse_searchPostsFlood($0) }
dict[-911191137] = { return Api.SearchResultsCalendarPeriod.parse_searchResultsCalendarPeriod($0) }
dict[2137295719] = { return Api.SearchResultsPosition.parse_searchResultPosition($0) }
dict[871426631] = { return Api.SecureCredentialsEncrypted.parse_secureCredentialsEncrypted($0) }
@ -1381,7 +1382,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-948520370] = { return Api.messages.Messages.parse_channelMessages($0) }
dict[-1938715001] = { return Api.messages.Messages.parse_messages($0) }
dict[1951620897] = { return Api.messages.Messages.parse_messagesNotModified($0) }
dict[978610270] = { return Api.messages.Messages.parse_messagesSlice($0) }
dict[1982539325] = { return Api.messages.Messages.parse_messagesSlice($0) }
dict[-83926371] = { return Api.messages.MyStickers.parse_myStickers($0) }
dict[863093588] = { return Api.messages.PeerDialogs.parse_peerDialogs($0) }
dict[1753266509] = { return Api.messages.PeerSettings.parse_peerSettings($0) }
@ -2099,6 +2100,8 @@ public extension Api {
_1.serialize(buffer, boxed)
case let _1 as Api.SavedStarGift:
_1.serialize(buffer, boxed)
case let _1 as Api.SearchPostsFlood:
_1.serialize(buffer, boxed)
case let _1 as Api.SearchResultsCalendarPeriod:
_1.serialize(buffer, boxed)
case let _1 as Api.SearchResultsPosition:

View File

@ -294,6 +294,54 @@ public extension Api {
}
}
public extension Api {
enum SearchPostsFlood: TypeConstructorDescription {
case searchPostsFlood(flags: Int32, remains: Int32, waitTill: Int32?, starsAmount: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .searchPostsFlood(let flags, let remains, let waitTill, let starsAmount):
if boxed {
buffer.appendInt32(-1810993028)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(remains, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(waitTill!, buffer: buffer, boxed: false)}
serializeInt64(starsAmount, buffer: buffer, boxed: false)
break
}
}
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .searchPostsFlood(let flags, let remains, let waitTill, let starsAmount):
return ("searchPostsFlood", [("flags", flags as Any), ("remains", remains as Any), ("waitTill", waitTill as Any), ("starsAmount", starsAmount as Any)])
}
}
public static func parse_searchPostsFlood(_ reader: BufferReader) -> SearchPostsFlood? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
var _4: Int64?
_4 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.SearchPostsFlood.searchPostsFlood(flags: _1!, remains: _2!, waitTill: _3, starsAmount: _4!)
}
else {
return nil
}
}
}
}
public extension Api {
enum SearchResultsCalendarPeriod: TypeConstructorDescription {
case searchResultsCalendarPeriod(date: Int32, minMsgId: Int32, maxMsgId: Int32, count: Int32)

View File

@ -633,7 +633,7 @@ public extension Api.messages {
case channelMessages(flags: Int32, pts: Int32, count: Int32, offsetIdOffset: Int32?, messages: [Api.Message], topics: [Api.ForumTopic], chats: [Api.Chat], users: [Api.User])
case messages(messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
case messagesNotModified(count: Int32)
case messagesSlice(flags: Int32, count: Int32, nextRate: Int32?, offsetIdOffset: Int32?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
case messagesSlice(flags: Int32, count: Int32, nextRate: Int32?, offsetIdOffset: Int32?, searchFlood: Api.SearchPostsFlood?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
@ -692,14 +692,15 @@ public extension Api.messages {
}
serializeInt32(count, buffer: buffer, boxed: false)
break
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let searchFlood, let messages, let chats, let users):
if boxed {
buffer.appendInt32(978610270)
buffer.appendInt32(1982539325)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(count, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(nextRate!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {searchFlood!.serialize(buffer, true)}
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(messages.count))
for item in messages {
@ -727,8 +728,8 @@ public extension Api.messages {
return ("messages", [("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
case .messagesNotModified(let count):
return ("messagesNotModified", [("count", count as Any)])
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
return ("messagesSlice", [("flags", flags as Any), ("count", count as Any), ("nextRate", nextRate as Any), ("offsetIdOffset", offsetIdOffset as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let searchFlood, let messages, let chats, let users):
return ("messagesSlice", [("flags", flags as Any), ("count", count as Any), ("nextRate", nextRate as Any), ("offsetIdOffset", offsetIdOffset as Any), ("searchFlood", searchFlood as Any), ("messages", messages as Any), ("chats", chats as Any), ("users", users as Any)])
}
}
@ -815,27 +816,32 @@ public extension Api.messages {
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
var _4: Int32?
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
var _5: [Api.Message]?
var _5: Api.SearchPostsFlood?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.SearchPostsFlood
} }
var _6: [Api.Message]?
if let _ = reader.readInt32() {
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
}
var _6: [Api.Chat]?
var _7: [Api.Chat]?
if let _ = reader.readInt32() {
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
}
var _7: [Api.User]?
var _8: [Api.User]?
if let _ = reader.readInt32() {
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
_8 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
}
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
let _c5 = _5 != nil
let _c5 = (Int(_1!) & Int(1 << 3) == 0) || _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.messages.Messages.messagesSlice(flags: _1!, count: _2!, nextRate: _3, offsetIdOffset: _4, messages: _5!, chats: _6!, users: _7!)
let _c8 = _8 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 {
return Api.messages.Messages.messagesSlice(flags: _1!, count: _2!, nextRate: _3, offsetIdOffset: _4, searchFlood: _5, messages: _6!, chats: _7!, users: _8!)
}
else {
return nil

View File

@ -2756,6 +2756,21 @@ public extension Api.functions.bots {
})
}
}
public extension Api.functions.channels {
static func checkSearchPostsFlood() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.SearchPostsFlood>) {
let buffer = Buffer()
buffer.appendInt32(-1146490591)
return (FunctionDescription(name: "channels.checkSearchPostsFlood", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.SearchPostsFlood? in
let reader = BufferReader(buffer)
var result: Api.SearchPostsFlood?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.SearchPostsFlood
}
return result
})
}
}
public extension Api.functions.channels {
static func checkUsername(channel: Api.InputChannel, username: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()

View File

@ -37,7 +37,7 @@ public func loadedPeerFromMessage(account: Account, peerId: PeerId, messageId: M
switch result {
case let .messages(_, _, users):
apiUsers = users
case let .messagesSlice(_, _, _, _, _, _, users):
case let .messagesSlice(_, _, _, _, _, _, _, users):
apiUsers = users
case let .channelMessages(_, _, _, _, _, _, _, users):
apiUsers = users

View File

@ -2683,7 +2683,7 @@ private func resolveAssociatedMessages(accountPeerId: PeerId, postbox: Postbox,
switch result {
case let .messages(messages, chats, users):
return (messages, chats, users)
case let .messagesSlice(_, _, _, _, messages, chats, users):
case let .messagesSlice(_, _, _, _, _, messages, chats, users):
return (messages, chats, users)
case let .channelMessages(_, _, _, _, messages, apiTopics, chats, users):
let _ = apiTopics
@ -2714,7 +2714,7 @@ private func resolveAssociatedMessages(accountPeerId: PeerId, postbox: Postbox,
switch result {
case let .messages(messages, chats, users):
return (messages, chats, users)
case let .messagesSlice(_, _, _, _, messages, chats, users):
case let .messagesSlice(_, _, _, _, _, messages, chats, users):
return (messages, chats, users)
case let .channelMessages(_, _, _, _, messages, apiTopics, chats, users):
let _ = apiTopics

View File

@ -104,7 +104,7 @@ private func fetchWebpage(account: Account, messageId: MessageId, threadId: Int6
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
case let .messagesSlice(_, _, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -1087,7 +1087,7 @@ public final class AccountViewTracker {
switch result {
case let .messages(messages, chats, users):
return (peer, messages, chats, users)
case let .messagesSlice(_, _, _, _, messages, chats, users):
case let .messagesSlice(_, _, _, _, _, messages, chats, users):
return (peer, messages, chats, users)
case let .channelMessages(_, _, _, _, messages, _, chats, users):
return (peer, messages, chats, users)

View File

@ -562,7 +562,7 @@ private func validateChannelMessagesBatch(postbox: Postbox, network: Network, ac
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
case let .messagesSlice(_, _, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -631,7 +631,7 @@ private func validateReplyThreadMessagesBatch(postbox: Postbox, network: Network
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
case let .messagesSlice(_, _, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -673,7 +673,7 @@ private func validateScheduledMessagesBatch(postbox: Postbox, network: Network,
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
case let .messagesSlice(_, _, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -719,7 +719,7 @@ private func validateQuickReplyMessagesBatch(postbox: Postbox, network: Network,
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
case let .messagesSlice(_, _, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -803,7 +803,7 @@ private func validateBatch(postbox: Postbox, network: Network, transaction: Tran
let _ = apiTopics
case let .messages(messages, _, _):
apiMessages = messages
case let .messagesSlice(_, _, _, _, messages, _, _):
case let .messagesSlice(_, _, _, _, _, messages, _, _):
apiMessages = messages
case .messagesNotModified:
return Set()
@ -1052,7 +1052,7 @@ private func validateReplyThreadBatch(postbox: Postbox, network: Network, transa
let _ = apiTopics
case let .messages(messages, _, _):
apiMessages = messages
case let .messagesSlice(_, _, _, _, messages, _, _):
case let .messagesSlice(_, _, _, _, _, messages, _, _):
apiMessages = messages
case .messagesNotModified:
return Set()

View File

@ -256,7 +256,7 @@ func withResolvedAssociatedMessages<T>(postbox: Postbox, source: FetchMessageHis
switch result {
case let .messages(messages, chats, users):
return (peer, messages, chats, users)
case let .messagesSlice(_, _, _, _, messages, chats, users):
case let .messagesSlice(_, _, _, _, _, messages, chats, users):
return (peer, messages, chats, users)
case let .channelMessages(_, _, _, _, messages, apiTopics, chats, users):
let _ = apiTopics
@ -287,7 +287,7 @@ func withResolvedAssociatedMessages<T>(postbox: Postbox, source: FetchMessageHis
switch result {
case let .messages(messages, chats, users):
return (peer, messages, chats, users)
case let .messagesSlice(_, _, _, _, messages, chats, users):
case let .messagesSlice(_, _, _, _, _, messages, chats, users):
return (peer, messages, chats, users)
case let .channelMessages(_, _, _, _, messages, apiTopics, chats, users):
let _ = apiTopics
@ -923,7 +923,7 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
case let .messagesSlice(_, _, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -1221,7 +1221,7 @@ func fetchCallListHole(network: Network, postbox: Postbox, accountPeerId: PeerId
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
case let .messagesSlice(_, _, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers

View File

@ -583,7 +583,7 @@ private func synchronizeMessageHistoryTagSummary(accountPeerId: PeerId, postbox:
case let .messagesNotModified(count):
apiMessages = []
apiCount = count
case let .messagesSlice(_, count, _, _, messages, _, _):
case let .messagesSlice(_, count, _, _, _, messages, _, _):
apiMessages = messages
apiCount = count
}

View File

@ -132,7 +132,7 @@ private func synchronizeMarkAllUnseen(transaction: Transaction, postbox: Postbox
return .single(messages.compactMap({ $0.id() }))
case .messagesNotModified:
return .single([])
case let .messagesSlice(_, _, _, _, messages, _, _):
case let .messagesSlice(_, _, _, _, _, messages, _, _):
return .single(messages.compactMap({ $0.id() }))
}
}

View File

@ -51,7 +51,7 @@ private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId
apiMessages = messages
case let .messages(messages, _, _):
apiMessages = messages
case let .messagesSlice(_, _, _, _, messages, _, _):
case let .messagesSlice(_, _, _, _, _, messages, _, _):
apiMessages = messages
case .messagesNotModified:
apiMessages = []

View File

@ -72,7 +72,7 @@ func _internal_getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Po
switch result {
case let .messages(messages, chats, users):
return (peer, messages, chats, users)
case let .messagesSlice(_, _, _, _, messages, chats, users):
case let .messagesSlice(_, _, _, _, _, messages, chats, users):
return (peer, messages, chats, users)
case let .channelMessages(_, _, _, _, messages, apiTopics, chats, users):
let _ = apiTopics

View File

@ -101,7 +101,7 @@ private func mergedState(transaction: Transaction, seedConfiguration: SeedConfig
users = apiUsers
totalCount = Int32(messages.count)
nextRate = nil
case let .messagesSlice(_, count, apiNextRate, _, apiMessages, apiChats, apiUsers):
case let .messagesSlice(_, count, apiNextRate, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -288,7 +288,7 @@ func _internal_getSearchMessageCount(account: Account, location: SearchMessagesL
return messages.count
case let .messagesNotModified(count):
return Int(count)
case let .messagesSlice(_, count, _, _, _, _, _):
case let .messagesSlice(_, count, _, _, _, _, _, _):
return Int(count)
}
}
@ -682,7 +682,7 @@ func _internal_downloadMessage(accountPeerId: PeerId, postbox: Postbox, network:
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, apiMessages, apiChats, apiUsers):
case let .messagesSlice(_, _, _, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -773,7 +773,7 @@ func fetchRemoteMessage(accountPeerId: PeerId, postbox: Postbox, source: FetchMe
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, apiMessages, apiChats, apiUsers):
case let .messagesSlice(_, _, _, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers
@ -839,7 +839,7 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
messages = apiMessages
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
messages = apiMessages
case let .messagesSlice(_, _, _, _, apiMessages, _, _):
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _):
messages = apiMessages
case .messagesNotModified:
messages = []
@ -876,7 +876,7 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
messages = apiMessages
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
messages = apiMessages
case let .messagesSlice(_, _, _, _, apiMessages, _, _):
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _):
messages = apiMessages
case .messagesNotModified:
messages = []
@ -909,7 +909,7 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
messages = apiMessages
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
messages = apiMessages
case let .messagesSlice(_, _, _, _, apiMessages, _, _):
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _):
messages = apiMessages
case .messagesNotModified:
messages = []
@ -933,7 +933,7 @@ func _internal_searchMessageIdByTimestamp(account: Account, peerId: PeerId, thre
messages = apiMessages
case let .channelMessages(_, _, _, _, apiMessages, _, _, _):
messages = apiMessages
case let .messagesSlice(_, _, _, _, apiMessages, _, _):
case let .messagesSlice(_, _, _, _, _, apiMessages, _, _):
messages = apiMessages
case .messagesNotModified:
messages = []

View File

@ -514,7 +514,7 @@ public extension TelegramEngine {
signals.append(self.account.network.request(Api.functions.messages.search(flags: flags, peer: inputPeer, q: "", fromId: nil, savedPeerId: inputSavedPeer, savedReaction: nil, topMsgId: topMsgId, filter: filter, minDate: 0, maxDate: 0, offsetId: 0, addOffset: 0, limit: 1, maxId: 0, minId: 0, hash: 0))
|> map { result -> (count: Int32?, topId: Int32?) in
switch result {
case let .messagesSlice(_, count, _, _, messages, _, _):
case let .messagesSlice(_, count, _, _, _, messages, _, _):
return (count, messages.first?.id(namespace: Namespaces.Message.Cloud)?.id)
case let .channelMessages(_, _, count, _, messages, _, _, _):
return (count, messages.first?.id(namespace: Namespaces.Message.Cloud)?.id)

View File

@ -973,7 +973,7 @@ public enum TransferStarGiftError {
public enum BuyStarGiftError {
case generic
case priceChanged(Int64)
case priceChanged(CurrencyAmount)
case starGiftResellTooEarly(Int32)
}
@ -999,7 +999,13 @@ func _internal_buyStarGift(account: Account, slug: String, peerId: EnginePeer.Id
|> mapToSignal { paymentForm in
if let paymentForm {
if let paymentPrice = paymentForm.invoice.prices.first?.amount, let price, paymentPrice > price.amount.value {
return .fail(.priceChanged(paymentPrice))
let currencyAmount: CurrencyAmount
if paymentForm.invoice.currency == "TON" {
currencyAmount = CurrencyAmount(amount: StarsAmount(value: paymentPrice, nanos: 0), currency: .ton)
} else {
currencyAmount = CurrencyAmount(amount: StarsAmount(value: paymentPrice, nanos: 0), currency: .stars)
}
return .fail(.priceChanged(currencyAmount))
}
return _internal_sendStarsPaymentForm(account: account, formId: paymentForm.id, source: source)
|> mapError { _ -> BuyStarGiftError in

View File

@ -87,7 +87,7 @@ func _internal_requestPeerPhotos(accountPeerId: PeerId, postbox: Postbox, networ
messages = apiMessages
chats = apiChats
users = apiUsers
case let .messagesSlice(_, _, _, _, apiMessages, apiChats, apiUsers):
case let .messagesSlice(_, _, _, _, _, apiMessages, apiChats, apiUsers):
messages = apiMessages
chats = apiChats
users = apiUsers

View File

@ -1209,8 +1209,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
case .stars:
starsString = strings.Notification_StarsGift_Bought_Stars(Int32(resaleStars.amount.value))
case .ton:
//TODO:localize
starsString = "\(Int32(resaleStars.amount.value)) TON"
starsString = formatTonAmountText(resaleStars.amount.value, dateTimeFormat: dateTimeFormat) + " TON"
}
if message.id.peerId == accountPeerId {
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_BoughtForYouself(starsString)._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
@ -1249,7 +1248,6 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
case .stars:
starsString = strings.Notification_StarsGift_Bought_Stars(Int32(resaleStars.amount.value))
case .ton:
//TODO:localize
starsString = formatTonAmountText(resaleStars.amount.value, dateTimeFormat: dateTimeFormat) + " TON"
}
let giftTitle = "\(gift.title) #\(presentationStringsFormattedNumber(gift.number, dateTimeFormat.groupingSeparator))"

View File

@ -233,7 +233,6 @@ final class GiftStoreScreenComponent: Component {
color: ribbonColor
)
//TODO:release
let subject: GiftItemComponent.Subject = .uniqueGift(gift: uniqueGift, price: "# \(presentationStringsFormattedNumber(Int32(uniqueGift.resellAmounts?.first(where: { $0.currency == .stars })?.amount.value ?? 0), environment.dateTimeFormat.groupingSeparator))")
let _ = visibleItem.update(
transition: itemTransition,

View File

@ -28,7 +28,7 @@ private final class GiftPurchaseAlertContentNode: AlertContentNode {
private let gift: StarGift.UniqueGift
private let peer: EnginePeer
private var currency: CurrencyAmount.Currency
fileprivate var currency: CurrencyAmount.Currency
fileprivate let header = ComponentView<Empty>()
private let title = ComponentView<Empty>()
@ -154,8 +154,8 @@ private final class GiftPurchaseAlertContentNode: AlertContentNode {
case .ton:
if let resellAmount = self.gift.resellAmounts?.first(where: { $0.currency == .ton }) {
resellPrice = resellAmount
let valueString = formatTonAmountText(resellAmount.amount.value, dateTimeFormat: presentationData.dateTimeFormat) + " TON"
actionNode.action = TextAlertAction(type: .defaultAction, title: "Buy for \(valueString)", action: actionNode.action.action)
let valueString = formatTonAmountText(resellAmount.amount.value, dateTimeFormat: presentationData.dateTimeFormat)
actionNode.action = TextAlertAction(type: .defaultAction, title: self.strings.Gift_Buy_Confirm_BuyForTon(valueString).string, action: actionNode.action.action)
}
}
}
@ -446,17 +446,16 @@ public func giftPurchaseAlertController(
gift: StarGift.UniqueGift,
peer: EnginePeer,
navigationController: NavigationController?,
commit: @escaping () -> Void
commit: @escaping (CurrencyAmount.Currency) -> Void
) -> AlertController {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let strings = presentationData.strings
var contentNode: GiftPurchaseAlertContentNode?
var dismissImpl: ((Bool) -> Void)?
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: "", action: { [weak contentNode] in
contentNode?.inProgress = true
dismissImpl?(true)
commit()
var commitImpl: (() -> Void)?
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: "", action: {
commitImpl?()
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
dismissImpl?(true)
})]
@ -472,6 +471,11 @@ public func giftPurchaseAlertController(
controller?.dismiss()
}
}
commitImpl = { [weak contentNode] in
contentNode?.inProgress = true
commit(contentNode?.currency ?? .stars)
}
contentNode?.updatedCurrency = { [weak controller] currency in
controller?.currency = currency
}

View File

@ -1176,7 +1176,7 @@ private final class GiftViewSheetContent: CombinedComponent {
}
func commitBuy(acceptedPrice: CurrencyAmount? = nil, skipConfirmation: Bool = false) {
guard let resellAmount = self.subject.arguments?.resellAmounts?.first, let starsContext = self.context.starsContext, let starsState = starsContext.currentState, case let .unique(uniqueGift) = self.subject.arguments?.gift else {
guard case let .unique(uniqueGift) = self.subject.arguments?.gift else {
return
}
@ -1204,7 +1204,16 @@ private final class GiftViewSheetContent: CombinedComponent {
let giftTitle = "\(uniqueGift.title) #\(uniqueGift.number)"
let recipientPeerId = self.recipientPeerId ?? self.context.account.peerId
let action = {
let action: (CurrencyAmount.Currency) -> Void = { currency in
guard let resellAmount = uniqueGift.resellAmounts?.first(where: { $0.currency == currency }) else {
guard let controller = self.getController() as? GiftViewScreen else {
return
}
let alertController = textAlertController(context: context, title: nil, text: presentationData.strings.Gift_Buy_ErrorUnknown, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true)
controller.present(alertController, in: .window(.root))
return
}
let proceed: () -> Void = {
guard let controller = self.getController() as? GiftViewScreen else {
return
@ -1242,10 +1251,26 @@ private final class GiftViewSheetContent: CombinedComponent {
switch error {
case let .priceChanged(newPrice):
//TODO:release
let errorTitle = presentationData.strings.Gift_Buy_ErrorPriceChanged_Title
let originalPriceString = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text_Stars(Int32(resellAmount.amount.value))
let newPriceString = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text_Stars(Int32(newPrice))
let originalPriceString: String
switch resellAmount.currency {
case .stars:
originalPriceString = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text_Stars(Int32(resellAmount.amount.value))
case .ton:
originalPriceString = formatTonAmountText(resellAmount.amount.value, dateTimeFormat: presentationData.dateTimeFormat) + " TON"
}
let newPriceString: String
let buttonText: String
switch newPrice.currency {
case .stars:
newPriceString = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text_Stars(Int32(newPrice.amount.value))
buttonText = presentationData.strings.Gift_Buy_Confirm_BuyFor(Int32(newPrice.amount.value))
case .ton:
let tonValueString = formatTonAmountText(newPrice.amount.value, dateTimeFormat: presentationData.dateTimeFormat)
newPriceString = tonValueString + " TON"
buttonText = presentationData.strings.Gift_Buy_Confirm_BuyForTon(tonValueString).string
}
let errorText = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text(originalPriceString, newPriceString).string
let alertController = textAlertController(
@ -1253,12 +1278,11 @@ private final class GiftViewSheetContent: CombinedComponent {
title: errorTitle,
text: errorText,
actions: [
TextAlertAction(type: .defaultAction, title: presentationData.strings.Gift_Buy_Confirm_BuyFor(Int32(newPrice)), action: { [weak self] in
TextAlertAction(type: .defaultAction, title: buttonText, action: { [weak self] in
guard let self else {
return
}
//TODO:release
self.commitBuy(acceptedPrice: CurrencyAmount(amount: StarsAmount(value: newPrice, nanos: 0), currency: .ton), skipConfirmation: true)
self.commitBuy(acceptedPrice: newPrice, skipConfirmation: true)
}),
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
})
@ -1274,54 +1298,31 @@ private final class GiftViewSheetContent: CombinedComponent {
controller.present(alertController, in: .window(.root))
}
},
completed: { [weak self, weak starsContext] in
guard let self,
let controller = self.getController() as? GiftViewScreen else {
return
}
self.inProgress = false
var animationFile: TelegramMediaFile?
for attribute in uniqueGift.attributes {
if case let .model(_, file, _) = attribute {
animationFile = file
break
completed: { [weak self] in
guard let self, let controller = self.getController() as? GiftViewScreen else {
return
}
}
if let navigationController = controller.navigationController as? NavigationController {
if recipientPeerId == self.context.account.peerId {
controller.dismissAnimated()
navigationController.view.addSubview(ConfettiView(frame: navigationController.view.bounds))
Queue.mainQueue().after(0.5, {
if let lastController = navigationController.viewControllers.last as? ViewController, let animationFile {
let resultController = UndoOverlayController(
presentationData: presentationData,
content: .sticker(context: context, file: animationFile, loop: false, title: presentationData.strings.Gift_View_Resale_SuccessYou_Title, text: presentationData.strings.Gift_View_Resale_SuccessYou_Text(giftTitle).string, undoText: nil, customAction: nil),
elevatedLayout: lastController is ChatController,
action: { _ in
return true
}
)
lastController.present(resultController, in: .window(.root))
}
})
} else {
var controllers = Array(navigationController.viewControllers.prefix(1))
let chatController = self.context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: recipientPeerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
chatController.hintPlayNextOutgoingGift()
controllers.append(chatController)
navigationController.setViewControllers(controllers, animated: true)
Queue.mainQueue().after(0.5, {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: recipientPeerId))
|> deliverOnMainQueue).start(next: { [weak navigationController] peer in
if let peer, let lastController = navigationController?.viewControllers.last as? ViewController, let animationFile {
self.inProgress = false
var animationFile: TelegramMediaFile?
for attribute in uniqueGift.attributes {
if case let .model(_, file, _) = attribute {
animationFile = file
break
}
}
if let navigationController = controller.navigationController as? NavigationController {
if recipientPeerId == self.context.account.peerId {
controller.dismissAnimated()
navigationController.view.addSubview(ConfettiView(frame: navigationController.view.bounds))
Queue.mainQueue().after(0.5, {
if let lastController = navigationController.viewControllers.last as? ViewController, let animationFile {
let resultController = UndoOverlayController(
presentationData: presentationData,
content: .sticker(context: context, file: animationFile, loop: false, title: presentationData.strings.Gift_View_Resale_Success_Title, text: presentationData.strings.Gift_View_Resale_Success_Text(peer.compactDisplayTitle).string, undoText: nil, customAction: nil),
content: .sticker(context: context, file: animationFile, loop: false, title: presentationData.strings.Gift_View_Resale_SuccessYou_Title, text: presentationData.strings.Gift_View_Resale_SuccessYou_Text(giftTitle).string, undoText: nil, customAction: nil),
elevatedLayout: lastController is ChatController,
action: { _ in
return true
@ -1330,20 +1331,43 @@ private final class GiftViewSheetContent: CombinedComponent {
lastController.present(resultController, in: .window(.root))
}
})
})
} else {
var controllers = Array(navigationController.viewControllers.prefix(1))
let chatController = self.context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: recipientPeerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
chatController.hintPlayNextOutgoingGift()
controllers.append(chatController)
navigationController.setViewControllers(controllers, animated: true)
Queue.mainQueue().after(0.5, {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: recipientPeerId))
|> deliverOnMainQueue).start(next: { [weak navigationController] peer in
if let peer, let lastController = navigationController?.viewControllers.last as? ViewController, let animationFile {
let resultController = UndoOverlayController(
presentationData: presentationData,
content: .sticker(context: context, file: animationFile, loop: false, title: presentationData.strings.Gift_View_Resale_Success_Title, text: presentationData.strings.Gift_View_Resale_Success_Text(peer.compactDisplayTitle).string, undoText: nil, customAction: nil),
elevatedLayout: lastController is ChatController,
action: { _ in
return true
}
)
lastController.present(resultController, in: .window(.root))
}
})
})
}
}
self.updated(transition: .spring(duration: 0.4))
Queue.mainQueue().after(0.5) {
context.starsContext?.load(force: true)
}
}
self.updated(transition: .spring(duration: 0.4))
Queue.mainQueue().after(0.5) {
starsContext?.load(force: true)
}
})
)
}
if let buyForm = self.buyForm, let price = buyForm.invoice.prices.first?.amount {
if buyForm.invoice.currency == "XTR", starsState.balance < StarsAmount(value: price, nanos: 0) {
if buyForm.invoice.currency == "XTR", let starsContext = context.starsContext, let starsState = context.starsContext?.currentState, starsState.balance < StarsAmount(value: price, nanos: 0) {
if self.options.isEmpty {
self.inProgress = true
self.updated()
@ -1355,8 +1379,8 @@ private final class GiftViewSheetContent: CombinedComponent {
guard let self, let controller = self.getController() else {
return
}
let purchaseController = self.context.sharedContext.makeStarsPurchaseScreen(
context: self.context,
let purchaseController = context.sharedContext.makeStarsPurchaseScreen(
context: context,
starsContext: starsContext,
options: options ?? [],
purpose: .buyStarGift(requiredStars: price),
@ -1391,7 +1415,7 @@ private final class GiftViewSheetContent: CombinedComponent {
)
controller.push(purchaseController)
})
} else if buyForm.invoice.currency == "TON", let tonState = self.context.tonContext?.currentState, tonState.balance < StarsAmount(value: price, nanos: 0) {
} else if buyForm.invoice.currency == "TON", let tonState = context.tonContext?.currentState, tonState.balance < StarsAmount(value: price, nanos: 0) {
guard let controller = self.getController() else {
return
}
@ -1423,7 +1447,7 @@ private final class GiftViewSheetContent: CombinedComponent {
}
if skipConfirmation {
action()
action(acceptedPrice?.currency ?? .stars)
} else {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: recipientPeerId))
|> deliverOnMainQueue).start(next: { [weak self] peer in
@ -1436,8 +1460,8 @@ private final class GiftViewSheetContent: CombinedComponent {
gift: uniqueGift,
peer: peer,
navigationController: controller.navigationController as? NavigationController,
commit: {
action()
commit: { currency in
action(currency)
}
)
controller.present(alertController, in: .window(.root))

View File

@ -533,7 +533,6 @@ final class GiftsListView: UIView {
itemAlpha = 0.3
}
//TODO:release
let _ = visibleItem.update(
transition: itemTransition,
component: AnyComponent(