- AuthScreen.kt: FocusManager is imported from androidx.compose.ui.focus,
not androidx.compose.ui.platform (only LocalFocusManager lives there).
The fully-qualified platform.FocusManager parameter types therefore
failed to resolve, cascading into the clearFocus() errors.
- MainScreen.kt: MitbringslTheme gained a required sessionManager
parameter in 729865b; the leftover template preview now passes
SessionManager(LocalContext.current).
Verified: ./gradlew compileDebugKotlin, assembleDebug and test all green.
Note: local builds must use JDK 21 (JAVA_HOME=/usr/lib/jvm/java-21-openjdk);
the system default JDK 26 breaks AGP's JdkImageTransform (jlink) on
android-36's core-for-system-modules.jar.
- settings.gradle.kts: comment out the foojay-resolver-convention plugin.
It tries to auto-download JDK toolchains from api.foojay.io, which fails
with 503 behind restrictive proxies. Re-enable at home if you want
auto-provisioning.
- app/build.gradle.kts: comment out jvmToolchain(17) for the same reason
(triggers toolchain resolution -> foojay download). The build JDK 21
plus compileOptions(source/target 17) achieves the same result locally.
- gradle-wrapper.properties: bump to gradle-9.6.1-all (matches the
manually provided distribution).
- .gitignore: ignore .ssl-work/ (local corporate-CA truststore).
Backend:
- New GET/PUT /api/me endpoint to read and update the authenticated
user's profile (currently display_name). UserStore.UpdateDisplayName.
- Wired into the authed router.
App:
- New SettingsScreen + SettingsViewModel with five sections:
* Account & Sync: login status, email, server URL, logout, connect.
* Profile: edit display name (pushed to PUT /api/me when logged in).
* Appearance: System / Light / Dark theme switch, persisted in
SessionManager and applied via MitbringslTheme(sessionManager).
* Data: 'Reset local data' wipes Room tables (server data kept).
* About: version, 'Developed by Janik Dietz', and credits to
GLM-5.2 + Gemini 3.6 Flash.
- Theme.kt now reads the user's theme preference (StateFlow) instead
of only the system default; MainActivity passes SessionManager in.
- Navigation: new SettingsNavKey; settings gear icon in ListsScreen
top bar; Settings links back to the Sync/Account screen.
- DTOs/API: UpdateMeRequestDto + getMe()/updateMe() for /api/me.
Backend:
- New AUTH_PASSWORD_ENABLED flag (default true). When false, email/password
registration and login return 403; the server enforces OIDC-only login.
- New OIDC_GENERIC_DISPLAY_NAME so the app can show 'Authentik'/'Keycloak'
instead of a generic 'OIDC' label.
- New public endpoint GET /api/config returns which auth methods the
server offers (password_enabled + per-provider OIDC capabilities).
No auth required, so the login screen can query it before logging in.
- .env.example and docker-compose.yml expose the new env vars.
App:
- DTOs + MitbringslApi.getServerConfig() for /api/config.
- AuthViewModel: new 'connect' flow. The user enters the server URL,
taps 'Verbinden', and the app fetches /api/config. The returned
ServerAuthConfig drives which login options are shown:
* password-only -> email/password form
* OIDC-only -> OIDC token form
* both -> toggle between the two
If the server offers no method, a clear error is shown.
- AuthScreen: split into ConnectView (server URL) and LoginView (the
login form matching the server's capabilities). The mode toggle only
appears when the server offers more than one method.
Sync engine (critical):
- SyncWorker now pulls server ops for EVERY tracked list, not just
lists with pending local outbox ops. Previously remote edits on
'quiet' lists (incl. shared/joined lists) never arrived.
- SyncWorker advances the local HLC with each incoming server op
(tick(op.hlcTs)) so LWW is correct across devices with skewed
clocks; previously a fast-clock device permanently won conflicts
and a slow-clock device's own edits were silently rejected.
- Added missing 'list_create' branch in applyServerOpProjection.
- Use server hlc_ts for createdAt/updatedAt in projections so lists
and items keep a stable order instead of jumping by sync time.
- Prune old synced op_log rows (deleteOldSynced) to bound growth.
- Added ListDao.getAllListIds() one-shot query for the pull loop.
Build / runtime (critical):
- Added proguard-rules.pro with keep rules for kotlinx.serialization
serializers and Retrofit interfaces; release builds with R8 would
otherwise crash with SerializationException on the first API call.
- Added network_security_config.xml allowing cleartext only to
10.0.2.2/localhost so the debug build can reach the local backend
(blocked by default on Android 9+).
- Manifest: disable default WorkManager initializer so Hilt's
HiltWorkerFactory is used (otherwise SyncWorker can fail to
instantiate); added ACCESS_NETWORK_STATE permission.
Data safety (critical/major):
- Removed fallbackToDestructiveMigration from DatabaseModule: in a
local-first app a destructive migration on schema bump would wipe
the source of truth. Provide explicit Migrations instead.
- ShoppingRepository: wrap every local projection write + op_log
insert in db.withTransaction{} so a crash between them can no
longer silently lose a pending sync op.
- ShoppingRepository: replace manual JSON string concatenation with
kotlinx.serialization buildJsonObject; the old escapeJson did not
handle tab/CR/control chars, producing malformed op payloads.
- Persist device clientId and clientSeq counter in SessionManager so
they survive process restarts (idempotency stays stable per device).
- Trigger immediate + periodic sync after login/register/OIDC so
users see their lists without waiting up to 15 minutes.
.gitignore: ignore desktop.ini and backend/.testbin.
- ListDetailScreen: hide Share action icon when not connected to a server (isLoggedIn == false)
- ListsScreen: show informative prompt dialog if user attempts to join a list without active server connection
- ListDetailViewModel: expose sessionManager to check auth state cleanly
- ADB reinstall & launch verified ✅
- Generate high-res 3D shopping bag icon with checkmark badge
- Populate mipmap densities (mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi)
- Configure adaptive icon XML & dark blue background color
- Re-install via ADB verified ✅
- SessionManager: return stable local_user ID when not logged in
- Navigation: start directly at ListsNavKey without requiring login
- ListsScreen: add 'Sync / Account' chip in top bar; lists work 100% locally by default
- AuthScreen: update text & add 'Zurück zu meinen Listen' button for returning to local mode
- ADB reinstall & launch verified ✅