3.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build commands
# 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)
# 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)
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
/synclong-polling coroutine loop - Exposes
authState: StateFlow<AuthState>andsyncState: 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
LoginViewModel.buildSsoUrl()constructs<homeserver>/_matrix/client/v3/login/sso/redirect?redirectUrl=matrixandroid://sso- The URL opens in a Chrome Custom Tab
- Homeserver redirects to
matrixandroid://sso?loginToken=<token> MainActivity.onNewIntent(hot) oronCreate(cold) reads the token and callsMatrixSession.handleSsoCallback(token)LoginScreenobservessession.pendingSsoTokenand callsvm.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
MatrixSessionis always obtained viaMatrixSession.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 byeventId; ordering is byorigin_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