Web app improvements

This commit is contained in:
Ilya Laktyushin 2022-04-10 13:29:22 +04:00
parent 98ba4e7d77
commit aec940a39e
5 changed files with 47 additions and 34 deletions

View file

@ -10694,10 +10694,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let _ = (context.engine.messages.getAttachMenuBot(botId: botId)
|> deliverOnMainQueue).start(next: { bot in
let peer = EnginePeer(bot.peer)
guard let icon = bot.icons[.default] else {
return
}
let controller = addWebAppToAttachmentController(context: context, peerName: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), peerIcon: icon, completion: {
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

View file

@ -558,10 +558,7 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
let _ = (context.engine.messages.getAttachMenuBot(botId: peerId)
|> deliverOnMainQueue).start(next: { bot in
let peer = EnginePeer(bot.peer)
guard let icon = bot.icons[.default] else {
return
}
let controller = addWebAppToAttachmentController(context: context, peerName: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), peerIcon: icon, completion: {
let controller = addWebAppToAttachmentController(context: context, peerName: peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder), icons: bot.icons, completion: {
let _ = (context.engine.messages.addBotToAttachMenu(botId: peerId)
|> deliverOnMainQueue).start(error: { _ in
presentError(presentationData.strings.WebApp_AddToAttachmentUnavailableError)

View file

@ -14,7 +14,7 @@ import PhotoResources
private final class WebAppAlertContentNode: AlertContentNode {
private let strings: PresentationStrings
private let peerName: String
private let peerIcon: TelegramMediaFile
private let peerIcon: TelegramMediaFile?
private let textNode: ASTextNode
private let appIconNode: ASImageNode
@ -32,10 +32,17 @@ private final class WebAppAlertContentNode: AlertContentNode {
return self.isUserInteractionEnabled
}
init(account: Account, theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, peerName: String, peerIcon: TelegramMediaFile, actions: [TextAlertAction]) {
init(account: Account, theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, peerName: String, icons: [AttachMenuBots.Bot.IconName: TelegramMediaFile], actions: [TextAlertAction]) {
self.strings = strings
self.peerName = peerName
self.peerIcon = peerIcon
if let icon = icons[.iOSStatic] {
self.peerIcon = icon
} else if let icon = icons[.default] {
self.peerIcon = icon
} else {
self.peerIcon = nil
}
self.textNode = ASTextNode()
self.textNode.maximumNumberOfLines = 0
@ -83,17 +90,19 @@ private final class WebAppAlertContentNode: AlertContentNode {
self.updateTheme(theme)
let _ = freeMediaFileInteractiveFetched(account: account, fileReference: .standalone(media: peerIcon)).start()
self.iconDisposable = (svgIconImageFile(account: account, fileReference: .standalone(media: peerIcon))
|> deliverOnMainQueue).start(next: { [weak self] transform in
if let strongSelf = self {
let availableSize = CGSize(width: 48.0, height: 48.0)
let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: availableSize, boundingSize: availableSize, intrinsicInsets: UIEdgeInsets())
let drawingContext = transform(arguments)
let image = drawingContext?.generateImage()?.withRenderingMode(.alwaysTemplate)
strongSelf.appIconNode.image = generateTintedImage(image: image, color: theme.accentColor, backgroundColor: nil)
}
})
if let peerIcon = self.peerIcon {
let _ = freeMediaFileInteractiveFetched(account: account, fileReference: .standalone(media: peerIcon)).start()
self.iconDisposable = (svgIconImageFile(account: account, fileReference: .standalone(media: peerIcon))
|> deliverOnMainQueue).start(next: { [weak self] transform in
if let strongSelf = self {
let availableSize = CGSize(width: 48.0, height: 48.0)
let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: availableSize, boundingSize: availableSize, intrinsicInsets: UIEdgeInsets())
let drawingContext = transform(arguments)
let image = drawingContext?.generateImage()?.withRenderingMode(.alwaysTemplate)
strongSelf.appIconNode.image = generateTintedImage(image: image, color: theme.accentColor, backgroundColor: nil)
}
})
}
}
deinit {
@ -230,7 +239,7 @@ private final class WebAppAlertContentNode: AlertContentNode {
}
}
public func addWebAppToAttachmentController(context: AccountContext, peerName: String, peerIcon: TelegramMediaFile, completion: @escaping () -> Void) -> AlertController {
public func addWebAppToAttachmentController(context: AccountContext, peerName: String, icons: [AttachMenuBots.Bot.IconName: TelegramMediaFile], completion: @escaping () -> Void) -> AlertController {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let theme = presentationData.theme
let strings = presentationData.strings
@ -245,7 +254,7 @@ public func addWebAppToAttachmentController(context: AccountContext, peerName: S
completion()
})]
contentNode = WebAppAlertContentNode(account: context.account, theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, peerName: peerName, peerIcon: peerIcon, actions: actions)
contentNode = WebAppAlertContentNode(account: context.account, theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, peerName: peerName, icons: icons, actions: actions)
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode!)
dismissImpl = { [weak controller] animated in

View file

@ -119,6 +119,12 @@ public final class WebAppController: ViewController, AttachmentContainable {
webView.handleScriptMessage = { [weak self] message in
self?.handleScriptMessage(message)
}
webView.onFirstTouch = { [weak self] in
if let strongSelf = self, let delayedScriptMessage = strongSelf.delayedScriptMessage {
strongSelf.delayedScriptMessage = nil
strongSelf.handleScriptMessage(delayedScriptMessage)
}
}
self.webView = webView
let placeholderNode = ShimmerEffectNode()
@ -315,11 +321,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
placeholderNode?.removeFromSupernode()
})
}
Queue.mainQueue().after(1.0, {
webView.handleTap()
})
if let (layout, navigationBarHeight) = self.validLayout {
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
}
@ -406,7 +408,8 @@ public final class WebAppController: ViewController, AttachmentContainable {
self.loadingProgressPromise.set(.single(CGFloat(webView.estimatedProgress)))
}
}
private var delayedScriptMessage: WKScriptMessage?
private func handleScriptMessage(_ message: WKScriptMessage) {
guard let body = message.body as? [String: Any] else {
return
@ -425,7 +428,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
}
case "web_app_setup_main_button":
if let webView = self.webView, !webView.didTouchOnce {
self.delayedScriptMessage = message
} else if let eventData = (body["eventData"] as? String)?.data(using: .utf8), let json = try? JSONSerialization.jsonObject(with: eventData, options: []) as? [String: Any] {
if var isVisible = json["is_visible"] as? Bool {
let text = json["text"] as? String

View file

@ -131,9 +131,7 @@ final class WebAppWebView: WKWebView {
}
private(set) var didTouchOnce = false
@objc func handleTap() {
self.didTouchOnce = true
}
var onFirstTouch: () -> Void = {}
func scrollToActiveElement(layout: ContainerViewLayout, completion: @escaping (CGPoint) -> Void, transition: ContainedViewLayoutTransition) {
self.evaluateJavaScript(findActiveElementY, completionHandler: { result, _ in
@ -159,6 +157,15 @@ final class WebAppWebView: WKWebView {
})
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let result = super.hitTest(point, with: event)
if result != nil && !self.didTouchOnce {
self.didTouchOnce = true
self.onFirstTouch()
}
return result
}
override var inputAccessoryView: UIView? {
return nil
}