139 lines
3.1 KiB
TypeScript
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
|
|
}
|