Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions apps/desktop/electron/preload.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"use strict";

const { contextBridge, ipcRenderer } = require("electron");

function readAdditionalArgument(argv, name) {
const prefix = `--${name}=`;
const match = argv.find((arg) => arg.startsWith(prefix));
Expand Down Expand Up @@ -63,7 +61,11 @@ function exposeEchoformApi(electron, preloadConfig = resolvePreloadConfig()) {
});
}

exposeEchoformApi({ contextBridge, ipcRenderer });
// Only touch the Electron module inside Electron. Requiring it from plain Node
// (unit tests) resolves the binary path and can trigger a binary download.
if (process.versions.electron) {
exposeEchoformApi(require("electron"));
}

module.exports = {
exposeEchoformApi,
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<!doctype html>
<html lang="en">
<html class="dark" lang="en">
<head>
<meta charset="UTF-8">
<link href="/echoform.svg" rel="icon" type="image/svg+xml">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Echoform</title>
</head>
<body class="dark">
<body>
<div id="root"></div>
<script src="/src/main.tsx" type="module"></script>
</body>
Expand Down
13 changes: 2 additions & 11 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,12 @@
"wavesurfer.js": "^7.12.11"
},
"devDependencies": {
"@base-ui/react": "^1.7.0",
"@biomejs/biome": "2.5.7",
"@fontsource-variable/inter": "^5.3.0",
"@fontsource-variable/geist-mono": "^5.3.0",
"@fontsource-variable/instrument-sans": "^5.3.0",
"@phosphor-icons/react": "^2.1.10",
"@rolldown/plugin-babel": "^0.2.3",
"@tailwindcss/vite": "^4.3.3",
"@tanstack/react-virtual": "^3.14.9",
"@testing-library/jest-dom": "^7.0.0",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.3",
Expand All @@ -56,28 +55,20 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.4.0",
"electron": "^43.2.0",
"electron-builder": "^26.15.3",
"electron-builder-squirrel-windows": "^26.15.3",
"embla-carousel-react": "^8.6.0",
"input-otp": "^1.4.2",
"jsdom": "^30.0.1",
"next-themes": "^0.4.6",
"radix-ui": "^1.6.7",
"react": "^19.2.8",
"react-day-picker": "^10.0.1",
"react-dom": "^19.2.8",
"react-resizable-panels": "^4.12.2",
"recharts": "3.10.1",
"shadcn": "^4.16.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.6.0",
"tailwindcss": "^4.3.3",
"tw-animate-css": "^1.4.0",
"typescript": "~7.0.2",
"ultracite": "7.10.0",
"vaul": "^1.1.2",
"vite": "^8.2.0",
"vitest": "^4.1.10",
"zustand": "^5.0.14"
Expand Down
43 changes: 0 additions & 43 deletions apps/desktop/public/vite.svg

This file was deleted.

87 changes: 42 additions & 45 deletions apps/desktop/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useEffect, useRef } from "react";
import { Logo } from "@/components/logo";
import { PreviewPlayer } from "@/components/preview-player";
import { ProjectHeader } from "@/components/project-header";
import { AppSidebar } from "@/components/sidebar";
import { Timeline } from "@/components/timeline";
import { Toaster } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { WelcomeOnboarding } from "@/components/welcome-onboarding";
import { useDaemonSync } from "@/hooks/use-daemon-sync";
import { usePreviewStatusToasts } from "@/hooks/use-preview-status-toasts";
Expand All @@ -16,35 +18,28 @@ import { useStore } from "@/lib/store";
function AppLoading() {
return (
<div className="flex h-screen w-screen items-center justify-center bg-background">
<div className="flex flex-col items-center gap-5">
<div className="h-1 w-24 overflow-hidden rounded-full bg-white/[0.06]">
<div className="h-full w-2/5 animate-[shimmer_1.6s_ease-in-out_infinite] rounded-full bg-white/15" />
</div>
<span className="text-[13px] text-white/20">Loading projects...</span>
<div className="flex flex-col items-center gap-4">
<Logo className="size-8 animate-pulse text-muted-foreground" />
<span className="text-[13px] text-muted-foreground">
Starting Echoform…
</span>
</div>
</div>
);
}

function ConnectionIndicator() {
function ConnectionBanner() {
const connected = useConnectionStore((s) => s.connected);
const snapshotReceived = useStore((s) => s.snapshotReceived);

// Don't show "reconnecting" on first load — the app loading screen handles it
if (!snapshotReceived) {
return null;
}

if (connected) {
return null;
}

return (
<div className="fade-in slide-in-from-top-2 fixed top-3 left-1/2 z-50 -translate-x-1/2 animate-in duration-300">
<div className="flex items-center gap-2.5 rounded-full border border-white/[0.08] bg-white/[0.04] px-4 py-2 text-[12px] text-white/40 shadow-black/20 shadow-lg backdrop-blur-xl">
<div className="size-1.5 shrink-0 animate-pulse rounded-full bg-amber-400/70" />
Reconnecting...
</div>
<div
className="border-warning/20 border-b bg-warning/10 px-6 py-2 text-[12px] text-warning"
role="status"
>
Lost connection to Echoform's background service. Reconnecting — saves
made in Ableton meanwhile are picked up once it's back.
</div>
);
}
Expand Down Expand Up @@ -78,8 +73,9 @@ function App() {
});
}, [connected, onboardingStep, projects.length, snapshotReceived]);

// Show loading screen while waiting for initial connection + snapshot
if (!(connected && snapshotReceived)) {
// Only block on the very first snapshot; later disconnects show a banner
// so the user keeps seeing their history.
if (!snapshotReceived) {
return (
<>
<AppLoading />
Expand All @@ -88,40 +84,41 @@ function App() {
);
}

// Show onboarding when not completed yet
if (onboardingStep !== "done") {
return (
<>
<TooltipProvider delayDuration={400}>
<WelcomeOnboarding />
<Toaster />
</>
</TooltipProvider>
);
}

return (
<div className="flex h-screen w-screen overflow-hidden bg-[#0d0e11] text-foreground">
<div className="w-[252px] shrink-0">
<AppSidebar />
</div>

<main className="flex min-h-0 min-w-0 flex-1 flex-col">
<ProjectHeader />
<div className="min-h-0 flex-1">
<Timeline />
<TooltipProvider delayDuration={400}>
<div className="flex h-screen w-screen overflow-hidden bg-background text-foreground">
<div className="w-[248px] shrink-0">
<AppSidebar />
</div>
{selectedProject && previewSave && (
<PreviewPlayer
key={previewSave.id}
onClose={closePreviewPlayer}
project={selectedProject}
save={previewSave}
/>
)}
</main>

<ConnectionIndicator />
<Toaster />
</div>
<main className="flex min-h-0 min-w-0 flex-1 flex-col">
<ConnectionBanner />
<ProjectHeader />
<div className="min-h-0 flex-1">
<Timeline />
</div>
{selectedProject && previewSave && (
<PreviewPlayer
key={previewSave.id}
onClose={closePreviewPlayer}
project={selectedProject}
save={previewSave}
/>
)}
</main>

<Toaster />
</div>
</TooltipProvider>
);
}

Expand Down
16 changes: 0 additions & 16 deletions apps/desktop/src/assets/react.svg

This file was deleted.

Loading
Loading