Update Quickstart for Android Kotlin to v5#239
Open
Aaron LaBeau (biozal) wants to merge 9 commits intomainfrom
Open
Update Quickstart for Android Kotlin to v5#239Aaron LaBeau (biozal) wants to merge 9 commits intomainfrom
Aaron LaBeau (biozal) wants to merge 9 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the Android Kotlin quickstart app to use Ditto Kotlin SDK v5, modernizing the app’s Ditto initialization/auth flow and moving UI/viewmodels toward Flow/StateFlow and lifecycle-aware Compose collection.
Changes:
- Upgrades Ditto dependency to v5 (
com.ditto:ditto-kotlin:5.0.0) and updates related AndroidX/Kotlin tooling versions. - Refactors app state to use
StateFlow+collectAsStateWithLifecycle, updates theming/resources, and improves runtime permission handling. - Adds focused unit tests for the
Taskmodel JSON parsing and tightens the UI test behavior.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| android-kotlin/README.md | Updates docs links and setup wording; adds Android CLI/Skills note. |
| android-kotlin/QuickStartTasks/gradle/libs.versions.toml | Bumps tool/library versions; switches Ditto artifact coordinates; adds JSON + compose-related libs. |
| android-kotlin/QuickStartTasks/app/src/test/java/live/ditto/quickstart/tasks/ExampleUnitTest.kt | Removes placeholder unit test. |
| android-kotlin/QuickStartTasks/app/src/test/java/live/ditto/quickstart/tasks/data/TaskTest.kt | Adds unit tests validating Task.fromJson behavior and defaults. |
| android-kotlin/QuickStartTasks/app/src/main/res/values/strings.xml | Centralizes UI strings and content descriptions for Compose screens. |
| android-kotlin/QuickStartTasks/app/src/main/res/values/colors.xml | Adjusts brand color values/formatting. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/ui/theme/Theme.kt | Updates Material3 color schemes and disables dynamic color by default. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/ui/theme/Color.kt | Adds brand color constants matching resource colors. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/TasksApplication.kt | Replaces v4 initialization with v5 Ditto config and authentication setup. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/MainActivity.kt | Updates permission request flow and enables edge-to-edge. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/list/TasksListScreenViewModel.kt | Moves tasks + sync state to StateFlow; refactors sync start/stop and store observation. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/list/TasksListScreen.kt | Switches from LiveData to lifecycle-aware Flow collection; string/resource cleanup; stable list keys. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/list/TaskRow.kt | Improves accessibility strings for icons/content descriptions. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/edit/EditScreenViewModel.kt | Migrates edit state to StateFlow and updates Ditto queries accordingly. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/edit/EditScreen.kt | Moves setup side-effect into LaunchedEffect; switches to lifecycle-aware Flow collection. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/edit/EditForm.kt | Replaces hardcoded strings/colors with resources and Material theme colors. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/DittoHandler.kt | Introduces explicit Ditto singleton initialization for v5. |
| android-kotlin/QuickStartTasks/app/src/main/java/live/ditto/quickstart/tasks/data/Task.kt | Adds toMap() and makes JSON parsing more defensive via opt* APIs. |
| android-kotlin/QuickStartTasks/app/src/androidTest/java/live/ditto/quickstart/tasks/TasksUITest.kt | Refactors UI test to fail loudly without a Compose hierarchy and clarifies title resolution. |
| android-kotlin/QuickStartTasks/app/build.gradle.kts | Updates SDK levels/JVM target; adds lifecycle-runtime-compose + JSON test dep; adjusts env parsing. |
| android-kotlin/QuickStartTasks/.gitignore | Ignores .kotlin/ directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
live.ditto:ditto→com.ditto:ditto-kotlin)kotlinOptionsDSLTask.fromJsoncovering malformed JSON, missing fields, type-mismatch coercion, round-trip, and unique IDsWhy
The quickstart was failing to build with a Kotlin compiler crash (
source must not be nullinsideFirIncompatibleClassExpressionChecker). Root cause: Koin 4.2.1 transitivelypulls
kotlin-stdlib:2.3.20, whose metadata is unreadable by the Kotlin 2.1.0 compiler. Beyond fixing the build, the existing code had a number of accumulated Android/Compose anti-patterns that this PR cleans up.Build / dependency changes
live.ditto:ditto:4.14.3com.ditto:ditto-kotlin:5.0.02.1.02.3.208.9.38.9.32025.07.002026.04.011.10.11.13.02.9.22.9.82.9.22.10.02.10.0collectAsStateWithLifecycleIcons.Outlined.Edit1.1.71.2.14.1.04.2.11.16.01.18.01.2.11.3.03.6.13.7.01.8.31.11.01.7.21.8.0org.json:json20240303(testImpl)JSONObjectfor unit tests1117kotlinOptions { jvmTarget = "11" }kotlin { compilerOptions { jvmTarget.set(JvmTarget.JVM_17) } }kotlinOptionsremoved in Kotlin 2.3testOptions.unitTests.isReturnDefaultValuestrueandroid.util.Log.gitignore.kotlin/Code-quality changes
Correctness / safety
MainActivity.ktActivity.requestPermissions(...)with the result silently droppedregisterForActivityResult(ActivityResultContracts.RequestMultiplePermissions()), denied perms loggedEditScreen.kteditScreenViewModel.setupWithTask(taskId)ran on every recompositionLaunchedEffect(taskId)TasksListScreenViewModel.kt,EditScreenViewModel.ktditto(lateinit) before theinit { check(...) }guardinitblock runs the precondition first; properties initialize afterTasksListScreenViewModel.ktMutableStateFlow(true)flashedtrueon cold start before disk readsyncEnabledderived directly from DataStore viastateIn(..., SharingStarted.Eagerly); separate collector applies start/stopTask.ktjson["done"] as BooleanthrewClassCastExceptionon type mismatch, bypassingJSONExceptioncatchoptBoolean(...)/optString(...)TasksListScreen.ktDITTO_PLAYGROUND_TOKENrendered into top bar in all buildsBuildConfig.DEBUGAccessibility / theming
TaskRow.ktcontentDescription = "Delete"(copy-paste bug)R.string.action_editTasksListScreen.kt,EditScreen.ktcolorResource(R.color.blue_700)/Color.WhiteeverywhereMaterialTheme.colorScheme.primary/onPrimaryprimaryContainer/onPrimaryContainerEditForm.ktColor.Red/Color.Whitefor delete buttonMaterialTheme.colorScheme.error/onErrorcolors.xmlblue_700was the same hex asblue_500(#3B82F6)#1D4ED8)Theme.kt,Color.ktdynamicColor = trueoverridden by hardcoded blueslightColorScheme/darkColorSchemedriven byBlue200/500/700/900;dynamicColoropt-in (defaultfalse) so brand winsTasksListScreen.kt,EditScreen.kt,EditForm.kt,TaskRow.ktstrings.xml(15 new keys)Compose / architecture
TasksListScreen.ktLazyColumnitems(tasks, key = { it._id })for stable identity / correct animationsEditForm.ktandroidx.compose.foundation.layout.*/androidx.compose.material3.*with explicit imports; namedhorizontalArrangementTasksListScreen.ktTextStyle(fontSize = 10.sp)withMaterialTheme.typography.labelSmallTests
ExampleUnitTest.ktaddition_isCorrect()placeholder)Tasktest coveragedata/TaskTest.kt(new)toMap, malformed-JSON fallback, missing-fields defaults, type-mismatch coercion (the case theas Booleancast crashed on), default-id uniquenessTasksUITest.ktIllegalStateException("no compose hierarchies")and turns it intoassertTrue(... .isNotEmpty())— aresolveTestDocumentTitle(),runCatchinginstead of nestedtry, named constants for timeout and arg key.Verification
./gradlew --stop && ./gradlew clean assembleDebug./gradlew testDebugUnitTestTaskTestTasksUITest(instrumented)Test plan
./gradlew --stop && ./gradlew clean assembleDebug./gradlew installDebugtrueon cold start)