Web app improvements

This commit is contained in:
Ilya Laktyushin 2024-07-01 22:04:35 +04:00
parent a28ec1d157
commit 2a48721e28
5 changed files with 122 additions and 47 deletions

View File

@ -5136,43 +5136,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
}
private func openPeer(peerId: PeerId, navigation: ChatControllerInteractionNavigateToPeer) {
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer in
guard let self, let peer = peer else {
return
}
switch navigation {
case .default:
if let navigationController = self.controller?.navigationController as? NavigationController {
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), keepStack: .always))
}
case let .chat(_, subject, peekData):
if let navigationController = self.controller?.navigationController as? NavigationController {
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), subject: subject, keepStack: .always, peekData: peekData))
}
case .info:
if peer.restrictionText(platform: "ios", contentSettings: self.context.currentContentSettings.with { $0 }) == nil {
if let infoController = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
(self.controller?.navigationController as? NavigationController)?.pushViewController(infoController)
}
}
case let .withBotStartPayload(startPayload):
if let navigationController = self.controller?.navigationController as? NavigationController {
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), botStart: startPayload))
}
case let .withAttachBot(attachBotStart):
if let navigationController = self.controller?.navigationController as? NavigationController {
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
}
case let .withBotApp(botAppStart):
if let navigationController = self.controller?.navigationController as? NavigationController {
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(peer), botAppStart: botAppStart))
}
}
})
guard let navigationController = self.controller?.navigationController as? NavigationController else {
return
}
PeerInfoScreenImpl.openPeer(context: self.context, peerId: peerId, navigation: navigation, navigationController: navigationController)
}
private func openPeerMention(_ name: String, navigation: ChatControllerInteractionNavigateToPeer = .default) {
let disposable: MetaDisposable
if let resolvePeerByNameDisposable = self.resolvePeerByNameDisposable {
@ -5311,17 +5280,55 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
guard let self else {
return
}
let context = self.context
let peerId = self.peerId
let params = WebAppParameters(source: .settings, peerId: self.context.account.peerId, botId: bot.peer.id, botName: bot.peer.compactDisplayTitle, url: nil, queryId: nil, payload: nil, buttonText: nil, keepAliveSignal: nil, forceHasSettings: bot.flags.contains(.hasSettings), fullSize: true)
let controller = standaloneWebAppController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, params: params, threadId: nil, openUrl: { [weak self] url, concealed, commit in
self?.openUrl(url: url, concealed: concealed, external: false, forceExternal: true, commit: commit)
var openUrlImpl: ((String, Bool, @escaping () -> Void) -> Void)?
var presentImpl: ((ViewController, Any?) -> Void)?
let controller = standaloneWebAppController(context: context, updatedPresentationData: self.controller?.updatedPresentationData, params: params, threadId: nil, openUrl: { url, concealed, commit in
openUrlImpl?(url, concealed, commit)
}, requestSwitchInline: { _, _, _ in
}, getNavigationController: { [weak self] in
return self?.controller?.navigationController as? NavigationController
return (self?.controller?.navigationController as? NavigationController) ?? context.sharedContext.mainWindow?.viewController as? NavigationController
})
controller.navigationPresentation = .flatModal
self.controller?.push(controller)
openUrlImpl = { [weak self, weak controller] url, concealed, commit in
let _ = openUserGeneratedUrl(context: context, peerId: peerId, url: url, concealed: concealed, present: { [weak self] c in
self?.controller?.present(c, in: .window(.root))
}, openResolved: { result in
var navigationController: NavigationController?
if let current = self?.controller?.navigationController as? NavigationController {
navigationController = current
} else if let current = controller?.navigationController as? NavigationController {
navigationController = current
}
context.sharedContext.openResolvedUrl(result, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, openPeer: { peer, navigation in
if let navigationController {
PeerInfoScreenImpl.openPeer(context: context, peerId: peer.id, navigation: navigation, navigationController: navigationController)
}
commit()
}, sendFile: nil,
sendSticker: nil,
sendEmoji: nil,
requestMessageActionUrlAuth: nil,
joinVoiceChat: { peerId, invite, call in
},
present: { c, a in
presentImpl?(c, a)
}, dismissInput: {
context.sharedContext.mainWindow?.viewController?.view.endEditing(false)
}, contentContext: nil, progress: nil, completion: nil)
})
}
presentImpl = { [weak controller] c, a in
controller?.present(c, in: .window(.root), with: a)
}
if installed {
Queue.mainQueue().after(0.3, {
let text: String
@ -12372,6 +12379,33 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
self.controllerNode.updateProfileVideo(image, asset: asset, adjustments: adjustments, mode: mode)
}
static func openPeer(context: AccountContext, peerId: PeerId, navigation: ChatControllerInteractionNavigateToPeer, navigationController: NavigationController) {
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|> deliverOnMainQueue).startStandalone(next: { peer in
guard let peer else {
return
}
switch navigation {
case .default:
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), keepStack: .always))
case let .chat(_, subject, peekData):
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), subject: subject, keepStack: .always, peekData: peekData))
case .info:
if peer.restrictionText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) == nil {
if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
navigationController.pushViewController(infoController)
}
}
case let .withBotStartPayload(startPayload):
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), botStart: startPayload))
case let .withAttachBot(attachBotStart):
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), attachBotStart: attachBotStart))
case let .withBotApp(botAppStart):
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer), botAppStart: botAppStart))
}
})
}
public static func displayChatNavigationMenu(context: AccountContext, chatNavigationStack: [ChatNavigationStackItem], nextFolderId: Int32?, parentController: ViewController, backButtonView: UIView, navigationController: NavigationController, gesture: ContextGesture) {
let peerMap = EngineDataMap(
Set(chatNavigationStack.map(\.peerId)).map(TelegramEngine.EngineData.Item.Peer.Peer.init)

View File

@ -178,7 +178,7 @@ final class SharedApplicationContext {
let notificationManager: SharedNotificationManager
let wakeupManager: SharedWakeupManager
let overlayMediaController: ViewController & OverlayMediaController
var minimizedContainer: MinimizedContainer?
var minimizedContainer: [AccountRecordId: MinimizedContainer] = [:]
init(sharedContext: SharedAccountContextImpl, notificationManager: SharedNotificationManager, wakeupManager: SharedWakeupManager) {
self.sharedContext = sharedContext

View File

@ -169,9 +169,12 @@ final class AuthorizedApplicationContext {
self.notificationController = NotificationContainerController(context: context)
self.rootController = TelegramRootController(context: context)
self.rootController.minimizedContainer = self.sharedApplicationContext.minimizedContainer
self.rootController.minimizedContainer = self.sharedApplicationContext.minimizedContainer[context.account.id]
self.rootController.minimizedContainerUpdated = { [weak self] minimizedContainer in
self?.sharedApplicationContext.minimizedContainer = minimizedContainer
guard let self else {
return
}
self.sharedApplicationContext.minimizedContainer[self.context.account.id] = minimizedContainer
}
self.rootController.globalOverlayControllersUpdated = { [weak self] in

View File

@ -34,7 +34,8 @@ swift_library(
"//submodules/Markdown:Markdown",
"//submodules/TextFormat:TextFormat",
"//submodules/LocalAuth",
"//submodules/InstantPageCache"
"//submodules/InstantPageCache",
"//submodules/OpenInExternalAppUI"
],
visibility = [
"//visibility:public",

View File

@ -25,6 +25,7 @@ import QrCodeUI
import InstantPageUI
import InstantPageCache
import LocalAuth
import OpenInExternalAppUI
private let durgerKingBotIds: [Int64] = [5104055776, 2200339955]
@ -158,7 +159,7 @@ public class WebAppCancelButtonNode: ASDisplayNode {
let color = self.color ?? self.theme.rootController.navigationBar.accentTextColor
self.arrowNode.isHidden = state == .cancel
self.labelNode.attributedText = NSAttributedString(string: state == .cancel ? self.strings.Common_Cancel : self.strings.Common_Back, font: Font.regular(17.0), textColor: color)
self.labelNode.attributedText = NSAttributedString(string: state == .cancel ? self.strings.Common_Close : self.strings.Common_Back, font: Font.regular(17.0), textColor: color)
let labelSize = self.labelNode.updateLayout(CGSize(width: 120.0, height: 56.0))
@ -941,6 +942,8 @@ public final class WebAppController: ViewController, AttachmentContainable {
}
let tryInstantView = json["try_instant_view"] as? Bool ?? false
let tryBrowser = json["try_browser"] as? String
if let lastTouchTimestamp = self.webView?.lastTouchTimestamp, currentTimestamp < lastTouchTimestamp + 10.0 {
self.webView?.lastTouchTimestamp = nil
if tryInstantView {
@ -964,6 +967,40 @@ public final class WebAppController: ViewController, AttachmentContainable {
}
})
} else {
var url = url
if let tryBrowser {
let openInOptions = availableOpenInOptions(context: self.context, item: .url(url: url))
var matchingOption: OpenInOption?
for option in openInOptions {
if case let .other(identifier, _, _, _) = option.application {
switch tryBrowser {
case "safari":
break
case "chrome":
if identifier == "chrome" {
matchingOption = option
break
}
case "firefox":
if ["firefox", "firefoxFocus"].contains(identifier) {
matchingOption = option
break
}
case "opera":
if ["operaMini", "operaTouch"].contains(identifier) {
matchingOption = option
break
}
default:
break
}
}
}
if let matchingOption, case let .openUrl(newUrl) = matchingOption.action() {
url = newUrl
}
}
self.context.sharedContext.openExternalUrl(context: self.context, urlContext: .generic, url: url, forceExternal: true, presentationData: self.context.sharedContext.currentPresentationData.with { $0 }, navigationController: nil, dismissInput: {})
}
}
@ -1920,9 +1957,9 @@ public final class WebAppController: ViewController, AttachmentContainable {
guard let self, let chatPeer else {
return
}
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(chatPeer), completion: { _ in
completion()
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: self.context, chatLocation: .peer(chatPeer), keepStack: .always, completion: { _ in
}))
completion()
})
}
}