Merge remote-tracking branch 'origin/main' into feat/capture

This commit is contained in:
Jamie Pine
2026-04-25 11:18:43 -07:00
3 changed files with 48 additions and 5 deletions
+10 -1
View File
@@ -14,7 +14,11 @@ import { cn } from '@/lib/utils/cn';
import { usePlatform } from '@/platform/PlatformContext';
import { router } from '@/router';
import { useLogStore } from '@/stores/logStore';
import { useServerStore } from '@/stores/serverStore';
import {
getDefaultServerUrl,
isLoopbackVoiceboxServerUrl,
useServerStore,
} from '@/stores/serverStore';
function isDictateView(): boolean {
if (typeof window === 'undefined') return false;
@@ -130,6 +134,11 @@ function MainApp() {
// Setup window close handler and auto-start server when running in Tauri (production only)
useEffect(() => {
if (!platform.metadata.isTauri) {
const serverUrl = getDefaultServerUrl();
const currentServerUrl = useServerStore.getState().serverUrl;
if (currentServerUrl !== serverUrl && isLoopbackVoiceboxServerUrl(currentServerUrl)) {
useServerStore.getState().setServerUrl(serverUrl);
}
setServerReady(true); // Web assumes server is running
return;
}
+35 -1
View File
@@ -27,10 +27,44 @@ function invalidateAllServerData() {
queryClient.invalidateQueries();
}
export function getDefaultServerUrl(): string {
const fallback = 'http://127.0.0.1:17493';
if (!import.meta.env.PROD || typeof window === 'undefined') {
return fallback;
}
const { protocol, origin, hostname } = window.location;
if (
(protocol === 'http:' || protocol === 'https:') &&
origin &&
hostname !== 'tauri.localhost'
) {
return origin;
}
return fallback;
}
export function isLoopbackVoiceboxServerUrl(url: string): boolean {
try {
const parsed = new URL(url);
return (
parsed.port === '17493' &&
(parsed.hostname === '127.0.0.1' ||
parsed.hostname === 'localhost' ||
parsed.hostname === '[::1]' ||
parsed.hostname === '::1')
);
} catch {
return false;
}
}
export const useServerStore = create<ServerStore>()(
persist(
(set, get) => ({
serverUrl: 'http://127.0.0.1:17493',
serverUrl: getDefaultServerUrl(),
setServerUrl: (url) => {
const prev = get().serverUrl;
set({ serverUrl: url });
+3 -3
View File
@@ -1,12 +1,12 @@
import type { PlatformLifecycle, ServerLogEntry } from '@/platform/types';
import { getDefaultServerUrl } from '@/stores/serverStore';
class WebLifecycle implements PlatformLifecycle {
onServerReady?: () => void;
async startServer(_remote = false, _modelsDir?: string | null): Promise<string> {
// Web assumes server is running externally
// Return a default URL - this should be configured via env vars
const serverUrl = import.meta.env.VITE_SERVER_URL || 'http://localhost:17493';
const serverUrl = import.meta.env.VITE_SERVER_URL || getDefaultServerUrl();
this.onServerReady?.();
return serverUrl;
}
@@ -17,7 +17,7 @@ class WebLifecycle implements PlatformLifecycle {
async restartServer(_modelsDir?: string | null): Promise<string> {
// No-op for web - server is managed externally
return import.meta.env.VITE_SERVER_URL || 'http://localhost:17493';
return import.meta.env.VITE_SERVER_URL || getDefaultServerUrl();
}
async setKeepServerRunning(_keep: boolean): Promise<void> {