Skip to content

Commit

Permalink
App starting, welcome page working.
Browse files Browse the repository at this point in the history
  • Loading branch information
Acumen-Desktop committed Feb 10, 2025
1 parent 0a9bd40 commit d5646a5
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 222 deletions.
88 changes: 79 additions & 9 deletions acumen/features/svelte-electron-ui/re-create_React_components.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,57 @@
# Re-creating React UI Components in Svelte 5
# Converting React UI to SvelteKit

## Current Approach

### Page-First Component Migration

We're taking a page-first approach to converting the React UI to SvelteKit. This means:

1. First, identify the main pages/routes in the React app
2. Create corresponding SvelteKit routes
3. Convert components as needed while building each route
4. Test the functionality as we go

### Current Focus

- Converting the main chat interface from React to SvelteKit
- Ensuring Electron integration works correctly
- Maintaining feature parity while improving the architecture

### Directory Structure

```
ui-svelte/
├── src-main/ # Electron main process
├── src-renderer/ # SvelteKit app
│ ├── routes/ # SvelteKit routes (pages)
│ │ ├── chat/ # Chat interface
│ │ ├── settings/ # Settings pages
│ │ └── +layout.svelte
│ └── lib/
│ ├── components/
│ │ ├── basic-ui/ # Atomic components
│ │ ├── compound/ # Reusable compound components
│ │ ├── features/ # Complex feature components
│ │ └── shadcn-ui/ # Shadcn components
│ ├── stores/ # Svelte stores
│ └── utils/ # Utility functions
```

### Component Categories

1. **Route Components** (`routes/`): Full pages/features
2. **Feature Components** (`lib/components/features/`): Complex, business-logic heavy components
3. **Compound Components** (`lib/components/compound/`): Reusable combinations of basic components
4. **Basic UI Components** (`lib/components/basic-ui/`): Atomic UI components

### Migration Status

- [] Project structure setup
- [] Basic UI components converted
- [] Main chat interface
- [] Settings pages
- [] Extension system
- [] Keyboard shortcuts

## Source Structure

Expand All @@ -10,19 +63,36 @@

## SVG Conversion Process

When encountering React components that are just SVG wrappers:
When converting React SVG components to Svelte:

1. Create a new .svg file in `ui-svelte/src-renderer/lib/assets/icons-svg`
2. Extract the SVG content from the React component
3. For dynamic props (like size), use CSS variables in the SVG:
```svg
<svg width="var(--size, 24)" height="var(--size, 24)" ...>
1. Create raw SVG files in `ui-svelte/src-renderer/lib/assets/icons-svg/`
2. Import SVGs directly in Svelte components:

```svelte
<script lang="ts">
import icon from "$lib/assets/icons-svg/icon.svg";
</script>
<img src={icon} alt="Icon description" />
```
4. Use the `Icon` component to render with props:

3. For dynamic styling, use CSS classes or style props on the `<img>` tag
4. For hover effects, use Svelte's class directives:
```svelte
<Icon name="icon-name" style="--size: {size}px" />
<img
src={icon}
class="{hover ? 'opacity-0 group-hover:opacity-100' : ''}"
/>
```

### Benefits of This Approach

- Better type safety with direct imports
- Vite handles asset optimization
- Simpler than using inline SVGs
- Works well with Svelte 5's new props syntax
- Easier to maintain and update SVG assets

## React Components List

Here is a list of all potential "shadcn-react" components:
Expand Down
64 changes: 38 additions & 26 deletions ui-svelte/src-main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import { startGoosed } from "./goosed";
import log from "./utils/logger";
import { loadRecentDirs } from "./utils/recentDirs";

import type { WindowType, IpcEvents } from './types/ipc';
import type { GooseProcess, GooseResult } from './types/process';
import type { WindowType, IpcEvents } from "./types/ipc";
import type { GooseProcess, GooseResult } from "./types/process";

// Prevent multiple instances
if (!app.requestSingleInstanceLock() || electronSquirrelStartup) {
Expand Down Expand Up @@ -100,7 +100,9 @@ async function createLauncher(): Promise<void> {
transparent: false,
webPreferences: {
preload: path.join(app.getAppPath(), ".vite/main/preload.cjs"),
additionalArguments: [JSON.stringify({ type: "launcher" } satisfies WindowType)],
additionalArguments: [
JSON.stringify({ type: "launcher" } satisfies WindowType),
],
contextIsolation: true,
nodeIntegration: false,
sandbox: false,
Expand Down Expand Up @@ -131,18 +133,22 @@ async function createLauncher(): Promise<void> {
});
}

async function createChat(query?: string, dir?: string, version?: string): Promise<BrowserWindow> {
async function createChat(
query?: string,
dir?: string,
version?: string
): Promise<BrowserWindow> {
try {
const [port, working_dir] = await startGoosed(app, dir);
log.info(`Goose server started on port ${port} in directory ${working_dir}`);
log.info(
`Goose server started on port ${port} in directory ${working_dir}`
);

const mainWindow = new BrowserWindow({
titleBarStyle: "hidden",
trafficLightPosition: { x: 16, y: 10 },
vibrancy: "window",
width: 750,
height: 800,
minWidth: 650,
x: 2048,
y: 0,
width: 1800,
height: 1000,
backgroundColor: "#374151",
icon: path.join(staticAssetsFolder, "icon.png"),
webPreferences: {
Expand Down Expand Up @@ -172,7 +178,9 @@ async function createChat(query?: string, dir?: string, version?: string): Promi
const xOffset = direction * initialOffset * Math.floor(windowCounter / 2);
mainWindow.setPosition(baseXPosition + xOffset, 100);

const queryParam = query ? `?initialQuery=${encodeURIComponent(query)}` : "";
const queryParam = query
? `?initialQuery=${encodeURIComponent(query)}`
: "";
if (import.meta.env.DEV) {
await mainWindow.loadURL(
`${VITE_DEV_SERVER_URLS["main_window"]}${queryParam}`
Expand All @@ -188,9 +196,12 @@ async function createChat(query?: string, dir?: string, version?: string): Promi
}
});

mainWindow.webContents.on("did-fail-load", (event, errorCode, errorDescription) => {
log.error("Window failed to load:", errorCode, errorDescription);
});
mainWindow.webContents.on(
"did-fail-load",
(event, errorCode, errorDescription) => {
log.error("Window failed to load:", errorCode, errorDescription);
}
);

mainWindow.webContents.on("console-message", (event, level, message) => {
log.info("Renderer Console:", message);
Expand Down Expand Up @@ -249,22 +260,22 @@ app.whenReady().then(async () => {
globalShortcut.register("Control+Alt+Command+G", createLauncher);

// Type-safe IPC event handlers
ipcMain.on('create-chat-window', ((_, query, dir, version) => {
ipcMain.on("create-chat-window", ((_, query, dir, version) => {
createChat(query, dir, version);
}) as IpcEvents['create-chat-window']);
}) as IpcEvents["create-chat-window"]);

ipcMain.on('directory-chooser', ((_, replace = false) => {
ipcMain.on("directory-chooser", ((_, replace = false) => {
// TODO: Implement directory chooser
}) as IpcEvents['directory-chooser']);
}) as IpcEvents["directory-chooser"]);

ipcMain.on('logInfo', ((_, info) => {
ipcMain.on("logInfo", ((_, info) => {
log.info("from renderer:", info);
}) as IpcEvents['logInfo']);
}) as IpcEvents["logInfo"]);

ipcMain.on('reload-app', (() => {
ipcMain.on("reload-app", (() => {
app.relaunch();
app.exit(0);
}) as IpcEvents['reload-app']);
}) as IpcEvents["reload-app"]);
});

// Window management
Expand All @@ -281,8 +292,9 @@ app.on("activate", () => {
});

// IPC handlers
ipcMain.on('toggleDevTools', ((event) => event.sender.toggleDevTools()) as IpcEvents['toggleDevTools']);
ipcMain.on('setTitleBarColors', ((event, bgColor, iconColor) => {
ipcMain.on("toggleDevTools", ((event) =>
event.sender.toggleDevTools()) as IpcEvents["toggleDevTools"]);
ipcMain.on("setTitleBarColors", ((event, bgColor, iconColor) => {
const window = BrowserWindow.fromWebContents(event.sender);
if (!window?.setTitleBarOverlay) return;

Expand All @@ -291,4 +303,4 @@ ipcMain.on('setTitleBarColors', ((event, bgColor, iconColor) => {
symbolColor: iconColor,
height: 40,
});
}) as IpcEvents['setTitleBarColors']);
}) as IpcEvents["setTitleBarColors"]);
Loading

0 comments on commit d5646a5

Please sign in to comment.