mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
271 lines
10 KiB
Swift
271 lines
10 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import SwiftSignalKit
|
|
import Postbox
|
|
import TelegramCore
|
|
import QuickLook
|
|
import Display
|
|
import TelegramPresentationData
|
|
|
|
private final class DocumentPreviewItem: NSObject, QLPreviewItem {
|
|
private let url: URL
|
|
private let title: String
|
|
|
|
var previewItemURL: URL? {
|
|
return self.url
|
|
}
|
|
|
|
var previewItemTitle: String? {
|
|
return self.title
|
|
}
|
|
|
|
init(url: URL, title: String) {
|
|
self.url = url
|
|
self.title = title
|
|
}
|
|
}
|
|
|
|
final class DocumentPreviewController: UINavigationController, QLPreviewControllerDelegate, QLPreviewControllerDataSource {
|
|
private let postbox: Postbox
|
|
private let file: TelegramMediaFile
|
|
|
|
private var item: DocumentPreviewItem?
|
|
|
|
private var tempFile: TempBoxFile?
|
|
|
|
init(theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile) {
|
|
self.postbox = postbox
|
|
self.file = file
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
|
|
self.navigationBar.barTintColor = theme.rootController.navigationBar.opaqueBackgroundColor
|
|
self.navigationBar.tintColor = theme.rootController.navigationBar.accentTextColor
|
|
self.navigationBar.shadowImage = generateImage(CGSize(width: 1.0, height: 1.0), rotatedContext: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
context.setFillColor(theme.rootController.navigationBar.separatorColor.cgColor)
|
|
context.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: UIScreenPixel)))
|
|
})
|
|
self.navigationBar.isTranslucent = false
|
|
self.navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor]
|
|
|
|
let controller = QLPreviewController(nibName: nil, bundle: nil)
|
|
controller.navigation_setDismiss({
|
|
}, rootController: self)
|
|
controller.delegate = self
|
|
controller.dataSource = self
|
|
if #available(iOS 16.0, *) {
|
|
controller.navigationItem.setLeftBarButton(UIBarButtonItem(title: strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false)
|
|
}
|
|
self.setViewControllers([controller], animated: false)
|
|
|
|
if let path = self.postbox.mediaBox.completedResourcePath(self.file.resource) {
|
|
var updatedPath = path
|
|
if let fileName = self.file.fileName {
|
|
let tempFile = TempBox.shared.file(path: path, fileName: fileName)
|
|
updatedPath = tempFile.path
|
|
self.tempFile = tempFile
|
|
}
|
|
self.item = DocumentPreviewItem(url: URL(fileURLWithPath: updatedPath), title: self.file.fileName ?? strings.Message_File)
|
|
}
|
|
}
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
deinit {
|
|
if let tempFile = self.tempFile {
|
|
TempBox.shared.dispose(tempFile)
|
|
}
|
|
}
|
|
|
|
@objc private func cancelPressed() {
|
|
self.presentingViewController?.dismiss(animated: true, completion: nil)
|
|
}
|
|
|
|
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
|
|
if self.item != nil {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
|
if let item = self.item {
|
|
return item
|
|
} else {
|
|
assertionFailure()
|
|
return DocumentPreviewItem(url: URL(fileURLWithPath: ""), title: "")
|
|
}
|
|
}
|
|
|
|
func previewControllerWillDismiss(_ controller: QLPreviewController) {
|
|
self.cancelPressed()
|
|
}
|
|
|
|
func previewControllerDidDismiss(_ controller: QLPreviewController) {
|
|
//self.cancelPressed()
|
|
}
|
|
}
|
|
|
|
final class CompactDocumentPreviewController: QLPreviewController, QLPreviewControllerDelegate, QLPreviewControllerDataSource {
|
|
private let postbox: Postbox
|
|
private let file: TelegramMediaFile
|
|
private let canShare: Bool
|
|
|
|
private var item: DocumentPreviewItem?
|
|
|
|
private var tempFile: TempBoxFile?
|
|
|
|
init(theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile, canShare: Bool = true) {
|
|
self.postbox = postbox
|
|
self.file = file
|
|
self.canShare = canShare
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
|
|
self.delegate = self
|
|
self.dataSource = self
|
|
|
|
if let path = self.postbox.mediaBox.completedResourcePath(self.file.resource) {
|
|
var updatedPath = path
|
|
if let fileName = self.file.fileName {
|
|
let tempFile = TempBox.shared.file(path: path, fileName: fileName)
|
|
updatedPath = tempFile.path
|
|
self.tempFile = tempFile
|
|
}
|
|
self.item = DocumentPreviewItem(url: URL(fileURLWithPath: updatedPath), title: self.file.fileName ?? strings.Message_File)
|
|
}
|
|
}
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
deinit {
|
|
if let tempFile = self.tempFile {
|
|
TempBox.shared.dispose(tempFile)
|
|
}
|
|
self.timer?.invalidate()
|
|
}
|
|
|
|
@objc private func cancelPressed() {
|
|
self.presentingViewController?.dismiss(animated: true, completion: nil)
|
|
}
|
|
|
|
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
|
|
if self.item != nil {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
|
|
if let item = self.item {
|
|
return item
|
|
} else {
|
|
assertionFailure()
|
|
return DocumentPreviewItem(url: URL(fileURLWithPath: ""), title: "")
|
|
}
|
|
}
|
|
|
|
func previewControllerWillDismiss(_ controller: QLPreviewController) {
|
|
self.cancelPressed()
|
|
}
|
|
|
|
func previewControllerDidDismiss(_ controller: QLPreviewController) {
|
|
//self.cancelPressed()
|
|
}
|
|
|
|
private var navigationBars: [UINavigationBar] = []
|
|
private var toolbars: [UIView] = []
|
|
private var observations : [NSKeyValueObservation] = []
|
|
|
|
private var initialized = false
|
|
private var timer: SwiftSignalKit.Timer?
|
|
override func viewDidLayoutSubviews() {
|
|
super.viewDidLayoutSubviews()
|
|
|
|
if !self.canShare && !self.initialized {
|
|
self.initialized = true
|
|
|
|
self.timer = SwiftSignalKit.Timer(timeout: 0.01, repeat: true, completion: { [weak self] in
|
|
self?.tick()
|
|
}, queue: Queue.mainQueue())
|
|
self.timer?.start()
|
|
}
|
|
}
|
|
|
|
private func tick() {
|
|
let (navigationBars, toolbars) = navigationAndToolbarsInSubviews(forView: self.view)
|
|
self.navigationBars = navigationBars
|
|
self.toolbars = toolbars
|
|
|
|
if #available(iOS 16.0, *) {
|
|
if let navigationController = self.children.first as? UINavigationController, let topController = navigationController.topViewController {
|
|
topController.navigationItem.titleMenuProvider = nil
|
|
}
|
|
|
|
for toolbar in self.toolbars {
|
|
toolbar.isHidden = true
|
|
}
|
|
} else {
|
|
self.navigationItem.rightBarButtonItems = [UIBarButtonItem()]
|
|
self.navigationItem.setRightBarButton(UIBarButtonItem(), animated: false)
|
|
|
|
self.navigationController?.toolbar.isHidden = true
|
|
|
|
for navigationBar in self.navigationBars {
|
|
navigationBar.topItem?.rightBarButtonItem = UIBarButtonItem()
|
|
navigationBar.topItem?.rightBarButtonItems = [UIBarButtonItem()]
|
|
}
|
|
|
|
for toolbar in self.toolbars {
|
|
toolbar.isHidden = true
|
|
}
|
|
}
|
|
}
|
|
|
|
private func navigationAndToolbarsInSubviews(forView view: UIView) -> ([UINavigationBar], [UIView]) {
|
|
var navigationBars: [UINavigationBar] = []
|
|
var toolbars: [UIView] = []
|
|
for subview in view.subviews {
|
|
if let subview = subview as? UINavigationBar {
|
|
navigationBars.append(subview)
|
|
} else if let subview = subview as? UIToolbar {
|
|
toolbars.append(subview)
|
|
} else {
|
|
let (subNavigationBars, subToolbars) = navigationAndToolbarsInSubviews(forView: subview)
|
|
navigationBars.append(contentsOf: subNavigationBars)
|
|
toolbars.append(contentsOf: subToolbars)
|
|
}
|
|
}
|
|
return (navigationBars, toolbars)
|
|
}
|
|
|
|
}
|
|
|
|
func presentDocumentPreviewController(rootController: UIViewController, theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile, canShare: Bool) {
|
|
if #available(iOSApplicationExtension 9.0, iOS 9.0, *) {
|
|
let navigationBar = UINavigationBar.appearance(whenContainedInInstancesOf: [QLPreviewController.self])
|
|
navigationBar.barTintColor = theme.rootController.navigationBar.opaqueBackgroundColor
|
|
navigationBar.setBackgroundImage(generateImage(CGSize(width: 1.0, height: 1.0), rotatedContext: { size, context in
|
|
context.setFillColor(theme.rootController.navigationBar.opaqueBackgroundColor.cgColor)
|
|
context.fill(CGRect(origin: CGPoint(), size: size))
|
|
}), for: .default)
|
|
navigationBar.isTranslucent = true
|
|
navigationBar.tintColor = theme.rootController.navigationBar.accentTextColor
|
|
navigationBar.shadowImage = generateImage(CGSize(width: 1.0, height: 1.0), rotatedContext: { size, context in
|
|
context.clear(CGRect(origin: CGPoint(), size: size))
|
|
context.setFillColor(theme.rootController.navigationBar.separatorColor.cgColor)
|
|
context.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: UIScreenPixel)))
|
|
})
|
|
navigationBar.titleTextAttributes = [NSAttributedString.Key.font: Font.semibold(17.0), NSAttributedString.Key.foregroundColor: theme.rootController.navigationBar.primaryTextColor]
|
|
}
|
|
|
|
rootController.present(CompactDocumentPreviewController(theme: theme, strings: strings, postbox: postbox, file: file, canShare: canShare), animated: true, completion: nil)
|
|
}
|