mirror of
https://gitlab.com/ArkHost/HelixNotes.git
synced 2026-07-24 07:45:57 +02:00
v1.0.7 - Virtual scroll, context menu fix, wiki-link cache fix
This commit is contained in:
+1
-1
@@ -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",
|
||||
|
||||
Generated
+1
-1
@@ -1778,7 +1778,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "helixnotes"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"dirs",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -54,16 +54,47 @@
|
||||
let qaDragOver = $state<number | null>(null);
|
||||
let qaDragHalf = $state<'top' | 'bottom'>('bottom');
|
||||
|
||||
// Virtual scroll
|
||||
let listContainer = $state<HTMLDivElement>(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 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="list-content">
|
||||
<div class="list-content" bind:this={listContainer} onscroll={onListScroll}>
|
||||
{#if $sortedNotes.length === 0}
|
||||
<div class="empty-state">
|
||||
{#if $viewMode === 'trash'}
|
||||
@@ -518,7 +549,9 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#each $sortedNotes as note, noteIndex (note.path)}
|
||||
<div style="height: {topPad}px"></div>
|
||||
{#each visibleNotes as note, i (note.path)}
|
||||
{@const noteIndex = startIndex + i}
|
||||
{#if editingNote === note.path}
|
||||
<div class="note-item active">
|
||||
<input
|
||||
@@ -626,6 +659,7 @@
|
||||
</button>
|
||||
{/if}
|
||||
{/each}
|
||||
<div style="height: {bottomPad}px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user