56 lines
1.9 KiB
Swift
56 lines
1.9 KiB
Swift
import Foundation
|
|
import SwiftData
|
|
import UIKit
|
|
|
|
@MainActor
|
|
final class BookDetailViewModel: ObservableObject {
|
|
@Published var book: BookRemote
|
|
@Published var isInLibrary = false
|
|
|
|
init(book: BookRemote) {
|
|
self.book = book
|
|
}
|
|
|
|
func refresh(context: ModelContext) {
|
|
let all = (try? context.fetch(FetchDescriptor<LibraryBook>())) ?? []
|
|
isInLibrary = all.contains(where: { local in
|
|
match(local: local, remote: book)
|
|
})
|
|
}
|
|
|
|
func toggleLibrary(context: ModelContext) {
|
|
let all = (try? context.fetch(FetchDescriptor<LibraryBook>())) ?? []
|
|
|
|
if let existing = all.first(where: { match(local: $0, remote: book) }) {
|
|
context.delete(existing)
|
|
isInLibrary = false
|
|
UINotificationFeedbackGenerator().notificationOccurred(.warning)
|
|
} else {
|
|
let local = LibraryBook(
|
|
title: book.title,
|
|
authorsString: book.authors.joined(separator: ", "),
|
|
coverUrlString: book.coverImageUrl?.absoluteString,
|
|
isbn10: book.isbn10,
|
|
isbn13: book.isbn13,
|
|
publishedYear: book.publishedYear,
|
|
categoriesString: book.categories.joined(separator: ", "),
|
|
summary: book.description,
|
|
language: book.language,
|
|
sourceLocale: book.sourceLocale,
|
|
remotePayloadJson: nil
|
|
)
|
|
context.insert(local)
|
|
isInLibrary = true
|
|
UINotificationFeedbackGenerator().notificationOccurred(.success)
|
|
}
|
|
|
|
try? context.save()
|
|
}
|
|
|
|
private func match(local: LibraryBook, remote: BookRemote) -> Bool {
|
|
if let lhs = local.isbn13, let rhs = remote.isbn13 { return lhs == rhs }
|
|
if let lhs = local.isbn10, let rhs = remote.isbn10 { return lhs == rhs }
|
|
return local.title == remote.title
|
|
}
|
|
}
|