Timeline scroll fix
This commit is contained in:
parent
f1279f55ee
commit
66e21f7cc5
@ -450,6 +450,7 @@
|
|||||||
|
|
||||||
const scene = payload.scenes[points[0].index];
|
const scene = payload.scenes[points[0].index];
|
||||||
if (scene?.timelineUrl) {
|
if (scene?.timelineUrl) {
|
||||||
|
window.PlotLineTimelineScroll?.save();
|
||||||
window.location.href = scene.timelineUrl;
|
window.location.href = scene.timelineUrl;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -534,6 +535,15 @@
|
|||||||
const collapsedKey = "plotline.timeline.collapsed";
|
const collapsedKey = "plotline.timeline.collapsed";
|
||||||
const densityKey = "plotline.timeline.density";
|
const densityKey = "plotline.timeline.density";
|
||||||
const zoomKey = "plotline.timeline.zoom";
|
const zoomKey = "plotline.timeline.zoom";
|
||||||
|
const scrollKey = "plotline.timeline.pending-scroll";
|
||||||
|
const scrollContainerSelector = [
|
||||||
|
".timeline-shell",
|
||||||
|
".plot-lane-board",
|
||||||
|
".asset-lane-board",
|
||||||
|
".character-lane-board",
|
||||||
|
".metric-graph-stack",
|
||||||
|
"[data-timeline-minimap]"
|
||||||
|
].join(",");
|
||||||
const densityValues = ["compact", "comfortable", "expanded"];
|
const densityValues = ["compact", "comfortable", "expanded"];
|
||||||
const zoomValues = ["book", "chapter", "scene-detail"];
|
const zoomValues = ["book", "chapter", "scene-detail"];
|
||||||
|
|
||||||
@ -548,6 +558,62 @@
|
|||||||
const hasCollapsedPreference = localStorage.getItem(collapsedKey) !== null;
|
const hasCollapsedPreference = localStorage.getItem(collapsedKey) !== null;
|
||||||
const collapsed = readSet(collapsedKey);
|
const collapsed = readSet(collapsedKey);
|
||||||
|
|
||||||
|
const getScrollContainers = () => [...root.querySelectorAll(scrollContainerSelector)];
|
||||||
|
|
||||||
|
const saveScrollPosition = () => {
|
||||||
|
try {
|
||||||
|
sessionStorage.setItem(scrollKey, JSON.stringify({
|
||||||
|
path: window.location.pathname,
|
||||||
|
top: window.scrollY,
|
||||||
|
left: window.scrollX,
|
||||||
|
workspaceLeft: workspace.scrollLeft,
|
||||||
|
workspaceTop: workspace.scrollTop,
|
||||||
|
containers: getScrollContainers().map((container, index) => ({
|
||||||
|
index,
|
||||||
|
left: container.scrollLeft,
|
||||||
|
top: container.scrollTop
|
||||||
|
}))
|
||||||
|
}));
|
||||||
|
} catch {
|
||||||
|
// Storage can be unavailable in private or restricted browser modes.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const restoreScrollPosition = () => {
|
||||||
|
let scrollPosition = null;
|
||||||
|
try {
|
||||||
|
scrollPosition = JSON.parse(sessionStorage.getItem(scrollKey) || "null");
|
||||||
|
sessionStorage.removeItem(scrollKey);
|
||||||
|
} catch {
|
||||||
|
try {
|
||||||
|
sessionStorage.removeItem(scrollKey);
|
||||||
|
} catch {
|
||||||
|
// Ignore storage failures; normal navigation should continue.
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scrollPosition || scrollPosition.path !== window.location.pathname) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
workspace.scrollLeft = Number(scrollPosition.workspaceLeft) || 0;
|
||||||
|
workspace.scrollTop = Number(scrollPosition.workspaceTop) || 0;
|
||||||
|
const containers = getScrollContainers();
|
||||||
|
(scrollPosition.containers || []).forEach((saved) => {
|
||||||
|
const container = containers[saved.index];
|
||||||
|
if (container) {
|
||||||
|
container.scrollLeft = Number(saved.left) || 0;
|
||||||
|
container.scrollTop = Number(saved.top) || 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
window.scrollTo(Number(scrollPosition.left) || 0, Number(scrollPosition.top) || 0);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
window.PlotLineTimelineScroll = { save: saveScrollPosition };
|
||||||
|
|
||||||
const applyMode = (kind, value, values) => {
|
const applyMode = (kind, value, values) => {
|
||||||
values.forEach((item) => root.classList.remove(`${kind}-${item}`));
|
values.forEach((item) => root.classList.remove(`${kind}-${item}`));
|
||||||
root.classList.add(`${kind}-${value}`);
|
root.classList.add(`${kind}-${value}`);
|
||||||
@ -638,7 +704,38 @@
|
|||||||
zoomSelect?.addEventListener("change", () => applyZoom(zoomSelect.value));
|
zoomSelect?.addEventListener("change", () => applyZoom(zoomSelect.value));
|
||||||
applyDensity(localStorage.getItem(densityKey) || "comfortable");
|
applyDensity(localStorage.getItem(densityKey) || "comfortable");
|
||||||
applyZoom(localStorage.getItem(zoomKey) || "chapter");
|
applyZoom(localStorage.getItem(zoomKey) || "chapter");
|
||||||
window.requestAnimationFrame(() => scrollActiveChapterIntoView("auto"));
|
const hadPendingScrollRestore = (() => {
|
||||||
|
try {
|
||||||
|
return sessionStorage.getItem(scrollKey) !== null;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
scrollActiveChapterIntoView("auto");
|
||||||
|
if (hadPendingScrollRestore) {
|
||||||
|
restoreScrollPosition();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const saveScrollForSceneSelection = (event) => {
|
||||||
|
if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = event.target instanceof Element ? event.target : null;
|
||||||
|
const link = target?.closest("a[href]");
|
||||||
|
if (!link || !root.contains(link)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = new URL(link.href, window.location.href);
|
||||||
|
if ([...url.searchParams.keys()].some((key) => key.toLowerCase() === "selectedsceneid")) {
|
||||||
|
saveScrollPosition();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
root.addEventListener("click", saveScrollForSceneSelection, { capture: true });
|
||||||
|
|
||||||
const runSearch = () => {
|
const runSearch = () => {
|
||||||
const query = searchInput?.value.trim().toLowerCase() || "";
|
const query = searchInput?.value.trim().toLowerCase() || "";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user