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

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 /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.ktMatrixGreen (#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