Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
023bc0218b | ||
|
|
634506f902 | ||
|
|
8c7f4e8008 | ||
|
|
b8d718caa6 | ||
|
|
d92005bf95 | ||
|
|
e90d154b83 |
@@ -73,8 +73,15 @@ class APIServer:
|
||||
original_state_cb = self.controller.on_state_changed
|
||||
|
||||
def on_state_changed(state: str, message: str):
|
||||
# Isolate the upstream callback so a failure there (e.g. a
|
||||
# broken stdout pipe in main_headless) cannot propagate into
|
||||
# _set_state and tear down engine init / reload_engine /
|
||||
# apply_settings request handling.
|
||||
if original_state_cb:
|
||||
original_state_cb(state, message)
|
||||
try:
|
||||
original_state_cb(state, message)
|
||||
except Exception:
|
||||
pass
|
||||
self._broadcast_control({"type": "state_changed", "state": state, "message": message})
|
||||
|
||||
self.controller.on_state_changed = on_state_changed
|
||||
@@ -273,6 +280,7 @@ class APIServer:
|
||||
data = resp.json()
|
||||
ctrl.config.set('remote.auth_token', data.get('token', ''))
|
||||
ctrl.config.set('remote.server_url', req.server_url)
|
||||
ctrl.config.set('remote.email', req.email)
|
||||
return {"status": "ok", "token": data.get('token', '')}
|
||||
else:
|
||||
raise HTTPException(status_code=resp.status_code, detail=resp.text)
|
||||
|
||||
@@ -75,10 +75,16 @@ def main():
|
||||
# Create controller and initialize
|
||||
controller = AppController(config=config)
|
||||
|
||||
# Wire a state callback that prints the ready event
|
||||
# Wire a state callback that prints state events for the parent
|
||||
# process to read. Stdout writes can fail with EINVAL on Windows
|
||||
# when the parent stops reading the sidecar pipe; swallow those
|
||||
# so the engine state machine isn't taken down by a logging path.
|
||||
def on_state_changed(state, message):
|
||||
event = {"event": "state", "state": state, "message": message}
|
||||
print(json.dumps(event), flush=True)
|
||||
try:
|
||||
print(json.dumps(event), flush=True)
|
||||
except (OSError, ValueError):
|
||||
pass
|
||||
|
||||
controller.on_state_changed = on_state_changed
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ remote:
|
||||
mode: byok # local | managed | byok
|
||||
server_url: "https://transcribe.shadowdao.com" # Proxy server URL for managed mode
|
||||
auth_token: "" # JWT stored after login (managed mode)
|
||||
email: "" # Email of the logged-in managed-mode account (for UI display)
|
||||
byok_api_key: "" # Deepgram API key for BYOK mode
|
||||
deepgram_model: nova-2 # Deepgram model to use
|
||||
language: en-US # Language code
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "local-transcription",
|
||||
"private": true,
|
||||
"version": "2.0.18",
|
||||
"version": "2.0.20",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "local-transcription"
|
||||
version = "1.0.12"
|
||||
version = "1.0.14"
|
||||
description = "A standalone desktop application for real-time speech-to-text transcription using Whisper models"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "local-transcription"
|
||||
version = "2.0.18"
|
||||
version = "2.0.20"
|
||||
description = "Real-time speech-to-text transcription for streamers"
|
||||
authors = ["Local Transcription Contributors"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"productName": "Local Transcription",
|
||||
"version": "2.0.18",
|
||||
"version": "2.0.20",
|
||||
"identifier": "net.anhonesthost.local-transcription",
|
||||
"build": {
|
||||
"frontendDist": "../dist",
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -257,15 +260,37 @@
|
||||
|
||||
const MANAGED_SERVER_URL = "https://transcribe.shadowdao.com";
|
||||
|
||||
let loginMessage = $state("");
|
||||
|
||||
async function handleManagedLogin() {
|
||||
loginMessage = "";
|
||||
try {
|
||||
await backendStore.apiPost("/api/login", {
|
||||
email: managedEmail,
|
||||
password: managedPassword,
|
||||
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}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,29 +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>
|
||||
<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 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}
|
||||
</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",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Version information for Local Transcription."""
|
||||
|
||||
__version__ = "2.0.18"
|
||||
__version_info__ = (2, 0, 18)
|
||||
__version__ = "2.0.20"
|
||||
__version_info__ = (2, 0, 20)
|
||||
|
||||
# Version history:
|
||||
# 1.4.0 - Auto-update feature:
|
||||
|
||||
Reference in New Issue
Block a user