mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-08 14:11:56 -07:00
bitview: initial history support
This commit is contained in:
@@ -97,9 +97,30 @@ const signals = {
|
||||
}-${paramKey}`,
|
||||
);
|
||||
|
||||
/** @type { ((this: Window, ev: PopStateEvent) => any) | undefined} */
|
||||
let popstateCallback;
|
||||
|
||||
let serialized = /** @type {string | null} */ (null);
|
||||
if (options.save.serializeParam !== false) {
|
||||
serialized = new URLSearchParams(window.location.search).get(paramKey);
|
||||
|
||||
// popstateCallback =
|
||||
// /** @type {(this: Window, ev: PopStateEvent) => any} */ (
|
||||
// (_) => {
|
||||
// serialized = new URLSearchParams(window.location.search).get(
|
||||
// paramKey,
|
||||
// );
|
||||
// set(() =>
|
||||
// serialized ? save.deserialize(serialized) : initialValue,
|
||||
// );
|
||||
// }
|
||||
// );
|
||||
// if (!popstateCallback) throw "Unreachable";
|
||||
// window.addEventListener("popstate", popstateCallback);
|
||||
// signals.onCleanup(() => {
|
||||
// if (popstateCallback)
|
||||
// window.removeEventListener("popstate", popstateCallback);
|
||||
// });
|
||||
}
|
||||
if (serialized === null) {
|
||||
try {
|
||||
|
||||
@@ -2205,15 +2205,29 @@ function main() {
|
||||
vecIdToIndexes,
|
||||
});
|
||||
|
||||
// window.addEventListener("popstate", (_) => {
|
||||
// const urlSelected = utils.url.pathnameToSelectedId();
|
||||
// const option = options.list.find(
|
||||
// (option) => urlSelected === option.id,
|
||||
// );
|
||||
// if (option) {
|
||||
// options.selected.set(option);
|
||||
// }
|
||||
// });
|
||||
window.addEventListener("popstate", (event) => {
|
||||
const path = window.document.location.pathname
|
||||
.split("/")
|
||||
.filter((v) => v);
|
||||
let folder = options.tree;
|
||||
|
||||
while (path.length) {
|
||||
const id = path.shift();
|
||||
const res = folder.find((v) => id === utils.stringToId(v.name));
|
||||
if (!res) throw "Option not found";
|
||||
if (path.length >= 1) {
|
||||
if (!("tree" in res)) {
|
||||
throw "Unreachable";
|
||||
}
|
||||
folder = res.tree;
|
||||
} else {
|
||||
if ("tree" in res) {
|
||||
throw "Unreachable";
|
||||
}
|
||||
options.selected.set(res);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function initSelected() {
|
||||
let firstRun = true;
|
||||
@@ -2239,14 +2253,6 @@ function main() {
|
||||
let firstTimeLoadingExplorer = true;
|
||||
|
||||
signals.createEffect(options.selected, (option) => {
|
||||
if (previousElement) {
|
||||
previousElement.hidden = true;
|
||||
utils.url.resetParams(option);
|
||||
utils.url.pushHistory(option.path);
|
||||
} else {
|
||||
utils.url.replaceHistory({ pathname: option.path });
|
||||
}
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
let element;
|
||||
|
||||
@@ -2364,7 +2370,15 @@ function main() {
|
||||
}
|
||||
}
|
||||
|
||||
element.hidden = false;
|
||||
if (element !== previousElement) {
|
||||
if (previousElement) previousElement.hidden = true;
|
||||
element.hidden = false;
|
||||
}
|
||||
|
||||
if (!previousElement) {
|
||||
utils.url.replaceHistory({ pathname: option.path });
|
||||
}
|
||||
|
||||
previousElement = element;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@
|
||||
*
|
||||
* @typedef {ExplorerOption | ChartOption | TableOption | SimulationOption | UrlOption} Option
|
||||
*
|
||||
* @typedef {(AnyPartialOption | PartialOptionsGroup)[]} PartialOptionsTree
|
||||
*
|
||||
* @typedef {Object} PartialOptionsGroup
|
||||
* @property {string} name
|
||||
* @property {PartialOptionsTree} tree
|
||||
@@ -112,8 +114,6 @@
|
||||
* @property {string} name
|
||||
* @property {OptionsTree} tree
|
||||
*
|
||||
* @typedef {(AnyPartialOption | PartialOptionsGroup)[]} PartialOptionsTree
|
||||
*
|
||||
* @typedef {(Option | OptionsGroup)[]} OptionsTree
|
||||
*
|
||||
*/
|
||||
@@ -4154,9 +4154,14 @@ export function initOptions({
|
||||
}) {
|
||||
const LS_SELECTED_KEY = `selected_id`;
|
||||
|
||||
const urlPath_ = window.document.location.pathname.substring(1).split("/");
|
||||
const urlPath_ = window.document.location.pathname
|
||||
.split("/")
|
||||
.filter((v) => v);
|
||||
const urlPath = urlPath_.length ? urlPath_ : undefined;
|
||||
const savedPath = utils.storage.read(LS_SELECTED_KEY)?.split("/");
|
||||
const savedPath = utils.storage
|
||||
.read(LS_SELECTED_KEY)
|
||||
?.split("/")
|
||||
.filter((v) => v);
|
||||
|
||||
/** @type {Signal<Option>} */
|
||||
const selected = signals.createSignal(/** @type {any} */ (undefined));
|
||||
@@ -4183,6 +4188,15 @@ export function initOptions({
|
||||
}, /** @type {Record<Unit, AnyFetchedSeriesBlueprint[]>} */ ({}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Option} option
|
||||
*/
|
||||
function selectOption(option) {
|
||||
utils.url.pushHistory(option.path);
|
||||
utils.url.resetParams(option);
|
||||
selected.set(option);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} args
|
||||
* @param {Option} args.option
|
||||
@@ -4217,7 +4231,7 @@ export function initOptions({
|
||||
title,
|
||||
text: name || option.name,
|
||||
onClick: () => {
|
||||
selected.set(() => option);
|
||||
selectOption(option);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -4343,52 +4357,66 @@ export function initOptions({
|
||||
}
|
||||
createRenderLiEffect();
|
||||
} else {
|
||||
/** @type {Option} */
|
||||
let option;
|
||||
const option = /** @type {Option} */ (anyPartial);
|
||||
|
||||
const name = anyPartial.name;
|
||||
const path = [...parentPath, utils.stringToId(anyPartial.name)];
|
||||
const name = option.name;
|
||||
const path = [...parentPath, utils.stringToId(option.name)];
|
||||
|
||||
if ("kind" in anyPartial && anyPartial.kind === "explorer") {
|
||||
option = /** @satisfies {ExplorerOption} */ ({
|
||||
kind: anyPartial.kind,
|
||||
name,
|
||||
path,
|
||||
title: anyPartial.title,
|
||||
});
|
||||
Object.assign(
|
||||
option,
|
||||
/** @satisfies {ExplorerOption} */ ({
|
||||
kind: anyPartial.kind,
|
||||
path,
|
||||
name,
|
||||
title: option.title,
|
||||
}),
|
||||
);
|
||||
} else if ("kind" in anyPartial && anyPartial.kind === "table") {
|
||||
option = /** @satisfies {TableOption} */ ({
|
||||
kind: anyPartial.kind,
|
||||
name,
|
||||
path,
|
||||
title: anyPartial.title,
|
||||
});
|
||||
Object.assign(
|
||||
option,
|
||||
/** @satisfies {TableOption} */ ({
|
||||
kind: anyPartial.kind,
|
||||
path,
|
||||
name,
|
||||
title: option.title,
|
||||
}),
|
||||
);
|
||||
} else if ("kind" in anyPartial && anyPartial.kind === "simulation") {
|
||||
option = /** @satisfies {SimulationOption} */ ({
|
||||
kind: anyPartial.kind,
|
||||
name,
|
||||
path,
|
||||
title: anyPartial.title,
|
||||
});
|
||||
Object.assign(
|
||||
option,
|
||||
/** @satisfies {SimulationOption} */ ({
|
||||
kind: anyPartial.kind,
|
||||
path,
|
||||
name,
|
||||
title: anyPartial.title,
|
||||
}),
|
||||
);
|
||||
} else if ("url" in anyPartial) {
|
||||
option = /** @satisfies {UrlOption} */ ({
|
||||
kind: "url",
|
||||
name,
|
||||
path,
|
||||
title: name,
|
||||
qrcode: !!anyPartial.qrcode,
|
||||
url: anyPartial.url,
|
||||
});
|
||||
Object.assign(
|
||||
option,
|
||||
/** @satisfies {UrlOption} */ ({
|
||||
kind: "url",
|
||||
path,
|
||||
name,
|
||||
title: name,
|
||||
qrcode: !!anyPartial.qrcode,
|
||||
url: anyPartial.url,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
const title = anyPartial.title || anyPartial.name;
|
||||
option = /** @satisfies {ChartOption} */ ({
|
||||
kind: "chart",
|
||||
name,
|
||||
title,
|
||||
path,
|
||||
top: arrayToRecord(anyPartial.top),
|
||||
bottom: arrayToRecord(anyPartial.bottom),
|
||||
});
|
||||
const title = option.title || option.name;
|
||||
Object.assign(
|
||||
option,
|
||||
/** @satisfies {ChartOption} */ ({
|
||||
kind: "chart",
|
||||
name,
|
||||
title,
|
||||
path,
|
||||
top: arrayToRecord(anyPartial.top),
|
||||
bottom: arrayToRecord(anyPartial.bottom),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
list.push(option);
|
||||
@@ -4455,6 +4483,7 @@ export function initOptions({
|
||||
tree: /** @type {OptionsTree} */ (partialOptions),
|
||||
parent,
|
||||
createOptionElement,
|
||||
selectOption,
|
||||
};
|
||||
}
|
||||
/** @typedef {ReturnType<typeof initOptions>} Options */
|
||||
|
||||
Reference in New Issue
Block a user