Fix sidecar pipe crash on state changes and show logged-in state in settings
The state callback in main_headless.py wrote events to stdout synchronously, so an EINVAL on the Tauri sidecar pipe (Windows) bubbled up through _set_state and tore down engine init and reload_engine. That turned PUT /api/config into a "Failed to fetch" for the user. The print is now pipe-safe and api_server isolates the chained callback so a future misbehaving listener cannot break the engine state machine. Settings also now persists remote.email on login and shows a "Logged in as <email>" indicator with a Log out button when an auth_token is present, instead of leaving the email/password fields blank on reload. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
let byokApiKey = $state("");
|
||||
let managedEmail = $state("");
|
||||
let managedPassword = $state("");
|
||||
let managedLoggedIn = $state(false);
|
||||
let autoCheckUpdates = $state(true);
|
||||
|
||||
let isCloudMode = $derived(remoteMode === "managed" || remoteMode === "byok");
|
||||
@@ -131,6 +132,8 @@
|
||||
remoteMode = cfg.remote.mode;
|
||||
remoteServerUrl = cfg.remote.server_url;
|
||||
byokApiKey = cfg.remote.byok_api_key ?? "";
|
||||
managedEmail = cfg.remote.email ?? "";
|
||||
managedLoggedIn = !!(cfg.remote.auth_token && cfg.remote.email);
|
||||
autoCheckUpdates = cfg.updates.auto_check;
|
||||
});
|
||||
|
||||
@@ -268,12 +271,29 @@
|
||||
server_url: remoteServerUrl || MANAGED_SERVER_URL,
|
||||
});
|
||||
loginMessage = "Logged in successfully!";
|
||||
managedPassword = "";
|
||||
managedLoggedIn = true;
|
||||
await configStore.fetchConfig();
|
||||
} catch (err) {
|
||||
console.error("Login failed:", err);
|
||||
loginMessage = "Login failed. Check your email and password.";
|
||||
}
|
||||
}
|
||||
|
||||
async function handleManagedLogout() {
|
||||
try {
|
||||
await configStore.updateConfig({
|
||||
remote: { auth_token: "", email: "" },
|
||||
});
|
||||
managedLoggedIn = false;
|
||||
managedPassword = "";
|
||||
loginMessage = "";
|
||||
} catch (err) {
|
||||
console.error("Logout failed:", err);
|
||||
loginMessage = `Error: ${err}`;
|
||||
}
|
||||
}
|
||||
|
||||
const CAPTION_SERVER = "https://caption.shadowdao.com";
|
||||
|
||||
function generateRandomName(): string {
|
||||
@@ -489,34 +509,44 @@
|
||||
{/if}
|
||||
{#if remoteMode === "managed"}
|
||||
<div class="managed-auth">
|
||||
<div class="field">
|
||||
<label for="managed-email">Email</label>
|
||||
<input
|
||||
id="managed-email"
|
||||
type="email"
|
||||
bind:value={managedEmail}
|
||||
placeholder="email@example.com"
|
||||
/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="managed-password">Password</label>
|
||||
<input
|
||||
id="managed-password"
|
||||
type="password"
|
||||
bind:value={managedPassword}
|
||||
/>
|
||||
</div>
|
||||
<div class="auth-buttons">
|
||||
<button onclick={handleManagedLogin}>Login</button>
|
||||
</div>
|
||||
{#if managedLoggedIn}
|
||||
<p style="font-size: 13px; margin: 0 0 8px;">
|
||||
<span style="color: var(--accent-green, #4CAF50);">✓ Logged in</span>
|
||||
as <strong>{managedEmail}</strong>
|
||||
</p>
|
||||
<div class="auth-buttons">
|
||||
<button onclick={handleManagedLogout}>Log out</button>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="field">
|
||||
<label for="managed-email">Email</label>
|
||||
<input
|
||||
id="managed-email"
|
||||
type="email"
|
||||
bind:value={managedEmail}
|
||||
placeholder="email@example.com"
|
||||
/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="managed-password">Password</label>
|
||||
<input
|
||||
id="managed-password"
|
||||
type="password"
|
||||
bind:value={managedPassword}
|
||||
/>
|
||||
</div>
|
||||
<div class="auth-buttons">
|
||||
<button onclick={handleManagedLogin}>Login</button>
|
||||
</div>
|
||||
<p style="font-size: 11px; color: var(--text-muted); margin-top: 8px;">
|
||||
Don't have an account? <a href="https://transcribe.shadowdao.com/register.html" target="_blank" rel="noopener" style="color: var(--accent-blue);">Sign up here</a>
|
||||
</p>
|
||||
{/if}
|
||||
{#if loginMessage}
|
||||
<p style="font-size: 12px; margin-top: 6px; color: {loginMessage.startsWith('Logged') ? 'var(--accent-green, #4CAF50)' : 'var(--accent-red, #f44336)'};">
|
||||
{loginMessage}
|
||||
</p>
|
||||
{/if}
|
||||
<p style="font-size: 11px; color: var(--text-muted); margin-top: 8px;">
|
||||
Don't have an account? <a href="https://transcribe.shadowdao.com/register.html" target="_blank" rel="noopener" style="color: var(--accent-blue);">Sign up here</a>
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
@@ -65,6 +65,7 @@ export interface AppConfig {
|
||||
mode: string;
|
||||
server_url: string;
|
||||
auth_token: string;
|
||||
email: string;
|
||||
byok_api_key: string;
|
||||
deepgram_model: string;
|
||||
language: string;
|
||||
@@ -131,6 +132,7 @@ function getDefaultConfig(): AppConfig {
|
||||
mode: "byok",
|
||||
server_url: "",
|
||||
auth_token: "",
|
||||
email: "",
|
||||
byok_api_key: "",
|
||||
deepgram_model: "nova-2",
|
||||
language: "en-US",
|
||||
|
||||
Reference in New Issue
Block a user