fix(electrobun): native folder picker dialog replaces inline PathBrowser
- Uses Electrobun's Utils.openFileDialog (canChooseDirectory: true)
- files.pickDirectory + files.homeDir RPC handlers
- ProjectWizard: 📂 button opens native OS dialog
- Removed broken inline PathBrowser (process.env.HOME not in WebView)
This commit is contained in:
parent
45bca3b96f
commit
bfc63bb595
3 changed files with 44 additions and 7 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { BrowserWindow, BrowserView, Updater } from "electrobun/bun";
|
import { BrowserWindow, BrowserView, Updater, Utils } from "electrobun/bun";
|
||||||
import { PtyClient } from "./pty-client.ts";
|
import { PtyClient } from "./pty-client.ts";
|
||||||
import { settingsDb } from "./settings-db.ts";
|
import { settingsDb } from "./settings-db.ts";
|
||||||
import { sessionDb } from "./session-db.ts";
|
import { sessionDb } from "./session-db.ts";
|
||||||
|
|
@ -128,6 +128,24 @@ const rpc = BrowserView.defineRPC<PtyRPCSchema>({
|
||||||
// Git
|
// Git
|
||||||
...gitHandlers,
|
...gitHandlers,
|
||||||
|
|
||||||
|
// Native folder picker dialog
|
||||||
|
"files.pickDirectory": async ({ startingFolder }) => {
|
||||||
|
try {
|
||||||
|
const paths = await Utils.openFileDialog({
|
||||||
|
startingFolder: startingFolder || "~/",
|
||||||
|
canChooseFiles: false,
|
||||||
|
canChooseDirectory: true,
|
||||||
|
allowsMultipleSelection: false,
|
||||||
|
});
|
||||||
|
return { path: paths?.[0] ?? null };
|
||||||
|
} catch { return { path: null }; }
|
||||||
|
},
|
||||||
|
|
||||||
|
// Home directory
|
||||||
|
"files.homeDir": async () => {
|
||||||
|
return { path: process.env.HOME || "/home" };
|
||||||
|
},
|
||||||
|
|
||||||
// Project templates (hardcoded list)
|
// Project templates (hardcoded list)
|
||||||
"project.templates": async () => ({
|
"project.templates": async () => ({
|
||||||
templates: [
|
templates: [
|
||||||
|
|
|
||||||
|
|
@ -210,10 +210,22 @@
|
||||||
|
|
||||||
function handleBrowserSelect(path: string) {
|
function handleBrowserSelect(path: string) {
|
||||||
localPath = path;
|
localPath = path;
|
||||||
showBrowser = false;
|
|
||||||
validatePath(path);
|
validatePath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleNativeBrowse() {
|
||||||
|
try {
|
||||||
|
const result = await appRpc.request['files.pickDirectory']({ startingFolder: localPath || '~/' });
|
||||||
|
if (result?.path) {
|
||||||
|
localPath = result.path;
|
||||||
|
validatePath(result.path);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Fallback: native dialog not available, user types path manually
|
||||||
|
console.warn('[wizard] Native folder picker not available');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Validation indicator
|
// Validation indicator
|
||||||
function validationIcon(state: typeof pathValid): string {
|
function validationIcon(state: typeof pathValid): string {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
@ -280,16 +292,13 @@
|
||||||
placeholder={t('wizard.step1.pathPlaceholder' as any)}
|
placeholder={t('wizard.step1.pathPlaceholder' as any)}
|
||||||
bind:value={localPath}
|
bind:value={localPath}
|
||||||
oninput={() => validatePath(localPath)} />
|
oninput={() => validatePath(localPath)} />
|
||||||
<button class="wz-browse-btn" onclick={() => showBrowser = !showBrowser}
|
<button class="wz-browse-btn" onclick={handleNativeBrowse}
|
||||||
aria-label={t('wizard.step1.browse' as any)}>🔍</button>
|
aria-label={t('wizard.step1.browse' as any)}>📂</button>
|
||||||
{#if pathValid !== 'idle'}
|
{#if pathValid !== 'idle'}
|
||||||
<span class="wz-validation" style:color={validationColor(pathValid)}>
|
<span class="wz-validation" style:color={validationColor(pathValid)}>
|
||||||
{validationIcon(pathValid)}
|
{validationIcon(pathValid)}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if showBrowser}
|
|
||||||
<PathBrowser onSelect={handleBrowserSelect} onClose={() => showBrowser = false} />
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{#if pathValid === 'valid' && isGitRepo}
|
{#if pathValid === 'valid' && isGitRepo}
|
||||||
<span class="wz-badge git-badge">{t('wizard.step1.gitDetected' as any)} ({gitBranch})</span>
|
<span class="wz-badge git-badge">{t('wizard.step1.gitDetected' as any)} ({gitBranch})</span>
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,16 @@ export type PtyRPCRequests = {
|
||||||
error?: string;
|
error?: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
/** Native folder picker dialog */
|
||||||
|
"files.pickDirectory": {
|
||||||
|
params: { startingFolder?: string };
|
||||||
|
response: { path: string | null };
|
||||||
|
};
|
||||||
|
/** Get home directory path */
|
||||||
|
"files.homeDir": {
|
||||||
|
params: {};
|
||||||
|
response: { path: string };
|
||||||
|
};
|
||||||
/** Write text content to a file (atomic temp+rename). */
|
/** Write text content to a file (atomic temp+rename). */
|
||||||
"files.write": {
|
"files.write": {
|
||||||
params: { path: string; content: string };
|
params: { path: string; content: string };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue