Pin notes

This commit is contained in:
Joscha 2025-02-09 18:21:45 +01:00
parent de6080c3ad
commit 0b485e6cfe
4 changed files with 50 additions and 11 deletions

View file

@ -1,4 +1,4 @@
import { pathAncestors, pathLiesOn } from "@/util";
import { pathAncestors, pathLiesOn, pathSlice } from "@/util";
import { defineStore } from "pinia";
import { ref, watchEffect } from "vue";
@ -6,6 +6,7 @@ export const useUiStore = defineStore("ui", () => {
const anchorId = ref<string>();
const focusPath = ref<string>("");
const openPaths = ref<Set<string>>(new Set());
const pinned = ref<string>(); // The last two segments of the path
// Ensure all nodes on the focusPath are unfolded.
watchEffect(() => {
@ -19,27 +20,42 @@ export const useUiStore = defineStore("ui", () => {
return openPaths.value.has(path);
}
function setOpen(path: string, open: boolean) {
function setOpen(path: string, value: boolean) {
// Move the focusPath if necessary
if (!open && isOpen(path) && pathLiesOn(path, focusPath.value)) {
if (!value && isOpen(path) && pathLiesOn(path, focusPath.value)) {
focusPath.value = path;
}
// Don't update openPaths unnecessarily.
// Just in case vue itself doesn't debounce Set operations.
if (open && !isOpen(path)) openPaths.value.add(path);
else if (!open && isOpen(path)) openPaths.value.delete(path);
if (value && !isOpen(path)) openPaths.value.add(path);
else if (!value && isOpen(path)) openPaths.value.delete(path);
}
function toggleOpen(path: string) {
setOpen(path, !isOpen(path));
}
function isPinned(path: string): boolean {
return pathSlice(path, -2) === pinned.value;
}
function setPinned(path: string) {
pinned.value = pathSlice(path, -2);
}
function unsetPinned() {
pinned.value = undefined;
}
return {
anchorId,
focusPath,
isOpen,
setOpen,
toggleOpen,
isPinned,
setPinned,
unsetPinned,
};
});