matrix-android/AGENTS.md
2026-05-14 23:22:06 -03:00

4.2 KiB

AGENTS.md — matrix-android

Progress log and architecture notes for AI agents working on this project.


Status

Component Status
Build infrastructure (Gradle, version catalog) done
Matrix networking (Retrofit API + Session) done
SSO / password login flow done
Room list screen done
Chat screen (send + receive) done
Terminal theme (green on black, monospace) done
Launcher icon (vector adaptive) done
README done

Design decisions

No heavy Matrix SDK

Instead of importing the full matrix-android-sdk2 (used by Element), we call the Matrix REST API directly with Retrofit. This keeps the APK small and the code easy to follow. The trade-off is no E2E encryption support.

SSO via Custom Tabs

Login opens the homeserver's /login/sso/redirect endpoint in a Chrome Custom Tab. After auth the homeserver redirects to matrixandroid://sso?loginToken=<token>. The app intercepts this URI via an <intent-filter> in AndroidManifest.xml and exchanges the token for an access token.

Single-activity Compose navigation

MainActivityAppNavigation hosts all three screens (Login, Rooms, Chat) inside a single NavHost. No fragments.

MatrixSession singleton

MatrixSession is a process-scoped singleton (companion object). It holds the Retrofit client, persists the access token in SharedPreferences, and runs the /sync long-polling loop in a coroutine scope. All screens observe syncState: StateFlow<SyncState>.

Sync filter

Initial and incremental syncs use a compact filter:

  • Timeline limited to 50 events per room
  • State events use lazy member loading
  • Presence and account data stripped

This prevents the first sync from being huge on accounts with many rooms.


Known issues / future work

  • E2E encryption: Matrix Olm/Megolm is not implemented. Encrypted rooms will show blank messages.
  • Push notifications: Not implemented. The app only receives messages while open.
  • Pagination: No scroll-back pagination for old messages.
  • Room member display names: Members are shown as their MXID, not display name.
  • Image/file messages: Silently dropped (only m.text is rendered).
  • Error handling: Network errors on send are silently swallowed; add a snackbar or retry UI.
  • Direct messages: DMs appear in the room list using the room ID; should resolve the other user's display name.

File map

matrix-android/
├── settings.gradle.kts
├── build.gradle.kts
├── gradle/
│   ├── libs.versions.toml          ← version catalog
│   └── wrapper/
│       └── gradle-wrapper.properties
├── app/
│   ├── build.gradle.kts
│   ├── proguard-rules.pro
│   └── src/main/
│       ├── AndroidManifest.xml
│       ├── java/com/ltadeu6/matrix/
│       │   ├── MainActivity.kt
│       │   ├── navigation/AppNavigation.kt
│       │   ├── auth/LoginScreen.kt
│       │   ├── auth/LoginViewModel.kt
│       │   ├── rooms/RoomListScreen.kt
│       │   ├── chat/ChatScreen.kt
│       │   ├── chat/ChatViewModel.kt
│       │   ├── matrix/MatrixApi.kt
│       │   ├── matrix/MatrixModels.kt
│       │   ├── matrix/MatrixSession.kt
│       │   └── ui/theme/Theme.kt
│       └── res/
│           ├── drawable/ic_launcher_foreground.xml
│           ├── mipmap-anydpi-v26/ic_launcher.xml
│           ├── mipmap-anydpi-v26/ic_launcher_round.xml
│           └── values/{strings,colors,themes}.xml
├── README.md
└── AGENTS.md

Session 1 — initial build (2026-05-14)

  • Inspected matrix-message terminal app for UI reference:
    • app.py: curses chat with < prefix for incoming, > for outgoing
    • font.py: big pixel ASCII font for incoming banners
    • Color scheme: COLOR_GREEN on black
  • Created full Android project from scratch (no fork)
  • Chose Retrofit + kotlinx.serialization over matrix-android-sdk2 for simplicity
  • SSO flow: Custom Tabs → homeserver → matrixandroid://sso deep link → token exchange
  • Compose UI with monospace font, #00FF41 green, #0A0A0A background
  • All screens text-only, no images/icons/avatars