Browser improvements

This commit is contained in:
Ilya Laktyushin 2024-08-09 06:34:09 +02:00
parent bbe90fcadb
commit d17391ad9b
5 changed files with 116 additions and 40 deletions

View File

@ -60,6 +60,7 @@ final class BrowserDocumentContent: UIView, BrowserContent, WKNavigationDelegate
}
var title: String = "file"
var url = ""
if let path = self.context.account.postbox.mediaBox.completedResourcePath(file.resource) {
var updatedPath = path
if let fileName = file.fileName {
@ -67,13 +68,14 @@ final class BrowserDocumentContent: UIView, BrowserContent, WKNavigationDelegate
updatedPath = tempFile.path
self.tempFile = tempFile
title = fileName
url = updatedPath
}
let request = URLRequest(url: URL(fileURLWithPath: updatedPath))
self.webView.load(request)
}
self._state = BrowserContentState(title: title, url: "", estimatedProgress: 0.0, readingProgress: 0.0, contentType: .document)
self._state = BrowserContentState(title: title, url: url, estimatedProgress: 0.0, readingProgress: 0.0, contentType: .document)
self.statePromise = Promise<BrowserContentState>(self._state)
super.init(frame: .zero)

View File

@ -71,13 +71,21 @@ final class BrowserPdfContent: UIView, BrowserContent, UIScrollViewDelegate, PDF
self.pdfView.displayDirection = .vertical
self.pdfView.autoScales = true
var title: String = "file"
if let path = self.context.account.postbox.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
self.pdfView.document = PDFDocument(data: data)
title = file.fileName ?? "file"
var title = "file"
var url = ""
if let path = self.context.account.postbox.mediaBox.completedResourcePath(file.resource) {
var updatedPath = path
if let fileName = file.fileName {
let tempFile = TempBox.shared.file(path: path, fileName: fileName)
updatedPath = tempFile.path
self.tempFile = tempFile
title = fileName
url = updatedPath
}
self.pdfView.document = PDFDocument(url: URL(fileURLWithPath: updatedPath))
}
self._state = BrowserContentState(title: title, url: "", estimatedProgress: 0.0, readingProgress: 0.0, contentType: .document)
self._state = BrowserContentState(title: title, url: url, estimatedProgress: 0.0, readingProgress: 0.0, contentType: .document)
self.statePromise = Promise<BrowserContentState>(self._state)
super.init(frame: .zero)

View File

@ -28,6 +28,7 @@ private final class BrowserScreenComponent: CombinedComponent {
let context: AccountContext
let contentState: BrowserContentState?
let presentationState: BrowserPresentationState
let canShare: Bool
let performAction: ActionSlot<BrowserScreen.Action>
let performHoldAction: (UIView, ContextGesture?, BrowserScreen.Action) -> Void
let panelCollapseFraction: CGFloat
@ -36,6 +37,7 @@ private final class BrowserScreenComponent: CombinedComponent {
context: AccountContext,
contentState: BrowserContentState?,
presentationState: BrowserPresentationState,
canShare: Bool,
performAction: ActionSlot<BrowserScreen.Action>,
performHoldAction: @escaping (UIView, ContextGesture?, BrowserScreen.Action) -> Void,
panelCollapseFraction: CGFloat
@ -43,6 +45,7 @@ private final class BrowserScreenComponent: CombinedComponent {
self.context = context
self.contentState = contentState
self.presentationState = presentationState
self.canShare = canShare
self.performAction = performAction
self.performHoldAction = performHoldAction
self.panelCollapseFraction = panelCollapseFraction
@ -58,6 +61,9 @@ private final class BrowserScreenComponent: CombinedComponent {
if lhs.presentationState != rhs.presentationState {
return false
}
if lhs.canShare != rhs.canShare {
return false
}
if lhs.panelCollapseFraction != rhs.panelCollapseFraction {
return false
}
@ -260,25 +266,27 @@ private final class BrowserScreenComponent: CombinedComponent {
),
at: 0
)
navigationRightItems.insert(
AnyComponentWithIdentity(
id: "share",
component: AnyComponent(
Button(
content: AnyComponent(
BundleIconComponent(
name: "Chat List/NavigationShare",
tintColor: environment.theme.rootController.navigationBar.accentTextColor
)
),
action: {
performAction.invoke(.share)
}
if context.component.canShare {
navigationRightItems.insert(
AnyComponentWithIdentity(
id: "share",
component: AnyComponent(
Button(
content: AnyComponent(
BundleIconComponent(
name: "Chat List/NavigationShare",
tintColor: environment.theme.rootController.navigationBar.accentTextColor
)
),
action: {
performAction.invoke(.share)
}
)
)
)
),
at: 0
)
),
at: 0
)
}
if canOpenIn {
navigationRightItems.append(
AnyComponentWithIdentity(
@ -359,6 +367,7 @@ private final class BrowserScreenComponent: CombinedComponent {
canGoBack: context.component.contentState?.canGoBack ?? false,
canGoForward: context.component.contentState?.canGoForward ?? false,
canOpenIn: canOpenIn,
canShare: context.component.canShare,
isDocument: context.component.contentState?.contentType == .document,
performAction: performAction,
performHoldAction: performHoldAction
@ -617,7 +626,19 @@ public class BrowserScreen: ViewController, MinimizableController {
case .minimize:
self.minimize()
case .openIn:
self.context.sharedContext.applicationBindings.openUrl(url)
var processed = false
if let controller = self.controller {
switch controller.subject {
case let .document(file, canShare), let .pdfDocument(file, canShare):
processed = true
controller.openDocument(file, canShare)
default:
break
}
}
if !processed {
self.context.sharedContext.applicationBindings.openUrl(url)
}
case .openSettings:
self.openSettings()
case let .updateSearchActive(active):
@ -806,9 +827,9 @@ public class BrowserScreen: ViewController, MinimizableController {
self.openPeer(peer)
}
browserContent = instantPageContent
case let .document(file):
case let .document(file, _):
browserContent = BrowserDocumentContent(context: self.context, presentationData: self.presentationData, file: file)
case let .pdfDocument(file):
case let .pdfDocument(file, _):
browserContent = BrowserPdfContent(context: self.context, presentationData: self.presentationData, file: file)
}
browserContent.pushContent = { [weak self] content in
@ -1087,8 +1108,16 @@ public class BrowserScreen: ViewController, MinimizableController {
openInUrl = url
}
let canOpenIn = !(self.contentState?.url.hasPrefix("tonsite") ?? false)
var canShare = true
if let controller = self.controller {
switch controller.subject {
case let .document(_, canShareValue), let .pdfDocument(_, canShareValue):
canShare = canShareValue
default:
break
}
}
var items: [ContextMenuItem] = []
if contentState.contentType == .document, contentState.title.lowercased().hasSuffix(".pdf") {
@ -1124,7 +1153,7 @@ public class BrowserScreen: ViewController, MinimizableController {
})))
}
if !layout.metrics.isTablet {
if canShare && !layout.metrics.isTablet {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.WebBrowser_Share, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Share"), color: theme.contextMenu.primaryColor) }, action: { (controller, action) in
performAction.invoke(.share)
action(.default)
@ -1295,6 +1324,16 @@ public class BrowserScreen: ViewController, MinimizableController {
return self?.controller
}
)
var canShare = true
if let controller = self.controller {
switch controller.subject {
case let .document(_, canShareValue), let .pdfDocument(_, canShareValue):
canShare = canShareValue
default:
break
}
}
let componentSize = self.componentHost.update(
transition: transition,
@ -1303,6 +1342,7 @@ public class BrowserScreen: ViewController, MinimizableController {
context: self.context,
contentState: self.contentState,
presentationState: self.presentationState,
canShare: canShare,
performAction: self.performAction,
performHoldAction: { [weak self] view, gesture, action in
if let self {
@ -1379,15 +1419,17 @@ public class BrowserScreen: ViewController, MinimizableController {
public enum Subject {
case webPage(url: String)
case instantPage(webPage: TelegramMediaWebpage, anchor: String?, sourceLocation: InstantPageSourceLocation)
case document(file: TelegramMediaFile)
case pdfDocument(file: TelegramMediaFile)
case document(file: TelegramMediaFile, canShare: Bool)
case pdfDocument(file: TelegramMediaFile, canShare: Bool)
}
private let context: AccountContext
private let subject: Subject
fileprivate let subject: Subject
private var preferredConfiguration: WKWebViewConfiguration?
private var openPreviousOnClose = false
public var openDocument: (TelegramMediaFile, Bool) -> Void = { _, _ in }
private var validLayout: ContainerViewLayout?
public static let supportedDocumentMimeTypes: [String] = [

View File

@ -125,6 +125,7 @@ final class NavigationToolbarContentComponent: CombinedComponent {
let canGoBack: Bool
let canGoForward: Bool
let canOpenIn: Bool
let canShare: Bool
let isDocument: Bool
let performAction: ActionSlot<BrowserScreen.Action>
let performHoldAction: (UIView, ContextGesture?, BrowserScreen.Action) -> Void
@ -135,6 +136,7 @@ final class NavigationToolbarContentComponent: CombinedComponent {
canGoBack: Bool,
canGoForward: Bool,
canOpenIn: Bool,
canShare: Bool,
isDocument: Bool,
performAction: ActionSlot<BrowserScreen.Action>,
performHoldAction: @escaping (UIView, ContextGesture?, BrowserScreen.Action) -> Void
@ -144,6 +146,7 @@ final class NavigationToolbarContentComponent: CombinedComponent {
self.canGoBack = canGoBack
self.canGoForward = canGoForward
self.canOpenIn = canOpenIn
self.canShare = canShare
self.isDocument = isDocument
self.performAction = performAction
self.performHoldAction = performHoldAction
@ -165,6 +168,9 @@ final class NavigationToolbarContentComponent: CombinedComponent {
if lhs.canOpenIn != rhs.canOpenIn {
return false
}
if lhs.canShare != rhs.canShare {
return false
}
if lhs.isDocument != rhs.isDocument {
return false
}
@ -188,13 +194,17 @@ final class NavigationToolbarContentComponent: CombinedComponent {
let sideInset: CGFloat = 5.0
let buttonSize = CGSize(width: 50.0, height: availableSize.height)
var buttonCount = 4
var buttonCount = 3
if context.component.canShare {
buttonCount += 1
}
if context.component.canOpenIn {
buttonCount += 1
}
let spacing = (availableSize.width - buttonSize.width * CGFloat(buttonCount) - sideInset * 2.0) / CGFloat(buttonCount - 1)
let canShare = context.component.canShare
let share = share.update(
component: Button(
content: AnyComponent(
@ -204,7 +214,9 @@ final class NavigationToolbarContentComponent: CombinedComponent {
)
),
action: {
performAction.invoke(.share)
if canShare {
performAction.invoke(.share)
}
}
).minSize(buttonSize),
availableSize: buttonSize,
@ -212,9 +224,15 @@ final class NavigationToolbarContentComponent: CombinedComponent {
)
if context.component.isDocument {
context.add(share
.position(CGPoint(x: availableSize.width / 2.0, y: availableSize.height / 2.0))
)
if !context.component.canShare {
context.add(share
.position(CGPoint(x: availableSize.width / 2.0, y: 10000.0))
)
} else {
context.add(share
.position(CGPoint(x: availableSize.width / 2.0, y: availableSize.height / 2.0))
)
}
let search = search.update(
component: Button(

View File

@ -231,17 +231,23 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
params.present(controller, nil)
} else if let rootController = params.navigationController?.view.window?.rootViewController {
let proceed = {
let canShare = !params.message.isCopyProtected()
if BrowserScreen.supportedDocumentMimeTypes.contains(file.mimeType) {
let subject: BrowserScreen.Subject
if file.mimeType == "application/pdf" {
subject = .pdfDocument(file: file)
subject = .pdfDocument(file: file, canShare: canShare)
} else {
subject = .document(file: file)
subject = .document(file: file, canShare: canShare)
}
let controller = BrowserScreen(context: params.context, subject: subject)
controller.openDocument = { file, canShare in
controller.dismiss()
presentDocumentPreviewController(rootController: rootController, theme: presentationData.theme, strings: presentationData.strings, postbox: params.context.account.postbox, file: file, canShare: canShare)
}
params.navigationController?.pushViewController(controller)
} else {
presentDocumentPreviewController(rootController: rootController, theme: presentationData.theme, strings: presentationData.strings, postbox: params.context.account.postbox, file: file, canShare: !params.message.isCopyProtected())
presentDocumentPreviewController(rootController: rootController, theme: presentationData.theme, strings: presentationData.strings, postbox: params.context.account.postbox, file: file, canShare: canShare)
}
}
if file.mimeType.contains("image/svg") {