From da164c2332eecf2fd270745b50447e726901eee6 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 2 May 2025 17:03:23 +0400 Subject: [PATCH] Various fixes --- .../GalleryUI/Sources/GalleryController.swift | 2 +- .../ChatMessageGiftBubbleContentNode.swift | 4 +-- .../ChatMessagePaymentAlertController.swift | 11 +++++++ ...hatMessageWallpaperBubbleContentNode.swift | 6 ++-- .../Sources/PeerInfoScreen.swift | 8 ++--- .../Chat/ChatControllerLoadDisplayNode.swift | 33 ++++++++++--------- .../Sources/ChatHistoryListNode.swift | 2 +- .../ChatPremiumRequiredInputPanelNode.swift | 4 +-- .../TranslateUI/Sources/ChatTranslation.swift | 25 +++++++++----- 9 files changed, 58 insertions(+), 37 deletions(-) diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift index 5072eab702..aec776a3b8 100644 --- a/submodules/GalleryUI/Sources/GalleryController.swift +++ b/submodules/GalleryUI/Sources/GalleryController.swift @@ -713,7 +713,7 @@ public class GalleryController: ViewController, StandalonePresentableController, return .single(message.flatMap { ($0, false) }) } } - translateToLanguage = chatTranslationState(context: context, peerId: messageId.peerId) + translateToLanguage = chatTranslationState(context: context, peerId: messageId.peerId, threadId: threadIdValue) |> map { translationState in if let translationState, translationState.isEnabled { let translateToLanguage = translationState.toLang ?? baseLanguageCode diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift index 75c0a68835..3c0945ed07 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift @@ -780,7 +780,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { let overlayColor = item.presentationData.theme.theme.overallDarkAppearance && uniquePatternFile == nil ? UIColor(rgb: 0xffffff, alpha: 0.12) : UIColor(rgb: 0x000000, alpha: 0.12) - let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - giftSize.width) / 2.0), y: hasServiceMessage ? labelLayout.size.height + 12.0 : 0.0), size: giftSize) + let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - giftSize.width) / 2.0), y: hasServiceMessage ? labelLayout.size.height + 12.0 : 0.0), size: giftSize) let mediaBackgroundFrame = imageFrame.insetBy(dx: -2.0, dy: -2.0) var iconSize = CGSize(width: 160.0, height: 160.0) @@ -852,7 +852,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { let _ = ribbonTextApply() let _ = moreApply() - let labelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - labelLayout.size.width) / 2.0), y: 2.0), size: labelLayout.size) + let labelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - labelLayout.size.width) / 2.0), y: 2.0), size: labelLayout.size) strongSelf.labelNode.frame = labelFrame let titleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - titleLayout.size.width) / 2.0) , y: mediaBackgroundFrame.minY + 151.0), size: titleLayout.size) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift b/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift index 75270b57dc..d78bb08410 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController/Sources/ChatMessagePaymentAlertController.swift @@ -325,6 +325,8 @@ public class ChatMessagePaymentAlertController: AlertController { private let balance = ComponentView() + private var didAppear = false + public init(context: AccountContext?, presentationData: PresentationData, contentNode: AlertContentNode, navigationController: NavigationController?, showBalance: Bool = true) { self.context = context self.presentationData = presentationData @@ -361,6 +363,15 @@ public class ChatMessagePaymentAlertController: AlertController { public override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { super.containerLayoutUpdated(layout, transition: transition) + if !self.didAppear { + self.didAppear = true + if !layout.metrics.isTablet && layout.size.width > layout.size.height { + Queue.mainQueue().after(0.1) { + self.view.window?.endEditing(true) + } + } + } + if let context = self.context, let _ = self.parentNavigationController, self.showBalance { let insets = layout.insets(options: .statusBar) let balanceSize = self.balance.update( diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift index d3280e0622..290a9c7f39 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageWallpaperBubbleContentNode/Sources/ChatMessageWallpaperBubbleContentNode.swift @@ -334,8 +334,8 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode strongSelf.buttonNode.isHidden = fromYou || isGroupOrChannel strongSelf.buttonTitleNode.isHidden = fromYou || isGroupOrChannel - let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - imageSize.width) / 2.0), y: 13.0), size: imageSize) - if let media, mediaUpdated { + let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - imageSize.width) / 2.0), y: 13.0), size: imageSize) + if let media, mediaUpdated { let boundingSize = imageSize var imageSize = boundingSize let updateImageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> @@ -440,7 +440,7 @@ public class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode } } - let mediaBackgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((backgroundSize.width - width) / 2.0), y: 0.0), size: backgroundSize) + let mediaBackgroundFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - width) / 2.0), y: 0.0), size: backgroundSize) strongSelf.mediaBackgroundNode.frame = mediaBackgroundFrame strongSelf.mediaBackgroundNode.updateColor(color: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: item.controllerInteraction.enableFullTranslucency && dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), transition: .immediate) diff --git a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift index 15b2105611..3ef862c66c 100644 --- a/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Components/PeerInfo/PeerInfoScreen/Sources/PeerInfoScreen.swift @@ -4978,7 +4978,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.refreshMessageTagStatsDisposable = context.engine.messages.refreshMessageTagStats(peerId: peerId, threadId: chatLocation.threadId, tags: [.video, .photo, .gif, .music, .voiceOrInstantVideo, .webPage, .file]).startStrict() if peerId.namespace == Namespaces.Peer.CloudChannel { - self.translationStateDisposable = (chatTranslationState(context: context, peerId: peerId) + self.translationStateDisposable = (chatTranslationState(context: context, peerId: peerId, threadId: nil) |> deliverOnMainQueue).startStrict(next: { [weak self] translationState in self?.translationState = translationState }) @@ -6507,7 +6507,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro f(.dismissWithoutContent) if let strongSelf = self { - let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, { current in + let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, threadId: nil, { current in return current?.withIsEnabled(true) }).startStandalone() @@ -6698,7 +6698,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro f(.dismissWithoutContent) if let strongSelf = self { - let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, { current in + let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, threadId: nil, { current in return current?.withIsEnabled(true) }).startStandalone() @@ -6957,7 +6957,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro f(.dismissWithoutContent) if let strongSelf = self { - let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, { current in + let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: strongSelf.peerId, threadId: nil, { current in return current?.withIsEnabled(true) }).startStandalone() diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift index e4795c62ec..3ca76e4c6f 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerLoadDisplayNode.swift @@ -681,6 +681,7 @@ extension ChatControllerImpl { let hasAutoTranslate = self.context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.AutoTranslateEnabled(id: peerId)) |> distinctUntilChanged + let chatLocation = self.chatLocation self.translationStateDisposable = (combineLatest( queue: .concurrentDefaultQueue(), isPremium, @@ -693,7 +694,7 @@ extension ChatControllerImpl { maybeSuggestPremium = true } if (isPremium || maybeSuggestPremium || hasAutoTranslate) && !isHidden { - return chatTranslationState(context: context, peerId: peerId) + return chatTranslationState(context: context, peerId: peerId, threadId: chatLocation.threadId) |> map { translationState -> ChatPresentationTranslationState? in if let translationState, !translationState.fromLang.isEmpty && (translationState.fromLang != baseLanguageCode || translationState.isEnabled) { return ChatPresentationTranslationState(isEnabled: translationState.isEnabled, fromLang: translationState.fromLang, toLang: translationState.toLang ?? baseLanguageCode) @@ -4357,32 +4358,32 @@ extension ChatControllerImpl { } let _ = strongSelf.context.engine.peers.setForumChannelTopicClosed(id: peerId, threadId: threadId, isClosed: false).startStandalone() }, toggleTranslation: { [weak self] type in - guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else { + guard let self, let peerId = self.chatLocation.peerId else { return } - let _ = (updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: peerId, { current in + let _ = (updateChatTranslationStateInteractively(engine: self.context.engine, peerId: peerId, threadId: self.chatLocation.threadId, { current in return current?.withIsEnabled(type == .translated) }) |> deliverOnMainQueue).startStandalone(completed: { [weak self] in - if let strongSelf = self, type == .translated { + if let self, type == .translated { Queue.mainQueue().after(0.15) { - strongSelf.chatDisplayNode.historyNode.refreshPollActionsForVisibleMessages() + self.chatDisplayNode.historyNode.refreshPollActionsForVisibleMessages() } } }) }, changeTranslationLanguage: { [weak self] langCode in - guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else { + guard let self, let peerId = self.chatLocation.peerId else { return } let langCode = normalizeTranslationLanguage(langCode) - let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: peerId, { current in + let _ = updateChatTranslationStateInteractively(engine: self.context.engine, peerId: peerId, threadId: self.chatLocation.threadId, { current in return current?.withToLang(langCode).withIsEnabled(true) }).startStandalone() }, addDoNotTranslateLanguage: { [weak self] langCode in - guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else { + guard let self, let peerId = self.chatLocation.peerId else { return } - let _ = updateTranslationSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { current in + let _ = updateTranslationSettingsInteractively(accountManager: self.context.sharedContext.accountManager, { current in var updated = current if var ignoredLanguages = updated.ignoredLanguages { if !ignoredLanguages.contains(langCode) { @@ -4391,7 +4392,7 @@ extension ChatControllerImpl { updated.ignoredLanguages = ignoredLanguages } else { var ignoredLanguages = Set() - ignoredLanguages.insert(strongSelf.presentationData.strings.baseLanguageCode) + ignoredLanguages.insert(self.presentationData.strings.baseLanguageCode) for language in systemLanguageCodes() { ignoredLanguages.insert(language) } @@ -4400,11 +4401,11 @@ extension ChatControllerImpl { } return updated }).startStandalone() - let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: peerId, { current in + let _ = updateChatTranslationStateInteractively(engine: self.context.engine, peerId: peerId, threadId: self.chatLocation.threadId, { current in return nil }).startStandalone() - let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } + let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } var languageCode = presentationData.strings.baseLanguageCode let rawSuffix = "-raw" if languageCode.hasSuffix(rawSuffix) { @@ -4413,11 +4414,11 @@ extension ChatControllerImpl { let locale = Locale(identifier: languageCode) let fromLanguage: String = locale.localizedString(forLanguageCode: langCode) ?? "" - strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .image(image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/Translate"), color: .white)!, title: nil, text: presentationData.strings.Conversation_Translation_AddedToDoNotTranslateText(fromLanguage).string, round: false, undoText: presentationData.strings.Conversation_Translation_Settings), elevatedLayout: false, animateInAsReplacement: false, action: { [weak self] action in - if case .undo = action, let strongSelf = self { - let controller = translationSettingsController(context: strongSelf.context) + self.present(UndoOverlayController(presentationData: presentationData, content: .image(image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/Translate"), color: .white)!, title: nil, text: presentationData.strings.Conversation_Translation_AddedToDoNotTranslateText(fromLanguage).string, round: false, undoText: presentationData.strings.Conversation_Translation_Settings), elevatedLayout: false, animateInAsReplacement: false, action: { [weak self] action in + if case .undo = action, let self { + let controller = translationSettingsController(context: self.context) controller.navigationPresentation = .modal - strongSelf.push(controller) + self.push(controller) } return true }), in: .current) diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index 723f3a53c3..57522caf86 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -1655,7 +1655,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto let translationState: Signal if let peerId = chatLocation.peerId, peerId.namespace != Namespaces.Peer.SecretChat && peerId != context.account.peerId && subject != .scheduledMessages { - translationState = chatTranslationState(context: context, peerId: peerId) + translationState = chatTranslationState(context: context, peerId: peerId, threadId: self.chatLocation.threadId) } else { translationState = .single(nil) } diff --git a/submodules/TelegramUI/Sources/ChatPremiumRequiredInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatPremiumRequiredInputPanelNode.swift index 0add3d1da0..51571afe63 100644 --- a/submodules/TelegramUI/Sources/ChatPremiumRequiredInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatPremiumRequiredInputPanelNode.swift @@ -115,7 +115,7 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode { } } - let size = CGSize(width: params.width - params.additionalSideInsets.left * 2.0 - params.leftInset * 2.0, height: height) + let size = CGSize(width: params.width - params.additionalSideInsets.left * 2.0 - params.leftInset * 2.0 - 32.0, height: height) let buttonSize = self.button.update( transition: .immediate, component: AnyComponent(PlainButtonComponent( @@ -136,7 +136,7 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode { if buttonView.superview == nil { self.view.addSubview(buttonView) } - transition.setFrame(view: buttonView, frame: CGRect(origin: CGPoint(), size: buttonSize)) + transition.setFrame(view: buttonView, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((params.width - buttonSize.width) / 2.0), y: 0.0), size: buttonSize)) } return height diff --git a/submodules/TranslateUI/Sources/ChatTranslation.swift b/submodules/TranslateUI/Sources/ChatTranslation.swift index 74ea83d24c..8c03916535 100644 --- a/submodules/TranslateUI/Sources/ChatTranslation.swift +++ b/submodules/TranslateUI/Sources/ChatTranslation.swift @@ -75,9 +75,12 @@ public struct ChatTranslationState: Codable { } } -private func cachedChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id) -> Signal { +private func cachedChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?) -> Signal { let key = EngineDataBuffer(length: 8) key.setInt64(0, value: peerId.id._internalGetInt64Value()) + if let threadId { + key.setInt64(8, value: threadId) + } return engine.data.subscribe(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.translationState, id: key)) |> map { entry -> ChatTranslationState? in @@ -85,9 +88,12 @@ private func cachedChatTranslationState(engine: TelegramEngine, peerId: EnginePe } } -private func updateChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id, state: ChatTranslationState?) -> Signal { +private func updateChatTranslationState(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?, state: ChatTranslationState?) -> Signal { let key = EngineDataBuffer(length: 8) key.setInt64(0, value: peerId.id._internalGetInt64Value()) + if let threadId { + key.setInt64(8, value: threadId) + } if let state { return engine.itemCache.put(collectionId: ApplicationSpecificItemCacheCollectionId.translationState, id: key, item: state) @@ -96,9 +102,12 @@ private func updateChatTranslationState(engine: TelegramEngine, peerId: EnginePe } } -public func updateChatTranslationStateInteractively(engine: TelegramEngine, peerId: EnginePeer.Id, _ f: @escaping (ChatTranslationState?) -> ChatTranslationState?) -> Signal { +public func updateChatTranslationStateInteractively(engine: TelegramEngine, peerId: EnginePeer.Id, threadId: Int64?, _ f: @escaping (ChatTranslationState?) -> ChatTranslationState?) -> Signal { let key = EngineDataBuffer(length: 8) key.setInt64(0, value: peerId.id._internalGetInt64Value()) + if let threadId { + key.setInt64(8, value: threadId) + } return engine.data.get(TelegramEngine.EngineData.Item.ItemCache.Item(collectionId: ApplicationSpecificItemCacheCollectionId.translationState, id: key)) |> map { entry -> ChatTranslationState? in @@ -106,7 +115,7 @@ public func updateChatTranslationStateInteractively(engine: TelegramEngine, peer } |> mapToSignal { current -> Signal in if let current { - return updateChatTranslationState(engine: engine, peerId: peerId, state: f(current)) + return updateChatTranslationState(engine: engine, peerId: peerId, threadId: threadId, state: f(current)) } else { return .never() } @@ -166,7 +175,7 @@ public func translateMessageIds(context: AccountContext, messageIds: [EngineMess } |> switchToLatest } -public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) -> Signal { +public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64?) -> Signal { if peerId.id == EnginePeer.Id.Id._internalFromInt64Value(777000) { return .single(nil) } @@ -202,7 +211,7 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) } } - return cachedChatTranslationState(engine: context.engine, peerId: peerId) + return cachedChatTranslationState(engine: context.engine, peerId: peerId, threadId: threadId) |> mapToSignal { cached in let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) if let cached, let timestamp = cached.timestamp, cached.baseLang == baseLang && currentTime - timestamp < 60 * 60 { @@ -214,7 +223,7 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) } else { return .single(nil) |> then( - context.account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId: peerId, threadId: nil), index: .upperBound, anchorIndex: .upperBound, count: 32, fixedCombinedReadStates: nil) + context.account.viewTracker.aroundMessageHistoryViewForLocation(.peer(peerId: peerId, threadId: threadId), index: .upperBound, anchorIndex: .upperBound, count: 32, fixedCombinedReadStates: nil) |> filter { messageHistoryView -> Bool in return messageHistoryView.0.entries.count > 1 } @@ -308,7 +317,7 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) toLang: cached?.toLang, isEnabled: isEnabled ) - let _ = updateChatTranslationState(engine: context.engine, peerId: peerId, state: state).start() + let _ = updateChatTranslationState(engine: context.engine, peerId: peerId, threadId: threadId, state: state).start() if !dontTranslateLanguages.contains(fromLang) { return state } else {