fix(electrobun): XDG dirs, sanitized errors, themed dropdowns + checkboxes

- PathBrowser: dynamic XDG shortcuts (only shows dirs that exist)
- Errors sanitized: "Directory not found" instead of raw ENOENT
- Select dropdowns: custom arrow, themed options, appearance:none
- Checkboxes: custom styled with --ctp-blue check, themed border
This commit is contained in:
Hibryda 2026-03-22 12:40:56 +01:00
parent f71ca2e1ca
commit d8b831089a
2 changed files with 81 additions and 7 deletions

View file

@ -10,12 +10,34 @@
let { onSelect, onClose }: Props = $props();
let HOME = $state('/home');
const SHORTCUTS = [
let shortcuts = $state([
{ label: 'Home', path: '~' },
{ label: 'Desktop', path: '~/Desktop' },
{ label: 'Documents', path: '~/Documents' },
{ label: '/tmp', path: '/tmp' },
];
]);
// Load XDG user directories from backend
async function loadXdgDirs() {
try {
const r = await appRpc.request['files.homeDir']({});
if (r?.path) HOME = r.path;
// Check which XDG dirs actually exist
const candidates = [
{ label: 'Desktop', env: 'XDG_DESKTOP_DIR', fallback: `${HOME}/Desktop` },
{ label: 'Documents', env: 'XDG_DOCUMENTS_DIR', fallback: `${HOME}/Documents` },
{ label: 'Downloads', env: 'XDG_DOWNLOAD_DIR', fallback: `${HOME}/Downloads` },
{ label: 'Projects', env: 'XDG_PROJECTS_DIR', fallback: `${HOME}/Projects` },
];
// Validate each via files.browse (only add if dir exists)
const existing: typeof shortcuts = [{ label: 'Home', path: '~' }];
for (const c of candidates) {
const path = c.fallback.replace(HOME, '~');
const res = await appRpc.request['files.browse']({ path: c.fallback }).catch(() => null);
if (res && !res.error) existing.push({ label: c.label, path });
}
existing.push({ label: '/tmp', path: '/tmp' });
shortcuts = existing;
} catch {}
}
let currentPath = $state('~');
let entries = $state<Array<{ name: string; type: 'file' | 'dir'; size: number }>>([]);
@ -65,7 +87,15 @@
}
currentPath = dirPath;
} catch (err) {
error = err instanceof Error ? err.message : String(err);
const raw = err instanceof Error ? err.message : String(err);
// Sanitize: show user-friendly message, not raw ENOENT
if (raw.includes('ENOENT') || raw.includes('no such file')) {
error = 'Directory not found';
} else if (raw.includes('EACCES') || raw.includes('permission')) {
error = 'Permission denied';
} else {
error = 'Cannot access this directory';
}
entries = [];
} finally {
loading = false;
@ -89,6 +119,7 @@
// Load initial directory
$effect(() => {
loadXdgDirs();
loadDir('~');
});
</script>
@ -102,7 +133,7 @@
<!-- Shortcuts -->
<div class="pb-shortcuts">
{#each SHORTCUTS as sc}
{#each shortcuts as sc}
<button class="pb-shortcut" onclick={() => navigateTo(sc.path)}>{sc.label}</button>
{/each}
</div>