Native Android client for Bangumi Dollars, the realtime chat room on Bangumi. Kotlin + Jetpack Compose + Material 3.
Reading and realtime updates go through the re-dollars-backend service; posting goes directly to Bangumi using your logged-in session, the same way the re-dollars-preact userscript does. See ANDROID_APP_SPEC.md for the full technical spec this app was built from.
- Live message stream over WebSocket, with REST-backed history/scrollback and gap recovery on reconnect
- Sending messages with optimistic bubbles, send/confirm, and retry on failure
- Replies (quote), reactions, edit/delete for your own messages
- BBCode rendering: text styles, links,
[user]mentions,[quote],[img]/[video]/[audio],[code],[mask]spoilers, smilies, and BMO emoji - Image lightbox, media gallery, in-app search
- Presence (online count, typing indicators), push notifications (FCM), voice message recording
- Per-user blocking, account sheet, Material 3 theming with dynamic color and light/dark support
- Android Studio (current stable)
- JDK 17
- Android SDK: minSdk 26, targetSdk 36, compileSdk 37
- Open the
re-dollars-Android/directory in Android Studio and let it sync Gradle. - Push notifications require Firebase: drop your own
app/google-services.jsonin place of/next to the existing one, or leave it as-is if you're not touching FCM. The build stays green either way (thegoogle-servicesplugin is only applied if the file exists). - Release builds are signed using
release.keystoreat the project root, with credentials fromlocal.properties(RELEASE_STORE_PASSWORD,RELEASE_KEY_ALIAS,RELEASE_KEY_PASSWORD) or the matching environment variables. Not needed for debug builds. - Backend/auth endpoints are hardcoded in
Config.kt— edit there to point at a different backend or Bangumi host.
./gradlew assembleDebug # debug APK
./gradlew installDebug # install on a connected device/emulator
./gradlew assembleRelease # signed release APKThere's no separate account system — login happens inside an in-app WebView against Bangumi
itself (bgm.tv), and posting reuses that browser session (cookies + formhash). A second,
one-time login via rymk-auth obtains a backend JWT, needed for reactions,
edit/delete, read state, uploads, and push registration. See §3 of the spec for details.
MVVM with a single-activity Compose UI:
app/src/main/java/mk/ry/redollars/
├─ net/ REST client, WebSocket client, models, config, uploads
├─ data/ MessageRepository — merges WS events + REST paging + Room cache
├─ di/ Hilt modules
├─ ui/
│ ├─ chat/ ChatScreen and its sheets (account, block manager, gallery,
│ │ notifications, reactions, search, typing indicator, ...)
│ ├─ render/ BBCode → Compose renderer, image/video/audio, smilies
│ └─ theme/ Material 3 theme
├─ bmo/ BMO emoji codec/renderer (Bangumi's custom emoji system)
├─ push/ FCM messaging service
└─ voice/ Voice message recording
ChatViewModel drives ChatScreen; MessageRepository is the single source of truth, backed by
Room and kept in sync by DollarsWs (WebSocket) and RestApi.