41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
const lookups = new Map<string, Promise<string | null>>()
|
|
|
|
async function lookUpCover(isbn: string): Promise<string | null> {
|
|
try {
|
|
const edition = await $fetch<{ covers?: number[] }>(`https://openlibrary.org/isbn/${isbn}.json`)
|
|
const id = edition.covers?.find(id => id > 0)
|
|
return id ? `https://covers.openlibrary.org/b/id/${id}-M.jpg` : null
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The book's cover: the one saved in the table, or else looked up on Open Library by ISBN
|
|
* and saved to the table so the next visit doesn't have to look it up again.
|
|
*/
|
|
export function useWishlistCover(book: MaybeRefOrGetter<WishlistBook>) {
|
|
const url = ref<string | null>(toValue(book).cover)
|
|
const loading = ref(!url.value)
|
|
|
|
onMounted(async () => {
|
|
if (url.value) return
|
|
const { id, isbn } = toValue(book)
|
|
const digits = isbn.replace(/[^\dX]/gi, '')
|
|
if (!digits) {
|
|
loading.value = false
|
|
return
|
|
}
|
|
|
|
if (!lookups.has(digits)) lookups.set(digits, lookUpCover(digits))
|
|
url.value = await lookups.get(digits)!
|
|
loading.value = false
|
|
|
|
if (url.value) {
|
|
$fetch(`/api/wishlist/books/${id}/cover`, { method: 'POST', body: { cover: url.value } }).catch(() => {})
|
|
}
|
|
})
|
|
|
|
return { url, loading }
|
|
}
|