Skip to content
This repository was archived by the owner on Apr 10, 2026. It is now read-only.

Add native Android app (Kotlin + Jetpack Compose)#18

Merged
dajbelshaw merged 7 commits intomainfrom
claude/android-app-development-n9dcO
Mar 27, 2026
Merged

Add native Android app (Kotlin + Jetpack Compose)#18
dajbelshaw merged 7 commits intomainfrom
claude/android-app-development-n9dcO

Conversation

@dajbelshaw
Copy link
Copy Markdown
Contributor

Summary

  • Native Android port of Stream as packages/android/ — Kotlin, Jetpack Compose, Material Design 3 with Nord theme
  • Faithful ports of river scoring engine, Feedbin and FreshRSS adapters (direct OkHttp, no CORS proxy)
  • Room database for offline article cache, DataStore for preferences
  • Swipe gestures (dismiss/save), pull-to-refresh, undo snackbar
  • WorkManager background sync every 30 minutes
  • GitHub Actions CI that builds debug + release APKs and creates a GitHub Release (no VPS deployment)

Test plan

  • CI workflow builds both APKs successfully
  • Install debug APK on Android device/emulator
  • Connect to Feedbin or FreshRSS backend
  • Verify articles load with correct velocity-based fade
  • Swipe left to dismiss (undo via snackbar), swipe right to save
  • Tap article to open reading view (WebView)
  • Settings: adjust velocity tiers, display prefs, mute sources
  • Kill app, reopen — cached articles display offline
  • Light/dark theme follows system

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf

claude added 2 commits March 27, 2026 20:04
New packages/android/ module — a full native Android port of Stream with:
- Kotlin + Jetpack Compose + Material Design 3 (Nord theme)
- Faithful ports of river scoring engine and Feedbin/FreshRSS adapters
- Room database for offline article cache, DataStore for preferences
- Swipe gestures (dismiss/save), pull-to-refresh, undo snackbar
- Connect, River, Reading (WebView), and Settings screens
- Compose Navigation with full screen flow
- WorkManager background sync (30-minute periodic refresh)
- Hilt dependency injection throughout
- No CORS proxy needed — direct OkHttp calls to RSS backends

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf
CI builds debug + release APKs on push/PR to main when android/ changes.
On main push, creates a GitHub Release with both APKs attached — no VPS
deployment. Uses gradle/actions/setup-gradle to bootstrap the wrapper
in CI, android-actions/setup-android for SDK, and softprops/action-gh-release
for the release.

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 27, 2026

Deploy Preview for stream-rss ready!

Name Link
🔨 Latest commit d8e4d0a
🔍 Latest deploy log https://app.netlify.com/projects/stream-rss/deploys/69c6ece265261a00082b006c
😎 Deploy Preview https://deploy-preview-18--stream-rss.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

claude added 5 commits March 27, 2026 20:15
The setup-gradle action doesn't install gradle on PATH by default.
Passing gradle-version explicitly installs it, so we can run gradle
directly without needing the wrapper jar in the repo.

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf
Two critical issues preventing compilation:

1. settings.gradle.kts used `dependencyResolution` (invalid) instead of
   `dependencyResolutionManagement` — Gradle couldn't resolve any repos.

2. RiverViewModel and SettingsViewModel passed 10 and 7 flows to
   combine() but typed overloads only exist up to 5. Switch to the
   Array<Flow> overload with `flows = arrayOf(...)`.

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf
… unused imports

1. combine() with >5 flows: use listOf() overload instead of invalid
   named vararg `flows = arrayOf(...)` syntax.

2. SwipeToDismissBox: remove nonexistent enableDismissFromStartToEnd/
   enableDismissFromEndToStart params (direction is controlled via
   confirmValueChange on the state).

3. Remove unused Icon and painterResource imports from RiverCard.kt.

4. Fix FreshRSSAdapter.get() double response.body.string() call —
   read body once into a val before checking success.

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf
The manifest referenced @mipmap/ic_launcher but no icon existed,
causing AAPT resource linking to fail.

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf
StreamApp implements Configuration.Provider for on-demand WorkManager
init, so the default InitializationProvider must be removed via
tools:node="remove" to avoid the RemoveWorkManagerInitializer lint error.

https://claude.ai/code/session_011Q4W1pgzkirqyoUmyqnjWf
@dajbelshaw dajbelshaw merged commit 291c897 into main Mar 27, 2026
6 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants