Vault picker: remove a vault from the Recent list (#93); fix Tasks view showing "All Notes" as the mobile header title

This commit is contained in:
Yuri Karamian
2026-06-11 20:48:20 +02:00
parent 784248f984
commit 2fea44bde6
5 changed files with 81 additions and 6 deletions
+11
View File
@@ -51,6 +51,17 @@ pub fn open_vault(app: AppHandle, state: State<'_, AppState>, path: String) -> R
Ok(()) Ok(())
} }
#[tauri::command]
pub fn remove_vault(state: State<'_, AppState>, path: String) -> Result<(), String> {
let mut config = state.config.lock().map_err(|e| e.to_string())?;
config.vaults.retain(|v| v.path != path);
if config.active_vault.as_deref() == Some(path.as_str()) {
config.active_vault = None;
}
save_app_config(&config)?;
Ok(())
}
#[tauri::command] #[tauri::command]
pub fn get_app_config(state: State<'_, AppState>) -> Result<AppConfig, String> { pub fn get_app_config(state: State<'_, AppState>) -> Result<AppConfig, String> {
let config = state.config.lock().map_err(|e| e.to_string())?; let config = state.config.lock().map_err(|e| e.to_string())?;
+1
View File
@@ -98,6 +98,7 @@ pub fn run() {
.manage(app_state) .manage(app_state)
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
commands::open_vault, commands::open_vault,
commands::remove_vault,
commands::get_app_config, commands::get_app_config,
commands::set_theme, commands::set_theme,
commands::set_accent_color, commands::set_accent_color,
+4
View File
@@ -20,6 +20,10 @@ export async function openVault(path: string): Promise<void> {
return invoke("open_vault", { path }); return invoke("open_vault", { path });
} }
export async function removeVault(path: string): Promise<void> {
return invoke("remove_vault", { path });
}
export async function getAppConfig(): Promise<AppConfig> { export async function getAppConfig(): Promise<AppConfig> {
return invoke("get_app_config"); return invoke("get_app_config");
} }
+1 -1
View File
@@ -724,7 +724,7 @@
{#if $mobileView === 'sidebar'} {#if $mobileView === 'sidebar'}
HelixNotes HelixNotes
{:else} {:else}
{#if $viewMode === 'notebook'}{$activeNotebook?.name ?? 'Notebook'}{:else if $viewMode === 'tag'}#{$activeTag}{:else if $viewMode === 'quickaccess'}Quick Access{:else if $viewMode === 'daily'}Daily Notes{:else if $viewMode === 'trash'}Trash{:else}All Notes{/if} {#if $viewMode === 'notebook'}{$activeNotebook?.name ?? 'Notebook'}{:else if $viewMode === 'tag'}#{$activeTag}{:else if $viewMode === 'quickaccess'}Quick Access{:else if $viewMode === 'daily'}Daily Notes{:else if $viewMode === 'tasks'}Tasks{:else if $viewMode === 'trash'}Trash{:else}All Notes{/if}
{/if} {/if}
</span> </span>
{#if $globalUpdateAvailable && $mobileView === 'sidebar'} {#if $globalUpdateAvailable && $mobileView === 'sidebar'}
+60 -1
View File
@@ -2,7 +2,7 @@
import { open } from '@tauri-apps/plugin-dialog'; import { open } from '@tauri-apps/plugin-dialog';
import { getCurrentWindow } from '@tauri-apps/api/window'; import { getCurrentWindow } from '@tauri-apps/api/window';
import { documentDir } from '@tauri-apps/api/path'; import { documentDir } from '@tauri-apps/api/path';
import { openVault, getAppConfig } from '$lib/api'; import { openVault, removeVault, getAppConfig } from '$lib/api';
import { appConfig, vaultReady } from '$lib/stores/app'; import { appConfig, vaultReady } from '$lib/stores/app';
import { isAndroid, isIOS, isMobile } from '$lib/platform'; import { isAndroid, isIOS, isMobile } from '$lib/platform';
import type { VaultConfig } from '$lib/types'; import type { VaultConfig } from '$lib/types';
@@ -107,6 +107,15 @@
loading = false; loading = false;
} }
} }
async function forgetVault(path: string) {
try {
await removeVault(path);
$appConfig = await getAppConfig();
} catch (e) {
error = String(e);
}
}
</script> </script>
<!-- svelte-ignore a11y_no_static_element_interactions --> <!-- svelte-ignore a11y_no_static_element_interactions -->
@@ -205,10 +214,18 @@
<div class="recent"> <div class="recent">
<span class="recent-label">Recent</span> <span class="recent-label">Recent</span>
{#each recentVaults as vault} {#each recentVaults as vault}
<div class="vault-row">
<button class="vault-item" onclick={() => openSelectedVault(vault.path)}> <button class="vault-item" onclick={() => openSelectedVault(vault.path)}>
<span class="vault-name">{vault.name}</span> <span class="vault-name">{vault.name}</span>
<span class="vault-path">{vault.path}</span> <span class="vault-path">{vault.path}</span>
</button> </button>
<button class="vault-remove" title="Remove from list" aria-label="Remove from list" onclick={() => forgetVault(vault.path)}>
<svg width="12" height="12" viewBox="0 0 10 10">
<line x1="1.5" y1="1.5" x2="8.5" y2="8.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" />
<line x1="8.5" y1="1.5" x2="1.5" y2="8.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" />
</svg>
</button>
</div>
{/each} {/each}
</div> </div>
{/if} {/if}
@@ -389,6 +406,48 @@
white-space: nowrap; white-space: nowrap;
} }
.vault-row {
display: flex;
align-items: stretch;
gap: 6px;
margin-bottom: 6px;
}
.vault-row .vault-item {
flex: 1;
min-width: 0;
margin-bottom: 0;
}
.vault-remove {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 36px;
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-tertiary);
cursor: pointer;
opacity: 0;
transition: opacity 0.15s, background 0.15s, color 0.15s;
}
.vault-row:hover .vault-remove,
.vault-remove:focus-visible {
opacity: 1;
}
.vault-remove:hover {
background: var(--bg-hover);
color: var(--text-primary);
}
.vault-picker.mobile .vault-remove {
opacity: 1;
}
.vault-name-input { .vault-name-input {
margin-bottom: 20px; margin-bottom: 20px;
text-align: left; text-align: left;