diff --git a/apps/desktop/index.html b/apps/desktop/index.html index d709691..2ae0112 100644 --- a/apps/desktop/index.html +++ b/apps/desktop/index.html @@ -15,38 +15,6 @@
- -
-
-
Loading Amical...
-
- diff --git a/apps/desktop/src/main/core/app-manager.ts b/apps/desktop/src/main/core/app-manager.ts index 9b6929f..63c59ca 100644 --- a/apps/desktop/src/main/core/app-manager.ts +++ b/apps/desktop/src/main/core/app-manager.ts @@ -90,6 +90,7 @@ export class AppManager { private async setupWindows(): Promise { this.windowManager.createWidgetWindow(); + this.windowManager.createOrShowMainWindow(); this.setupTRPCHandler(); if (process.platform === "darwin" && app.dock) { diff --git a/apps/desktop/src/renderer/main/content.tsx b/apps/desktop/src/renderer/main/content.tsx new file mode 100644 index 0000000..4496416 --- /dev/null +++ b/apps/desktop/src/renderer/main/content.tsx @@ -0,0 +1,122 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import React, { useState, useEffect } from "react"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ipcLink } from "electron-trpc-experimental/renderer"; +import superjson from "superjson"; +import { + SidebarProvider, + SidebarInset, + SidebarTrigger, +} from "@/components/ui/sidebar"; +import { AppSidebar } from "@/components/app-sidebar"; +import { TranscriptionsPage } from "./pages/transcriptions"; +import { VocabularyPage } from "./pages/vocabulary"; +import { ModelsPage } from "./pages/models"; +import { SettingsPage } from "./pages/settings"; +import { SiteHeader } from "@/components/site-header"; +import { api } from "@/trpc/react"; + +// import { Waveform } from '../components/Waveform'; // Waveform might not be needed if hook is removed +// import { useRecording } from '../hooks/useRecording'; // Remove hook import + +const NUM_WAVEFORM_BARS = 10; // This might be unused now + +// Create a client +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + refetchOnWindowFocus: false, + }, + }, +}); + +// Create tRPC client +const trpcClient = api.createClient({ + links: [ipcLink({ transformer: superjson })], +}); + +const App: React.FC = () => { + const [currentView, setCurrentView] = useState(() => { + // Try to restore the view from localStorage, fallback to default + if (typeof window !== "undefined") { + return localStorage.getItem("amical-current-view") || "Voice Recording"; + } + return "Voice Recording"; + }); + + const handleNavigation = (item: any) => { + setCurrentView(item.title); + // Save to localStorage to preserve during HMR + localStorage.setItem("amical-current-view", item.title); + }; + + const renderContent = () => { + switch (currentView) { + case "Transcriptions": + return ; + case "Vocabulary": + return ; + case "Models": + return ; + case "Settings": + return ; + default: + return ( +
+

Welcome to Amical

+

Select an option from the sidebar to get started.

+
+ ); + } + }; + + return ( + + + +
+ {/* Header spans full width with traffic light spacing */} + + +
+ + +
+
+
+
+ {renderContent()} +
+
+
+
+
+
+
+
+
+
+ ); +}; + +// Export the App component as default for lazy loading +export default App; diff --git a/apps/desktop/src/renderer/main/index.tsx b/apps/desktop/src/renderer/main/index.tsx index 0d7f596..b5ca196 100644 --- a/apps/desktop/src/renderer/main/index.tsx +++ b/apps/desktop/src/renderer/main/index.tsx @@ -1,24 +1,15 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -import React, { useState, useEffect } from "react"; +import React, { Suspense } from "react"; import { createRoot } from "react-dom/client"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { ipcLink } from "electron-trpc-experimental/renderer"; -import superjson from "superjson"; -import { - SidebarProvider, - SidebarInset, - SidebarTrigger, -} from "@/components/ui/sidebar"; -import { AppSidebar } from "@/components/app-sidebar"; -import { ThemeProvider } from "@/components/theme-provider"; -import { TranscriptionsPage } from "./pages/transcriptions"; -import { VocabularyPage } from "./pages/vocabulary"; -import { ModelsPage } from "./pages/models"; -import { SettingsPage } from "./pages/settings"; import "@/styles/globals.css"; -import { SiteHeader } from "@/components/site-header"; -import { api } from "@/trpc/react"; +import { ThemeProvider } from "@/components/theme-provider"; + +// Lazy import the main content +const Content = React.lazy( + () => + import("./content.js") as unknown as Promise<{ + default: React.ComponentType; + }>, +); // Extend Console interface to include original methods declare global { @@ -62,109 +53,33 @@ console.debug = (...args: any[]) => { // Keep original methods available if needed console.original = originalConsole; -// import { Waveform } from '../components/Waveform'; // Waveform might not be needed if hook is removed -// import { useRecording } from '../hooks/useRecording'; // Remove hook import - -const NUM_WAVEFORM_BARS = 10; // This might be unused now - -// Create a client -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - refetchOnWindowFocus: false, - }, - }, -}); - -// Create tRPC client -const trpcClient = api.createClient({ - links: [ipcLink({ transformer: superjson })], -}); - -const App: React.FC = () => { - const [currentView, setCurrentView] = useState(() => { - // Try to restore the view from localStorage, fallback to default - if (typeof window !== "undefined") { - return localStorage.getItem("amical-current-view") || "Voice Recording"; - } - return "Voice Recording"; - }); - - const handleNavigation = (item: any) => { - setCurrentView(item.title); - // Save to localStorage to preserve during HMR - localStorage.setItem("amical-current-view", item.title); - }; - - const renderContent = () => { - switch (currentView) { - case "Transcriptions": - return ; - case "Vocabulary": - return ; - case "Models": - return ; - case "Settings": - return ; - default: - return ( -
-

Welcome to Amical

-

Select an option from the sidebar to get started.

-
- ); - } - }; - +// Loading spinner component +const LoadingSpinner: React.FC = () => { return ( - - - - -
- {/* Header spans full width with traffic light spacing */} - - -
- - -
-
-
-
- {renderContent()} -
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+

Loading Amical...

+
+
); }; +// Main App component with Suspense +const App: React.FC = () => { + return ( + + }> + + + + ); +}; + +// Render the app const container = document.getElementById("root"); if (container) { const root = createRoot(container); diff --git a/apps/desktop/widget.html b/apps/desktop/widget.html index 685c988..578f35c 100644 --- a/apps/desktop/widget.html +++ b/apps/desktop/widget.html @@ -2,7 +2,7 @@ - Floating Button + Widget