72 lines
1.9 KiB
Swift
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)")
|
|
}
|
|
}
|
|
}
|
|
}
|