pi-weave 0.3.9 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/package.json +1 -1
- package/src/web/client/context/context.model.ts +5 -0
- package/src/web/client/dist/app.js +400 -167
- package/src/web/client/graph/Graph.tsx +148 -12
- package/src/web/client/graph/column.model.ts +58 -1
- package/src/web/client/graph/graph.model.ts +114 -0
- package/src/web/client/graph/renderer.ts +21 -7
- package/src/web/client/graph/spotlight.model.ts +476 -0
- package/src/web/client/note/Note.tsx +212 -59
- package/src/web/client/note/Replay.tsx +18 -7
- package/src/web/client/note/drafts.ts +69 -6
- package/src/web/client/note/editbar.model.ts +153 -0
- package/src/web/client/note/note.model.ts +65 -1
- package/src/web/client/note/replay.model.ts +75 -0
- package/src/web/client/search/SearchPalette.tsx +103 -34
- package/src/web/client/search/search.model.ts +533 -26
- package/src/web/client/shell/Shell.tsx +79 -21
- package/src/web/client/shell/StatusBar.tsx +1 -0
- package/src/web/client/shell/icons.model.ts +68 -1
- package/src/web/client/shell/keys.model.ts +11 -1
- package/src/web/client/shell/shell.model.ts +48 -1
- package/src/web/client/shell/theme.model.ts +3 -0
- package/src/web/client/shell/theme.ts +260 -61
- package/src/web/client/shell/workspace.css.ts +38 -11
- package/src/web/client/trail/TrailStrip.tsx +0 -1
- package/src/web/client/trail/trail.model.ts +61 -6
- package/src/web/client/tree/Tree.tsx +3 -7
- package/src/web/shared/themes.ts +1 -1
- package/src/web/shared/workspace.ts +10 -2
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/** The vault and repository tree column. */
|
|
2
2
|
|
|
3
|
-
import type { TrailMark } from "../trail/trail.model";
|
|
4
|
-
import { trailRowClass } from "../trail/trail.model";
|
|
5
3
|
import { NOTE_DRAG_TYPE } from "../shell/shell.model";
|
|
6
4
|
import { useLayoutEffect, useRef, useState } from "preact/hooks";
|
|
7
5
|
import { createFolder, deleteFolder, deleteNote, moveNote, renameFolder, renameNote } from "../api";
|
|
@@ -48,8 +46,6 @@ export interface TreeProps {
|
|
|
48
46
|
graph: GraphPayload | null;
|
|
49
47
|
selectedId: string | null;
|
|
50
48
|
recentIds: ReadonlySet<string>;
|
|
51
|
-
/** Recall-trail glows by row id (`trail/trail.model.ts`). */
|
|
52
|
-
trail?: ReadonlyMap<string, TrailMark>;
|
|
53
49
|
onSelect: (id: string, newTab?: boolean, keepSidebar?: boolean) => void;
|
|
54
50
|
/**
|
|
55
51
|
* Ask before a mutation that would invalidate an open draft. `false` means
|
|
@@ -80,13 +76,13 @@ export function Icon({ name, class: className }: { name: IconName; class?: strin
|
|
|
80
76
|
);
|
|
81
77
|
}
|
|
82
78
|
|
|
83
|
-
function Row({ view, recentIds,
|
|
79
|
+
function Row({ view, recentIds, edit, onEdit, onRename, onSelect, onToggle, onMenu, onDrop }: { view: ReturnType<typeof rowViews>[number]; recentIds: ReadonlySet<string>; edit: string | null; onEdit: (value: string) => void; onRename: (value: string | null) => void; onSelect: (newTab: boolean) => void; onToggle: () => void; onMenu: (x: number, y: number) => void; onDrop: (id: string) => void }) {
|
|
84
80
|
const folder = dropFolder(view.id);
|
|
85
81
|
return (
|
|
86
82
|
<li
|
|
87
83
|
id={view.domId}
|
|
88
84
|
data-row-id={view.id}
|
|
89
|
-
class={`weave-row weave-row-${view.kind}${view.selected ? " weave-row-on" : ""}${recentIds.has(view.id) ? " weave-row-new" : ""}
|
|
85
|
+
class={`weave-row weave-row-${view.kind}${view.selected ? " weave-row-on" : ""}${recentIds.has(view.id) ? " weave-row-new" : ""}`}
|
|
90
86
|
role="treeitem"
|
|
91
87
|
aria-level={view.level}
|
|
92
88
|
aria-posinset={view.posinset}
|
|
@@ -301,7 +297,7 @@ export function Tree(props: TreeProps) {
|
|
|
301
297
|
setMenu({ id: "vault", label: "Vault", x: event.clientX, y: event.clientY });
|
|
302
298
|
}}
|
|
303
299
|
>
|
|
304
|
-
{rowViews(rows, props.selectedId, props.now).map((view) => <Row key={view.id} view={view} recentIds={props.recentIds}
|
|
300
|
+
{rowViews(rows, props.selectedId, props.now).map((view) => <Row key={view.id} view={view} recentIds={props.recentIds} edit={editing?.id === view.id ? editing.value : null} onEdit={(value) => setEditing((current) => current === null ? null : { ...current, value })} onRename={commitEdit} onSelect={(newTab) => { props.onSelect(view.id, newTab); if (view.hasKids) setState((current) => toggleExpanded(current, view.id)); }} onToggle={() => setState(toggleExpanded(state, view.id))} onMenu={(x, y) => setMenu({ id: view.id, label: view.label, x, y })} onDrop={(dragged) => { const folder = dropFolder(view.id); if (dragged.startsWith("note:") && folder !== undefined) { const target = mutableTreeRow(dragged); if (target !== null && !props.onMutate(affectedNoteSlugs(props.graph, target))) return; void run(moveNote(fetchJson, dragged.slice("note:".length), folder)); } }} />)}
|
|
305
301
|
</ul>
|
|
306
302
|
) : <p class="weave-tree-empty">{empty}</p>}
|
|
307
303
|
<p class="weave-tree-count">{rowCountLabel(rows)}</p>
|
package/src/web/shared/themes.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* `light` and `dark` keep existing saved choices compatible.
|
|
4
4
|
*/
|
|
5
5
|
const latte = {
|
|
6
|
-
bg: "#eff1f5", panel: "#e6e9ef", page: "#
|
|
6
|
+
bg: "#eff1f5", panel: "#e6e9ef", page: "#ffffff", raise: "#ccd0da",
|
|
7
7
|
fg: "#4c4f69", dim: "#56586a", faint: "#606274", line: "#ccd0da", "line-strong": "#bcc0cc",
|
|
8
8
|
accent: "#7113ec", ok: "#28641b", warn: "#7c4f10", bad: "#b20d30",
|
|
9
9
|
};
|
|
@@ -27,6 +27,11 @@ export interface WorkspaceLayout {
|
|
|
27
27
|
readonly ratio: number;
|
|
28
28
|
readonly treeVisible: boolean;
|
|
29
29
|
readonly contextVisible: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Context as a docked column (true) or a card floating over the page's
|
|
32
|
+
* right margin (false, the default since the refresh).
|
|
33
|
+
*/
|
|
34
|
+
readonly contextPinned: boolean;
|
|
30
35
|
readonly treeWidth: number;
|
|
31
36
|
readonly contextWidth: number;
|
|
32
37
|
readonly contextGraphHeight: number;
|
|
@@ -50,6 +55,7 @@ export function initialLayout(): WorkspaceLayout {
|
|
|
50
55
|
ratio: 0.5,
|
|
51
56
|
treeVisible: true,
|
|
52
57
|
contextVisible: true,
|
|
58
|
+
contextPinned: false,
|
|
53
59
|
treeWidth: 240,
|
|
54
60
|
contextWidth: 240,
|
|
55
61
|
contextGraphHeight: 260,
|
|
@@ -246,11 +252,13 @@ function boundedId(value: unknown, prefix?: "pane" | "tab"): value is string {
|
|
|
246
252
|
}
|
|
247
253
|
|
|
248
254
|
export function parseWorkspaceLayout(value: unknown): WorkspaceLayout | null {
|
|
249
|
-
if (!record(value) || !exactKeys(value, ["version", "panes", "activePane", "split", "ratio", "treeVisible", "contextVisible", "treeWidth", "contextWidth", "theme", ...["preferences", "contextGraphHeight", "contextTagsHeight"].filter(key => Object.hasOwn(value, key))])) return null;
|
|
255
|
+
if (!record(value) || !exactKeys(value, ["version", "panes", "activePane", "split", "ratio", "treeVisible", "contextVisible", "treeWidth", "contextWidth", "theme", ...["preferences", "contextGraphHeight", "contextTagsHeight", "contextPinned"].filter(key => Object.hasOwn(value, key))])) return null;
|
|
250
256
|
if (value["version"] !== 1 || !Array.isArray(value["panes"]) || value["panes"].length < 1 || value["panes"].length > 2 || !boundedId(value["activePane"], "pane")) return null;
|
|
251
257
|
if (value["split"] !== "right" && value["split"] !== "down") return null;
|
|
252
258
|
if (typeof value["ratio"] !== "number" || !Number.isFinite(value["ratio"]) || value["ratio"] < 0.1 || value["ratio"] > 0.9) return null;
|
|
253
259
|
if (typeof value["treeVisible"] !== "boolean" || typeof value["contextVisible"] !== "boolean") return null;
|
|
260
|
+
const contextPinned = Object.hasOwn(value, "contextPinned") ? value["contextPinned"] : false;
|
|
261
|
+
if (typeof contextPinned !== "boolean") return null;
|
|
254
262
|
if (typeof value["treeWidth"] !== "number" || !Number.isFinite(value["treeWidth"]) || value["treeWidth"] < 120 || value["treeWidth"] > 800) return null;
|
|
255
263
|
if (typeof value["contextWidth"] !== "number" || !Number.isFinite(value["contextWidth"]) || value["contextWidth"] < 120 || value["contextWidth"] > 800) return null;
|
|
256
264
|
const contextGraphHeight = Object.hasOwn(value, "contextGraphHeight") ? value["contextGraphHeight"] : 260;
|
|
@@ -292,7 +300,7 @@ export function parseWorkspaceLayout(value: unknown): WorkspaceLayout | null {
|
|
|
292
300
|
panes.push({ id: rawPane["id"], tabs, activeTab: rawPane["activeTab"], ...(typeof lastDocumentTab === "string" ? { lastDocumentTab } : {}) });
|
|
293
301
|
}
|
|
294
302
|
if (count > MAX_TABS || graphs > 1 || !panes.some((pane) => pane.id === value["activePane"])) return null;
|
|
295
|
-
return { version: 1, panes, activePane: value["activePane"], split: value["split"], ratio: value["ratio"], treeVisible: value["treeVisible"], contextVisible: value["contextVisible"], treeWidth: value["treeWidth"], contextWidth: value["contextWidth"], contextGraphHeight, contextTagsHeight, theme: value["theme"], preferences };
|
|
303
|
+
return { version: 1, panes, activePane: value["activePane"], split: value["split"], ratio: value["ratio"], treeVisible: value["treeVisible"], contextVisible: value["contextVisible"], contextPinned, treeWidth: value["treeWidth"], contextWidth: value["contextWidth"], contextGraphHeight, contextTagsHeight, theme: value["theme"], preferences };
|
|
296
304
|
}
|
|
297
305
|
|
|
298
306
|
/** Startup choice resets navigation only; appearance and sidebar preferences survive. */
|