mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Merge commit '9ff797d9a42b6bb169ae647ab8d64d08c15dc70f'
This commit is contained in:
commit
a693668a1e
@ -2283,8 +2283,19 @@ public func instantPageImageFile(account: Account, fileReference: FileMediaRefer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func svgIconImageFile(account: Account, fileReference: FileMediaReference, stickToTop: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
public func svgIconImageFile(account: Account, fileReference: FileMediaReference?, stickToTop: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||||
let data = account.postbox.mediaBox.cachedResourceRepresentation(fileReference.media.resource, representation: CachedPreparedSvgRepresentation(), complete: false, fetch: true)
|
let data: Signal<MediaResourceData, NoError>
|
||||||
|
if let fileReference = fileReference {
|
||||||
|
data = account.postbox.mediaBox.cachedResourceRepresentation(fileReference.media.resource, representation: CachedPreparedSvgRepresentation(), complete: false, fetch: true)
|
||||||
|
} else {
|
||||||
|
data = Signal { subscriber in
|
||||||
|
if let url = getAppBundle().url(forResource: "durgerking", withExtension: "placeholder"), let data = try? Data(contentsOf: url, options: .mappedRead) {
|
||||||
|
subscriber.putNext(MediaResourceData(path: url.path, offset: 0, size: data.count, complete: true))
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}
|
||||||
|
return EmptyDisposable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|> map { value in
|
|> map { value in
|
||||||
@ -2301,8 +2312,6 @@ public func svgIconImageFile(account: Account, fileReference: FileMediaReference
|
|||||||
|
|
||||||
if fullSizeComplete, let data = try? Data(contentsOf: URL(fileURLWithPath: fullSizePath)) {
|
if fullSizeComplete, let data = try? Data(contentsOf: URL(fileURLWithPath: fullSizePath)) {
|
||||||
fullSizeImage = renderPreparedImage(data, CGSize.zero, .clear, UIScreenScale)
|
fullSizeImage = renderPreparedImage(data, CGSize.zero, .clear, UIScreenScale)
|
||||||
|
|
||||||
// fullSizeImage = drawSvgImage(data, stickToTop ? CGSize.zero : CGSize(width: 90.0, height: 90.0), .clear, .black, false)
|
|
||||||
if let image = fullSizeImage {
|
if let image = fullSizeImage {
|
||||||
fittedSize = image.size.aspectFitted(arguments.boundingSize)
|
fittedSize = image.size.aspectFitted(arguments.boundingSize)
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
submodules/TelegramUI/Resources/durgerking.placeholder
Normal file
BIN
submodules/TelegramUI/Resources/durgerking.placeholder
Normal file
Binary file not shown.
@ -18,6 +18,8 @@ import PhotoResources
|
|||||||
import LegacyComponents
|
import LegacyComponents
|
||||||
import UrlHandling
|
import UrlHandling
|
||||||
|
|
||||||
|
private let durgerKingBotIds: [Int64] = [5104055776, 2200339955]
|
||||||
|
|
||||||
public struct WebAppParameters {
|
public struct WebAppParameters {
|
||||||
let peerId: PeerId
|
let peerId: PeerId
|
||||||
let botId: PeerId
|
let botId: PeerId
|
||||||
@ -89,6 +91,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
private let present: (ViewController, Any?) -> Void
|
private let present: (ViewController, Any?) -> Void
|
||||||
private var queryId: Int64?
|
private var queryId: Int64?
|
||||||
|
|
||||||
|
private var placeholderDisposable: Disposable?
|
||||||
private var iconDisposable: Disposable?
|
private var iconDisposable: Disposable?
|
||||||
private var keepAliveDisposable: Disposable?
|
private var keepAliveDisposable: Disposable?
|
||||||
|
|
||||||
@ -122,11 +125,18 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
self.addSubnode(placeholderNode)
|
self.addSubnode(placeholderNode)
|
||||||
self.placeholderNode = placeholderNode
|
self.placeholderNode = placeholderNode
|
||||||
|
|
||||||
let _ = (self.context.engine.messages.getAttachMenuBot(botId: controller.botId, cached: true)
|
let placeholder: Signal<(FileMediaReference, Bool)?, NoError>
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] bot in
|
if durgerKingBotIds.contains(controller.botId.id._internalGetInt64Value()) {
|
||||||
guard let strongSelf = self else {
|
placeholder = .single(nil)
|
||||||
return
|
|> delay(0.05, queue: Queue.mainQueue())
|
||||||
|
} else {
|
||||||
|
placeholder = self.context.engine.messages.getAttachMenuBot(botId: controller.botId, cached: true)
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { error -> Signal<AttachMenuBot?, NoError> in
|
||||||
|
return .complete()
|
||||||
}
|
}
|
||||||
|
|> mapToSignal { bot -> Signal<(FileMediaReference, Bool)?, NoError> in
|
||||||
|
if let bot = bot, let peerReference = PeerReference(bot.peer) {
|
||||||
var imageFile: TelegramMediaFile?
|
var imageFile: TelegramMediaFile?
|
||||||
var isPlaceholder = false
|
var isPlaceholder = false
|
||||||
if let file = bot.icons[.placeholder] {
|
if let file = bot.icons[.placeholder] {
|
||||||
@ -137,15 +147,42 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
} else if let file = bot.icons[.default] {
|
} else if let file = bot.icons[.default] {
|
||||||
imageFile = file
|
imageFile = file
|
||||||
}
|
}
|
||||||
if let imageFile = imageFile, let peer = PeerReference(bot.peer) {
|
if let imageFile = imageFile {
|
||||||
let _ = freeMediaFileInteractiveFetched(account: strongSelf.context.account, fileReference: .attachBot(peer: peer, media: imageFile)).start()
|
return .single((.attachBot(peer: peerReference, media: imageFile), isPlaceholder))
|
||||||
strongSelf.iconDisposable = (svgIconImageFile(account: strongSelf.context.account, fileReference: .attachBot(peer: peer, media: imageFile), stickToTop: isPlaceholder)
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.placeholderDisposable = (placeholder
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] fileReferenceAndIsPlaceholder in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let fileReference: FileMediaReference?
|
||||||
|
let isPlaceholder: Bool
|
||||||
|
if let (maybeFileReference, maybeIsPlaceholder) = fileReferenceAndIsPlaceholder {
|
||||||
|
fileReference = maybeFileReference
|
||||||
|
isPlaceholder = maybeIsPlaceholder
|
||||||
|
} else {
|
||||||
|
fileReference = nil
|
||||||
|
isPlaceholder = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if let fileReference = fileReference {
|
||||||
|
let _ = freeMediaFileInteractiveFetched(account: strongSelf.context.account, fileReference: fileReference).start()
|
||||||
|
}
|
||||||
|
strongSelf.iconDisposable = (svgIconImageFile(account: strongSelf.context.account, fileReference: fileReference, stickToTop: isPlaceholder)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] transform in
|
|> deliverOnMainQueue).start(next: { [weak self] transform in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let imageSize: CGSize
|
let imageSize: CGSize
|
||||||
if isPlaceholder, let (layout, _) = strongSelf.validLayout {
|
if isPlaceholder, let (layout, _) = strongSelf.validLayout {
|
||||||
let minSize = min(layout.size.width, layout.size.height)
|
let minSize = min(layout.size.width, layout.size.height)
|
||||||
imageSize = CGSize(width: minSize, height: minSize * 3.0)
|
imageSize = CGSize(width: minSize, height: minSize * 2.0)
|
||||||
} else {
|
} else {
|
||||||
imageSize = CGSize(width: 75.0, height: 75.0)
|
imageSize = CGSize(width: 75.0, height: 75.0)
|
||||||
}
|
}
|
||||||
@ -157,9 +194,9 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
|
strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
strongSelf.placeholderNode?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if let url = controller.url, !controller.fromMenu {
|
if let url = controller.url, !controller.fromMenu {
|
||||||
@ -207,6 +244,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
self.placeholderDisposable?.dispose()
|
||||||
self.iconDisposable?.dispose()
|
self.iconDisposable?.dispose()
|
||||||
self.keepAliveDisposable?.dispose()
|
self.keepAliveDisposable?.dispose()
|
||||||
|
|
||||||
@ -262,7 +300,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
|
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
|
||||||
Queue.mainQueue().after(0.65, {
|
Queue.mainQueue().after(1.0, {
|
||||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .linear)
|
let transition = ContainedViewLayoutTransition.animated(duration: 0.2, curve: .linear)
|
||||||
transition.updateAlpha(layer: webView.layer, alpha: 1.0)
|
transition.updateAlpha(layer: webView.layer, alpha: 1.0)
|
||||||
if let placeholderNode = self.placeholderNode {
|
if let placeholderNode = self.placeholderNode {
|
||||||
@ -283,9 +321,14 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
decisionHandler(.prompt)
|
decisionHandler(.prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var targetContentOffset: CGPoint?
|
||||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||||
let contentOffset = scrollView.contentOffset.y
|
let contentOffset = scrollView.contentOffset.y
|
||||||
self.controller?.navigationBar?.updateBackgroundAlpha(min(30.0, contentOffset) / 30.0, transition: .immediate)
|
self.controller?.navigationBar?.updateBackgroundAlpha(min(30.0, contentOffset) / 30.0, transition: .immediate)
|
||||||
|
|
||||||
|
if let targetContentOffset = self.targetContentOffset, scrollView.contentOffset != targetContentOffset {
|
||||||
|
scrollView.contentOffset = targetContentOffset
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var validLayout: (ContainerViewLayout, CGFloat)?
|
private var validLayout: (ContainerViewLayout, CGFloat)?
|
||||||
@ -298,8 +341,16 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
let viewportFrame = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: navigationBarHeight), size: CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right, height: max(1.0, layout.size.height - navigationBarHeight - layout.intrinsicInsets.bottom - layout.additionalInsets.bottom)))
|
let viewportFrame = CGRect(origin: CGPoint(x: layout.safeInsets.left, y: navigationBarHeight), size: CGSize(width: layout.size.width - layout.safeInsets.left - layout.safeInsets.right, height: max(1.0, layout.size.height - navigationBarHeight - layout.intrinsicInsets.bottom - layout.additionalInsets.bottom)))
|
||||||
|
|
||||||
if previousLayout != nil && (previousLayout?.inputHeight ?? 0.0).isZero, let inputHeight = layout.inputHeight, inputHeight > 44.0, transition.isAnimated {
|
if previousLayout != nil && (previousLayout?.inputHeight ?? 0.0).isZero, let inputHeight = layout.inputHeight, inputHeight > 44.0, transition.isAnimated {
|
||||||
|
webView.scrollToActiveElement(layout: layout, completion: { [weak self] contentOffset in
|
||||||
|
self?.targetContentOffset = contentOffset
|
||||||
|
}, transition: transition)
|
||||||
Queue.mainQueue().after(0.4, {
|
Queue.mainQueue().after(0.4, {
|
||||||
|
if let inputHeight = self.validLayout?.0.inputHeight, inputHeight > 44.0 {
|
||||||
transition.updateFrame(view: webView, frame: frame)
|
transition.updateFrame(view: webView, frame: frame)
|
||||||
|
Queue.mainQueue().after(0.1) {
|
||||||
|
self.targetContentOffset = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
transition.updateFrame(view: webView, frame: frame)
|
transition.updateFrame(view: webView, frame: frame)
|
||||||
|
|||||||
@ -4,6 +4,17 @@ import Display
|
|||||||
import WebKit
|
import WebKit
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
|
private let findActiveElementY = """
|
||||||
|
function getOffset(el) {
|
||||||
|
const rect = el.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
left: rect.left + window.scrollX,
|
||||||
|
top: rect.top + window.scrollY
|
||||||
|
};
|
||||||
|
}
|
||||||
|
getOffset(document.activeElement).top;
|
||||||
|
"""
|
||||||
|
|
||||||
private class WeakGameScriptMessageHandler: NSObject, WKScriptMessageHandler {
|
private class WeakGameScriptMessageHandler: NSObject, WKScriptMessageHandler {
|
||||||
private let f: (WKScriptMessage) -> ()
|
private let f: (WKScriptMessage) -> ()
|
||||||
|
|
||||||
@ -64,6 +75,8 @@ final class WebAppWebView: WKWebView {
|
|||||||
|
|
||||||
super.init(frame: CGRect(), configuration: configuration)
|
super.init(frame: CGRect(), configuration: configuration)
|
||||||
|
|
||||||
|
self.disablesInteractiveKeyboardGestureRecognizer = true
|
||||||
|
|
||||||
self.isOpaque = false
|
self.isOpaque = false
|
||||||
self.backgroundColor = .clear
|
self.backgroundColor = .clear
|
||||||
if #available(iOSApplicationExtension 9.0, iOS 9.0, *) {
|
if #available(iOSApplicationExtension 9.0, iOS 9.0, *) {
|
||||||
@ -82,10 +95,6 @@ final class WebAppWebView: WKWebView {
|
|||||||
strongSelf.handleScriptMessage(message)
|
strongSelf.handleScriptMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let tapGestureRecognizer = WebViewTouchGestureRecognizer(target: self, action: #selector(self.handleTap))
|
|
||||||
// tapGestureRecognizer.delegate = self
|
|
||||||
// self.addGestureRecognizer(tapGestureRecognizer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
@ -104,6 +113,10 @@ final class WebAppWebView: WKWebView {
|
|||||||
}
|
}
|
||||||
contentView?.removeInteraction(dragInteraction)
|
contentView?.removeInteraction(dragInteraction)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
|
||||||
|
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
|
||||||
|
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,6 +135,30 @@ final class WebAppWebView: WKWebView {
|
|||||||
self.didTouchOnce = true
|
self.didTouchOnce = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func scrollToActiveElement(layout: ContainerViewLayout, completion: @escaping (CGPoint) -> Void, transition: ContainedViewLayoutTransition) {
|
||||||
|
self.evaluateJavaScript(findActiveElementY, completionHandler: { result, _ in
|
||||||
|
if let result = result as? CGFloat {
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
let convertedY = result - self.scrollView.contentOffset.y
|
||||||
|
let viewportHeight = self.frame.height - (layout.inputHeight ?? 0.0) + 26.0
|
||||||
|
if convertedY < 0.0 || (convertedY + 44.0) > viewportHeight {
|
||||||
|
let targetOffset: CGFloat
|
||||||
|
if convertedY < 0.0 {
|
||||||
|
targetOffset = max(0.0, result - 36.0)
|
||||||
|
} else {
|
||||||
|
targetOffset = max(0.0, result + 60.0 - viewportHeight)
|
||||||
|
}
|
||||||
|
let contentOffset = CGPoint(x: 0.0, y: targetOffset)
|
||||||
|
completion(contentOffset)
|
||||||
|
transition.animateView({
|
||||||
|
self.scrollView.contentOffset = contentOffset
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
override var inputAccessoryView: UIView? {
|
override var inputAccessoryView: UIView? {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user