feat: Add slashcommand api

This commit is contained in:
2026-06-05 17:12:26 +02:00
parent 4070ef6caf
commit 8ecfc9a1fe
101 changed files with 3526 additions and 147 deletions

View File

@@ -25,6 +25,13 @@ Durable rules for AI agents working on this project. Read this file at session s
## Lessons
### Declare MODIFY_AUDIO_SETTINGS for Android WebRTC mic capture [mobile] [android]
- **Trigger:** Android users accept the microphone prompt but voice calls and channels still fail to join.
- **Rule:** include `android.permission.MODIFY_AUDIO_SETTINGS` in `toju-app/android/app/src/main/AndroidManifest.xml` and preflight Capacitor capture through `MobileMediaService.ensureVoiceCapturePermissions()` before `getUserMedia`.
- **Why:** Capacitor's `BridgeWebChromeClient.onPermissionRequest` requests `RECORD_AUDIO` and `MODIFY_AUDIO_SETTINGS` together; if the latter is undeclared, the combined grant is treated as denied even after the user taps Allow.
- **Example:** `ANDROID_REQUIRED_MANIFEST_PERMISSIONS` in `mobile-android-manifest-permissions.rules.ts`.
### Do not override Tailwind with box-sizing inherit [mobile] [css]
- **Trigger:** mobile pages still overflow horizontally until devtools disables `*, *::before, *::after { box-sizing: inherit }` in global styles.

View File

@@ -54,7 +54,7 @@ The job installs JDK 21 and Android SDK platform 36 inside the `node:22` contain
Optional `google-services.json` is not injected in CI; push registration in artifact builds follows the same optional-Firebase behavior as local unsigned debug builds.
After dependency or plugin changes, run `npm run build:prod && npm run cap:sync` so native projects register `@capacitor/app`, `@capacitor-community/sqlite`, push plugins, and `MetoyouMobile`.
After dependency or plugin changes, run `npm run build:prod && npm run cap:sync` so native projects register `@capacitor/app`, `@capacitor-community/sqlite`, `@capawesome/capacitor-app-update`, push plugins, and `MetoyouMobile`.
## Feature status
@@ -71,6 +71,7 @@ After dependency or plugin changes, run `npm run build:prod && npm run cap:sync`
| Camera sharing | **Working** | Existing `getUserMedia` camera path in WebRTC stack |
| Speakerphone | **Working (partial)** | Android `AudioManager` via `MetoyouMobile`; iOS `@capgo/capacitor-audio-session`; direct-call speaker toggle on native mobile |
| Local DB (SQLite) | **Working** | `DatabaseService` routes Capacitor shells to `CapacitorDatabaseService` (native SQLite CRUD) |
| Store app updates | **Working (partial)** | `@capawesome/capacitor-app-update` via `MobileAppUpdateService`; Android in-app updates when Play allows, iOS opens App Store |
## Platform limitations
@@ -91,9 +92,26 @@ The app starts without Firebase. `MobilePushRegistrationService` probes `Metoyou
2. Copy `toju-app/android/app/google-services.json.example` to `google-services.json` (gitignored) and fill in your Firebase values.
3. Run `npm run cap:sync` so the Google Services Gradle plugin applies when the file is present (`build.gradle` applies it only when the JSON exists).
4. Rebuild with `npm run cap:build:android`.
5. Ensure `POST_NOTIFICATIONS`, `RECORD_AUDIO`, and foreground-service permissions are granted on Android 13+.
5. Ensure `POST_NOTIFICATIONS`, `RECORD_AUDIO`, `MODIFY_AUDIO_SETTINGS`, `CAMERA`, and foreground-service permissions are granted on Android 13+.
6. Verify `MobilePushRegistrationService` logs a registration token after login.
### Android runtime permissions (voice / camera)
Capacitor's WebView requests `RECORD_AUDIO` **and** `MODIFY_AUDIO_SETTINGS` together for microphone capture. If `MODIFY_AUDIO_SETTINGS` is missing from `AndroidManifest.xml`, users can accept the prompt and `getUserMedia` still fails.
Declared in `toju-app/android/app/src/main/AndroidManifest.xml`:
| Permission | Purpose |
|------------|---------|
| `RECORD_AUDIO` | Microphone capture for voice calls and channels |
| `MODIFY_AUDIO_SETTINGS` | Required by Capacitor WebChromeClient alongside `RECORD_AUDIO` |
| `CAMERA` | WebRTC camera sharing and WebView file capture |
| `BLUETOOTH_CONNECT` | Bluetooth headset routing during calls (Android 12+) |
| `POST_NOTIFICATIONS` | Incoming/active call notifications |
| `FOREGROUND_SERVICE` / `FOREGROUND_SERVICE_MICROPHONE` | Background voice session |
Before WebRTC capture, the client calls `MobileMediaService.ensureVoiceCapturePermissions()` / `ensureCameraCapturePermissions()`, which delegate to `MetoyouMobile.requestVoiceCapturePermissions()` / `requestCameraCapturePermissions()` on Capacitor shells.
### iOS (APNs)
1. Enable Push Notifications capability in Xcode for the `App` target.
@@ -135,6 +153,7 @@ POST /api/users/device-tokens/:userId/dispatch
- `FOREGROUND_SERVICE`
- `FOREGROUND_SERVICE_MICROPHONE`
- `RECORD_AUDIO`
- `MODIFY_AUDIO_SETTINGS`
- `POST_NOTIFICATIONS`
The service shows a low-importance ongoing notification while a call is active.
@@ -152,7 +171,7 @@ The service shows a low-importance ongoing notification while a call is active.
## Capacitor plugin loading
- `infrastructure/mobile/adapters/capacitor/capacitor-plugin-loader.ts` uses **static** `@capacitor/*` imports and `Capacitor.isPluginAvailable()` before returning a plugin. Do not `import()` plugin modules dynamically or `await` plugin objects (Capacitor proxies expose a throwing `.then()` stub).
- After adding or upgrading Capacitor plugins, run `npm run build:prod && npm run cap:sync` so Android/iOS native projects register `App`, `LocalNotifications`, push, and SQLite.
- After adding or upgrading Capacitor plugins, run `npm run build:prod && npm run cap:sync` so Android/iOS native projects register `App`, `AppUpdate`, `LocalNotifications`, push, and SQLite.
## Safe area (Android)
@@ -208,7 +227,8 @@ Network security configs:
- `ChatMessageComposerComponent` — `shouldShowAttachmentButton` + `pickAttachmentsFromDevice()`.
- `VoiceWorkspaceStreamTileComponent` — PiP when focused stream tile backgrounds.
- `MobileCallSessionService` — CallKit + foreground service + in-call notifications.
- `App` bootstrap — initializes mobile persistence, lifecycle, call-session, and push registration wiring.
- `App` bootstrap — initializes mobile persistence, lifecycle, app-update polling, call-session, and push registration wiring.
- `MobileAppUpdateService` — periodic Play Store / App Store checks (30 min) and settings UI actions; mirrors Electron `DesktopAppUpdateService` polling but uses native store APIs instead of release manifests.
## Phase 3 completion notes