v1.0.4 - Quick Access reorder, performance improvements, search fixes

- Quick Access drag-to-reorder: drag notes to rearrange, order persists
- Quick Access preserves order when moving notes between notebooks
- In-note search: debounced input, proper scroll-to-match
- Panel resize: RAF-batched updates, editor containment during resize
- Thinner resize handles (3px)
- Note list: removed transition, added CSS containment for 1200+ notes
- Escape closes Settings and Info panels
- Fix Quick Access cache invalidation on remove
This commit is contained in:
Yuri Karamian
2026-02-10 21:14:50 +01:00
parent a95e240bcd
commit f688cf4bd4
12 changed files with 193 additions and 51 deletions
+1 -1
View File
@@ -1778,7 +1778,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "helixnotes"
version = "1.0.3"
version = "1.0.4"
dependencies = [
"chrono",
"dirs",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "helixnotes"
version = "1.0.3"
version = "1.0.4"
description = "Local-first markdown note-taking app"
authors = ["HelixNotes"]
license = "AGPL-3.0-or-later"
+41 -2
View File
@@ -2,6 +2,7 @@ use crate::search::SearchIndex;
use crate::state::AppState;
use crate::types::*;
use crate::vault::{operations, watcher};
use std::path::Path;
use tauri::{AppHandle, Manager, State};
// ── Vault Management ──
@@ -195,8 +196,39 @@ pub fn delete_note(state: State<'_, AppState>, path: String) -> Result<(), Strin
}
#[tauri::command]
pub fn move_note(note_path: String, dest_notebook: String) -> Result<String, String> {
operations::move_note(&note_path, &dest_notebook)
pub fn move_note(
state: State<'_, AppState>,
note_path: String,
dest_notebook: String,
) -> Result<String, String> {
let config = state.config.lock().map_err(|e| e.to_string())?;
let vault_path = config.active_vault.as_ref().ok_or("No active vault")?;
// Compute old relative path before move
let old_relative = Path::new(&note_path)
.strip_prefix(vault_path)
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default();
let new_full_path = operations::move_note(&note_path, &dest_notebook)?;
// Update quick access if the moved note was in it
if !old_relative.is_empty() {
if let Ok(mut qa) = operations::load_quick_access(vault_path) {
if let Some(pos) = qa.iter().position(|p| *p == old_relative) {
let new_relative = Path::new(&new_full_path)
.strip_prefix(vault_path)
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default();
if !new_relative.is_empty() {
qa[pos] = new_relative;
let _ = operations::save_quick_access(vault_path, &qa);
}
}
}
}
Ok(new_full_path)
}
// ── Tags ──
@@ -437,6 +469,13 @@ pub fn remove_quick_access(
operations::remove_quick_access(vault_path, &note_relative)
}
#[tauri::command]
pub fn reorder_quick_access(state: State<'_, AppState>, paths: Vec<String>) -> Result<(), String> {
let config = state.config.lock().map_err(|e| e.to_string())?;
let vault_path = config.active_vault.as_ref().ok_or("No active vault")?;
operations::save_quick_access(vault_path, &paths)
}
#[tauri::command]
pub fn get_vault_stats(state: State<'_, AppState>) -> Result<VaultStats, String> {
let config = state.config.lock().map_err(|e| e.to_string())?;
+1
View File
@@ -79,6 +79,7 @@ pub fn run() {
commands::get_quick_access,
commands::add_quick_access,
commands::remove_quick_access,
commands::reorder_quick_access,
commands::get_vault_stats,
commands::import_obsidian,
commands::open_file,
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "HelixNotes",
"version": "1.0.3",
"version": "1.0.4",
"identifier": "com.helixnotes.app",
"build": {
"frontendDist": "../build",