-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathbookmarksmodel.ts
More file actions
100 lines (86 loc) · 3.1 KB
/
Copy pathbookmarksmodel.ts
File metadata and controls
100 lines (86 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2026, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { atoms } from "@/app/store/global-atoms";
import { globalStore } from "@/app/store/jotaiStore";
import { RpcApi } from "@/app/store/wshclientapi";
import { TabRpcClient } from "@/app/store/wshrpcutil";
import { Atom, atom } from "jotai";
type BookmarkEntry = FileBookmark & { key: string };
function sortBookmarks(map: { [key: string]: FileBookmark }): BookmarkEntry[] {
if (map == null) {
return [];
}
const entries: BookmarkEntry[] = Object.keys(map).map((key) => ({ key, ...map[key] }));
entries.sort((a, b) => (a["display:order"] ?? 0) - (b["display:order"] ?? 0));
return entries;
}
function nextDisplayOrder(entries: BookmarkEntry[]): number {
let max = 0;
for (const e of entries) {
const ord = e["display:order"] ?? 0;
if (ord > max) {
max = ord;
}
}
return max + 1;
}
const fileBookmarksAtom: Atom<BookmarkEntry[]> = atom((get) => {
const fullConfig = get(atoms.fullConfigAtom);
return sortBookmarks(fullConfig?.filebookmarks);
});
class BookmarksModel {
private static instance: BookmarksModel | null = null;
static getInstance(): BookmarksModel {
if (!BookmarksModel.instance) {
BookmarksModel.instance = new BookmarksModel();
}
return BookmarksModel.instance;
}
private constructor() {}
getBookmarks(): BookmarkEntry[] {
return globalStore.get(fileBookmarksAtom);
}
async add(bookmark: FileBookmark): Promise<string> {
const key = crypto.randomUUID();
const order = nextDisplayOrder(this.getBookmarks());
await RpcApi.SetFileBookmarkCommand(TabRpcClient, {
key,
bookmark: { ...bookmark, "display:order": order },
});
return key;
}
async update(key: string, patch: Partial<FileBookmark>): Promise<void> {
const existing = this.getBookmarks().find((b) => b.key == key);
if (existing == null) {
return;
}
const { key: _omit, ...rest } = existing;
await RpcApi.SetFileBookmarkCommand(TabRpcClient, {
key,
bookmark: { ...rest, ...patch },
});
}
async remove(key: string): Promise<void> {
await RpcApi.DeleteFileBookmarkCommand(TabRpcClient, key);
}
async reorder(orderedKeys: string[]): Promise<void> {
const byKey = new Map(this.getBookmarks().map((b) => [b.key, b]));
for (let i = 0; i < orderedKeys.length; i++) {
const b = byKey.get(orderedKeys[i]);
if (b == null) {
continue;
}
const newOrder = i + 1;
if ((b["display:order"] ?? 0) == newOrder) {
continue;
}
const { key: _omit, ...rest } = b;
await RpcApi.SetFileBookmarkCommand(TabRpcClient, {
key: b.key,
bookmark: { ...rest, "display:order": newOrder },
});
}
}
}
export { BookmarksModel, fileBookmarksAtom, nextDisplayOrder, sortBookmarks };
export type { BookmarkEntry };