From e5762bd9c88eadb22442d90057ff4b6cf3c844cb Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Sun, 18 May 2025 04:35:56 +0400 Subject: [PATCH] Various fixes --- .../Telegram-iOS/en.lproj/Localizable.strings | 3 ++ .../ChatSendMessageContextScreen.swift | 9 ++++- .../Sources/DrawingEntitiesView.swift | 1 + .../DrawingUI/Sources/DrawingScreen.swift | 6 ++- .../Sources/DrawingTextEntityView.swift | 2 + .../Items/UniversalVideoGalleryItem.swift | 6 ++- .../Payments/BotPaymentForm.swift | 6 +++ .../TelegramEngine/Payments/StarGifts.swift | 4 ++ .../Sources/GiftViewScreen.swift | 39 +++++++++++++++++-- .../ChatbotSearchResultItemComponent.swift | 2 +- .../TelegramUI/Sources/AppDelegate.swift | 1 - .../Sources/ChatTextInputPanelNode.swift | 31 +++++---------- versions.json | 2 +- 13 files changed, 80 insertions(+), 32 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 3f01fa60c6..335936cef8 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14333,3 +14333,6 @@ Sorry for the inconvenience."; "ChatbotSetup.Gift.Warning.StarsText" = "The bot **%@** will be able to **transfer your stars**."; "ChatbotSetup.Gift.Warning.UsernameText" = "The bot **%@** will be able to **set and remove usernames** for your account, which may result in the loss of your current username."; "ChatbotSetup.Gift.Warning.Proceed" = "Proceed"; + +"Gift.Buy.ErrorTooEarly.Title" = "Try Later"; +"Gift.Buy.ErrorTooEarly.Text" = "You will be able to buy this gift on %@."; diff --git a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift index f329936da6..e5140c9846 100644 --- a/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift +++ b/submodules/ChatSendMessageActionUI/Sources/ChatSendMessageContextScreen.swift @@ -338,8 +338,13 @@ final class ChatSendMessageContextScreenComponent: Component { guard let animateInTimestamp = self.animateInTimestamp, animateInTimestamp < CFAbsoluteTimeGetCurrent() - 0.35 else { return } - - actionsStackNode.highlightGestureMoved(location: actionsStackNode.view.convert(location, from: view)) + let localPoint: CGPoint + if let metrics = self.environment?.metrics, metrics.isTablet, availableSize.width > availableSize.height, let view { + localPoint = view.convert(location, to: nil) + } else { + localPoint = self.convert(location, from: view) + } + actionsStackNode.highlightGestureMoved(location: self.convert(localPoint, to: actionsStackNode.view)) } component.gesture.externalEnded = { [weak self] viewAndLocation in guard let self, let actionsStackNode = self.actionsStackNode else { diff --git a/submodules/DrawingUI/Sources/DrawingEntitiesView.swift b/submodules/DrawingUI/Sources/DrawingEntitiesView.swift index 01b660ad8d..108b0dcfba 100644 --- a/submodules/DrawingUI/Sources/DrawingEntitiesView.swift +++ b/submodules/DrawingUI/Sources/DrawingEntitiesView.swift @@ -109,6 +109,7 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView { public var onInteractionUpdated: (Bool) -> Void = { _ in } public var edgePreviewUpdated: (Bool) -> Void = { _ in } + public var onTextEditingEnded: (Bool) -> Void = { _ in } private let hapticFeedback = HapticFeedback() diff --git a/submodules/DrawingUI/Sources/DrawingScreen.swift b/submodules/DrawingUI/Sources/DrawingScreen.swift index 3da8876d9c..225cc6ed66 100644 --- a/submodules/DrawingUI/Sources/DrawingScreen.swift +++ b/submodules/DrawingUI/Sources/DrawingScreen.swift @@ -3078,6 +3078,11 @@ public final class DrawingToolsInteraction { self.onInteractionUpdated(isInteracting) } } + self.entitiesView.onTextEditingEnded = { [weak self] reset in + if let self { + self.onTextEditingEnded(reset) + } + } self.entitiesView.requestedMenuForEntityView = { [weak self] entityView, isTopmost in guard let self, let node = self.getControllerNode() else { return @@ -3267,7 +3272,6 @@ public final class DrawingToolsInteraction { public func endTextEditing(reset: Bool) { if let entityView = self.entitiesView.selectedEntityView as? DrawingTextEntityView { entityView.endEditing(reset: reset) - self.onTextEditingEnded(reset) } } diff --git a/submodules/DrawingUI/Sources/DrawingTextEntityView.swift b/submodules/DrawingUI/Sources/DrawingTextEntityView.swift index ce68e000e1..98a3d0cbf7 100644 --- a/submodules/DrawingUI/Sources/DrawingTextEntityView.swift +++ b/submodules/DrawingUI/Sources/DrawingTextEntityView.swift @@ -357,6 +357,8 @@ public final class DrawingTextEntityView: DrawingEntityView, UITextViewDelegate selectionView.alpha = 1.0 selectionView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) } + + parentView.onTextEditingEnded(reset) } func suspendEditing() { diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index 73c47b9b04..f4bf3b8f89 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -1539,8 +1539,10 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { strongSelf.videoNode?.playOnceWithSound(playAndRecord: false, seek: .none, actionAtEnd: isAnimated ? .loop : strongSelf.actionAtEnd) } - if let playbackRate = strongSelf.playbackRate { - strongSelf.videoNode?.setBaseRate(playbackRate) + Queue.mainQueue().after(0.1) { + if let playbackRate = strongSelf.playbackRate { + strongSelf.videoNode?.setBaseRate(playbackRate) + } } } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift index 9abcd3c23f..9330c8db39 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/BotPaymentForm.swift @@ -179,6 +179,7 @@ public enum BotPaymentFormRequestError { case alreadyActive case noPaymentNeeded case disallowedStarGift + case starGiftResellTooEarly(Int32) } extension BotPaymentInvoice { @@ -482,6 +483,11 @@ func _internal_fetchBotPaymentForm(accountPeerId: PeerId, postbox: Postbox, netw return .fail(.noPaymentNeeded) } else if error.errorDescription == "USER_DISALLOWED_STARGIFTS" { return .fail(.disallowedStarGift) + } else if error.errorDescription.hasPrefix("STARGIFT_RESELL_TOO_EARLY_") { + let timeout = String(error.errorDescription[error.errorDescription.index(error.errorDescription.startIndex, offsetBy: "STARGIFT_RESELL_TOO_EARLY_".count)...]) + if let value = Int32(timeout) { + return .fail(.starGiftResellTooEarly(value)) + } } return .fail(.generic) } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift index df4b73d391..1e93ee353b 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Payments/StarGifts.swift @@ -855,6 +855,7 @@ public enum TransferStarGiftError { public enum BuyStarGiftError { case generic case priceChanged(Int64) + case starGiftResellTooEarly(Int32) } public enum UpdateStarGiftPriceError { @@ -871,6 +872,9 @@ func _internal_buyStarGift(account: Account, slug: String, peerId: EnginePeer.Id return _internal_fetchBotPaymentForm(accountPeerId: account.peerId, postbox: account.postbox, network: account.network, source: source, themeParams: nil) |> map(Optional.init) |> `catch` { error -> Signal in + if case let .starGiftResellTooEarly(timestamp) = error { + return .fail(.starGiftResellTooEarly(timestamp)) + } return .fail(.generic) } |> mapToSignal { paymentForm in diff --git a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift index 2fd8a02ec2..1d528e70ea 100644 --- a/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift +++ b/submodules/TelegramUI/Components/Gifts/GiftViewScreen/Sources/GiftViewScreen.swift @@ -107,6 +107,7 @@ private final class GiftViewSheetContent: CombinedComponent { var buyForm: BotPaymentForm? var buyFormDisposable: Disposable? var buyDisposable: Disposable? + var resellTooEarlyTimestamp: Int32? var inWearPreview = false var pendingWear = false @@ -180,6 +181,14 @@ private final class GiftViewSheetContent: CombinedComponent { } self.buyForm = paymentForm self.updated() + }, error: { [weak self] error in + guard let self else { + return + } + if case let .starGiftResellTooEarly(remaining) = error { + let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) + self.resellTooEarlyTimestamp = currentTime + remaining + } }) } } else if case let .generic(gift) = arguments.gift { @@ -871,7 +880,7 @@ private final class GiftViewSheetContent: CombinedComponent { title = nil text = presentationData.strings.Gift_Send_ErrorUnknown case let .starGiftResellTooEarly(canResaleDate): - let dateString = stringForFullDate(timestamp: canResaleDate, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) + let dateString = stringForFullDate(timestamp: currentTime + canResaleDate, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) title = presentationData.strings.Gift_Resale_Unavailable_Title text = presentationData.strings.Gift_Resale_Unavailable_Text(dateString).string } @@ -1150,10 +1159,28 @@ private final class GiftViewSheetContent: CombinedComponent { return } - let giftTitle = "\(uniqueGift.title) #\(uniqueGift.number)" - let context = self.context let presentationData = context.sharedContext.currentPresentationData.with { $0 } + + if let resellTooEarlyTimestamp = self.resellTooEarlyTimestamp { + guard let controller = self.getController() else { + return + } + let dateString = stringForFullDate(timestamp: resellTooEarlyTimestamp, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) + let alertController = textAlertController( + context: context, + title: presentationData.strings.Gift_Buy_ErrorTooEarly_Title, + text: presentationData.strings.Gift_Buy_ErrorTooEarly_Text(dateString).string, + actions: [ + TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {}) + ], + parseMarkdown: true + ) + controller.present(alertController, in: .window(.root)) + return + } + + let giftTitle = "\(uniqueGift.title) #\(uniqueGift.number)" let recipientPeerId = self.recipientPeerId ?? self.context.account.peerId let action = { @@ -1344,6 +1371,12 @@ private final class GiftViewSheetContent: CombinedComponent { } else { proceed() } + } else { + guard let controller = self.getController() 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)) } } diff --git a/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSearchResultItemComponent.swift b/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSearchResultItemComponent.swift index 7ac100863b..3423eb4caf 100644 --- a/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSearchResultItemComponent.swift +++ b/submodules/TelegramUI/Components/Settings/ChatbotSetupScreen/Sources/ChatbotSearchResultItemComponent.swift @@ -128,7 +128,7 @@ final class ChatbotSearchResultItemComponent: Component { animateScale: false )), environment: {}, - containerSize: CGSize(width: 100.0, height: 100.0) + containerSize: CGSize(width: 140.0, height: 100.0) ) } else { if let addButton = self.addButton { diff --git a/submodules/TelegramUI/Sources/AppDelegate.swift b/submodules/TelegramUI/Sources/AppDelegate.swift index 76ffbe7991..a28067e1b4 100644 --- a/submodules/TelegramUI/Sources/AppDelegate.swift +++ b/submodules/TelegramUI/Sources/AppDelegate.swift @@ -2401,7 +2401,6 @@ private func extractAccountManagerState(records: AccountRecordsView