148 lines
4.2 KiB
JavaScript
148 lines
4.2 KiB
JavaScript
// MNote debug /tree shell picker focus and selection reducers.
|
|
|
|
import { normalizeTreeShellText } from "./tree-shell-state-runtime.js";
|
|
|
|
export function getTreeShellVisiblePickerEntries(context) {
|
|
if (context.mode !== "picker") {
|
|
return [];
|
|
}
|
|
|
|
const visible = [];
|
|
if (context.allowRootPick) {
|
|
visible.push({
|
|
pickerItemKey: "__root__",
|
|
item: null,
|
|
});
|
|
}
|
|
|
|
const walk = (entries) => {
|
|
entries.forEach((item) => {
|
|
visible.push({
|
|
pickerItemKey: item.nodeId,
|
|
item,
|
|
});
|
|
if (item.childCount > 0 && context.expanded.has(item.nodeId)) {
|
|
walk(context.getSiblings(item.nodeId));
|
|
}
|
|
});
|
|
};
|
|
|
|
walk(context.roots);
|
|
return visible;
|
|
}
|
|
|
|
export function isTreeShellPickerEntryPickable(entry, context) {
|
|
if (!entry) return false;
|
|
if (entry.pickerItemKey === "__root__") {
|
|
return context.allowRootPick;
|
|
}
|
|
const documentId = normalizeTreeShellText(entry.item?.nodeId || entry.pickerItemKey);
|
|
return Boolean(documentId && !context.excludedIds.has(documentId));
|
|
}
|
|
|
|
export function normalizeTreeShellPickerItemKey(pickerItemKey, context) {
|
|
const normalizedItemKey = normalizeTreeShellText(pickerItemKey);
|
|
if (normalizedItemKey === "__root__" && context.allowRootPick) {
|
|
return "__root__";
|
|
}
|
|
if (
|
|
normalizedItemKey &&
|
|
context.itemById.has(normalizedItemKey) &&
|
|
!context.excludedIds.has(normalizedItemKey)
|
|
) {
|
|
return normalizedItemKey;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
export function resolveTreeShellCurrentPickerItemKey(context) {
|
|
const fromActive = context.normalizePickerItemKey(context.currentActivePickerItemKey);
|
|
if (fromActive) return fromActive;
|
|
const fromDocument = context.normalizePickerItemKey(context.currentActiveDocumentId);
|
|
if (fromDocument) return fromDocument;
|
|
return context.getPickablePickerEntries()[0]?.pickerItemKey || "";
|
|
}
|
|
|
|
export function computeTreeShellPickerStateActionResult(context, action) {
|
|
const currentPickerItemKey = context.resolveCurrentPickerItemKey();
|
|
if (
|
|
context.mode !== "picker" ||
|
|
context.pickerStateReducerContractName !== "rust_picker_state_reducer_v1" ||
|
|
!context.pickerStateReducerActions.has(action?.kind || "")
|
|
) {
|
|
return {
|
|
nextItemKey: currentPickerItemKey,
|
|
pickedDocumentId:
|
|
action?.kind === "pick" && currentPickerItemKey !== "__root__"
|
|
? currentPickerItemKey || null
|
|
: null,
|
|
pickedRoot: action?.kind === "pick" && currentPickerItemKey === "__root__",
|
|
};
|
|
}
|
|
|
|
const pickable = context.getPickablePickerEntries();
|
|
if (pickable.length === 0) {
|
|
return {
|
|
nextItemKey: "",
|
|
pickedDocumentId: null,
|
|
pickedRoot: false,
|
|
};
|
|
}
|
|
const currentIndex = pickable.findIndex(
|
|
(entry) => entry.pickerItemKey === currentPickerItemKey,
|
|
);
|
|
const resolvedIndex = currentIndex >= 0 ? currentIndex : 0;
|
|
const actionKind = action.kind;
|
|
|
|
if (actionKind === "normalize") {
|
|
return {
|
|
nextItemKey: pickable[resolvedIndex]?.pickerItemKey || "",
|
|
pickedDocumentId: null,
|
|
pickedRoot: false,
|
|
};
|
|
}
|
|
|
|
if (actionKind === "focus") {
|
|
const nextItemKey = context.normalizePickerItemKey(action.itemKey);
|
|
return {
|
|
nextItemKey: nextItemKey || pickable[0]?.pickerItemKey || "",
|
|
pickedDocumentId: null,
|
|
pickedRoot: false,
|
|
};
|
|
}
|
|
|
|
if (actionKind === "pick") {
|
|
const target = pickable[resolvedIndex];
|
|
const targetKey = target?.pickerItemKey || "";
|
|
return {
|
|
nextItemKey: targetKey,
|
|
pickedDocumentId:
|
|
targetKey && targetKey !== "__root__" ? targetKey : null,
|
|
pickedRoot: targetKey === "__root__",
|
|
};
|
|
}
|
|
|
|
let nextIndex = resolvedIndex;
|
|
if (actionKind === "next") {
|
|
nextIndex = Math.min(pickable.length - 1, resolvedIndex + 1);
|
|
} else if (actionKind === "previous") {
|
|
nextIndex = Math.max(0, resolvedIndex - 1);
|
|
} else if (actionKind === "home") {
|
|
nextIndex = 0;
|
|
} else if (actionKind === "end") {
|
|
nextIndex = pickable.length - 1;
|
|
} else {
|
|
return {
|
|
nextItemKey: currentPickerItemKey,
|
|
pickedDocumentId: null,
|
|
pickedRoot: false,
|
|
};
|
|
}
|
|
|
|
return {
|
|
nextItemKey: pickable[nextIndex]?.pickerItemKey || "",
|
|
pickedDocumentId: null,
|
|
pickedRoot: false,
|
|
};
|
|
}
|