diff --git a/submodules/PremiumUI/Resources/star.scn b/submodules/PremiumUI/Resources/star2.scn similarity index 50% rename from submodules/PremiumUI/Resources/star.scn rename to submodules/PremiumUI/Resources/star2.scn index c336915b82..e013831e9f 100644 Binary files a/submodules/PremiumUI/Resources/star.scn and b/submodules/PremiumUI/Resources/star2.scn differ diff --git a/submodules/PremiumUI/Sources/CreateGiveawayHeaderItem.swift b/submodules/PremiumUI/Sources/CreateGiveawayHeaderItem.swift index 25a3269efc..8585e0f23b 100644 --- a/submodules/PremiumUI/Sources/CreateGiveawayHeaderItem.swift +++ b/submodules/PremiumUI/Sources/CreateGiveawayHeaderItem.swift @@ -196,7 +196,16 @@ class CreateGiveawayHeaderItemNode: ItemListControllerHeaderItemNode { self.backgroundNode.update(size: CGSize(width: layout.size.width, height: navigationBarHeight), transition: transition) - let component = AnyComponent(PremiumStarComponent(isIntro: true, isVisible: true, hasIdleAnimations: true)) + let component = AnyComponent(PremiumStarComponent( + isIntro: true, + isVisible: true, + hasIdleAnimations: true, + colors: [ + UIColor(rgb: 0x6a94ff), + UIColor(rgb: 0x9472fd), + UIColor(rgb: 0xe26bd3) + ] + )) let containerSize = CGSize(width: min(414.0, layout.size.width), height: 220.0) if let hostView = self.hostView { diff --git a/submodules/PremiumUI/Sources/PremiumGiftCodeScreen.swift b/submodules/PremiumUI/Sources/PremiumGiftCodeScreen.swift index fa58f2b3f5..fb48f4a8c9 100644 --- a/submodules/PremiumUI/Sources/PremiumGiftCodeScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumGiftCodeScreen.swift @@ -266,7 +266,16 @@ private final class PremiumGiftCodeSheetContent: CombinedComponent { ) let star = star.update( - component: PremiumStarComponent(isIntro: false, isVisible: true, hasIdleAnimations: true), + component: PremiumStarComponent( + isIntro: false, + isVisible: true, + hasIdleAnimations: true, + colors: [ + UIColor(rgb: 0x6a94ff), + UIColor(rgb: 0x9472fd), + UIColor(rgb: 0xe26bd3) + ] + ), availableSize: CGSize(width: context.availableSize.width, height: 200.0), transition: .immediate ) diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 43b2b98045..643acb0adf 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -3212,7 +3212,12 @@ private final class PremiumIntroScreenComponent: CombinedComponent { component: PremiumStarComponent( isIntro: isIntro, isVisible: starIsVisible, - hasIdleAnimations: state.hasIdleAnimations + hasIdleAnimations: state.hasIdleAnimations, + colors: [ + UIColor(rgb: 0x6a94ff), + UIColor(rgb: 0x9472fd), + UIColor(rgb: 0xe26bd3) + ] ), availableSize: CGSize(width: min(414.0, context.availableSize.width), height: 220.0), transition: context.transition diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index d357139077..4c238de4fd 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -870,7 +870,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1108478618] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) } dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) } dict[198776256] = { return Api.StarsTopupOption.parse_starsTopupOption($0) } - dict[1600878860] = { return Api.StarsTransaction.parse_starsTransaction($0) } + dict[-865044046] = { return Api.StarsTransaction.parse_starsTransaction($0) } dict[-670195363] = { return Api.StarsTransactionPeer.parse_starsTransactionPeer($0) } dict[-1269320843] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerAppStore($0) } dict[-382740222] = { return Api.StarsTransactionPeer.parse_starsTransactionPeerFragment($0) } @@ -1302,6 +1302,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1610250415] = { return Api.payments.PaymentForm.parse_paymentForm($0) } dict[2079764828] = { return Api.payments.PaymentForm.parse_paymentFormStars($0) } dict[1891958275] = { return Api.payments.PaymentReceipt.parse_paymentReceipt($0) } + dict[-319617530] = { return Api.payments.PaymentReceipt.parse_paymentReceiptStars($0) } dict[1314881805] = { return Api.payments.PaymentResult.parse_paymentResult($0) } dict[-666824391] = { return Api.payments.PaymentResult.parse_paymentVerificationNeeded($0) } dict[-74456004] = { return Api.payments.SavedInfo.parse_savedInfo($0) } @@ -1379,7 +1380,7 @@ public extension Api { return parser(reader) } else { - telegramApiLog("Type constructor \(String(UInt32(bitPattern: signature), radix: 16, uppercase: false)) not found") + telegramApiLog("Type constructor \(String(signature, radix: 16, uppercase: false)) not found") return nil } } diff --git a/submodules/TelegramApi/Sources/Api23.swift b/submodules/TelegramApi/Sources/Api23.swift index a5b2dfc96c..733ac161c8 100644 --- a/submodules/TelegramApi/Sources/Api23.swift +++ b/submodules/TelegramApi/Sources/Api23.swift @@ -656,46 +656,64 @@ public extension Api { } public extension Api { enum StarsTransaction: TypeConstructorDescription { - case starsTransaction(id: String, stars: Int64, date: Int32, peer: Api.StarsTransactionPeer) + case starsTransaction(flags: Int32, id: String, stars: Int64, date: Int32, peer: Api.StarsTransactionPeer, title: String?, description: String?, photo: Api.WebDocument?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .starsTransaction(let id, let stars, let date, let peer): + case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo): if boxed { - buffer.appendInt32(1600878860) + buffer.appendInt32(-865044046) } + serializeInt32(flags, buffer: buffer, boxed: false) serializeString(id, buffer: buffer, boxed: false) serializeInt64(stars, buffer: buffer, boxed: false) serializeInt32(date, buffer: buffer, boxed: false) peer.serialize(buffer, true) + if Int(flags) & Int(1 << 0) != 0 {serializeString(title!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 1) != 0 {serializeString(description!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 2) != 0 {photo!.serialize(buffer, true)} break } } public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .starsTransaction(let id, let stars, let date, let peer): - return ("starsTransaction", [("id", id as Any), ("stars", stars as Any), ("date", date as Any), ("peer", peer as Any)]) + case .starsTransaction(let flags, let id, let stars, let date, let peer, let title, let description, let photo): + return ("starsTransaction", [("flags", flags as Any), ("id", id as Any), ("stars", stars as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any)]) } } public static func parse_starsTransaction(_ reader: BufferReader) -> StarsTransaction? { - var _1: String? - _1 = parseString(reader) - var _2: Int64? - _2 = reader.readInt64() - var _3: Int32? - _3 = reader.readInt32() - var _4: Api.StarsTransactionPeer? + var _1: Int32? + _1 = reader.readInt32() + var _2: String? + _2 = parseString(reader) + var _3: Int64? + _3 = reader.readInt64() + var _4: Int32? + _4 = reader.readInt32() + var _5: Api.StarsTransactionPeer? if let signature = reader.readInt32() { - _4 = Api.parse(reader, signature: signature) as? Api.StarsTransactionPeer + _5 = Api.parse(reader, signature: signature) as? Api.StarsTransactionPeer } + var _6: String? + if Int(_1!) & Int(1 << 0) != 0 {_6 = parseString(reader) } + var _7: String? + if Int(_1!) & Int(1 << 1) != 0 {_7 = parseString(reader) } + var _8: Api.WebDocument? + if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() { + _8 = Api.parse(reader, signature: signature) as? Api.WebDocument + } } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil let _c4 = _4 != nil - if _c1 && _c2 && _c3 && _c4 { - return Api.StarsTransaction.starsTransaction(id: _1!, stars: _2!, date: _3!, peer: _4!) + let _c5 = _5 != nil + let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil + let _c7 = (Int(_1!) & Int(1 << 1) == 0) || _7 != nil + let _c8 = (Int(_1!) & Int(1 << 2) == 0) || _8 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 { + return Api.StarsTransaction.starsTransaction(flags: _1!, id: _2!, stars: _3!, date: _4!, peer: _5!, title: _6, description: _7, photo: _8) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api33.swift b/submodules/TelegramApi/Sources/Api33.swift index d394381236..5c79cc9116 100644 --- a/submodules/TelegramApi/Sources/Api33.swift +++ b/submodules/TelegramApi/Sources/Api33.swift @@ -771,6 +771,7 @@ public extension Api.payments { public extension Api.payments { enum PaymentReceipt: TypeConstructorDescription { case paymentReceipt(flags: Int32, date: Int32, botId: Int64, providerId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, info: Api.PaymentRequestedInfo?, shipping: Api.ShippingOption?, tipAmount: Int64?, currency: String, totalAmount: Int64, credentialsTitle: String, users: [Api.User]) + case paymentReceiptStars(flags: Int32, date: Int32, botId: Int64, title: String, description: String, photo: Api.WebDocument?, invoice: Api.Invoice, currency: String, totalAmount: Int64, users: [Api.User]) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -798,6 +799,25 @@ public extension Api.payments { item.serialize(buffer, true) } break + case .paymentReceiptStars(let flags, let date, let botId, let title, let description, let photo, let invoice, let currency, let totalAmount, let users): + if boxed { + buffer.appendInt32(-319617530) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt32(date, buffer: buffer, boxed: false) + serializeInt64(botId, buffer: buffer, boxed: false) + serializeString(title, buffer: buffer, boxed: false) + serializeString(description, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 2) != 0 {photo!.serialize(buffer, true)} + invoice.serialize(buffer, true) + serializeString(currency, buffer: buffer, boxed: false) + serializeInt64(totalAmount, buffer: buffer, boxed: false) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(users.count)) + for item in users { + item.serialize(buffer, true) + } + break } } @@ -805,6 +825,8 @@ public extension Api.payments { switch self { case .paymentReceipt(let flags, let date, let botId, let providerId, let title, let description, let photo, let invoice, let info, let shipping, let tipAmount, let currency, let totalAmount, let credentialsTitle, let users): return ("paymentReceipt", [("flags", flags as Any), ("date", date as Any), ("botId", botId as Any), ("providerId", providerId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("info", info as Any), ("shipping", shipping as Any), ("tipAmount", tipAmount as Any), ("currency", currency as Any), ("totalAmount", totalAmount as Any), ("credentialsTitle", credentialsTitle as Any), ("users", users as Any)]) + case .paymentReceiptStars(let flags, let date, let botId, let title, let description, let photo, let invoice, let currency, let totalAmount, let users): + return ("paymentReceiptStars", [("flags", flags as Any), ("date", date as Any), ("botId", botId as Any), ("title", title as Any), ("description", description as Any), ("photo", photo as Any), ("invoice", invoice as Any), ("currency", currency as Any), ("totalAmount", totalAmount as Any), ("users", users as Any)]) } } @@ -871,6 +893,50 @@ public extension Api.payments { return nil } } + public static func parse_paymentReceiptStars(_ reader: BufferReader) -> PaymentReceipt? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: Int64? + _3 = reader.readInt64() + var _4: String? + _4 = parseString(reader) + var _5: String? + _5 = parseString(reader) + var _6: Api.WebDocument? + if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() { + _6 = Api.parse(reader, signature: signature) as? Api.WebDocument + } } + var _7: Api.Invoice? + if let signature = reader.readInt32() { + _7 = Api.parse(reader, signature: signature) as? Api.Invoice + } + var _8: String? + _8 = parseString(reader) + var _9: Int64? + _9 = reader.readInt64() + var _10: [Api.User]? + if let _ = reader.readInt32() { + _10 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = _4 != nil + let _c5 = _5 != nil + let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil + let _c7 = _7 != nil + let _c8 = _8 != nil + let _c9 = _9 != nil + let _c10 = _10 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 { + return Api.payments.PaymentReceipt.paymentReceiptStars(flags: _1!, date: _2!, botId: _3!, title: _4!, description: _5!, photo: _6, invoice: _7!, currency: _8!, totalAmount: _9!, users: _10!) + } + else { + return nil + } + } } } @@ -1612,67 +1678,3 @@ public extension Api.photos { } } -public extension Api.premium { - enum BoostsList: TypeConstructorDescription { - case boostsList(flags: Int32, count: Int32, boosts: [Api.Boost], nextOffset: String?, users: [Api.User]) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .boostsList(let flags, let count, let boosts, let nextOffset, let users): - if boxed { - buffer.appendInt32(-2030542532) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeInt32(count, buffer: buffer, boxed: false) - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(boosts.count)) - for item in boosts { - item.serialize(buffer, true) - } - if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)} - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(users.count)) - for item in users { - item.serialize(buffer, true) - } - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .boostsList(let flags, let count, let boosts, let nextOffset, let users): - return ("boostsList", [("flags", flags as Any), ("count", count as Any), ("boosts", boosts as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)]) - } - } - - public static func parse_boostsList(_ reader: BufferReader) -> BoostsList? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int32? - _2 = reader.readInt32() - var _3: [Api.Boost]? - if let _ = reader.readInt32() { - _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Boost.self) - } - var _4: String? - if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) } - var _5: [Api.User]? - if let _ = reader.readInt32() { - _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) - } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil - let _c5 = _5 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 { - return Api.premium.BoostsList.boostsList(flags: _1!, count: _2!, boosts: _3!, nextOffset: _4, users: _5!) - } - else { - return nil - } - } - - } -} diff --git a/submodules/TelegramApi/Sources/Api34.swift b/submodules/TelegramApi/Sources/Api34.swift index e179398299..8952189c1c 100644 --- a/submodules/TelegramApi/Sources/Api34.swift +++ b/submodules/TelegramApi/Sources/Api34.swift @@ -1,3 +1,67 @@ +public extension Api.premium { + enum BoostsList: TypeConstructorDescription { + case boostsList(flags: Int32, count: Int32, boosts: [Api.Boost], nextOffset: String?, users: [Api.User]) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .boostsList(let flags, let count, let boosts, let nextOffset, let users): + if boxed { + buffer.appendInt32(-2030542532) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt32(count, buffer: buffer, boxed: false) + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(boosts.count)) + for item in boosts { + item.serialize(buffer, true) + } + if Int(flags) & Int(1 << 0) != 0 {serializeString(nextOffset!, buffer: buffer, boxed: false)} + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(users.count)) + for item in users { + item.serialize(buffer, true) + } + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .boostsList(let flags, let count, let boosts, let nextOffset, let users): + return ("boostsList", [("flags", flags as Any), ("count", count as Any), ("boosts", boosts as Any), ("nextOffset", nextOffset as Any), ("users", users as Any)]) + } + } + + public static func parse_boostsList(_ reader: BufferReader) -> BoostsList? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: [Api.Boost]? + if let _ = reader.readInt32() { + _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Boost.self) + } + var _4: String? + if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) } + var _5: [Api.User]? + if let _ = reader.readInt32() { + _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) + } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return Api.premium.BoostsList.boostsList(flags: _1!, count: _2!, boosts: _3!, nextOffset: _4, users: _5!) + } + else { + return nil + } + } + + } +} public extension Api.premium { enum BoostsStatus: TypeConstructorDescription { case boostsStatus(flags: Int32, level: Int32, currentLevelBoosts: Int32, boosts: Int32, giftBoosts: Int32?, nextLevelBoosts: Int32?, premiumAudience: Api.StatsPercentValue?, boostUrl: String, prepaidGiveaways: [Api.PrepaidGiveaway]?, myBoostSlots: [Int32]?) diff --git a/submodules/TelegramApi/Sources/Api36.swift b/submodules/TelegramApi/Sources/Api36.swift index b6cf49ba95..283bdcd1dc 100644 --- a/submodules/TelegramApi/Sources/Api36.swift +++ b/submodules/TelegramApi/Sources/Api36.swift @@ -8794,6 +8794,23 @@ public extension Api.functions.payments { }) } } +public extension Api.functions.payments { + static func refundStarsCharge(userId: Api.InputUser, msgId: Int32, chargeId: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(-258950164) + userId.serialize(buffer, true) + serializeInt32(msgId, buffer: buffer, boxed: false) + serializeString(chargeId, buffer: buffer, boxed: false) + return (FunctionDescription(name: "payments.refundStarsCharge", parameters: [("userId", String(describing: userId)), ("msgId", String(describing: msgId)), ("chargeId", String(describing: chargeId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in + let reader = BufferReader(buffer) + var result: Api.Updates? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.Updates + } + return result + }) + } +} public extension Api.functions.payments { static func sendPaymentForm(flags: Int32, formId: Int64, invoice: Api.InputInvoice, requestedInfoId: String?, shippingOptionId: String?, credentials: Api.InputPaymentCredentials, tipAmount: Int64?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift index 480bb8c7b1..c8a574059e 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift @@ -693,6 +693,27 @@ func _internal_requestBotPaymentReceipt(account: Account, messageId: MessageId) let botPaymentId = PeerId.init(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)) return BotPaymentReceipt(invoice: parsedInvoice, info: parsedInfo, shippingOption: shippingOption, credentialsTitle: credentialsTitle, invoiceMedia: invoiceMedia, tipAmount: tipAmount, botPaymentId: botPaymentId) + case let .paymentReceiptStars(_, _, botId, title, description, photo, invoice, currency, totalAmount, users: users): + let parsedPeers = AccumulatedPeers(transaction: transaction, chats: [], users: users) + updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers) + + let parsedInvoice = BotPaymentInvoice(apiInvoice: invoice) + + let invoiceMedia = TelegramMediaInvoice( + title: title, + description: description, + photo: photo.flatMap(TelegramMediaWebFile.init), + receiptMessageId: nil, + currency: currency, + totalAmount: totalAmount, + startParam: "", + extendedMedia: nil, + flags: [], + version: TelegramMediaInvoice.lastVersion + ) + + let botPaymentId = PeerId.init(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)) + return BotPaymentReceipt(invoice: parsedInvoice, info: nil, shippingOption: nil, credentialsTitle: "", invoiceMedia: invoiceMedia, tipAmount: nil, botPaymentId: botPaymentId) } } |> castError(RequestBotPaymentReceiptError.self) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift index 710a63d477..9e87fb6957 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/Stars.swift @@ -183,7 +183,7 @@ private final class StarsContextImpl { func add(balance: Int64) { if var state = self._state { var transactions = state.transactions - transactions.insert(.init(id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore), at: 0) + transactions.insert(.init(id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil), at: 0) state.balance = state.balance + balance self._state = state @@ -216,7 +216,7 @@ private final class StarsContextImpl { private extension StarsContext.State.Transaction { init?(apiTransaction: Api.StarsTransaction, transaction: Transaction) { switch apiTransaction { - case let .starsTransaction(id, stars, date, transactionPeer): + case let .starsTransaction(_, id, stars, date, transactionPeer, title, description, photo): let parsedPeer: StarsContext.State.Transaction.Peer switch transactionPeer { case .starsTransactionPeerAppStore: @@ -235,7 +235,7 @@ private extension StarsContext.State.Transaction { } parsedPeer = .peer(EnginePeer(peer)) } - self.init(id: id, count: stars, date: date, peer: parsedPeer) + self.init(id: id, count: stars, date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init)) } } } @@ -256,12 +256,26 @@ public final class StarsContext { public let count: Int64 public let date: Int32 public let peer: Peer + public let title: String? + public let description: String? + public let photo: TelegramMediaWebFile? - init(id: String, count: Int64, date: Int32, peer: Peer) { + init( + id: String, + count: Int64, + date: Int32, + peer: Peer, + title: String?, + description: String?, + photo: TelegramMediaWebFile? + ) { self.id = id self.count = count self.date = date self.peer = peer + self.title = title + self.description = description + self.photo = photo } } diff --git a/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift index f5ddb8d0ad..ecfe9f9f54 100644 --- a/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Components/Chat/ChatBotInfoItem/Sources/ChatBotInfoItem.swift @@ -175,7 +175,7 @@ public final class ChatBotInfoItemNode: ListViewItemNode { break case .ignore: return .fail - case .url, .phone, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji: + case .url, .phone, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji, .custom: return .waitForSingleTap } } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageActionButtonsNode/Sources/ChatMessageActionButtonsNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageActionButtonsNode/Sources/ChatMessageActionButtonsNode.swift index 1b24ac7b2c..49cb6a9f55 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageActionButtonsNode/Sources/ChatMessageActionButtonsNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageActionButtonsNode/Sources/ChatMessageActionButtonsNode.swift @@ -172,6 +172,7 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { let incoming = message.effectivelyIncoming(context.account.peerId) let graphics = PresentationResourcesChat.additionalGraphics(theme.theme, wallpaper: theme.wallpaper, bubbleCorners: bubbleCorners) + var isStarsPayment = false let iconImage: UIImage? switch button.action { case .text: @@ -191,7 +192,8 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { case .switchInline: iconImage = incoming ? graphics.chatBubbleActionButtonIncomingShareIconImage : graphics.chatBubbleActionButtonOutgoingShareIconImage case .payment: - if button.title.contains("Pay XTR") { + if button.title.contains("⭐️") { + isStarsPayment = true iconImage = nil } else { iconImage = incoming ? graphics.chatBubbleActionButtonIncomingPaymentIconImage : graphics.chatBubbleActionButtonOutgoingPaymentIconImage @@ -222,10 +224,10 @@ private final class ChatMessageActionButtonNode: ASDisplayNode { let titleColor = bubbleVariableColor(variableColor: messageTheme.actionButtonsTextColor, wallpaper: theme.wallpaper) let attributedTitle: NSAttributedString - if title.contains("Pay XTR") { - let stars = title.replacingOccurrences(of: "Pay XTR", with: "") - let buttonAttributedString = NSMutableAttributedString(string: "Pay > \(stars)", font: titleFont, textColor: titleColor, paragraphAlignment: .center) - if let range = buttonAttributedString.string.range(of: ">"), let starImage = UIImage(bundleImageName: "Item List/PremiumIcon") { + if isStarsPayment { + let updatedTitle = title.replacingOccurrences(of: "⭐️", with: " # ") + let buttonAttributedString = NSMutableAttributedString(string: updatedTitle, font: titleFont, textColor: titleColor, paragraphAlignment: .center) + if let range = buttonAttributedString.string.range(of: "#"), let starImage = UIImage(bundleImageName: "Item List/PremiumIcon") { buttonAttributedString.addAttribute(.attachment, value: starImage, range: NSRange(range, in: buttonAttributedString.string)) buttonAttributedString.addAttribute(.foregroundColor, value: titleColor, range: NSRange(range, in: buttonAttributedString.string)) buttonAttributedString.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: buttonAttributedString.string)) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift index 242acf7eaa..68b9fecff9 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode/Sources/ChatMessageBubbleContentNode.swift @@ -159,6 +159,7 @@ public struct ChatMessageBubbleContentTapAction { case copy(String) case largeEmoji(String, String?, TelegramMediaFile) case customEmoji(TelegramMediaFile) + case custom(() -> Void) } public var content: Content diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index 4b3582b94a..8ee49224b3 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -1178,7 +1178,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI break case .ignore: return .fail - case .url, .phone, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji: + case .url, .phone, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .theme, .call, .openMessage, .timecode, .bankCard, .tooltip, .openPollResults, .copy, .largeEmoji, .customEmoji, .custom: return .waitForSingleTap } } @@ -4623,6 +4623,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI return .action(InternalBubbleTapAction.Action { }) } + case let .custom(action): + return .action(InternalBubbleTapAction.Action({ + action() + }, contextMenuOnLongPress: !tapAction.hasLongTapAction)) case let .url(url): if case .longTap = gesture, !tapAction.hasLongTapAction, let item = self.item { let tapMessage = item.content.firstMessage @@ -4872,6 +4876,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI break case .customEmoji: break + case .custom: + break } } if let tapMessage = tapMessage { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/BUILD b/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/BUILD index f6555b701f..fc309e1bda 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/BUILD +++ b/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/BUILD @@ -24,6 +24,7 @@ swift_library( "//submodules/TelegramUI/Components/Chat/ChatMessageBubbleContentNode", "//submodules/TelegramUI/Components/Chat/ChatMessageItemCommon", "//submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView", + "//submodules/TextSelectionNode", ], visibility = [ "//visibility:public", diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/Sources/ChatMessageFactCheckBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/Sources/ChatMessageFactCheckBubbleContentNode.swift index 1b9624e41b..4d42893c8b 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/Sources/ChatMessageFactCheckBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageFactCheckBubbleContentNode/Sources/ChatMessageFactCheckBubbleContentNode.swift @@ -12,6 +12,7 @@ import ChatMessageDateAndStatusNode import ChatMessageBubbleContentNode import ChatMessageItemCommon import MessageInlineBlockBackgroundView +import TextSelectionNode import Geocoding import UrlEscaping @@ -44,6 +45,7 @@ public class ChatMessageFactCheckBubbleContentNode: ChatMessageBubbleContentNode private let textNode: TextNode private let additionalTextNode: TextNode private var linkHighlightingNode: LinkHighlightingNode? + private var textSelectionNode: TextSelectionNode? private let lineNode: ASDisplayNode @@ -51,7 +53,6 @@ public class ChatMessageFactCheckBubbleContentNode: ChatMessageBubbleContentNode private var maskOverlayView: UIView? private var expandIcon: ASImageNode - private var expandButton: HighlightTrackingButtonNode? private let statusNode: ChatMessageDateAndStatusNode @@ -136,10 +137,58 @@ public class ChatMessageFactCheckBubbleContentNode: ChatMessageBubbleContentNode let _ = item.controllerInteraction.requestMessageUpdate(item.message.id, false) } - public override func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction { - if let expandButton = self.expandButton, expandButton.frame.contains(point) { - return ChatMessageBubbleContentTapAction(content: .ignore) + public override func willUpdateIsExtractedToContextPreview(_ value: Bool) { + if !value { + if let textSelectionNode = self.textSelectionNode { + self.textSelectionNode = nil + textSelectionNode.highlightAreaNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) + textSelectionNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak textSelectionNode] _ in + textSelectionNode?.highlightAreaNode.removeFromSupernode() + textSelectionNode?.removeFromSupernode() + }) + } } + } + + public override func updateIsExtractedToContextPreview(_ value: Bool) { + if value { + if self.textSelectionNode == nil, let item = self.item, let rootNode = item.controllerInteraction.chatControllerNode() { + let selectionColor: UIColor = item.presentationData.theme.theme.chat.message.incoming.textSelectionColor + let knobColor: UIColor = item.presentationData.theme.theme.chat.message.incoming.textSelectionKnobColor + + let textSelectionNode = TextSelectionNode(theme: TextSelectionTheme(selection: selectionColor, knob: knobColor, isDark: item.presentationData.theme.theme.overallDarkAppearance), strings: item.presentationData.strings, textNode: self.textNode, updateIsActive: { [weak self] value in + self?.updateIsTextSelectionActive?(value) + }, present: { [weak self] c, a in + self?.item?.controllerInteraction.presentGlobalOverlayController(c, a) + }, rootNode: { [weak rootNode] in + return rootNode + }, performAction: { [weak self] text, action in + guard let strongSelf = self, let item = strongSelf.item else { + return + } + item.controllerInteraction.performTextSelectionAction(item.message, true, text, action) + }) + textSelectionNode.enableQuote = false + self.textSelectionNode = textSelectionNode + self.addSubnode(textSelectionNode) + self.insertSubnode(textSelectionNode.highlightAreaNode, belowSubnode: self.textClippingNode) + textSelectionNode.frame = self.textClippingNode.view.convert(self.textNode.frame, to: self.view) + textSelectionNode.highlightAreaNode.frame = textSelectionNode.frame + } + } else { + if let textSelectionNode = self.textSelectionNode { + self.textSelectionNode = nil + self.updateIsTextSelectionActive?(false) + textSelectionNode.highlightAreaNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false) + textSelectionNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak textSelectionNode] _ in + textSelectionNode?.highlightAreaNode.removeFromSupernode() + textSelectionNode?.removeFromSupernode() + }) + } + } + } + + public override func tapActionAtPoint(_ point: CGPoint, gesture: TapLongTapOrDoubleTapGesture, isEstimating: Bool) -> ChatMessageBubbleContentTapAction { if let titleBadgeButton = self.titleBadgeButton, titleBadgeButton.frame.contains(point) { return ChatMessageBubbleContentTapAction(content: .ignore) } @@ -162,6 +211,11 @@ public class ChatMessageFactCheckBubbleContentNode: ChatMessageBubbleContentNode return ChatMessageBubbleContentTapAction(content: .hashtag(hashtag.peerName, hashtag.hashtag)) } } + if let backgroundView = self.backgroundView, backgroundView.frame.contains(point), case .tap = gesture { + return ChatMessageBubbleContentTapAction(content: .custom({ [weak self] in + self?.expandPressed() + }), hasLongTapAction: false) + } return ChatMessageBubbleContentTapAction(content: .none) } @@ -585,35 +639,21 @@ public class ChatMessageFactCheckBubbleContentNode: ChatMessageBubbleContentNode } strongSelf.expandIcon.bounds = CGRect(origin: .zero, size: expandIconFrame.size) } - - let expandButtonFrame = expandIconFrame.insetBy(dx: -8.0, dy: -8.0) - - let expandButton: HighlightTrackingButtonNode - if let current = strongSelf.expandButton { - expandButton = current - } else { - expandButton = HighlightTrackingButtonNode() - expandButton.addTarget(self, action: #selector(strongSelf.expandPressed), forControlEvents: .touchUpInside) - expandButton.highligthedChanged = { [weak self] highlighted in - if let strongSelf = self { - if highlighted { - strongSelf.expandIcon.layer.removeAnimation(forKey: "opacity") - strongSelf.expandIcon.alpha = 0.4 - } else { - strongSelf.expandIcon.alpha = 1.0 - strongSelf.expandIcon.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2) - } - } - } - strongSelf.expandButton = expandButton - strongSelf.addSubnode(expandButton) - } - expandButton.frame = expandButtonFrame } else { strongSelf.expandIcon.isHidden = true strongSelf.textClippingNode.view.mask = nil } + if let textSelectionNode = strongSelf.textSelectionNode { + let shouldUpdateLayout = textSelectionNode.frame.size != textFrame.size + textSelectionNode.frame = strongSelf.textClippingNode.view.convert(strongSelf.textNode.frame, to: strongSelf.view) + textSelectionNode.highlightAreaNode.frame = textSelectionNode.frame + + if shouldUpdateLayout { + textSelectionNode.updateLayout() + } + } + if let statusSizeAndApply = statusSizeAndApply { strongSelf.statusNode.reactionSelected = { [weak strongSelf] _, value, sourceView in guard let strongSelf, let item = strongSelf.item else { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageThreadInfoNode/Sources/ChatMessageThreadInfoNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageThreadInfoNode/Sources/ChatMessageThreadInfoNode.swift index 3e5efe2ef5..eb2b0893f6 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageThreadInfoNode/Sources/ChatMessageThreadInfoNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageThreadInfoNode/Sources/ChatMessageThreadInfoNode.swift @@ -494,7 +494,12 @@ public class ChatMessageThreadInfoNode: ASDisplayNode { node.contentNode.addSubnode(avatarNode) } avatarNode.frame = CGRect(origin: CGPoint(x: -1.0, y: -3.0), size: CGSize(width: 26.0, height: 26.0)) - avatarNode.setPeer(context: arguments.context, theme: arguments.presentationData.theme.theme, peer: peer) + + var overrideImage: AvatarNodeImageOverride? + if peer.id.isReplies { + overrideImage = .repliesIcon + } + avatarNode.setPeer(context: arguments.context, theme: arguments.presentationData.theme.theme, peer: peer, overrideImage: overrideImage) } else { let titleTopicIconView: ComponentHostView if let current = node.titleTopicIconView { diff --git a/submodules/TelegramUI/Components/Chat/FactCheckAlertController/Sources/FactCheckAlertController.swift b/submodules/TelegramUI/Components/Chat/FactCheckAlertController/Sources/FactCheckAlertController.swift index 869ea6242a..66b836d6b1 100644 --- a/submodules/TelegramUI/Components/Chat/FactCheckAlertController/Sources/FactCheckAlertController.swift +++ b/submodules/TelegramUI/Components/Chat/FactCheckAlertController/Sources/FactCheckAlertController.swift @@ -222,7 +222,7 @@ private final class FactCheckAlertContentNode: AlertContentNode { characterLimit: 1024, emptyLineHandling: .oneConsecutive, formatMenuAvailability: .available([.bold, .italic, .link]), - returnKeyType: .done, + returnKeyType: .default, lockedFormatAction: { }, present: { [weak self] c in diff --git a/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift b/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift index e99e47c3c5..6cafc0a8d2 100644 --- a/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift +++ b/submodules/TelegramUI/Components/Premium/PremiumStarComponent/Sources/PremiumStarComponent.swift @@ -33,7 +33,11 @@ private func generateShineTexture() -> UIImage { private func generateDiffuseTexture(colors: [UIColor]) -> UIImage { return generateImage(CGSize(width: 256, height: 256), rotatedContext: { size, context in let colorsArray: [CGColor] = colors.map { $0.cgColor } - var locations: [CGFloat] = [0.0, 0.25, 0.5, 0.75, 1.0] + var locations: [CGFloat] = [] + for i in 0 ..< colors.count { + let t = CGFloat(i) / CGFloat(colors.count - 1) + locations.append(t) + } let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray as CFArray, locations: &locations)! context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: size.height), end: CGPoint(x: size.width, y: 0.0), options: CGGradientDrawingOptions()) @@ -281,7 +285,7 @@ public final class PremiumStarComponent: Component { private var didSetup = false private func setup() { - guard !self.didSetup, let scene = loadCompressedScene(name: "star", version: sceneVersion) else { + guard !self.didSetup, let scene = loadCompressedScene(name: "star2", version: sceneVersion) else { return } @@ -289,23 +293,23 @@ public final class PremiumStarComponent: Component { self.sceneView.scene = scene self.sceneView.delegate = self - if let node = scene.rootNode.childNode(withName: "star", recursively: false), let colors = self.component?.colors, let color = colors.first { + if let node = scene.rootNode.childNode(withName: "star", recursively: false), let colors = self.component?.colors, let _ = colors.first { node.geometry?.materials.first?.diffuse.contents = generateDiffuseTexture(colors: colors) - let names: [String] = [ - "particles_left", - "particles_right", - "particles_left_bottom", - "particles_right_bottom", - "particles_center" - ] - - for name in names { - if let node = scene.rootNode.childNode(withName: name, recursively: false), let particleSystem = node.particleSystems?.first { - particleSystem.particleColor = color - particleSystem.particleColorVariation = SCNVector4Make(0, 0, 0, 0) - } - } +// let names: [String] = [ +// "particles_left", +// "particles_right", +// "particles_left_bottom", +// "particles_right_bottom", +// "particles_center" +// ] +// +// for name in names { +// if let node = scene.rootNode.childNode(withName: name, recursively: false), let particleSystem = node.particleSystems?.first { +// particleSystem.particleColor = color +// particleSystem.particleColorVariation = SCNVector4Make(0, 0, 0, 0) +// } +// } } if self.animateFrom != nil { @@ -450,9 +454,9 @@ public final class PremiumStarComponent: Component { return } - if #available(iOS 17.0, *), let material = node.geometry?.materials.first { - material.metalness.intensity = 0.2 - } +// if let material = node.geometry?.materials.first { +// material.metalness.intensity = 0.4 +// } let animation = CABasicAnimation(keyPath: "contentsTransform") animation.fillMode = .forwards diff --git a/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift b/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift index ecddb0f63b..8676b05a48 100644 --- a/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsPurchaseScreen/Sources/StarsPurchaseScreen.swift @@ -696,10 +696,10 @@ private final class StarsPurchaseScreenComponent: CombinedComponent { isVisible: starIsVisible, hasIdleAnimations: state.hasIdleAnimations, colors: [ - UIColor(rgb: 0xea8904), + UIColor(rgb: 0xe57d02), UIColor(rgb: 0xf09903), - UIColor(rgb: 0xfec209), - UIColor(rgb: 0xfed31a) + UIColor(rgb: 0xf9b004), + UIColor(rgb: 0xfdd219) ] ), availableSize: CGSize(width: min(414.0, context.availableSize.width), height: 220.0), diff --git a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift index 248b1b8876..2398bbfd58 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransactionsScreen/Sources/StarsTransactionsScreen.swift @@ -371,10 +371,10 @@ final class StarsTransactionsScreenComponent: Component { isVisible: true, hasIdleAnimations: true, colors: [ - UIColor(rgb: 0xea8904), + UIColor(rgb: 0xe57d02), UIColor(rgb: 0xf09903), - UIColor(rgb: 0xfec209), - UIColor(rgb: 0xfed31a) + UIColor(rgb: 0xf9b004), + UIColor(rgb: 0xfdd219) ] )), environment: {}, diff --git a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift index d5a25d275b..abf0a3408d 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift @@ -216,7 +216,8 @@ private final class SheetContent: CombinedComponent { let constrainedTitleWidth = context.availableSize.width - 16.0 * 2.0 - contentSize.height += 130.0 + contentSize.height += 126.0 + let title = title.update( component: Text(text: strings.Stars_Transfer_Title, font: Font.bold(24.0), color: theme.list.itemPrimaryTextColor), availableSize: CGSize(width: constrainedTitleWidth, height: context.availableSize.height), @@ -258,13 +259,14 @@ private final class SheetContent: CombinedComponent { .position(CGPoint(x: context.availableSize.width / 2.0, y: contentSize.height + text.size.height / 2.0)) ) contentSize.height += text.size.height - contentSize.height += 24.0 + contentSize.height += 28.0 if state.cachedChevronImage == nil || state.cachedChevronImage?.1 !== theme { state.cachedChevronImage = (generateTintedImage(image: UIImage(bundleImageName: "Premium/Stars/Star"), color: UIColor(rgb: 0xf09903))!, theme) } - let balanceAttributedString = parseMarkdownIntoAttributedString("\(strings.Stars_Transfer_Balance)\n # **\(state.balance ?? 0)**", attributes: markdownAttributes).mutableCopy() as! NSMutableAttributedString + let balanceAttributedString = NSMutableAttributedString(string: strings.Stars_Transfer_Balance, font: Font.regular(14.0), textColor: textColor) + balanceAttributedString.append(NSMutableAttributedString(string: "\n # \(state.balance ?? 0)", font: Font.semibold(16.0), textColor: textColor)) if let range = balanceAttributedString.string.range(of: "#"), let chevronImage = state.cachedChevronImage?.0 { balanceAttributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: balanceAttributedString.string)) balanceAttributedString.addAttribute(.foregroundColor, value: UIColor(rgb: 0xf09903), range: NSRange(range, in: balanceAttributedString.string)) @@ -274,13 +276,14 @@ private final class SheetContent: CombinedComponent { component: MultilineTextComponent( text: .plain(balanceAttributedString), horizontalAlignment: .left, - maximumNumberOfLines: 0 + maximumNumberOfLines: 0, + lineSpacing: 0.25 ), availableSize: CGSize(width: constrainedTitleWidth, height: context.availableSize.height), transition: .immediate ) context.add(balanceText - .position(CGPoint(x: 16.0 + balanceText.size.width / 2.0, y: 29.0)) + .position(CGPoint(x: 16.0 + balanceText.size.width / 2.0, y: 31.0)) ) if state.cachedStarImage == nil || state.cachedStarImage?.1 !== theme { @@ -315,14 +318,17 @@ private final class SheetContent: CombinedComponent { isEnabled: true, displaysProgress: state.inProgress, action: { [weak state, weak controller] in - state?.buy(requestTopUp: { [weak controller] _ in + state?.buy(requestTopUp: { [weak controller] completion in let purchaseController = accountContext.sharedContext.makeStarsPurchaseScreen( context: accountContext, starsContext: starsContext, options: state?.options ?? [], peerId: state?.peer?.id, requiredStars: invoice.totalAmount, - completion: { _ in } + completion: { [weak starsContext] stars in + starsContext?.add(balance: stars) + completion() + } ) controller?.push(purchaseController) }, completion: { [weak controller] in