mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 01:10:09 +00:00
Web app improvements
This commit is contained in:
parent
08ec00bf91
commit
b92746d357
@ -829,8 +829,12 @@ public class AttachmentController: ViewController {
|
|||||||
super.dismiss(animated: false, completion: {})
|
super.dismiss(animated: false, completion: {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var ensureUnfocused = true
|
||||||
|
|
||||||
public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
|
public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
|
||||||
self.view.endEditing(true)
|
if self.ensureUnfocused {
|
||||||
|
self.view.endEditing(true)
|
||||||
|
}
|
||||||
if flag {
|
if flag {
|
||||||
if !self.didDismiss {
|
if !self.didDismiss {
|
||||||
self.didDismiss = true
|
self.didDismiss = true
|
||||||
|
|||||||
@ -806,7 +806,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
let type = self.buttons[i]
|
let type = self.buttons[i]
|
||||||
if case let .app(peer, _, iconFiles) = type {
|
if case let .app(peer, _, iconFiles) = type {
|
||||||
for (name, file) in iconFiles {
|
for (name, file) in iconFiles {
|
||||||
if [.default, .iOSAnimated].contains(name) {
|
if [.default, .iOSAnimated, .placeholder].contains(name) {
|
||||||
if self.iconDisposables[file.fileId] == nil, let peer = PeerReference(peer) {
|
if self.iconDisposables[file.fileId] == nil, let peer = PeerReference(peer) {
|
||||||
self.iconDisposables[file.fileId] = freeMediaFileInteractiveFetched(account: self.context.account, fileReference: .attachBot(peer: peer, media: file)).start()
|
self.iconDisposables[file.fileId] = freeMediaFileInteractiveFetched(account: self.context.account, fileReference: .attachBot(peer: peer, media: file)).start()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2283,7 +2283,7 @@ public func instantPageImageFile(account: Account, fileReference: FileMediaRefer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func svgIconImageFile(account: Account, fileReference: FileMediaReference, fetched: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
public func svgIconImageFile(account: Account, fileReference: FileMediaReference, stickToTop: Bool = false, fetched: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||||
return chatMessageFileDatas(account: account, fileReference: fileReference, progressive: false, fetched: false)
|
return chatMessageFileDatas(account: account, fileReference: fileReference, progressive: false, fetched: false)
|
||||||
|> map { value in
|
|> map { value in
|
||||||
let fullSizePath = value._1
|
let fullSizePath = value._1
|
||||||
@ -2300,11 +2300,14 @@ public func svgIconImageFile(account: Account, fileReference: FileMediaReference
|
|||||||
|
|
||||||
if let fullSizePath = fullSizePath {
|
if let fullSizePath = fullSizePath {
|
||||||
if fullSizeComplete, let data = try? Data(contentsOf: URL(fileURLWithPath: fullSizePath)) {
|
if fullSizeComplete, let data = try? Data(contentsOf: URL(fileURLWithPath: fullSizePath)) {
|
||||||
fullSizeImage = drawSvgImage(data, CGSize(width: 90.0, height: 90.0), .clear, .black, false)
|
fullSizeImage = drawSvgImage(data, CGSize.zero, .clear, .black, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize)
|
var fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize)
|
||||||
|
if stickToTop {
|
||||||
|
fittedRect.origin.y = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
context.withFlippedContext { c in
|
context.withFlippedContext { c in
|
||||||
if let fullSizeImage = fullSizeImage?.cgImage {
|
if let fullSizeImage = fullSizeImage?.cgImage {
|
||||||
|
|||||||
@ -111,6 +111,10 @@ UIImage * _Nullable drawSvgImage(NSData * _Nonnull data, CGSize size, UIColor *b
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CGSizeEqualToSize(size, CGSizeZero)) {
|
||||||
|
size = CGSizeMake(image->width, image->height);
|
||||||
|
}
|
||||||
|
|
||||||
double deltaTime = -1.0f * [startTime timeIntervalSinceNow];
|
double deltaTime = -1.0f * [startTime timeIntervalSinceNow];
|
||||||
printf("parseTime = %f\n", deltaTime);
|
printf("parseTime = %f\n", deltaTime);
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ public final class AttachMenuBots: Equatable, Codable {
|
|||||||
case iOSStatic
|
case iOSStatic
|
||||||
case iOSAnimated
|
case iOSAnimated
|
||||||
case macOSAnimated
|
case macOSAnimated
|
||||||
|
case placeholder
|
||||||
|
|
||||||
init?(string: String) {
|
init?(string: String) {
|
||||||
switch string {
|
switch string {
|
||||||
@ -27,6 +28,8 @@ public final class AttachMenuBots: Equatable, Codable {
|
|||||||
self = .iOSAnimated
|
self = .iOSAnimated
|
||||||
case "macos_animated":
|
case "macos_animated":
|
||||||
self = .macOSAnimated
|
self = .macOSAnimated
|
||||||
|
case "placeholder_static":
|
||||||
|
self = .placeholder
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3377,7 +3377,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
self?.interfaceInteraction?.updateShowWebView { _ in
|
self?.interfaceInteraction?.updateShowWebView { _ in
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
let isFocused = strongSelf.chatDisplayNode.textInputPanelNode?.isFocused ?? false
|
||||||
strongSelf.chatDisplayNode.insertSubnode(strongSelf.chatDisplayNode.inputPanelContainerNode, aboveSubnode: strongSelf.chatDisplayNode.historyNodeContainer)
|
strongSelf.chatDisplayNode.insertSubnode(strongSelf.chatDisplayNode.inputPanelContainerNode, aboveSubnode: strongSelf.chatDisplayNode.historyNodeContainer)
|
||||||
|
if isFocused {
|
||||||
|
strongSelf.chatDisplayNode.textInputPanelNode?.ensureFocused()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
strongSelf.present(controller, in: .window(.root))
|
strongSelf.present(controller, in: .window(.root))
|
||||||
strongSelf.currentMenuWebAppController = controller
|
strongSelf.currentMenuWebAppController = controller
|
||||||
@ -9772,6 +9776,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
if let currentMenuWebAppController = self.currentMenuWebAppController, !self.presentationInterfaceState.showWebView {
|
if let currentMenuWebAppController = self.currentMenuWebAppController, !self.presentationInterfaceState.showWebView {
|
||||||
self.currentMenuWebAppController = nil
|
self.currentMenuWebAppController = nil
|
||||||
|
if let currentMenuWebAppController = currentMenuWebAppController as? AttachmentController {
|
||||||
|
currentMenuWebAppController.ensureUnfocused = false
|
||||||
|
}
|
||||||
currentMenuWebAppController.dismiss(animated: true, completion: nil)
|
currentMenuWebAppController.dismiss(animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -75,7 +75,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
private weak var controller: WebAppController?
|
private weak var controller: WebAppController?
|
||||||
|
|
||||||
fileprivate var webView: WebAppWebView?
|
fileprivate var webView: WebAppWebView?
|
||||||
private var placeholderIcon: UIImage?
|
private var placeholderIcon: (UIImage, Bool)?
|
||||||
private var placeholderNode: ShimmerEffectNode?
|
private var placeholderNode: ShimmerEffectNode?
|
||||||
|
|
||||||
fileprivate let loadingProgressPromise = Promise<CGFloat?>(nil)
|
fileprivate let loadingProgressPromise = Promise<CGFloat?>(nil)
|
||||||
@ -124,22 +124,31 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var iconFile: TelegramMediaFile?
|
var imageFile: TelegramMediaFile?
|
||||||
if let file = bot.icons[.iOSStatic] {
|
var isPlaceholder = false
|
||||||
iconFile = file
|
if let file = bot.icons[.placeholder] {
|
||||||
|
imageFile = file
|
||||||
|
isPlaceholder = true
|
||||||
|
} else if let file = bot.icons[.iOSStatic] {
|
||||||
|
imageFile = file
|
||||||
} else if let file = bot.icons[.default] {
|
} else if let file = bot.icons[.default] {
|
||||||
iconFile = file
|
imageFile = file
|
||||||
}
|
}
|
||||||
if let iconFile = iconFile, let peer = PeerReference(bot.peer) {
|
if let imageFile = imageFile, let peer = PeerReference(bot.peer) {
|
||||||
let _ = freeMediaFileInteractiveFetched(account: strongSelf.context.account, fileReference: .attachBot(peer: peer, media: iconFile)).start()
|
let _ = freeMediaFileInteractiveFetched(account: strongSelf.context.account, fileReference: .attachBot(peer: peer, media: imageFile)).start()
|
||||||
strongSelf.iconDisposable = (svgIconImageFile(account: strongSelf.context.account, fileReference: .attachBot(peer: peer, media: iconFile))
|
strongSelf.iconDisposable = (svgIconImageFile(account: strongSelf.context.account, fileReference: .attachBot(peer: peer, media: imageFile), 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(width: 75.0, height: 75.0)
|
let imageSize: CGSize
|
||||||
|
if isPlaceholder, let (layout, _) = strongSelf.validLayout {
|
||||||
|
imageSize = layout.size
|
||||||
|
} else {
|
||||||
|
imageSize = CGSize(width: 75.0, height: 75.0)
|
||||||
|
}
|
||||||
let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets())
|
let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets())
|
||||||
let drawingContext = transform(arguments)
|
let drawingContext = transform(arguments)
|
||||||
if let image = drawingContext?.generateImage()?.withRenderingMode(.alwaysTemplate) {
|
if let image = drawingContext?.generateImage()?.withRenderingMode(.alwaysTemplate) {
|
||||||
strongSelf.placeholderIcon = image
|
strongSelf.placeholderIcon = (image, isPlaceholder)
|
||||||
if let (layout, navigationBarHeight) = strongSelf.validLayout {
|
if let (layout, navigationBarHeight) = strongSelf.validLayout {
|
||||||
strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
|
strongSelf.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
|
||||||
}
|
}
|
||||||
@ -213,31 +222,15 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
self.webView?.sendEvent(name: "main_button_pressed", data: nil)
|
self.webView?.sendEvent(name: "main_button_pressed", data: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updatePlaceholder(grid: Bool, layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) -> CGSize {
|
private func updatePlaceholder(layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
var shapes: [ShimmerEffect.ShimmerEffectNode.Shape] = []
|
var shapes: [ShimmerEffect.ShimmerEffectNode.Shape] = []
|
||||||
var placeholderSize: CGSize = CGSize()
|
var placeholderSize: CGSize = CGSize()
|
||||||
if grid {
|
|
||||||
let spacing: CGFloat = 8.0
|
|
||||||
let cols: Int = min(4, Int(floor(layout.size.width / 118.0)))
|
|
||||||
let itemSize: CGSize = CGSize(width: cols == 4 ? 111.0 : 118.0, height: 150.0)
|
|
||||||
let rows: Int = 4
|
|
||||||
|
|
||||||
let sideInset = floorToScreenPixels((layout.size.width - layout.safeInsets.left - layout.safeInsets.right - itemSize.width * CGFloat(cols) - spacing * CGFloat(cols - 1)) / 2.0)
|
|
||||||
|
|
||||||
for row in 0 ..< rows {
|
|
||||||
for col in 0 ..< cols {
|
|
||||||
shapes.append(.roundedRect(rect: CGRect(x: layout.safeInsets.left + sideInset + CGFloat(col) * (itemSize.width + spacing), y: navigationBarHeight + CGFloat(row) * (itemSize.height + spacing), width: itemSize.width, height: itemSize.height), cornerRadius: 10.0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
placeholderSize = layout.size
|
|
||||||
} else {
|
|
||||||
if let icon = self.placeholderIcon {
|
|
||||||
shapes = [.image(image: icon, rect: CGRect(origin: CGPoint(), size: icon.size))]
|
|
||||||
placeholderSize = icon.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if let (image, _) = self.placeholderIcon {
|
||||||
|
shapes = [.image(image: image, rect: CGRect(origin: CGPoint(), size: image.size))]
|
||||||
|
placeholderSize = image.size
|
||||||
|
}
|
||||||
|
|
||||||
let theme = self.presentationData.theme
|
let theme = self.presentationData.theme
|
||||||
self.placeholderNode?.update(backgroundColor: self.backgroundColor ?? .clear, foregroundColor: theme.list.mediaPlaceholderColor, shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, horizontal: true, size: placeholderSize)
|
self.placeholderNode?.update(backgroundColor: self.backgroundColor ?? .clear, foregroundColor: theme.list.mediaPlaceholderColor, shimmeringColor: theme.list.itemBlocksBackgroundColor.withAlphaComponent(0.4), shapes: shapes, horizontal: true, size: placeholderSize)
|
||||||
|
|
||||||
@ -294,7 +287,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) {
|
func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) {
|
||||||
decisionHandler(.prompt)
|
decisionHandler(.prompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -309,7 +302,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
let frame = 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)))
|
let frame = 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)))
|
||||||
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 == nil, 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 {
|
||||||
Queue.mainQueue().after(0.4, {
|
Queue.mainQueue().after(0.4, {
|
||||||
transition.updateFrame(view: webView, frame: frame)
|
transition.updateFrame(view: webView, frame: frame)
|
||||||
})
|
})
|
||||||
@ -328,9 +321,13 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
height = layout.size.height - layout.intrinsicInsets.bottom
|
height = layout.size.height - layout.intrinsicInsets.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
let grid = self.controller?.botId.id._internalGetInt64Value() == 2200339955
|
let placeholderSize = self.updatePlaceholder(layout: layout, navigationBarHeight: navigationBarHeight, transition: transition)
|
||||||
let placeholderSize = self.updatePlaceholder(grid: grid, layout: layout, navigationBarHeight: navigationBarHeight, transition: transition)
|
let placeholderY: CGFloat
|
||||||
let placeholderY: CGFloat = grid ? 0.0 : floorToScreenPixels((height - placeholderSize.height) / 2.0)
|
if let (_, isPlaceholder) = self.placeholderIcon, isPlaceholder {
|
||||||
|
placeholderY = navigationBarHeight
|
||||||
|
} else {
|
||||||
|
placeholderY = floorToScreenPixels((height - placeholderSize.height) / 2.0)
|
||||||
|
}
|
||||||
let placeholderFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - placeholderSize.width) / 2.0), y: placeholderY), size: placeholderSize)
|
let placeholderFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((layout.size.width - placeholderSize.width) / 2.0), y: placeholderY), size: placeholderSize)
|
||||||
transition.updateFrame(node: placeholderNode, frame: placeholderFrame)
|
transition.updateFrame(node: placeholderNode, frame: placeholderFrame)
|
||||||
placeholderNode.updateAbsoluteRect(placeholderFrame, within: layout.size)
|
placeholderNode.updateAbsoluteRect(placeholderFrame, within: layout.size)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user