diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 26be1b2e9a..bc403edcca 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -7441,6 +7441,7 @@ Sorry for the inconvenience."; "WebApp.AddToAttachmentUnavailableError" = "This bot can't be added to the attachment menu."; "WebApp.AddToAttachmentAlreadyAddedError" = "This bot is already added to your attachment menu."; +"WebApp.AddToAttachmentSucceeded" = "**%@** has been added to your attachment menu."; "WebApp.OpenWebViewAlertTitle" = "Open Web App"; "WebApp.OpenWebViewAlertText" = "**%@** would like to open its web app to proceed.\n\nIt will be able to access your **IP address** and basic device info."; diff --git a/submodules/AccountContext/Sources/ChatController.swift b/submodules/AccountContext/Sources/ChatController.swift index 764839370a..d56a64bea5 100644 --- a/submodules/AccountContext/Sources/ChatController.swift +++ b/submodules/AccountContext/Sources/ChatController.swift @@ -151,10 +151,12 @@ public struct ChatControllerInitialBotStart { public struct ChatControllerInitialAttachBotStart { public let botId: PeerId public let payload: String? + public let justInstalled: Bool - public init(botId: PeerId, payload: String?) { + public init(botId: PeerId, payload: String?, justInstalled: Bool) { self.botId = botId self.payload = payload + self.justInstalled = justInstalled } } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index faf0be6ecb..542e98c7fb 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -9734,7 +9734,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if let attachBotStart = self.attachBotStart { self.attachBotStart = nil - self.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload) + self.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled) } } @@ -11134,12 +11134,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) } - public func presentAttachmentBot(botId: PeerId, payload: String?) { + public func presentAttachmentBot(botId: PeerId, payload: String?, justInstalled: Bool) { self.attachmentController?.dismiss(animated: true, completion: nil) - self.presentAttachmentMenu(editMediaOptions: nil, editMediaReference: nil, botId: botId, botPayload: payload) + self.presentAttachmentMenu(editMediaOptions: nil, editMediaReference: nil, botId: botId, botPayload: payload, botJustInstalled: justInstalled) } - private func presentAttachmentMenu(editMediaOptions: MessageMediaEditingOptions?, editMediaReference: AnyMediaReference?, botId: PeerId? = nil, botPayload: String? = nil) { + private func presentAttachmentMenu(editMediaOptions: MessageMediaEditingOptions?, editMediaReference: AnyMediaReference?, botId: PeerId? = nil, botPayload: String? = nil, botJustInstalled: Bool = false) { guard let peer = self.presentationInterfaceState.renderedPeer?.peer else { return } @@ -11184,33 +11184,35 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G isScheduledMessages = true } - let buttons: Signal<([AttachmentButtonType], AttachmentButtonType?), NoError> + var peerType: AttachMenuBots.Bot.PeerFlags = [] + if let user = peer as? TelegramUser { + if let _ = user.botInfo { + peerType.insert(.bot) + } else { + peerType.insert(.user) + } + } else if let _ = peer as? TelegramGroup { + peerType = .group + } else if let channel = peer as? TelegramChannel { + if case .broadcast = channel.info { + peerType = .channel + } else { + peerType = .group + } + } + + let buttons: Signal<([AttachmentButtonType], [AttachmentButtonType], AttachmentButtonType?), NoError> if !isScheduledMessages { buttons = self.context.engine.messages.attachMenuBots() |> map { attachMenuBots in var buttons = availableButtons + var allButtons = availableButtons + var initialButton: AttachmentButtonType? if botId == nil { initialButton = .gallery } - var peerType: AttachMenuBots.Bot.PeerFlags = [] - if let user = peer as? TelegramUser { - if let _ = user.botInfo { - peerType.insert(.bot) - } else { - peerType.insert(.user) - } - } else if let _ = peer as? TelegramGroup { - peerType = .group - } else if let channel = peer as? TelegramChannel { - if case .broadcast = channel.info { - peerType = .channel - } else { - peerType = .group - } - } - for bot in attachMenuBots.reversed() { var peerType = peerType if bot.peer.id == peer.id { @@ -11218,19 +11220,20 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G peerType.remove(.bot) } + let button: AttachmentButtonType = .app(bot.peer, bot.shortName, bot.icons) if !bot.peerTypes.intersection(peerType).isEmpty { - let button: AttachmentButtonType = .app(bot.peer, bot.shortName, bot.icons) buttons.insert(button, at: 1) if initialButton == nil && bot.peer.id == botId { initialButton = button } } + allButtons.insert(button, at: 1) } - return (buttons, initialButton) + return (buttons, allButtons, initialButton) } } else { - buttons = .single((availableButtons, .gallery)) + buttons = .single((availableButtons, availableButtons, .gallery)) } let dataSettings = self.context.sharedContext.accountManager.transaction { transaction -> GeneratedMediaStoreSettings in @@ -11243,25 +11246,35 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } - let (buttons, initialButton) = buttonsAndInitialButton + let (buttons, allButtons, initialButton) = buttonsAndInitialButton guard let initialButton = initialButton else { if let botId = botId { - let _ = (context.engine.messages.getAttachMenuBot(botId: botId) - |> deliverOnMainQueue).start(next: { bot in - let peer = EnginePeer(bot.peer) - let controller = addWebAppToAttachmentController(context: context, peerName: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), icons: bot.icons, completion: { - let _ = (context.engine.messages.addBotToAttachMenu(botId: botId) - |> deliverOnMainQueue).start(error: { _ in - - }, completed: { - strongSelf.presentAttachmentBot(botId: botId, payload: botPayload) + if let button = allButtons.first(where: { button in + if case let .app(botPeer, _, _) = button, botPeer.id == botId { + return true + } else { + return false + } + }), case let .app(_, botName, _) = button { + strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: botJustInstalled ? strongSelf.presentationData.strings.WebApp_AddToAttachmentSucceeded(botName).string : strongSelf.presentationData.strings.WebApp_AddToAttachmentAlreadyAddedError), elevatedLayout: false, action: { _ in return false }), in: .current) + } else { + let _ = (context.engine.messages.getAttachMenuBot(botId: botId) + |> deliverOnMainQueue).start(next: { bot in + let peer = EnginePeer(bot.peer) + let controller = addWebAppToAttachmentController(context: context, peerName: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), icons: bot.icons, completion: { + let _ = (context.engine.messages.addBotToAttachMenu(botId: botId) + |> deliverOnMainQueue).start(error: { _ in + + }, completed: { + strongSelf.presentAttachmentBot(botId: botId, payload: botPayload, justInstalled: true) + }) }) + strongSelf.present(controller, in: .window(.root)) + }, error: { _ in + strongSelf.present(textAlertController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) }) - strongSelf.present(controller, in: .window(.root)) - }, error: { _ in - strongSelf.present(textAlertController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) - }) + } } return } diff --git a/submodules/TelegramUI/Sources/NavigateToChatController.swift b/submodules/TelegramUI/Sources/NavigateToChatController.swift index 6fc9b3688e..40909b91ee 100644 --- a/submodules/TelegramUI/Sources/NavigateToChatController.swift +++ b/submodules/TelegramUI/Sources/NavigateToChatController.swift @@ -66,7 +66,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam }) } if let attachBotStart = params.attachBotStart { - controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload) + controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled) } params.setupController(controller) found = true @@ -85,7 +85,7 @@ public func navigateToChatControllerImpl(_ params: NavigateToChatControllerParam }) } if let attachBotStart = params.attachBotStart { - controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload) + controller.presentAttachmentBot(botId: attachBotStart.botId, payload: attachBotStart.payload, justInstalled: attachBotStart.justInstalled) } } else { controller = ChatControllerImpl(context: params.context, chatLocation: params.chatLocation, chatLocationContextHolder: params.chatLocationContextHolder, subject: params.subject, botStart: params.botStart, attachBotStart: params.attachBotStart, peekData: params.peekData, peerNearbyData: params.peerNearbyData, chatListFilter: params.chatListFilter, chatNavigationStack: params.chatNavigationStack) diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index aca743fddd..6c32e35454 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -579,13 +579,13 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur if let navigationController = navigationController { let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat)) controller.peerSelected = { peer in - let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: bot.peer.id, payload: payload), useExisting: true)) + let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: bot.peer.id, payload: payload, justInstalled: false), useExisting: true)) } navigationController.pushViewController(controller) } } else { if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext { - let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: peerId, payload: payload), useExisting: true)) + let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: peerId, payload: payload, justInstalled: false), useExisting: true)) } else { presentError(presentationData.strings.WebApp_AddToAttachmentAlreadyAddedError) } @@ -622,13 +622,13 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur if let navigationController = navigationController { let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, updatedPresentationData: updatedPresentationData, filter: filters, hasChatListSelector: true, hasContactSelector: false, title: presentationData.strings.WebApp_SelectChat)) controller.peerSelected = { peer in - let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload), useExisting: true)) + let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: peer.id), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true)) } navigationController.pushViewController(controller) } } else { if let navigationController = navigationController, case let .chat(chatPeerId, _) = urlContext { - let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload), useExisting: true)) + let _ = context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(id: chatPeerId), attachBotStart: ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: true), useExisting: true)) } } }) diff --git a/submodules/UrlHandling/Sources/UrlHandling.swift b/submodules/UrlHandling/Sources/UrlHandling.swift index a277e28ba8..4baca26a92 100644 --- a/submodules/UrlHandling/Sources/UrlHandling.swift +++ b/submodules/UrlHandling/Sources/UrlHandling.swift @@ -477,7 +477,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl) |> take(1) |> map { botPeer -> ResolvedUrl? in if let botPeer = botPeer?._asPeer() { - return .peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: startAttach))) + return .peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: startAttach, justInstalled: false))) } else { return .peer(peer.id, .chat(textInputState: nil, subject: nil, peekData: nil)) } @@ -511,7 +511,7 @@ private func resolveInternalUrl(context: AccountContext, url: ParsedInternalUrl) } |> mapToSignal { botPeer -> Signal in if let botPeer = botPeer { - return .single(.peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload)))) + return .single(.peer(peer.id, .withAttachBot(ChatControllerInitialAttachBotStart(botId: botPeer.id, payload: payload, justInstalled: false)))) } else { return .single(.peer(peer.id, .chat(textInputState: nil, subject: nil, peekData: nil))) }