mirror of
https://gitlab.com/ArkHost/HelixNotes.git
synced 2026-07-24 07:45:57 +02:00
add unfiled notes
This commit is contained in:
@@ -112,6 +112,13 @@ pub fn get_notebooks(state: State<'_, AppState>) -> Result<Vec<NotebookEntry>, S
|
|||||||
operations::scan_notebooks(vault_path)
|
operations::scan_notebooks(vault_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn count_root_notes(state: State<'_, AppState>) -> Result<usize, 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::count_root_notes(vault_path)
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn create_notebook(
|
pub fn create_notebook(
|
||||||
state: State<'_, AppState>,
|
state: State<'_, AppState>,
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ pub fn run() {
|
|||||||
commands::set_font_family,
|
commands::set_font_family,
|
||||||
commands::set_line_height,
|
commands::set_line_height,
|
||||||
commands::get_notebooks,
|
commands::get_notebooks,
|
||||||
|
commands::count_root_notes,
|
||||||
commands::create_notebook,
|
commands::create_notebook,
|
||||||
commands::rename_notebook,
|
commands::rename_notebook,
|
||||||
commands::delete_notebook,
|
commands::delete_notebook,
|
||||||
|
|||||||
@@ -167,6 +167,22 @@ fn is_hidden(path: &Path) -> bool {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn count_root_notes(vault_path: &str) -> Result<usize, String> {
|
||||||
|
let root = Path::new(vault_path);
|
||||||
|
if !root.exists() {
|
||||||
|
return Err("Vault path does not exist".to_string());
|
||||||
|
}
|
||||||
|
let count = fs::read_dir(root)
|
||||||
|
.map_err(|e| e.to_string())?
|
||||||
|
.filter_map(|e| e.ok())
|
||||||
|
.filter(|e| {
|
||||||
|
e.file_type().map(|ft| ft.is_file()).unwrap_or(false)
|
||||||
|
&& e.path().extension().and_then(|x| x.to_str()) == Some("md")
|
||||||
|
})
|
||||||
|
.count();
|
||||||
|
Ok(count)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn scan_notes(vault_path: &str, notebook_path: Option<&str>) -> Result<Vec<NoteEntry>, String> {
|
pub fn scan_notes(vault_path: &str, notebook_path: Option<&str>) -> Result<Vec<NoteEntry>, String> {
|
||||||
let scan_path = notebook_path.unwrap_or(vault_path);
|
let scan_path = notebook_path.unwrap_or(vault_path);
|
||||||
let root = Path::new(scan_path);
|
let root = Path::new(scan_path);
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ export async function getNotebooks(): Promise<NotebookEntry[]> {
|
|||||||
return invoke("get_notebooks");
|
return invoke("get_notebooks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function countRootNotes(): Promise<number> {
|
||||||
|
return invoke("count_root_notes");
|
||||||
|
}
|
||||||
|
|
||||||
export async function createNotebook(
|
export async function createNotebook(
|
||||||
parentRelative: string | null,
|
parentRelative: string | null,
|
||||||
name: string,
|
name: string,
|
||||||
|
|||||||
@@ -15,9 +15,10 @@
|
|||||||
notebookIcons,
|
notebookIcons,
|
||||||
appConfig,
|
appConfig,
|
||||||
quickAccessPaths,
|
quickAccessPaths,
|
||||||
collapsedNotebooks
|
collapsedNotebooks,
|
||||||
|
rootNoteCount
|
||||||
} from '$lib/stores/app';
|
} from '$lib/stores/app';
|
||||||
import { getNotebooks, getAllTags, createNotebook, deleteNotebook, renameNotebook, moveNotebook, getNotebookIcons, setNotebookIcon, saveAttachment, getQuickAccess, addQuickAccess, removeQuickAccess, emptyTrash, moveNote, readNote, getNotes } from '$lib/api';
|
import { getNotebooks, getAllTags, createNotebook, deleteNotebook, renameNotebook, moveNotebook, getNotebookIcons, setNotebookIcon, saveAttachment, getQuickAccess, addQuickAccess, removeQuickAccess, emptyTrash, moveNote, readNote, getNotes, countRootNotes } from '$lib/api';
|
||||||
import { open as openDialog } from '@tauri-apps/plugin-dialog';
|
import { open as openDialog } from '@tauri-apps/plugin-dialog';
|
||||||
import { readFile } from '@tauri-apps/plugin-fs';
|
import { readFile } from '@tauri-apps/plugin-fs';
|
||||||
import { convertFileSrc } from '@tauri-apps/api/core';
|
import { convertFileSrc } from '@tauri-apps/api/core';
|
||||||
@@ -53,16 +54,20 @@
|
|||||||
try {
|
try {
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
// On mobile, parallelize and skip getAllTags (derive from $notes instead)
|
// On mobile, parallelize and skip getAllTags (derive from $notes instead)
|
||||||
const [nbs, icons, qaNotes] = await Promise.all([
|
const [nbs, icons, qaNotes, rootCount] = await Promise.all([
|
||||||
getNotebooks(),
|
getNotebooks(),
|
||||||
getNotebookIcons(),
|
getNotebookIcons(),
|
||||||
getQuickAccess(),
|
getQuickAccess(),
|
||||||
|
countRootNotes(),
|
||||||
]);
|
]);
|
||||||
$notebooks = nbs;
|
$notebooks = nbs;
|
||||||
$notebookIcons = icons;
|
$notebookIcons = icons;
|
||||||
$quickAccessPaths = qaNotes.map(n => n.relative_path);
|
$quickAccessPaths = qaNotes.map(n => n.relative_path);
|
||||||
|
$rootNoteCount = rootCount;
|
||||||
} else {
|
} else {
|
||||||
$notebooks = await getNotebooks();
|
const [nbs, rootCount] = await Promise.all([getNotebooks(), countRootNotes()]);
|
||||||
|
$notebooks = nbs;
|
||||||
|
$rootNoteCount = rootCount;
|
||||||
$tags = await getAllTags();
|
$tags = await getAllTags();
|
||||||
$notebookIcons = await getNotebookIcons();
|
$notebookIcons = await getNotebookIcons();
|
||||||
const qaNotes = await getQuickAccess();
|
const qaNotes = await getQuickAccess();
|
||||||
@@ -80,6 +85,19 @@
|
|||||||
onViewChanged();
|
onViewChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectUnfiled() {
|
||||||
|
const vault = $appConfig?.active_vault;
|
||||||
|
if (!vault) return;
|
||||||
|
if ($viewMode === 'notebook' && $activeNotebook?.relative_path === '') {
|
||||||
|
selectAllNotes();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$viewMode = 'notebook';
|
||||||
|
$activeNotebook = { name: 'Unfiled Notes', path: vault, relative_path: '', children: [], note_count: $rootNoteCount };
|
||||||
|
$activeTag = null;
|
||||||
|
onViewChanged();
|
||||||
|
}
|
||||||
|
|
||||||
function selectNotebook(nb: NotebookEntry) {
|
function selectNotebook(nb: NotebookEntry) {
|
||||||
// Deselect if clicking the already-active notebook
|
// Deselect if clicking the already-active notebook
|
||||||
if ($viewMode === 'notebook' && $activeNotebook?.path === nb.path) {
|
if ($viewMode === 'notebook' && $activeNotebook?.path === nb.path) {
|
||||||
@@ -466,6 +484,20 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="notebook-list">
|
<div class="notebook-list">
|
||||||
|
{#if $rootNoteCount > 0}
|
||||||
|
<button
|
||||||
|
class="notebook-item"
|
||||||
|
class:active={$viewMode === 'notebook' && $activeNotebook?.relative_path === ''}
|
||||||
|
onclick={selectUnfiled}
|
||||||
|
>
|
||||||
|
<span class="chevron-spacer"></span>
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;opacity:0.6">
|
||||||
|
<path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
|
||||||
|
<polyline points="14 2 14 8 20 8" />
|
||||||
|
</svg>
|
||||||
|
<span class="notebook-name">Unfiled Notes <span class="notebook-count">{$rootNoteCount}</span></span>
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
{#each $notebooks as nb (nb.path)}
|
{#each $notebooks as nb (nb.path)}
|
||||||
{@render notebookItem(nb, 0)}
|
{@render notebookItem(nb, 0)}
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export const collapsedNotebooks = writable<string[]>([]);
|
|||||||
|
|
||||||
// Data
|
// Data
|
||||||
export const notebooks = writable<NotebookEntry[]>([]);
|
export const notebooks = writable<NotebookEntry[]>([]);
|
||||||
|
export const rootNoteCount = writable<number>(0);
|
||||||
export const notes = writable<NoteEntry[]>([]);
|
export const notes = writable<NoteEntry[]>([]);
|
||||||
export const tags = writable<[string, number][]>([]);
|
export const tags = writable<[string, number][]>([]);
|
||||||
export const activeNote = writable<NoteContent | null>(null);
|
export const activeNote = writable<NoteContent | null>(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user