124 lines
4.3 KiB
Python
124 lines
4.3 KiB
Python
import asyncio
|
|
|
|
from nicegui import ui, app
|
|
from journal.core.config import (
|
|
SPEECH_RECOGNITION_ENGINE,
|
|
WHISPER_MODEL_SIZE,
|
|
SERVER_CONTROL_FILE,
|
|
)
|
|
from typing import cast
|
|
|
|
|
|
def settings_dialog():
|
|
"""Creates a dialog for application settings."""
|
|
async def request_server_action(action: str) -> None:
|
|
try:
|
|
SERVER_CONTROL_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
SERVER_CONTROL_FILE.write_text(action, encoding="utf-8")
|
|
except Exception as error:
|
|
ui.notify(f"Failed to queue server action: {error}", type="negative")
|
|
return
|
|
|
|
if action == "restart":
|
|
ui.notify("Server restart requested...", type="warning")
|
|
else:
|
|
ui.notify("Server shutdown requested...", type="warning")
|
|
|
|
# Give the notification a moment to flush before shutdown.
|
|
await asyncio.sleep(0.2)
|
|
app.shutdown()
|
|
|
|
async def restart_server() -> None:
|
|
await request_server_action("restart")
|
|
|
|
async def shutdown_server() -> None:
|
|
await request_server_action("shutdown")
|
|
|
|
with ui.dialog() as dialog, ui.card().classes("w-80"):
|
|
_ = ui.label("Settings").classes("text-xl font-bold")
|
|
|
|
_ = ui.label("Speech to Text").classes("text-lg font-medium mt-4")
|
|
|
|
if "speech_engine" in app.storage.user:
|
|
initial_engine_value = cast(str, app.storage.user["speech_engine"])
|
|
else:
|
|
initial_engine_value = SPEECH_RECOGNITION_ENGINE
|
|
|
|
_ = (
|
|
ui.select(
|
|
["whisper", "google", "sphinx"],
|
|
label="Recognition Engine",
|
|
value=initial_engine_value,
|
|
on_change=lambda e: ui.notify(
|
|
f"Engine set to {cast(str, e.value)}. Takes effect on next recording."
|
|
),
|
|
)
|
|
.bind_value(app.storage.user, "speech_engine")
|
|
.classes("w-full")
|
|
)
|
|
_ = ui.markdown(
|
|
"`whisper` is local & private (recommended).\n`google` is online.\n`sphinx` is offline & fast."
|
|
).classes("text-xs text-gray-500")
|
|
|
|
# Add whisper model select
|
|
_ = ui.separator().classes("my-2")
|
|
_ = ui.label("Whisper Model Size").classes("font-medium")
|
|
|
|
if "whisper_model" in app.storage.user:
|
|
initial_whisper_model = cast(str, app.storage.user["whisper_model"])
|
|
else:
|
|
initial_whisper_model = WHISPER_MODEL_SIZE
|
|
|
|
_ = (
|
|
ui.select(
|
|
["tiny", "base", "small", "medium", "large"],
|
|
label="Accuracy vs. Speed",
|
|
value=initial_whisper_model,
|
|
on_change=lambda e: ui.notify(
|
|
f"Whisper model set to {cast(str, e.value)}. Takes effect on next recording."
|
|
),
|
|
)
|
|
.bind_value(app.storage.user, "whisper_model")
|
|
.classes("w-full")
|
|
)
|
|
_ = ui.markdown(
|
|
"`base` is a good balance. Larger models are more accurate but slower."
|
|
).classes("text-xs text-gray-500")
|
|
|
|
_ = ui.separator().classes("my-2")
|
|
_ = ui.label("Server Controls").classes("font-medium")
|
|
if cast(bool, app.storage.user.get("authenticated", False)):
|
|
_ = ui.markdown(
|
|
"Use these when running via `run_desktop.py`.\n"
|
|
"`Restart` reconnects quickly, `Shutdown` stops the server wrapper."
|
|
).classes("text-xs text-gray-500")
|
|
|
|
with ui.row().classes("w-full gap-2 mt-1"):
|
|
_ = (
|
|
ui.button(
|
|
"Restart Server",
|
|
on_click=restart_server,
|
|
)
|
|
.props("color=warning")
|
|
.classes("flex-1")
|
|
)
|
|
_ = (
|
|
ui.button(
|
|
"Shutdown Server",
|
|
on_click=shutdown_server,
|
|
)
|
|
.props("color=negative")
|
|
.classes("flex-1")
|
|
)
|
|
else:
|
|
_ = ui.label("Log in to enable restart/shutdown controls.").classes(
|
|
"text-xs text-gray-500"
|
|
)
|
|
|
|
_ = (
|
|
ui.button("Close", on_click=dialog.close)
|
|
.props("flat")
|
|
.classes("mt-4 self-end")
|
|
)
|
|
return dialog
|