mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-08 20:01:15 -04:00
Share PDF added
This commit is contained in:
parent
24aab85522
commit
fa1aa99ce3
@ -41,6 +41,7 @@ struct Kiwix: App {
|
||||
.environmentObject(navigation)
|
||||
.modifier(AlertHandler())
|
||||
.modifier(OpenFileHandler())
|
||||
.modifier(SharePDFHandler())
|
||||
.modifier(SaveContentHandler())
|
||||
.onChange(of: scenePhase) { newValue in
|
||||
guard newValue == .inactive else { return }
|
||||
|
@ -175,6 +175,7 @@ struct RootView: View {
|
||||
.modifier(AlertHandler())
|
||||
.modifier(OpenFileHandler())
|
||||
.modifier(SaveContentHandler())
|
||||
.modifier(SharePDFHandler())
|
||||
.onOpenURL { url in
|
||||
if url.isFileURL {
|
||||
NotificationCenter.openFiles([url], context: .file)
|
||||
|
@ -41,4 +41,17 @@ extension URL {
|
||||
init(appStoreReviewForName appName: String, appStoreID: String) {
|
||||
self.init(string: "itms-apps://itunes.apple.com/us/app/\(appName)/\(appStoreID)?action=write-review")!
|
||||
}
|
||||
|
||||
init(temporaryFileWithName fileName: String) {
|
||||
let directory = FileManager.default.temporaryDirectory
|
||||
if #available(macOS 13.0, iOS 16.0, *) {
|
||||
self = directory.appending(path: fileName)
|
||||
} else {
|
||||
self = directory.appendingPathComponent(fileName)
|
||||
}
|
||||
}
|
||||
|
||||
func toTemporaryFileURL() -> URL? {
|
||||
URL(temporaryFileWithName: lastPathComponent)
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ extension Notification.Name {
|
||||
static let alert = Notification.Name("alert")
|
||||
static let openFiles = Notification.Name("openFiles")
|
||||
static let openURL = Notification.Name("openURL")
|
||||
static let sharePDF = Notification.Name("sharePDF")
|
||||
static let saveContent = Notification.Name("saveContent")
|
||||
static let toggleSidebar = Notification.Name("toggleSidebar")
|
||||
}
|
||||
@ -89,6 +90,10 @@ extension NotificationCenter {
|
||||
NotificationCenter.default.post(name: .openFiles, object: nil, userInfo: ["urls": urls, "context": context])
|
||||
}
|
||||
|
||||
static func sharePDF(_ data: Data, fileName: String) {
|
||||
NotificationCenter.default.post(name: .sharePDF, object: nil, userInfo: ["data": data, "fileName": fileName])
|
||||
}
|
||||
|
||||
static func saveContent(url: URL) {
|
||||
NotificationCenter.default.post(name: .saveContent, object: nil, userInfo: ["url": url])
|
||||
}
|
||||
|
@ -21,7 +21,15 @@ struct ShareButton: View {
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
debugPrint("share this")
|
||||
Task {
|
||||
guard let browserURLName = browser.webView.url?.lastPathComponent else {
|
||||
return
|
||||
}
|
||||
guard let pdfData = try? await browser.webView.pdf() else {
|
||||
return
|
||||
}
|
||||
NotificationCenter.sharePDF(pdfData, fileName: browserURLName)
|
||||
}
|
||||
} label: {
|
||||
Label {
|
||||
Text("Share".localized)
|
||||
|
135
Views/ViewModifiers/SharePDFHandler.swift
Normal file
135
Views/ViewModifiers/SharePDFHandler.swift
Normal file
@ -0,0 +1,135 @@
|
||||
// This file is part of Kiwix for iOS & macOS.
|
||||
//
|
||||
// Kiwix is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kiwix is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kiwix; If not, see https://www.gnu.org/licenses/.
|
||||
|
||||
import SwiftUI
|
||||
|
||||
/// On receiving pdf content and a file name, it gives the ability to share it
|
||||
struct SharePDFHandler: ViewModifier {
|
||||
|
||||
private let sharePDF = NotificationCenter.default.publisher(for: .sharePDF)
|
||||
@State private var temporaryURL: URL?
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content.onReceive(sharePDF) { notification in
|
||||
|
||||
guard let userInfo = notification.userInfo,
|
||||
let pdfData = userInfo["data"] as? Data,
|
||||
let fileName = userInfo["fileName"] as? String,
|
||||
let tempFileName = fileName.split(separator: ".").first?.appending(".pdf") else {
|
||||
return
|
||||
}
|
||||
|
||||
let tempFileURL = URL(temporaryFileWithName: tempFileName)
|
||||
guard (try? pdfData.write(to: tempFileURL)) != nil else {
|
||||
temporaryURL = nil
|
||||
return
|
||||
}
|
||||
temporaryURL = tempFileURL
|
||||
}
|
||||
#if os(iOS)
|
||||
.sheet(
|
||||
isPresented: Binding<Bool>.constant($temporaryURL.wrappedValue != nil),
|
||||
onDismiss: {
|
||||
if let temporaryURL {
|
||||
try? FileManager.default.removeItem(at: temporaryURL)
|
||||
}
|
||||
temporaryURL = nil
|
||||
}, content: {
|
||||
#if os(iOS)
|
||||
ActivityViewController(activityItems: [temporaryURL].compactMap { $0 })
|
||||
#else
|
||||
NSSharingServicePicker(items: [temporaryURL])
|
||||
#endif
|
||||
}
|
||||
)
|
||||
#else
|
||||
.background(SharingsPicker(
|
||||
isPresented: Binding<Bool>.constant($temporaryURL.wrappedValue != nil),
|
||||
sharingItems: [temporaryURL].compactMap { $0 },
|
||||
onDismiss: {
|
||||
temporaryURL = nil
|
||||
}
|
||||
))
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
struct ActivityViewController: UIViewControllerRepresentable {
|
||||
|
||||
var activityItems: [Any]
|
||||
@Environment(\.dismiss) var dismissAction
|
||||
func makeUIViewController(
|
||||
context: UIViewControllerRepresentableContext<ActivityViewController>
|
||||
) -> UIActivityViewController {
|
||||
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
|
||||
controller.modalPresentationStyle = .pageSheet
|
||||
controller.completionWithItemsHandler = { (_, _, _, _) in
|
||||
self.dismissAction()
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if os(macOS)
|
||||
struct SharingsPicker: NSViewRepresentable {
|
||||
@Binding var isPresented: Bool {
|
||||
didSet {
|
||||
if isPresented == false {
|
||||
onDismiss?()
|
||||
}
|
||||
}
|
||||
}
|
||||
var sharingItems: [Any] = []
|
||||
let onDismiss: (() -> Void)?
|
||||
|
||||
func makeNSView(context: Context) -> NSView {
|
||||
NSView()
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSView, context: Context) {
|
||||
if isPresented {
|
||||
let picker = NSSharingServicePicker(items: sharingItems)
|
||||
picker.delegate = context.coordinator
|
||||
DispatchQueue.main.async { // call async, to not to block updates
|
||||
picker.show(relativeTo: .zero, of: nsView, preferredEdge: .minX)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(owner: self)
|
||||
}
|
||||
|
||||
class Coordinator: NSObject, NSSharingServicePickerDelegate {
|
||||
let owner: SharingsPicker
|
||||
|
||||
init(owner: SharingsPicker) {
|
||||
self.owner = owner
|
||||
}
|
||||
|
||||
func sharingServicePicker(_ sharingServicePicker: NSSharingServicePicker, didChoose service: NSSharingService?) {
|
||||
sharingServicePicker.delegate = nil // << cleanup
|
||||
owner.isPresented = false // << dismiss
|
||||
owner.onDismiss?()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user