diff --git a/submodules/OpenInExternalAppUI/Sources/OpenInOptions.swift b/submodules/OpenInExternalAppUI/Sources/OpenInOptions.swift index cdc9c00032..b335164ac4 100644 --- a/submodules/OpenInExternalAppUI/Sources/OpenInOptions.swift +++ b/submodules/OpenInExternalAppUI/Sources/OpenInOptions.swift @@ -235,6 +235,13 @@ private func allOpenInOptions(context: AccountContext, item: OpenInItem) -> [Ope } } })) + options.append(OpenInOption(identifier: "yangoMaps", application: .other(title: "Yango Maps", identifier: 1665672451, scheme: "yangomaps", store: nil), action: { + if let _ = directions { + return .openUrl(url: "yangomaps://build_route_on_map?lat_to=\(lat)&lon_to=\(lon)") + } else { + return .openUrl(url: "yangomaps://maps.yango.com/?pt=\(lon),\(lat)&z=16") + } + })) options.append(OpenInOption(identifier: "yandexMaps", application: .other(title: "Yandex.Maps", identifier: 313877526, scheme: "yandexmaps", store: nil), action: { if let _ = directions { diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift index 181736089e..e3b1394167 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift @@ -264,8 +264,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([ } else if let _ = media as? TelegramMediaExpiredContent { result.removeAll() result.append((message, ChatMessageActionBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default))) - needReactions = false - return (result, false, false) + break inner } else if let _ = media as? TelegramMediaPoll { result.append((message, ChatMessagePollBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default))) needReactions = false @@ -2735,6 +2734,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI default: centerAligned = true } + } else if let _ = media as? TelegramMediaExpiredContent { + centerAligned = true } break } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift index 852f601241..38c0ff482f 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemCommon/Sources/ChatMessageItemCommon.swift @@ -299,8 +299,6 @@ public func canAddMessageReactions(message: Message) -> Bool { if story.isMention { return false } - } else if let _ = media as? TelegramMediaExpiredContent { - return false } } return true diff --git a/submodules/TelegramUI/Components/Chat/QuickShareScreen/BUILD b/submodules/TelegramUI/Components/Chat/QuickShareScreen/BUILD index c1ed545428..1822500c99 100644 --- a/submodules/TelegramUI/Components/Chat/QuickShareScreen/BUILD +++ b/submodules/TelegramUI/Components/Chat/QuickShareScreen/BUILD @@ -24,6 +24,7 @@ swift_library( "//submodules/AppBundle", "//submodules/PresentationDataUtils", "//submodules/TelegramUI/Components/LottieComponent", + "//submodules/TelegramUI/Components/PlainButtonComponent", "//submodules/AvatarNode", ], visibility = [ diff --git a/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareScreen.swift b/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareScreen.swift index fb7fa471e6..02024baeb3 100644 --- a/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareScreen.swift +++ b/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareScreen.swift @@ -22,22 +22,19 @@ private final class QuickShareScreenComponent: Component { let context: AccountContext let sourceNode: ASDisplayNode let gesture: ContextGesture - let openPeer: (EnginePeer.Id) -> Void - let completion: (EnginePeer.Id) -> Void + let completion: (EnginePeer, CGRect) -> Void let ready: Promise init( context: AccountContext, sourceNode: ASDisplayNode, gesture: ContextGesture, - openPeer: @escaping (EnginePeer.Id) -> Void, - completion: @escaping (EnginePeer.Id) -> Void, + completion: @escaping (EnginePeer, CGRect) -> Void, ready: Promise ) { self.context = context self.sourceNode = sourceNode self.gesture = gesture - self.openPeer = openPeer self.completion = completion self.ready = ready } @@ -184,24 +181,9 @@ private final class QuickShareScreenComponent: Component { func highlightGestureFinished(performAction: Bool) { if let selectedPeerId = self.selectedPeerId, performAction { - if let component = self.component, let peer = self.peers?.first(where: { $0.id == selectedPeerId }), let view = self.items[selectedPeerId]?.view as? ItemComponent.View, let controller = self.environment?.controller() { - controller.window?.forEachController({ controller in - if let controller = controller as? QuickShareToastScreen { - controller.dismiss() - } - }) - let toastScreen = QuickShareToastScreen( - context: component.context, - peer: peer, - sourceFrame: view.convert(view.bounds, to: nil), - action: { - component.openPeer(peer.id) - } - ) - controller.present(toastScreen, in: .window(.root)) + if let component = self.component, let peer = self.peers?.first(where: { $0.id == selectedPeerId }), let view = self.items[selectedPeerId]?.view as? ItemComponent.View { + component.completion(peer, view.convert(view.bounds, to: nil)) view.avatarNode.isHidden = true - - component.completion(peer.id) } self.animateOut { @@ -296,7 +278,7 @@ private final class QuickShareScreenComponent: Component { if theme.overallDarkAppearance { self.backgroundView.updateColor(color: theme.contextMenu.backgroundColor, forceKeepBlur: true, transition: .immediate) - self.backgroundTintView.backgroundColor = UIColor(white: 1.0, alpha: 0.5) + self.backgroundTintView.backgroundColor = .clear } else { self.backgroundView.updateColor(color: .clear, forceKeepBlur: true, transition: .immediate) self.backgroundTintView.backgroundColor = theme.contextMenu.backgroundColor @@ -411,8 +393,7 @@ public class QuickShareScreen: ViewControllerComponentContainer { context: AccountContext, sourceNode: ASDisplayNode, gesture: ContextGesture, - openPeer: @escaping (EnginePeer.Id) -> Void, - completion: @escaping (EnginePeer.Id) -> Void + completion: @escaping (EnginePeer, CGRect) -> Void ) { let componentReady = Promise() @@ -422,7 +403,6 @@ public class QuickShareScreen: ViewControllerComponentContainer { context: context, sourceNode: sourceNode, gesture: gesture, - openPeer: openPeer, completion: completion, ready: componentReady ), @@ -528,7 +508,7 @@ private final class ItemComponent: Component { private weak var state: EmptyComponentState? override init(frame: CGRect) { - self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 14.0)) + self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 26.0)) self.backgroundNode = NavigationBackgroundNode(color: .clear) super.init(frame: frame) diff --git a/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareToastScreen.swift b/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareToastScreen.swift index 04d10d5eb6..8864d62ac6 100644 --- a/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareToastScreen.swift +++ b/submodules/TelegramUI/Components/Chat/QuickShareScreen/Sources/QuickShareToastScreen.swift @@ -14,18 +14,19 @@ import MultilineTextComponent import AvatarNode import Markdown import LottieComponent +import PlainButtonComponent private final class QuickShareToastScreenComponent: Component { let context: AccountContext let peer: EnginePeer let sourceFrame: CGRect - let action: () -> Void + let action: (QuickShareToastScreen.Action) -> Void init( context: AccountContext, peer: EnginePeer, sourceFrame: CGRect, - action: @escaping () -> Void + action: @escaping (QuickShareToastScreen.Action) -> Void ) { self.context = context self.peer = peer @@ -51,6 +52,7 @@ private final class QuickShareToastScreenComponent: Component { private let animation = ComponentView() private let content = ComponentView() + private let actionButton = ComponentView() private var isUpdating: Bool = false private var component: QuickShareToastScreenComponent? @@ -93,7 +95,8 @@ private final class QuickShareToastScreenComponent: Component { guard let component = self.component else { return } - component.action() + component.action(.info) + self.doneTimer?.invalidate() self.environment?.controller()?.dismiss() } @@ -187,10 +190,10 @@ private final class QuickShareToastScreenComponent: Component { if self.component == nil { self.doneTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false, block: { [weak self] _ in - guard let self else { + guard let self, let controller = self.environment?.controller() as? QuickShareToastScreen else { return } - self.environment?.controller()?.dismiss() + controller.dismissWithCommitAction() }) } @@ -230,6 +233,29 @@ private final class QuickShareToastScreenComponent: Component { tooltipText = environment.strings.Conversation_ForwardTooltip_Chat_One(component.peer.compactDisplayTitle).string } + let actionButtonSize = self.actionButton.update( + transition: .immediate, + component: AnyComponent(PlainButtonComponent( + content: AnyComponent(MultilineTextComponent( + text: .plain(NSAttributedString(string: "Undo", font: Font.regular(17.0), textColor: environment.theme.list.itemAccentColor.withMultiplied(hue: 0.933, saturation: 0.61, brightness: 1.0))) + )), + effectAlignment: .center, + contentInsets: UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0), + action: { [weak self] in + guard let self, let _ = self.component else { + return + } + self.doneTimer?.invalidate() + self.environment?.controller()?.dismiss() + }, + animateAlpha: true, + animateScale: false, + animateContents: false + )), + environment: {}, + containerSize: CGSize(width: availableContentSize.width - contentInsets.left - contentInsets.right - spacing - iconSize.width, height: availableContentSize.height) + ) + let contentSize = self.content.update( transition: transition, component: AnyComponent(MultilineTextComponent(text: .markdown( @@ -279,6 +305,13 @@ private final class QuickShareToastScreenComponent: Component { transition.setFrame(view: contentView, frame: CGRect(origin: CGPoint(x: contentInsets.left + iconSize.width + spacing, y: floor((contentHeight - contentSize.height) * 0.5)), size: contentSize)) } + if let actionButtonView = self.actionButton.view { + if actionButtonView.superview == nil { + self.backgroundView.addSubview(actionButtonView) + } + transition.setFrame(view: actionButtonView, frame: CGRect(origin: CGPoint(x: availableContentSize.width - contentInsets.right - 16.0 - actionButtonSize.width, y: floor((contentHeight - actionButtonSize.height) * 0.5)), size: actionButtonSize)) + } + let size = CGSize(width: availableContentSize.width, height: contentHeight) let backgroundFrame = CGRect(origin: CGPoint(x: containerInsets.left, y: availableSize.height - containerInsets.bottom - size.height), size: size) @@ -301,16 +334,24 @@ private final class QuickShareToastScreenComponent: Component { } } -final class QuickShareToastScreen: ViewControllerComponentContainer { +public final class QuickShareToastScreen: ViewControllerComponentContainer { + public enum Action { + case info + case commit + } + private var processedDidAppear: Bool = false private var processedDidDisappear: Bool = false - init( + private let action: (Action) -> Void + + public init( context: AccountContext, peer: EnginePeer, sourceFrame: CGRect, - action: @escaping () -> Void + action: @escaping (Action) -> Void ) { + self.action = action super.init( context: context, component: QuickShareToastScreenComponent( @@ -334,11 +375,11 @@ final class QuickShareToastScreen: ViewControllerComponentContainer { deinit { } - override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { + public override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) { super.containerLayoutUpdated(layout, transition: transition) } - override func viewDidAppear(_ animated: Bool) { + public override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if !self.processedDidAppear { @@ -353,7 +394,12 @@ final class QuickShareToastScreen: ViewControllerComponentContainer { super.dismiss() } - override func dismiss(completion: (() -> Void)? = nil) { + public func dismissWithCommitAction() { + self.action(.commit) + self.dismiss() + } + + public override func dismiss(completion: (() -> Void)? = nil) { if !self.processedDidDisappear { self.processedDidDisappear = true diff --git a/submodules/TelegramUI/Components/Chat/TopMessageReactions/Sources/TopMessageReactions.swift b/submodules/TelegramUI/Components/Chat/TopMessageReactions/Sources/TopMessageReactions.swift index d817a3b4b7..0f549ecfeb 100644 --- a/submodules/TelegramUI/Components/Chat/TopMessageReactions/Sources/TopMessageReactions.swift +++ b/submodules/TelegramUI/Components/Chat/TopMessageReactions/Sources/TopMessageReactions.swift @@ -15,9 +15,9 @@ public func peerMessageAllowedReactions(context: AccountContext, message: Messag return .single((.all, false)) } - if message.containsSecretMedia { - return .single((AllowedReactions.set(Set()), false)) - } +// if message.containsSecretMedia { +// return .single((AllowedReactions.set(Set()), false)) +// } return combineLatest( context.engine.data.get( diff --git a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift index d556d7a17c..0dafcc6410 100644 --- a/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift +++ b/submodules/TelegramUI/Components/Stars/StarsTransferScreen/Sources/StarsTransferScreen.swift @@ -593,7 +593,6 @@ private final class SheetContent: CombinedComponent { return } starsContext.add(balance: StarsAmount(value: stars, nanos: 0)) - let _ = (starsContext.onUpdate |> deliverOnMainQueue).start(next: { completion() diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift index 16d06cfde1..b7a20e66e7 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerPaidMessage.swift @@ -71,7 +71,8 @@ extension ChatControllerImpl { guard let self else { return } - let controller = self.context.sharedContext.makeStarsPurchaseScreen(context: self.context, starsContext: starsContext, options: options, purpose: .sendMessage(peerId: peer.id, requiredStars: totalAmount), completion: { _ in + let controller = self.context.sharedContext.makeStarsPurchaseScreen(context: self.context, starsContext: starsContext, options: options, purpose: .sendMessage(peerId: peer.id, requiredStars: totalAmount), completion: { stars in + starsContext.add(balance: StarsAmount(value: stars, nanos: 0)) let _ = (starsContext.onUpdate |> deliverOnMainQueue).start(next: { completion(false) diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerQuickShare.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerQuickShare.swift index 202366bcb3..33ae49c27e 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerQuickShare.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerQuickShare.swift @@ -12,39 +12,48 @@ extension ChatControllerImpl { context: self.context, sourceNode: node, gesture: gesture, - openPeer: { [weak self] peerId in + completion: { [weak self] peer, sourceFrame in guard let self else { return } - let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) - |> deliverOnMainQueue).start(next: { [weak self] peer in - guard let self else { - return + self.window?.forEachController({ controller in + if let controller = controller as? QuickShareToastScreen { + controller.dismissWithCommitAction() } - self.openPeer(peer: peer, navigation: .chat(textInputState: nil, subject: nil, peekData: nil), fromMessage: nil) }) - }, - completion: { [weak self] peerId in - guard let self else { - return - } - let enqueueMessage = StandaloneSendEnqueueMessage( - content: .forward(forward: StandaloneSendEnqueueMessage.Forward( - sourceId: id, - threadId: nil - )), - replyToMessageId: nil + let toastScreen = QuickShareToastScreen( + context: self.context, + peer: peer, + sourceFrame: sourceFrame, + action: { [weak self] action in + guard let self else { + return + } + switch action { + case .info: + self.openPeer(peer: peer, navigation: .chat(textInputState: nil, subject: nil, peekData: nil), fromMessage: nil) + case .commit: + let enqueueMessage = StandaloneSendEnqueueMessage( + content: .forward(forward: StandaloneSendEnqueueMessage.Forward( + sourceId: id, + threadId: nil + )), + replyToMessageId: nil + ) + let _ = (standaloneSendEnqueueMessages( + accountPeerId: self.context.account.peerId, + postbox: self.context.account.postbox, + network: self.context.account.network, + stateManager: self.context.account.stateManager, + auxiliaryMethods: self.context.account.auxiliaryMethods, + peerId: peer.id, + threadId: nil, + messages: [enqueueMessage] + )).startStandalone() + } + } ) - let _ = (standaloneSendEnqueueMessages( - accountPeerId: self.context.account.peerId, - postbox: self.context.account.postbox, - network: self.context.account.network, - stateManager: self.context.account.stateManager, - auxiliaryMethods: self.context.account.auxiliaryMethods, - peerId: peerId, - threadId: nil, - messages: [enqueueMessage] - )).startStandalone() + self.present(toastScreen, in: .window(.root)) } ) self.presentInGlobalOverlay(controller) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index c989df76e6..9b6582e675 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -134,6 +134,7 @@ import AdsReportScreen import AdUI import ChatMessagePaymentAlertController import TelegramCallsUI +import QuickShareScreen public enum ChatControllerPeekActions { case standard @@ -10740,6 +10741,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let controller = controller as? UndoOverlayController { controller.dismissWithCommitAction() } + if let controller = controller as? QuickShareToastScreen { + controller.dismissWithCommitAction() + } }) self.forEachController({ controller in if let controller = controller as? UndoOverlayController {