Resizable sidebar remembered in settings.json; nest tags by / like branches

This commit is contained in:
2026-10-14 22:21:09 +02:00
parent bf9b3baa1f
commit f027ebe2aa
7 changed files with 127 additions and 13 deletions
+55
View File
@@ -25,6 +25,48 @@ const selected = ref(0);
const toast = ref<string | null>(null);
const sidebar = ref<InstanceType<typeof Sidebar>>();
// ---- settings: the sidebar width -------------------------------------------
const SIDEBAR_MIN = 160;
const SIDEBAR_MAX = 700;
const sidebarWidth = ref(270);
let settingsLoaded = false;
async function loadSettings() {
const saved = await invoke<{ sidebarWidth?: number } | null>("load_settings").catch(() => null);
if (typeof saved?.sidebarWidth === "number") {
sidebarWidth.value = Math.min(SIDEBAR_MAX, Math.max(SIDEBAR_MIN, saved.sidebarWidth));
}
settingsLoaded = true;
}
let settingsTimer: number | undefined;
watch(sidebarWidth, () => {
if (!settingsLoaded) return;
clearTimeout(settingsTimer);
settingsTimer = window.setTimeout(() => {
invoke("save_settings", { value: { sidebarWidth: sidebarWidth.value } }).catch((e) =>
showToast(`could not save settings: ${e}`),
);
}, 300);
});
function startResize(e: PointerEvent) {
const handle = e.currentTarget as HTMLElement;
handle.setPointerCapture(e.pointerId);
const startX = e.clientX;
const startWidth = sidebarWidth.value;
const move = (ev: PointerEvent) => {
sidebarWidth.value = Math.min(SIDEBAR_MAX, Math.max(SIDEBAR_MIN, startWidth + ev.clientX - startX));
};
const stop = () => {
handle.removeEventListener("pointermove", move);
handle.removeEventListener("pointerup", stop);
};
handle.addEventListener("pointermove", move);
handle.addEventListener("pointerup", stop);
}
// ---- loading and saving -------------------------------------------------
let filtersLoadedFor: string | null = null;
@@ -228,6 +270,7 @@ onMounted(() => {
viewWidth.value = scroller.value?.clientWidth ?? 1000;
});
if (scroller.value) resizeObserver.observe(scroller.value);
loadSettings();
load();
});
onUnmounted(() => {
@@ -270,8 +313,10 @@ onUnmounted(() => {
:filters="filters"
:head-ref="repo.head_ref"
:time-of="timeOf"
:style="{ width: sidebarWidth + 'px' }"
@jump="jumpTo"
/>
<div v-if="repo" class="splitter" title="drag to resize" @pointerdown.prevent="startResize" />
<div v-if="error" class="error">
<h2>Could not open the repository</h2>
@@ -372,6 +417,16 @@ onUnmounted(() => {
.collapse:disabled { opacity: 0.4; cursor: default; background: none; }
.collapse.on { border-color: var(--accent); color: var(--accent); background: #b197fc1a; }
.main { flex: 1; display: flex; min-height: 0; }
.splitter {
flex: none;
width: 5px;
margin-left: -3px;
margin-right: -2px;
cursor: col-resize;
position: relative;
z-index: 5;
}
.splitter:hover, .splitter:active { background: var(--accent); opacity: 0.6; }
.list { flex: 1; overflow: auto; position: relative; }
.spacer-rows { position: relative; min-width: 700px; }
.row {