diff --git a/.github/PENDING_ISSUES/01-upgrade-kotlin-2.md b/.github/PENDING_ISSUES/01-upgrade-kotlin-2.md new file mode 100644 index 00000000..4a30796c --- /dev/null +++ b/.github/PENDING_ISSUES/01-upgrade-kotlin-2.md @@ -0,0 +1,28 @@ +--- +title: "Enhancement: Upgrade Kotlin to 2.1.x" +labels: enhancement, dependencies +--- + +## Summary + +The project currently uses **Kotlin 1.9.22**. Kotlin 2.0 is now stable and 2.1.x is the latest release, bringing significant improvements. + +## Motivation + +- **Kotlin 2.0 K2 Compiler** is ~2x faster than the K1 compiler, reducing build times. +- **New Compose Compiler Gradle Plugin** — in Kotlin 2.0+, the Compose compiler is distributed as a separate Kotlin compiler plugin (`org.jetbrains.kotlin.plugin.compose`) instead of being tied to the Kotlin version. This simplifies version management. +- Bug fixes, new language features (e.g. improved `data object`, power assert plugin), and improved type inference. +- Kotlin 1.9.x reaches end-of-life maintenance. + +## Proposed Changes + +1. Bump `kotlin-gradle-plugin` in `build.gradle.kts` from `1.9.22` → `2.1.x` (e.g. `2.1.20`). +2. In `buildSrc/src/main/kotlin/.../Versions.kt`, update `kotlin = "1.9.22"` → `"2.1.20"`. +3. Switch the Compose compiler from `kotlinCompilerExtensionVersion` to the new `org.jetbrains.kotlin.plugin.compose` Gradle plugin (see [official migration guide](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compiler.html)). +4. Remove the now-redundant `composeCompiler` version constant from `Versions.kt` and `ProjectConfigs.kt`. +5. Verify all modules compile and tests pass. + +## References + +- [Kotlin 2.0 release blog](https://blog.jetbrains.com/kotlin/2024/05/kotlin-2-0-0-release/) +- [Compose Compiler Migration Guide](https://developer.android.com/develop/ui/compose/compiler) diff --git a/.github/PENDING_ISSUES/02-migrate-exoplayer-to-media3.md b/.github/PENDING_ISSUES/02-migrate-exoplayer-to-media3.md new file mode 100644 index 00000000..37c8b08c --- /dev/null +++ b/.github/PENDING_ISSUES/02-migrate-exoplayer-to-media3.md @@ -0,0 +1,32 @@ +--- +title: "Bug/Deprecation: Migrate from ExoPlayer 2.x to AndroidX Media3" +labels: bug, dependencies, deprecation +--- + +## Summary + +The project depends on `com.google.android.exoplayer:exoplayer:2.19.1`, which is **deprecated** and no longer receiving new features. Google has migrated ExoPlayer to **AndroidX Media3**. + +## Impact + +- ExoPlayer 2.x is in maintenance-only mode; no new features are added. +- Building against deprecated libraries increases future technical debt. +- Media3 is the recommended library for all new Android media development. +- The project's `demos/youtube` and any other screens using ExoPlayer will need updating. + +## Proposed Changes + +1. Replace `com.google.android.exoplayer:exoplayer:2.19.1` with: + ``` + androidx.media3:media3-exoplayer:1.x.x + androidx.media3:media3-ui:1.x.x + ``` +2. Update import statements in all usages from `com.google.android.exoplayer2.*` to `androidx.media3.*`. +3. Update `Versions.kt` to remove the `exoplayer` entry and add a `media3` entry. +4. Update `Dependencies.kt` and `GroupedDependencies.kt` accordingly. +5. Test playback in the YouTube demo screen. + +## References + +- [ExoPlayer migration guide to Media3](https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide) +- [Media3 release notes](https://github.com/androidx/media/releases) diff --git a/.github/PENDING_ISSUES/03-migrate-kapt-to-ksp.md b/.github/PENDING_ISSUES/03-migrate-kapt-to-ksp.md new file mode 100644 index 00000000..df342e89 --- /dev/null +++ b/.github/PENDING_ISSUES/03-migrate-kapt-to-ksp.md @@ -0,0 +1,36 @@ +--- +title: "Enhancement: Migrate Room annotation processing from KAPT to KSP" +labels: enhancement, performance, dependencies +--- + +## Summary + +The project uses `kotlin-kapt` to process Room's annotation processor (`androidx.room:room-compiler`). **KSP (Kotlin Symbol Processing)** is the modern replacement for KAPT and is now the recommended processor for Room. + +## Motivation + +- **KSP is ~2x faster** than KAPT because it runs natively in Kotlin, avoiding the Java stub generation step. +- `kotlin-kapt` is in maintenance mode; JetBrains recommends moving to KSP. +- Room has first-class KSP support since Room 2.5.0 (current version is 2.6.1). +- The `app/build.gradle.kts` already uses `kotlin-kapt` and has `kapt { correctErrorTypes = true }` which can be removed. + +## Proposed Changes + +1. In `app/build.gradle.kts` (and any module using Room), replace: + ```kotlin + id("kotlin-kapt") + ``` + with: + ```kotlin + id("com.google.devtools.ksp") + ``` +2. In `build.gradle.kts` (root), add the KSP plugin to the buildscript classpath. +3. In `DependencyHandlerExtensions.kt`, change `add("kapt", Dependencies.roomCompiler)` to `add("ksp", Dependencies.roomCompiler)`. +4. Update `Dependencies.kt`: `room-compiler` artifact stays the same; only the configuration changes. +5. Remove the `kapt { correctErrorTypes = true }` block from `app/build.gradle.kts`. +6. Add `ksp` version constant to `Versions.kt` (match the Kotlin version). + +## References + +- [KSP Quick Start](https://kotlinlang.org/docs/ksp-quickstart.html) +- [Room KSP Support](https://developer.android.com/training/data-storage/room#ksp) diff --git a/.github/PENDING_ISSUES/04-bump-target-sdk-to-35.md b/.github/PENDING_ISSUES/04-bump-target-sdk-to-35.md new file mode 100644 index 00000000..e8239d62 --- /dev/null +++ b/.github/PENDING_ISSUES/04-bump-target-sdk-to-35.md @@ -0,0 +1,32 @@ +--- +title: "Enhancement: Bump compileSdk and targetSdk to API 35 (Android 15)" +labels: enhancement, dependencies +--- + +## Summary + +The project currently targets **Android 14 (API 34)**. Android 15 (API 35) is now stable and Google Play requires apps to target it by August 2025. + +## Motivation + +- Apps targeting API 35 unlock Android 15 features (edge-to-edge enforcement, predictive back, photo picker improvements, health connect). +- Google Play's target API level policy requires apps to target API 35 by **August 31, 2025** for updates to existing apps. +- Jetpack Compose components have improved behavior when `targetSdk = 35` (e.g., better edge-to-edge inset handling). + +## Proposed Changes + +1. In `buildSrc/src/main/kotlin/.../ProjectConfigs.kt`: + ```kotlin + const val compileSdkVersion = 35 + const val targetSdkVersion = 35 + ``` +2. Ensure the Android Gradle Plugin version in `build.gradle.kts` supports SDK 35 (AGP 8.2.2 supports it; AGP 8.3+ recommended). +3. Test for any behavior changes introduced by targeting API 35: + - **Edge-to-edge** is enforced by default on Android 15; ensure all screens handle window insets correctly using `WindowInsets` composables. + - Verify the app handles the predictive back gesture where applicable. +4. Update the README badge which references an old Compose version. + +## References + +- [Android 15 Behavior Changes](https://developer.android.com/about/versions/15/behavior-changes-15) +- [Google Play target API requirements](https://developer.android.com/google/play/requirements/target-sdk) diff --git a/.github/PENDING_ISSUES/05-adopt-compose-bom.md b/.github/PENDING_ISSUES/05-adopt-compose-bom.md new file mode 100644 index 00000000..9dc0c486 --- /dev/null +++ b/.github/PENDING_ISSUES/05-adopt-compose-bom.md @@ -0,0 +1,32 @@ +--- +title: "Enhancement: Adopt Compose BOM for unified Compose version management" +labels: enhancement, dependencies +--- + +## Summary + +The project currently pins individual Compose artifact versions via a single `compose` version constant. The **Compose Bill of Materials (BOM)** is the recommended way to manage Compose library versions, ensuring all libraries are always at compatible versions. + +## Motivation + +- The Compose BOM guarantees all Compose libraries are version-compatible with each other, eliminating the risk of mismatched artifact versions causing runtime crashes. +- Updating Compose only requires updating one BOM version instead of multiple individual version strings. +- Google actively maintains and publishes the BOM; it's the recommended approach in official documentation. +- Currently `compose = "1.6.1"` is used for `ui`, `material`, `runtime`, etc. — the BOM maps all of these automatically. + +## Proposed Changes + +1. Add a `composeBom` version to `Versions.kt` (e.g., `const val composeBom = "2024.xx.xx"`). +2. In `Dependencies.kt`, add a BOM platform dependency: + ```kotlin + const val composeBom = "androidx.compose:compose-bom:${Versions.composeBom}" + ``` +3. In `DependencyHandlerExtensions.kt`, add `platform(Dependencies.composeBom)` as a BOM import before adding individual Compose artifacts. +4. Remove the explicit version strings from Compose artifact declarations that are covered by the BOM (e.g., `composeUi`, `composeMaterial`, `composeRuntime`). +5. Keep `material3` version explicit if needed (or let BOM manage it too). +6. Remove the standalone `compose` and `material3` version constants from `Versions.kt` once fully managed by BOM. + +## References + +- [Compose BOM documentation](https://developer.android.com/jetpack/compose/setup#bom-version-mapping) +- [Compose BOM to library version mapping](https://developer.android.com/jetpack/compose/bom/bom-mapping) diff --git a/.github/PENDING_ISSUES/06-feature-pull-to-refresh.md b/.github/PENDING_ISSUES/06-feature-pull-to-refresh.md new file mode 100644 index 00000000..77aeb381 --- /dev/null +++ b/.github/PENDING_ISSUES/06-feature-pull-to-refresh.md @@ -0,0 +1,35 @@ +--- +title: "Feature: Add Pull-to-Refresh demo" +labels: feature request, enhancement +--- + +## Summary + +The README lists "Pull Refresh" under "Coming Soon." Jetpack Compose Material3 introduced a first-party `PullToRefreshBox` composable. This feature should be demonstrated in the app. + +## Description + +Compose Material3 ships `androidx.compose.material3.pulltorefresh.PullToRefreshBox` (stable in Material3 1.3.0+). Adding a demo would cover: + +- Basic `PullToRefreshBox` usage showing a loading indicator. +- Integration with a `ViewModel` and a `LazyColumn` that reloads data on pull. +- Optionally, a custom indicator to demonstrate customization. + +## Proposed Location + +Add the demo to one of: +- **Home screen list** — as a new list item under "Advance Lists & Animations." +- **A new screen** in `components/` — `components/pullrefresh/`. + +## Acceptance Criteria + +- [ ] A composable screen demonstrating `PullToRefreshBox` (or `PullToRefresh` with `rememberPullToRefreshState()`). +- [ ] Simulates a network delay (e.g. `delay(1500)`) to show the indicator in action. +- [ ] Supports both light and dark themes. +- [ ] Registered in the app's navigation/home screen list. +- [ ] README "Coming Soon" section updated to move this item to "Done." + +## References + +- [Material3 Pull-to-Refresh docs](https://developer.android.com/reference/kotlin/androidx/compose/material3/pulltorefresh/package-summary) +- [Compose Samples — PullToRefresh](https://github.com/android/compose-samples) diff --git a/.github/PENDING_ISSUES/07-feature-swipe-to-dismiss.md b/.github/PENDING_ISSUES/07-feature-swipe-to-dismiss.md new file mode 100644 index 00000000..dc085249 --- /dev/null +++ b/.github/PENDING_ISSUES/07-feature-swipe-to-dismiss.md @@ -0,0 +1,36 @@ +--- +title: "Feature: Add Swipe-to-Dismiss / Swipe Actions list demo" +labels: feature request, enhancement +--- + +## Summary + +The README lists "Swipe lists" under "Coming Soon." Compose Material3 provides `SwipeToDismissBox`, the recommended API for implementing swipe-to-dismiss and swipe actions on list items. + +## Description + +This feature would add a demo showcasing: + +1. **Basic SwipeToDismissBox** — swipe an item left to delete it from a `LazyColumn`. +2. **Swipe with reveal actions** — swipe right to reveal an action button (e.g. "Archive"). +3. **Undo delete** — a `Snackbar` with an "Undo" action after dismissal, demonstrating the interaction pattern recommended by Material Design 3 guidelines. + +## Proposed Location + +- New component in `components/swipedismiss/` or as a section within an existing "Lists" demo screen. +- Exposed from the Home screen under "Advance Lists & Animations." + +## Acceptance Criteria + +- [ ] `SwipeToDismissBox` demo with directional thresholds configured. +- [ ] Background shown during swipe (e.g. red "Delete" background with icon). +- [ ] Item is removed from the list on full swipe. +- [ ] Undo `Snackbar` appears after deletion. +- [ ] Supports dark mode. +- [ ] Added to navigation and the Home screen list. +- [ ] README updated. + +## References + +- [Material3 SwipeToDismissBox docs](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#SwipeToDismissBox) +- [Material Design 3 Swipe guidelines](https://m3.material.io/components/lists/guidelines) diff --git a/.github/PENDING_ISSUES/08-migrate-to-version-catalog.md b/.github/PENDING_ISSUES/08-migrate-to-version-catalog.md new file mode 100644 index 00000000..de6cd258 --- /dev/null +++ b/.github/PENDING_ISSUES/08-migrate-to-version-catalog.md @@ -0,0 +1,29 @@ +--- +title: "Enhancement: Migrate to Gradle Version Catalog (libs.versions.toml)" +labels: enhancement, build +--- + +## Summary + +The project manages dependency versions via a custom `buildSrc` Kotlin module. While functional, the modern Gradle best practice is to use a **Version Catalog** (`gradle/libs.versions.toml`). This is the default in all new Android Studio projects as of Flamingo (2022.2.1). + +## Motivation + +- Version Catalog provides IDE auto-complete for dependency declarations. +- Single source of truth — no separate `Versions.kt`, `Dependencies.kt`, `GroupedDependencies.kt`, and `DependencyHandlerExtensions.kt` files. +- Enables Gradle's built-in `./gradlew dependencyUpdates` and Renovate/Dependabot to suggest version bumps automatically. +- Works seamlessly with `buildSrc` convention plugins if those are kept. +- Reduces boilerplate: `libs.compose.ui` instead of `Dependencies.composeUi`. + +## Proposed Changes + +1. Create `gradle/libs.versions.toml` with all versions, libraries, and plugins currently defined in `buildSrc/src/main/kotlin/.../Versions.kt` and `Dependencies.kt`. +2. Migrate `app/build.gradle.kts` and all module `build.gradle.kts` files to reference `libs.` instead of `Dependencies.*`. +3. Keep the convention plugins in `buildSrc` (`common-kotlin-module-configs-script-plugin.gradle.kts`, `common-compose-module-configs-script-plugin.gradle.kts`) but have them call `libs.*` instead of the Kotlin constants. +4. Delete `buildSrc/src/main/kotlin/.../Versions.kt`, `Dependencies.kt`, `GroupedDependencies.kt`, and `DependencyHandlerExtensions.kt`. +5. Update `settings.gradle.kts` to enable the version catalog feature (already on by default in AGP 8+). + +## References + +- [Gradle Version Catalogs docs](https://docs.gradle.org/current/userguide/version_catalogs.html) +- [Android docs: Migrate to version catalogs](https://developer.android.com/build/migrate-to-catalogs) diff --git a/.github/PENDING_ISSUES/09-feature-adaptive-layouts.md b/.github/PENDING_ISSUES/09-feature-adaptive-layouts.md new file mode 100644 index 00000000..bc9a565e --- /dev/null +++ b/.github/PENDING_ISSUES/09-feature-adaptive-layouts.md @@ -0,0 +1,43 @@ +--- +title: "Feature: Add Adaptive Layout / Large Screen support" +labels: feature request, enhancement +--- + +## Summary + +The app currently has no adaptive layout support for large screens (tablets, foldables, desktops). Jetpack Compose provides `WindowSizeClass` and `adaptive` layout libraries specifically for this. Adding a demo would significantly improve the showcase value of this cookbook. + +## Description + +Android now requires apps targeting large screens to follow [large screen quality guidelines](https://developer.android.com/docs/quality-guidelines/large-screen-app-quality). The Compose toolkit provides: + +- `WindowSizeClass` (from `androidx.compose.material3:material3-window-size-class`) — already in `Dependencies.kt`. +- `androidx.compose.material3.adaptive` — new adaptive navigation and scaffold APIs. +- `NavigationSuiteScaffold` — automatically switches between `NavigationBar`, `NavigationRail`, and `NavigationDrawer` based on window size. + +## Proposed Demo + +A demo screen that shows: +1. **Adaptive navigation** using `NavigationSuiteScaffold` — bottom bar on compact, rail on medium, drawer on expanded. +2. **Two-pane layout** using `ListDetailPaneScaffold` from `androidx.compose.material3.adaptive.layout`. +3. Sample: a list of items on the left pane, detail view on the right pane when screen is large enough. + +## Proposed Changes + +1. Add `androidx.compose.material3:material3-adaptive-navigation-suite` to `Dependencies.kt`. +2. Create a new demo module or screen `demos/adaptive/`. +3. Update `app/build.gradle.kts` and navigation to include the adaptive demo. +4. Update README to document the new demo. + +## Acceptance Criteria + +- [ ] `NavigationSuiteScaffold` switches navigation component based on `WindowSizeClass`. +- [ ] `ListDetailPaneScaffold` shows a two-pane layout on tablets. +- [ ] Works on phone (single pane), tablet (two pane), and foldable (hinge-aware). +- [ ] Supports dark mode. + +## References + +- [Adaptive layouts in Compose](https://developer.android.com/develop/ui/compose/layouts/adaptive) +- [NavigationSuiteScaffold](https://developer.android.com/reference/kotlin/androidx/compose/material3/adaptive/navigationsuite/package-summary) +- [ListDetailPaneScaffold](https://developer.android.com/reference/kotlin/androidx/compose/material3/adaptive/layout/package-summary) diff --git a/.github/PENDING_ISSUES/10-upgrade-coil-3.md b/.github/PENDING_ISSUES/10-upgrade-coil-3.md new file mode 100644 index 00000000..db04980a --- /dev/null +++ b/.github/PENDING_ISSUES/10-upgrade-coil-3.md @@ -0,0 +1,36 @@ +--- +title: "Enhancement: Upgrade Coil to 3.x" +labels: enhancement, dependencies +--- + +## Summary + +The project uses **Coil 2.5.0** (`io.coil-kt:coil-compose`). Coil 3.0 is now stable and is a major version bump with breaking changes that also bring significant improvements. + +## Key Changes in Coil 3 + +- **Multiplatform support** — Coil 3 supports Kotlin Multiplatform (KMP), enabling future Desktop/Web targets. +- **Improved performance** — Faster image loading and better memory management. +- **New artifact group**: `io.coil-kt.coil3:coil-compose` (note the `coil3` group ID). +- **OkHttp is now optional**: Coil 3 uses Ktor or OkHttp interchangeably; `coil-network-okhttp` sub-artifact needed to keep OkHttp. +- **Breaking API changes**: `AsyncImage` API is largely the same but `ImageLoader` configuration has changed. + +## Proposed Changes + +1. In `Versions.kt`, update: + ```kotlin + const val coilCompose = "3.x.x" // e.g. "3.1.0" + ``` +2. In `Dependencies.kt`, update the artifact group: + ```kotlin + const val coilCompose = "io.coil-kt.coil3:coil-compose:${Versions.coilCompose}" + const val coilNetworkOkHttp = "io.coil-kt.coil3:coil-network-okhttp:${Versions.coilCompose}" + ``` +3. Add `coilNetworkOkHttp` to `GroupedDependencies.kt` alongside `coilCompose`. +4. Update any call sites that use deprecated Coil 2 APIs. +5. Ensure all demo screens that load images (Instagram, Movies, Crypto, etc.) still function correctly. + +## References + +- [Coil 3 Migration Guide](https://coil-kt.github.io/coil/upgrading_to_coil3/) +- [Coil 3 GitHub Releases](https://github.com/coil-kt/coil/releases) diff --git a/.github/PENDING_ISSUES/11-upgrade-lifecycle-2.8.md b/.github/PENDING_ISSUES/11-upgrade-lifecycle-2.8.md new file mode 100644 index 00000000..cf467889 --- /dev/null +++ b/.github/PENDING_ISSUES/11-upgrade-lifecycle-2.8.md @@ -0,0 +1,35 @@ +--- +title: "Enhancement: Upgrade AndroidX Lifecycle to 2.8.x" +labels: enhancement, dependencies +--- + +## Summary + +The project uses `androidLifecycleGrouped = "2.7.0"` for all lifecycle-related artifacts (`lifecycle-viewmodel-compose`, `lifecycle-runtime-ktx`, `lifecycle-livedata-ktx`, etc.). Lifecycle **2.8.x** is now stable and includes important improvements. + +## Key Improvements in Lifecycle 2.8 + +- **`LifecycleEventEffect` and `LifecycleStartEffect`/`LifecycleResumeEffect`** composables — cleaner replacements for `DisposableEffect` with `LocalLifecycleOwner`. +- **`collectAsStateWithLifecycle`** improvements for safer Flow collection tied to UI lifecycle. +- **`viewModel()` KMP support** — multiplatform ViewModel for future KMP migration. +- Bug fixes and improved SavedState integration. + +## Proposed Changes + +1. In `Versions.kt`, update: + ```kotlin + const val androidLifecycleGrouped = "2.8.x" // e.g. "2.8.7" + ``` +2. All lifecycle artifacts using this version constant update automatically: + - `lifecycle-viewmodel-compose` + - `lifecycle-viewmodel-ktx` + - `lifecycle-livedata-ktx` + - `lifecycle-runtime-ktx` + - `lifecycle-viewmodel-savedstate` +3. Review usages of `DisposableEffect(lifecycleOwner)` in the codebase and consider migrating to the new `LifecycleEventEffect` API where applicable. +4. Run all tests to confirm no regressions. + +## References + +- [Lifecycle 2.8.0 Release Notes](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.0) +- [LifecycleEventEffect API](https://developer.android.com/reference/kotlin/androidx/lifecycle/compose/package-summary#LifecycleEventEffect) diff --git a/.github/PENDING_ISSUES/12-upgrade-navigation-2.8-type-safe.md b/.github/PENDING_ISSUES/12-upgrade-navigation-2.8-type-safe.md new file mode 100644 index 00000000..8bc34976 --- /dev/null +++ b/.github/PENDING_ISSUES/12-upgrade-navigation-2.8-type-safe.md @@ -0,0 +1,33 @@ +--- +title: "Enhancement: Upgrade Navigation Compose to 2.8.x and adopt type-safe navigation" +labels: enhancement, dependencies +--- + +## Summary + +The project uses `navCompose = "2.7.7"`. Navigation Compose **2.8.0** is stable and introduces **type-safe navigation** using Kotlin serialization, eliminating stringly-typed route strings. + +## Key Improvements in Navigation 2.8 + +- **Type-safe routes** via `@Serializable` data classes instead of string route patterns — no more parsing `navBackStackEntry.arguments?.getString("id")`. +- `NavController.navigate(MyRoute(id = 42))` instead of `navController.navigate("detail/42")`. +- Compatible with Kotlin serialization (`kotlinx.serialization`). +- Improved `NavController` query APIs. + +## Proposed Changes + +1. In `Versions.kt`, update: + ```kotlin + const val navCompose = "2.8.x" // e.g. "2.8.9" + ``` +2. Add `kotlinx-serialization-json` to `Dependencies.kt` and `kotlinDependencies` in `GroupedDependencies.kt`. +3. Apply the `kotlin("plugin.serialization")` Gradle plugin in `build.gradle.kts` (root). +4. Migrate existing string routes in the app to `@Serializable` data class routes. +5. Update `DependencyHandlerExtensions.kt` to include the serialization dependency. +6. Verify all navigation in demos still works correctly. + +## References + +- [Navigation 2.8 type-safe navigation guide](https://developer.android.com/guide/navigation/design/type-safety) +- [Navigation release notes](https://developer.android.com/jetpack/androidx/releases/navigation) +- [Kotlin Serialization](https://kotlinlang.org/docs/serialization.html)