mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-16 13:20:39 -07:00
Update development scripts and add macOS icon assets
- Renamed backend development script from `dev:backend` to `dev:server` for clarity. - Added new macOS icon assets and configuration files for the application. - Enhanced App component to improve server management during production and development modes. - Updated ConnectionForm to reset state after successful submission and conditionally render the update button. - Implemented database initialization on application startup in the backend.
This commit is contained in:
+22
-10
@@ -16,45 +16,57 @@ function App() {
|
||||
const [activeTab, setActiveTab] = useState('profiles');
|
||||
const [serverReady, setServerReady] = useState(false);
|
||||
|
||||
// Setup window close handler and auto-start server when running in Tauri
|
||||
// Setup window close handler and auto-start server when running in Tauri (production only)
|
||||
useEffect(() => {
|
||||
if (!isTauri()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup window close handler to check setting and stop server if needed
|
||||
// This works in both dev and prod, but will only stop server if it was started by the app
|
||||
setupWindowCloseHandler().catch((error) => {
|
||||
console.error('Failed to setup window close handler:', error);
|
||||
});
|
||||
|
||||
// Auto-start server
|
||||
// Only auto-start server in production mode
|
||||
// In dev mode, user runs server separately
|
||||
if (!import.meta.env?.PROD) {
|
||||
console.log('Dev mode: Skipping auto-start of server (run it separately)');
|
||||
setServerReady(true); // Mark as ready so UI doesn't show loading screen
|
||||
// Mark that server was not started by app (so we don't try to stop it on close)
|
||||
// @ts-expect-error - adding property to window
|
||||
window.__voiceboxServerStartedByApp = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Auto-start server in production
|
||||
if (serverStarting) {
|
||||
return;
|
||||
}
|
||||
|
||||
serverStarting = true;
|
||||
console.log('Running in Tauri, starting bundled server...');
|
||||
console.log('Production mode: Starting bundled server...');
|
||||
|
||||
startServer(false)
|
||||
.then(() => {
|
||||
console.log('Server is ready');
|
||||
setServerReady(true);
|
||||
// Mark that we started the server (so we know to stop it on close)
|
||||
// @ts-expect-error - adding property to window
|
||||
window.__voiceboxServerStartedByApp = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to auto-start server:', error);
|
||||
serverStarting = false;
|
||||
// @ts-expect-error - adding property to window
|
||||
window.__voiceboxServerStartedByApp = false;
|
||||
});
|
||||
|
||||
// Cleanup: stop server on actual unmount (not StrictMode remount)
|
||||
// Note: Window close is handled separately in Tauri Rust code
|
||||
return () => {
|
||||
// In dev mode, React StrictMode causes remounts, so we skip cleanup
|
||||
// In production, window close event handles server shutdown based on setting
|
||||
if (import.meta.env?.PROD) {
|
||||
// Only stop if setting says to stop (handled by window close event)
|
||||
// This cleanup is mainly for React remounts in dev mode
|
||||
serverStarting = false;
|
||||
}
|
||||
// Window close event handles server shutdown based on setting
|
||||
serverStarting = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useEffect } from 'react';
|
||||
import * as z from 'zod';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
@@ -37,8 +38,16 @@ export function ConnectionForm() {
|
||||
},
|
||||
});
|
||||
|
||||
// Sync form with store when serverUrl changes externally
|
||||
useEffect(() => {
|
||||
form.reset({ serverUrl });
|
||||
}, [serverUrl, form]);
|
||||
|
||||
const { isDirty } = form.formState;
|
||||
|
||||
function onSubmit(data: ConnectionFormValues) {
|
||||
setServerUrl(data.serverUrl);
|
||||
form.reset(data); // Reset form state after successful submission
|
||||
toast({
|
||||
title: 'Server URL updated',
|
||||
description: `Connected to ${data.serverUrl}`,
|
||||
@@ -68,7 +77,9 @@ export function ConnectionForm() {
|
||||
)}
|
||||
/>
|
||||
|
||||
<Button type="submit">Update Connection</Button>
|
||||
{isDirty && (
|
||||
<Button type="submit">Update Connection</Button>
|
||||
)}
|
||||
</form>
|
||||
</Form>
|
||||
|
||||
|
||||
@@ -62,8 +62,14 @@ export async function setupWindowCloseHandler(): Promise<void> {
|
||||
const { useServerStore } = await import('@/stores/serverStore');
|
||||
const keepRunning = useServerStore.getState().keepServerRunningOnClose;
|
||||
|
||||
if (!keepRunning) {
|
||||
// Stop server before closing
|
||||
// Check if server was started by this app instance
|
||||
// In dev mode, serverStartedByApp will be false, so we won't try to stop a separately-run server
|
||||
// We need to access the module-level variable - this is a bit hacky but works
|
||||
// @ts-expect-error - accessing module-level variable from another module
|
||||
const serverStartedByApp = window.__voiceboxServerStartedByApp ?? false;
|
||||
|
||||
if (!keepRunning && serverStartedByApp) {
|
||||
// Stop server before closing (only if we started it)
|
||||
try {
|
||||
await stopServer();
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user