matrix-android/CLAUDE.md
ltadeu6 1d99440b01
Update CLAUDE.md with release build and secrets setup
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 17:06:52 -03:00

77 lines
3.2 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Build commands
```bash
# First-time setup: generate the Gradle wrapper (requires Gradle installed)
gradle wrapper --gradle-version 8.9
# Build debug APK (inside nix dev shell)
nix develop --command gradle --no-daemon assembleDebug
# Build release APK — requires android-signing-env (sets signing vars + PUSH_GATEWAY_URL)
android-signing-env nix develop --command gradle --no-daemon assembleRelease
# Install on connected device/emulator
./gradlew installDebug
# Run lint
./gradlew lint
# Clean
./gradlew clean
```
### Secrets setup (required before release build)
```bash
# Creates symlinks for google-services.json, firebase-service-account.json, .mc/credentials.json
# Only needed once per boot (symlinks point into /run/agenix which is tmpfs)
matrix-android-secrets /home/ltadeu6/Projetos/Codigo/matrix-android
```
### Deploy Cloudflare Worker (push gateway)
```bash
cloudflare-worker-env nix develop --command wrangler deploy --config gateway/wrangler.toml
```
The project has no unit tests yet. Android Studio is the recommended way to open, sync, and run the project.
## Architecture
Single-activity Compose app. All screens live inside one `NavHost` in `AppNavigation.kt`. Navigation flow: **Login → Rooms → Chat**.
### State ownership
`MatrixSession` (singleton, `matrix/MatrixSession.kt`) is the single source of truth. It:
- Persists the access token in `SharedPreferences`
- Owns and runs the `/sync` long-polling coroutine loop
- Exposes `authState: StateFlow<AuthState>` and `syncState: StateFlow<SyncState>`
All ViewModels and screens observe these flows directly — there is no local room/message database.
### Matrix transport
Direct REST API via Retrofit (`MatrixApi.kt`). No Matrix SDK dependency. Only `m.room.message` text events are rendered; encrypted events are silently dropped.
### SSO login flow
1. `LoginViewModel.buildSsoUrl()` constructs `<homeserver>/_matrix/client/v3/login/sso/redirect?redirectUrl=matrixandroid://sso`
2. The URL opens in a Chrome Custom Tab
3. Homeserver redirects to `matrixandroid://sso?loginToken=<token>`
4. `MainActivity.onNewIntent` (hot) or `onCreate` (cold) reads the token and calls `MatrixSession.handleSsoCallback(token)`
5. `LoginScreen` observes `session.pendingSsoToken` and calls `vm.loginWithSsoToken(token)` which POSTs to `/_matrix/client/v3/login`
### Theme
`ui/theme/Theme.kt``MatrixGreen` (`#00FF41`) on `MatrixBackground` (`#0A0A0A`). All text uses `TerminalFont` (`FontFamily.Monospace`). No Material components with default colors — always pass explicit `colors =` overrides to `OutlinedTextField` and `Button`.
## Key conventions
- `MatrixSession` is always obtained via `MatrixSession.getInstance(context)` — never constructed directly
- Room IDs (`!abc:homeserver`) are URL-encoded when passed as nav arguments (`Route.chat(roomId)`)
- `SyncState.messages[roomId]` is append-only and deduped by `eventId`; ordering is by `origin_server_ts`
- The sync filter (`MatrixSession.syncFilter`) limits timeline to 50 events and strips presence/account data — change it here if more history is needed