+
+
+## Main Toju app Structure
+
+| Path | Description |
+|------|-------------|
+| `src/app/` | Main application root |
+| `src/app/core/` | Core utilities, services, models |
+| `src/app/domains/` | Domain-driven modules |
+| `src/app/features/` | UI feature modules |
+| `src/app/infrastructure/` | Low-level infrastructure (DB, realtime, etc.) |
+| `src/app/shared/` | Shared UI components |
+| `src/app/shared-kernel/` | Shared domain contracts & models |
+| `src/app/store/` | Global state management |
+| `src/assets/` | Static assets |
+| `src/environments/` | Environment configs |
+
+---
+
+### Domains
+
+| Path | Link |
+|------|------|
+| Attachment | [app/domains/attachment/README.md](src/app/domains/attachment/README.md) |
+| Auth | [app/domains/auth/README.md](src/app/domains/auth/README.md) |
+| Chat | [app/domains/chat/README.md](src/app/domains/chat/README.md) |
+| Screen Share | [app/domains/screen-share/README.md](src/app/domains/screen-share/README.md) |
+| Server Directory | [app/domains/server-directory/README.md](src/app/domains/server-directory/README.md) |
+| Voice Connection | [app/domains/voice-connection/README.md](src/app/domains/voice-connection/README.md) |
+| Voice Session | [app/domains/voice-session/README.md](src/app/domains/voice-session/README.md) |
+| Domains Root | [app/domains/README.md](src/app/domains/README.md) |
+
+---
+
+### Infrastructure
+
+| Path | Link |
+|------|------|
+| Persistence | [src/app/infrastructure/persistence/README.md](src/app/infrastructure/persistence/README.md) |
+| Realtime | [src/app/infrastructure/realtime/README.md](src/app/infrastructure/realtime/README.md) |
+
+---
+
+### Shared Kernel
+
+| Path | Link |
+|------|------|
+| Shared Kernel | [src/app/shared-kernel/README.md](src/app/shared-kernel/README.md) |
+
+---
+
+### Entry Points
+
+| File | Link |
+|------|------|
+| Main | [main.ts](src/main.ts) |
+| Index HTML | [index.html](src/index.html) |
+| App Root | [app/app.ts](src/app/app.ts) |
diff --git a/dev.sh b/dev.sh
index 7eef7fa..3088327 100755
--- a/dev.sh
+++ b/dev.sh
@@ -20,12 +20,12 @@ if [ "$SSL" = "true" ]; then
"$DIR/generate-cert.sh"
fi
- NG_SERVE="ng serve --host=0.0.0.0 --ssl --ssl-cert=.certs/localhost.crt --ssl-key=.certs/localhost.key"
+ NG_SERVE="cd toju-app && npx ng serve --host=0.0.0.0 --ssl --ssl-cert=../.certs/localhost.crt --ssl-key=../.certs/localhost.key"
WAIT_URL="https://localhost:4200"
HEALTH_URL="https://localhost:3001/api/health"
export NODE_TLS_REJECT_UNAUTHORIZED=0
else
- NG_SERVE="ng serve --host=0.0.0.0"
+ NG_SERVE="cd toju-app && npx ng serve --host=0.0.0.0"
WAIT_URL="http://localhost:4200"
HEALTH_URL="http://localhost:3001/api/health"
fi
diff --git a/electron/app/auto-start.ts b/electron/app/auto-start.ts
index e29bcdb..6de1b3a 100644
--- a/electron/app/auto-start.ts
+++ b/electron/app/auto-start.ts
@@ -1,8 +1,13 @@
import { app } from 'electron';
import AutoLaunch from 'auto-launch';
+import * as fsp from 'fs/promises';
+import * as path from 'path';
import { readDesktopSettings } from '../desktop-settings';
let autoLauncher: AutoLaunch | null = null;
+let autoLaunchPath = '';
+
+const LINUX_AUTO_START_ARGUMENTS = ['--no-sandbox', '%U'];
function resolveLaunchPath(): string {
// AppImage runs from a temporary mount; APPIMAGE points to the real file path.
@@ -13,15 +18,77 @@ function resolveLaunchPath(): string {
return appImagePath || process.execPath;
}
+function escapeDesktopEntryExecArgument(argument: string): string {
+ const escapedArgument = argument.replace(/(["\\$`])/g, '\\$1');
+
+ return /[\s"]/u.test(argument)
+ ? `"${escapedArgument}"`
+ : escapedArgument;
+}
+
+function getLinuxAutoStartDesktopEntryPath(launchPath: string): string {
+ return path.join(app.getPath('home'), '.config', 'autostart', `${path.basename(launchPath)}.desktop`);
+}
+
+function buildLinuxAutoStartExecLine(launchPath: string): string {
+ return `Exec=${[escapeDesktopEntryExecArgument(launchPath), ...LINUX_AUTO_START_ARGUMENTS].join(' ')}`;
+}
+
+function buildLinuxAutoStartDesktopEntry(launchPath: string): string {
+ const appName = path.basename(launchPath);
+
+ return [
+ '[Desktop Entry]',
+ 'Type=Application',
+ 'Version=1.0',
+ `Name=${appName}`,
+ `Comment=${appName}startup script`,
+ buildLinuxAutoStartExecLine(launchPath),
+ 'StartupNotify=false',
+ 'Terminal=false'
+ ].join('\n');
+}
+
+async function synchronizeLinuxAutoStartDesktopEntry(launchPath: string): PromiseLaunch on system startup
- - @if (isElectron) { -Automatically start MetoYou when you sign in
- } @else { -This setting is only available in the desktop app.
- } -