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:
Jamie Pine
2026-01-25 12:15:47 -08:00
parent 7b1e2295ef
commit edbdf0ce3f
19 changed files with 155 additions and 17 deletions
+22 -10
View File
@@ -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>
+8 -2
View File
@@ -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) {