Make entire ui store state public

This commit is contained in:
Joscha 2025-02-12 12:58:35 +01:00
parent aaca49f1d2
commit 6a3d701e82
2 changed files with 43 additions and 37 deletions

View file

@ -10,7 +10,7 @@ window.addEventListener("keypress", (ev) => {
if (document.activeElement !== document.body) return; if (document.activeElement !== document.body) return;
if (ev.key === "Escape") { if (ev.key === "Escape") {
if (ui.mode !== "focus") { if (ui.mode.type !== "focus") {
ui.focus(); ui.focus();
return; return;
} }

View file

@ -1,6 +1,6 @@
import { Segment, Path as UiPath } from "@/lib/path"; import { Segment, Path as UiPath } from "@/lib/path";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { computed, ref, watchEffect } from "vue"; import { ref, watchEffect } from "vue";
interface HistoryEntry { interface HistoryEntry {
anchorId: string; anchorId: string;
@ -17,22 +17,22 @@ export const useUiStore = defineStore("ui", () => {
const history = ref<HistoryEntry[]>([]); const history = ref<HistoryEntry[]>([]);
// Managed by history // Managed by history
const _anchorId = ref<string>(); const anchorId = ref<string>();
const _focusPath = ref<UiPath>(new UiPath()); const focusPath = ref<UiPath>(new UiPath());
const openPaths = ref<Set<string>>(new Set()); const openPaths = ref<Set<string>>(new Set());
const _mode = ref<Mode>({ type: "focus" }); const mode = ref<Mode>({ type: "focus" });
const pinned = ref<{ segment: Segment; parentId?: string }>(); const pinned = ref<{ segment: Segment; parentId?: string }>();
// Ensure the currently focused note is visible. // Ensure the currently focused note is visible.
watchEffect(() => { watchEffect(() => {
if (_mode.value.type === "insert") { if (mode.value.type === "insert") {
for (const ancestor of _mode.value.path.ancestors()) { for (const ancestor of mode.value.path.ancestors()) {
setOpen(ancestor, true); setOpen(ancestor, true);
} }
} else { } else {
// The node pointed to by the path itself doesn't need to be unfolded. // The node pointed to by the path itself doesn't need to be unfolded.
for (const ancestor of _focusPath.value.ancestors().slice(1)) { for (const ancestor of focusPath.value.ancestors().slice(1)) {
setOpen(ancestor, true); setOpen(ancestor, true);
} }
} }
@ -42,22 +42,20 @@ export const useUiStore = defineStore("ui", () => {
// History and anchor management // // History and anchor management //
/////////////////////////////////// ///////////////////////////////////
const anchorId = computed(() => _anchorId.value); // Getter
function pushAnchorId(id: string): void { function pushAnchorId(id: string): void {
if (_anchorId.value) { if (anchorId.value) {
history.value.push({ history.value.push({
anchorId: _anchorId.value, anchorId: anchorId.value,
focusPath: _focusPath.value, focusPath: focusPath.value,
openPaths: openPaths.value, openPaths: openPaths.value,
}); });
} }
_anchorId.value = id; anchorId.value = id;
_focusPath.value = new UiPath(); focusPath.value = new UiPath();
openPaths.value = new Set(); openPaths.value = new Set();
_mode.value = { type: "focus" }; mode.value = { type: "focus" };
} }
function popAnchorId(): void { function popAnchorId(): void {
@ -66,55 +64,52 @@ export const useUiStore = defineStore("ui", () => {
const entry = history.value.pop(); const entry = history.value.pop();
if (entry) { if (entry) {
_anchorId.value = entry.anchorId; anchorId.value = entry.anchorId;
_focusPath.value = entry.focusPath; focusPath.value = entry.focusPath;
openPaths.value = entry.openPaths; openPaths.value = entry.openPaths;
} else { } else {
_anchorId.value = undefined; anchorId.value = undefined;
_focusPath.value = new UiPath(); focusPath.value = new UiPath();
openPaths.value = new Set(); openPaths.value = new Set();
} }
_mode.value = { type: "focus" }; mode.value = { type: "focus" };
} }
/////////////////////////////// ///////////////////////////////
// Mode and focus management // // Mode and focus management //
/////////////////////////////// ///////////////////////////////
const mode = computed(() => _mode.value.type);
const focusPath = computed(() => _focusPath.value);
function isFocused(path: UiPath): boolean { function isFocused(path: UiPath): boolean {
return _mode.value.type === "focus" && _focusPath.value.eq(path); return mode.value.type === "focus" && focusPath.value.eq(path);
} }
function isEditing(path: UiPath): boolean { function isEditing(path: UiPath): boolean {
return _mode.value.type === "edit" && _mode.value.path.eq(path); return mode.value.type === "edit" && mode.value.path.eq(path);
} }
function getInsertIndex(path: UiPath): number | undefined { function getInsertIndex(path: UiPath): number | undefined {
if (_mode.value.type !== "insert") return; if (mode.value.type !== "insert") return;
if (!_mode.value.path.eq(path)) return; if (!mode.value.path.eq(path)) return;
if (_mode.value.index < 0) return; if (mode.value.index < 0) return;
return _mode.value.index; return mode.value.index;
} }
function focus(): void { function focus(): void {
_mode.value = { type: "focus" }; mode.value = { type: "focus" };
} }
function focusOn(path: UiPath): void { function focusOn(path: UiPath): void {
focus(); focus();
_focusPath.value = path; focusPath.value = path;
} }
function edit(path: UiPath): void { function edit(path: UiPath): void {
_mode.value = { type: "edit", path }; mode.value = { type: "edit", path };
} }
function insertAt(path: UiPath, index: number): void { function insertAt(path: UiPath, index: number): void {
_mode.value = { type: "insert", path, index }; mode.value = { type: "insert", path, index };
} }
////////////////// //////////////////
@ -132,7 +127,7 @@ export const useUiStore = defineStore("ui", () => {
openPaths.value.add(path.fmt()); openPaths.value.add(path.fmt());
} else if (!value && isOpen(path)) { } else if (!value && isOpen(path)) {
// Move the focusPath if necessary // Move the focusPath if necessary
if (path.isPrefixOf(_focusPath.value)) _focusPath.value = path; if (path.isPrefixOf(focusPath.value)) focusPath.value = path;
openPaths.value.delete(path.fmt()); openPaths.value.delete(path.fmt());
} }
@ -160,21 +155,32 @@ export const useUiStore = defineStore("ui", () => {
} }
return { return {
history,
anchorId, anchorId,
focusPath,
openPaths,
mode,
pinned,
// History and anchor management
pushAnchorId, pushAnchorId,
popAnchorId, popAnchorId,
// Mode and focus management
isFocused, isFocused,
isEditing, isEditing,
getInsertIndex, getInsertIndex,
mode,
focusPath,
focus, focus,
focusOn, focusOn,
edit, edit,
insertAt, insertAt,
// Node folding
isOpen, isOpen,
setOpen, setOpen,
toggleOpen, toggleOpen,
// Pinning
isPinned, isPinned,
setPinned, setPinned,
unsetPinned, unsetPinned,