From 6dfea864f34cf158b6b50a3ecc3ffeac4cbb1181 Mon Sep 17 00:00:00 2001 From: Yuri Karamian Date: Wed, 11 Feb 2026 15:08:28 +0100 Subject: [PATCH] v1.0.7 - Virtual scroll, context menu fix, wiki-link cache fix --- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/lib/components/Editor.svelte | 4 ++- src/lib/components/NoteList.svelte | 40 +++++++++++++++++++++++++++--- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 33a873f..15ca19a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "helixnotes", "private": true, "license": "AGPL-3.0-or-later", - "version": "1.0.6", + "version": "1.0.7", "type": "module", "scripts": { "dev": "vite dev", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 6378dd4..d30ca9e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1778,7 +1778,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "helixnotes" -version = "1.0.6" +version = "1.0.7" dependencies = [ "chrono", "dirs", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 4540c6f..14c45b9 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helixnotes" -version = "1.0.6" +version = "1.0.7" description = "Local-first markdown note-taking app" authors = ["HelixNotes"] license = "AGPL-3.0-or-later" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index ba767c1..0940897 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", "productName": "HelixNotes", - "version": "1.0.6", + "version": "1.0.7", "identifier": "com.helixnotes.app", "build": { "frontendDist": "../build", diff --git a/src/lib/components/Editor.svelte b/src/lib/components/Editor.svelte index e8b719f..2cc8a4c 100644 --- a/src/lib/components/Editor.svelte +++ b/src/lib/components/Editor.svelte @@ -723,6 +723,8 @@ closeWikiLinkMenu(); return; } + // Refresh titles when the menu first opens so newly created notes are found + if (!wikiLinkMenu) refreshWikiLinkTitles(); const query = match[1]; const bracketOffset = textBefore.length - match[0].length; const from = resolvedFrom.start() + bracketOffset; @@ -1759,7 +1761,7 @@ let x = event.clientX; let y = event.clientY; const menuWidth = 220; - const menuHeight = 640; + const menuHeight = 740; if (x + menuWidth > window.innerWidth) x = window.innerWidth - menuWidth - 8; if (y + menuHeight > window.innerHeight) y = window.innerHeight - menuHeight - 8; if (x < 4) x = 4; diff --git a/src/lib/components/NoteList.svelte b/src/lib/components/NoteList.svelte index 8ca79b1..125568b 100644 --- a/src/lib/components/NoteList.svelte +++ b/src/lib/components/NoteList.svelte @@ -54,16 +54,47 @@ let qaDragOver = $state(null); let qaDragHalf = $state<'top' | 'bottom'>('bottom'); + // Virtual scroll + let listContainer = $state(null!); + let scrollTop = $state(0); + let containerHeight = $state(600); + let itemHeight = $derived(compact ? 33 : 62); + const BUFFER = 10; + + let totalHeight = $derived($sortedNotes.length * itemHeight); + let startIndex = $derived(Math.max(0, Math.floor(scrollTop / itemHeight) - BUFFER)); + let endIndex = $derived(Math.min($sortedNotes.length, Math.ceil((scrollTop + containerHeight) / itemHeight) + BUFFER)); + let visibleNotes = $derived($sortedNotes.slice(startIndex, endIndex)); + let topPad = $derived(startIndex * itemHeight); + let bottomPad = $derived(Math.max(0, ($sortedNotes.length - endIndex) * itemHeight)); + + function onListScroll(e: Event) { + const el = e.currentTarget as HTMLDivElement; + scrollTop = el.scrollTop; + } + function clearSelection() { selectedPaths = new Set(); lastClickedPath = null; batchMovePicker = false; } - // Clear selection when view/notebook changes + // Clear selection and reset scroll when view/notebook changes $effect(() => { const _ = [$viewMode, $activeNotebook, $activeTag]; clearSelection(); + scrollTop = 0; + if (listContainer) listContainer.scrollTop = 0; + }); + + // Track container height via ResizeObserver + $effect(() => { + if (!listContainer) return; + const ro = new ResizeObserver((entries) => { + containerHeight = entries[0].contentRect.height; + }); + ro.observe(listContainer); + return () => ro.disconnect(); }); interface FlatNotebook { name: string; path: string; depth: number; } @@ -506,7 +537,7 @@ {/if} -
+
{#if $sortedNotes.length === 0}
{#if $viewMode === 'trash'} @@ -518,7 +549,9 @@
{/if} - {#each $sortedNotes as note, noteIndex (note.path)} +
+ {#each visibleNotes as note, i (note.path)} + {@const noteIndex = startIndex + i} {#if editingNote === note.path}
{/if} {/each} +