Files
fnx_web/svelte/src/lib/Bookmarks.ts

139 lines
3.1 KiB
TypeScript

import { writable } from "svelte/store"
import { fs_check_response, fs_path_url, type FSNode } from "./FilesystemAPI"
import { loading_finish, loading_start } from "lib/Loading"
import { get_user } from "lib/NovaAPI"
const bookmarks_file = "/me/.nova/bookmarks.json"
export type Bookmark = {
id: string,
path: string,
icon: string,
label: string,
}
export let bookmarks_store = writable<Bookmark[]>(
[],
(set: (value: Bookmark[]) => void) => {
bookmarks_get().then((bm: Bookmark[]) => {
set(bm)
}).catch((err: any) => {
alert("Could not fetch bookmarks:\n" + JSON.stringify(err))
})
},
)
export const bookmarks_get = async (): Promise<Bookmark[]> => {
try {
loading_start()
const user = await get_user()
if (user === null) {
return []
}
const bookmarks = await fs_check_response(
await fetch(fs_path_url(bookmarks_file), { cache: "no-store" })
) as Bookmark[]
// Sanity checks
for (const bookmark of bookmarks) {
if (typeof bookmark.id !== "string") { bookmark.id = "" }
if (typeof bookmark.path !== "string") { bookmark.path = "" }
if (typeof bookmark.icon !== "string") { bookmark.icon = "" }
if (typeof bookmark.label !== "string") { bookmark.label = "" }
}
console.debug("Fetched", bookmarks.length, "bookmarks:", bookmarks)
bookmarks_store.set(bookmarks)
return bookmarks
} catch (err) {
// If the bookmarks were not found when we return an empty bookmarks
// list
if (
err.value !== "path_not_found" &&
err.value !== "forbidden" &&
err.value !== "authentication_required"
) {
throw err
} else {
return []
}
} finally {
loading_finish()
}
}
export const bookmarks_save = async (bookmarks: Bookmark[]) => {
try {
loading_start()
await fs_check_response(
await fetch(
fs_path_url(bookmarks_file) + "?make_parents=true",
{ method: "PUT", body: JSON.stringify(bookmarks) },
)
)
console.debug("Saved", bookmarks.length, "bookmarks:", bookmarks)
bookmarks_store.set(bookmarks)
} finally {
loading_finish()
}
}
export const bookmark_add = async (node: FSNode): Promise<Bookmark[]> => {
try {
loading_start()
// Get bookmarks
const bookmarks = await bookmarks_get()
// Add new bookmark
bookmarks.push({
id: node.id,
path: node.path,
icon: "bookmark",
label: node.name,
})
// Save new bookmarks
await bookmarks_save(bookmarks)
return bookmarks
} finally {
loading_finish()
}
}
export const bookmark_del = async (id: string): Promise<Bookmark[]> => {
let bookmarks: Bookmark[] = []
try {
loading_start()
// Get bookmarks
bookmarks = await bookmarks_get()
// Delete bookmark
for (let i = 0; i < bookmarks.length; i++) {
if (bookmarks[i].id === id) {
console.debug("Deleting bookmark at index", i, bookmarks[i])
bookmarks.splice(i, 1)
break
}
}
// Save new bookmarks
await bookmarks_save(bookmarks)
} finally {
loading_finish()
}
return bookmarks
}
export const is_bookmark = (bookmarks: Bookmark[], id: string): boolean => {
for (const bm of bookmarks) {
if (bm.id === id) {
return true
}
}
return false
}