Files
vorleser/Vorleser-macOS/MacLibraryView.swift
2026-03-13 22:29:10 +01:00

72 lines
1.9 KiB
Swift

import SwiftUI
import SwiftData
import Storage
import BookParser
struct MacLibraryView: View {
@Environment(\.modelContext) private var modelContext
@Query(sort: \StoredBook.lastRead, order: .reverse) private var books: [StoredBook]
@State private var selectedBook: StoredBook?
@State private var showFileImporter = false
private var bookStore: BookStore {
BookStore(
modelContainer: modelContext.container,
documentsDirectory: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
)
}
var body: some View {
NavigationSplitView {
List(books, selection: $selectedBook) { book in
VStack(alignment: .leading) {
Text(book.title).font(.headline)
if let author = book.author {
Text(author).font(.subheadline).foregroundStyle(.secondary)
}
}
.tag(book)
.contextMenu {
Button("Delete", role: .destructive) {
try? bookStore.deleteBook(book)
}
}
}
.navigationTitle("Library")
.toolbar {
Button("Import", systemImage: "plus") {
showFileImporter = true
}
}
.fileImporter(
isPresented: $showFileImporter,
allowedContentTypes: [.epub, .plainText],
allowsMultipleSelection: false
) { result in
handleImport(result)
}
} detail: {
if let selectedBook {
MacReaderView(storedBook: selectedBook)
} else {
ContentUnavailableView("Select a Book", systemImage: "book", description: Text("Choose a book from the sidebar or import one."))
}
}
}
private func handleImport(_ result: Result<[URL], Error>) {
guard case .success(let urls) = result, let url = urls.first else { return }
guard url.startAccessingSecurityScopedResource() else { return }
defer { url.stopAccessingSecurityScopedResource() }
Task {
do {
let parsed = try BookParser.parse(url: url)
try bookStore.importBook(from: url, title: parsed.title, author: parsed.author)
} catch {
print("Import failed: \(error)")
}
}
}
}