From ca940a5e896532de2a78f8d4c581d87c97c9dca6 Mon Sep 17 00:00:00 2001 From: jhavatar Date: Wed, 25 Mar 2026 03:39:16 +0200 Subject: [PATCH 1/6] Refactor to create feature-module --- .idea/gradle.xml | 5 +- app/build.gradle | 14 ++- app/src/main/AndroidManifest.xml | 13 ++- .../java/io/chthonic/weather}/AppContainer.kt | 6 +- .../io/chthonic/weather/AppContainerNav.kt | 25 ++++++ .../java/io/chthonic/weather}/MainActivity.kt | 4 +- .../cityforecast}/.gitignore | 0 .../cityforecast}/build.gradle | 19 ++-- .../cityforecast}/consumer-rules.pro | 0 .../cityforecast}/proguard-rules.pro | 0 .../cityforecast/src/main/AndroidManifest.xml | 4 + .../feature/cityforecast/AppContainerNav.kt | 43 +++++++++ .../cityforecast/CityForecastDestination.kt | 8 +- .../cityforecast}/models/ListUiState.kt | 4 +- .../models/LocationPermissionState.kt | 4 +- .../cityforecast}/models/TemperatureUnits.kt | 4 +- .../cityforecast}/models/WeatherCondition.kt | 8 +- .../screens/location/DayWeather.kt | 12 +-- .../screens/location/LocationDetailScreen.kt | 50 +++++------ .../screens/location/LocationDetailState.kt | 8 +- .../location/LocationDetailViewModel.kt | 6 +- .../locationlist/LocationCurrentWeather.kt | 10 +-- .../locationlist/LocationListScreen.kt | 60 ++++++------- .../screens/locationlist/LocationListState.kt | 10 +-- .../LocationListUiStateResolver.kt | 6 +- .../locationlist/LocationListViewModel.kt | 8 +- .../screens/locationlist/NavigationEvent.kt | 4 +- .../feature/cityforecast/theme/TempColors.kt | 84 ++++++++++++++++++ .../widgets/HandleLocationPermissions.kt | 12 +-- .../widgets/ListUiStasteContent.kt | 20 ++--- .../widgets/PermissionDialogs.kt | 8 +- .../cityforecast}/widgets/TemperatureText.kt | 8 +- .../widgets/TemperatureUnitsButton.kt | 8 +- .../LocationListUiStateResolverTest.kt | 4 +- presentation/src/main/AndroidManifest.xml | 15 ---- .../weather/presentation/AppContainerNav.kt | 54 ----------- settings.gradle | 5 +- ui/common/.gitignore | 1 + ui/common/build.gradle | 67 ++++++++++++++ ui/common/consumer-rules.pro | 0 ui/common/proguard-rules.pro | 21 +++++ ui/common/src/main/AndroidManifest.xml | 2 + .../weather/ui/common}/AppContainerState.kt | 7 +- .../weather/ui/common}/theme/AppColors.kt | 81 +---------------- .../weather/ui/common}/theme/AppShapes.kt | 2 +- .../weather/ui/common}/theme/AppTheme.kt | 2 +- .../weather/ui/common}/theme/AppTypography.kt | 4 +- .../weather/ui/common}/theme/Spacing.kt | 2 +- .../common}/widgets/PreviewSharedAnimation.kt | 5 +- .../src/main/res/font/outfit_black.ttf | Bin .../common}/src/main/res/font/outfit_bold.ttf | Bin .../src/main/res/font/outfit_extrabold.ttf | Bin .../src/main/res/font/outfit_extralight.ttf | Bin .../src/main/res/font/outfit_light.ttf | Bin .../src/main/res/font/outfit_medium.ttf | Bin .../src/main/res/font/outfit_regular.ttf | Bin .../src/main/res/font/outfit_semibold.ttf | Bin .../common}/src/main/res/font/outfit_thin.ttf | Bin .../common}/src/main/res/values/strings.xml | 0 59 files changed, 435 insertions(+), 312 deletions(-) rename {presentation/src/main/java/io/chthonic/weather/presentation => app/src/main/java/io/chthonic/weather}/AppContainer.kt (95%) create mode 100644 app/src/main/java/io/chthonic/weather/AppContainerNav.kt rename {presentation/src/main/java/io/chthonic/weather/presentation => app/src/main/java/io/chthonic/weather}/MainActivity.kt (85%) rename {presentation => feature/cityforecast}/.gitignore (100%) rename {presentation => feature/cityforecast}/build.gradle (84%) rename {presentation => feature/cityforecast}/consumer-rules.pro (100%) rename {presentation => feature/cityforecast}/proguard-rules.pro (100%) create mode 100644 feature/cityforecast/src/main/AndroidManifest.xml create mode 100644 feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/AppContainerNav.kt rename presentation/src/main/java/io/chthonic/weather/presentation/nav/Destination.kt => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt (83%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/models/ListUiState.kt (65%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/models/LocationPermissionState.kt (61%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/models/TemperatureUnits.kt (88%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/models/WeatherCondition.kt (94%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/location/DayWeather.kt (70%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/location/LocationDetailScreen.kt (86%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/location/LocationDetailState.kt (60%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/location/LocationDetailViewModel.kt (92%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/locationlist/LocationCurrentWeather.kt (75%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/locationlist/LocationListScreen.kt (90%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/locationlist/LocationListState.kt (60%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/locationlist/LocationListUiStateResolver.kt (75%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/locationlist/LocationListViewModel.kt (97%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/screens/locationlist/NavigationEvent.kt (54%) create mode 100644 feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TempColors.kt rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/widgets/HandleLocationPermissions.kt (92%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/widgets/ListUiStasteContent.kt (87%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/widgets/PermissionDialogs.kt (91%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/widgets/TemperatureText.kt (90%) rename {presentation/src/main/java/io/chthonic/weather/presentation => feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast}/widgets/TemperatureUnitsButton.kt (83%) rename {presentation/src/test/java/io/chthonic/weather/presentation => feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast}/screens/locationlist/LocationListUiStateResolverTest.kt (99%) delete mode 100644 presentation/src/main/AndroidManifest.xml delete mode 100644 presentation/src/main/java/io/chthonic/weather/presentation/AppContainerNav.kt create mode 100644 ui/common/.gitignore create mode 100644 ui/common/build.gradle create mode 100644 ui/common/consumer-rules.pro create mode 100644 ui/common/proguard-rules.pro create mode 100644 ui/common/src/main/AndroidManifest.xml rename {presentation/src/main/java/io/chthonic/weather/presentation => ui/common/src/main/java/io/chthonic/weather/ui/common}/AppContainerState.kt (92%) rename {presentation/src/main/java/io/chthonic/weather/presentation => ui/common/src/main/java/io/chthonic/weather/ui/common}/theme/AppColors.kt (75%) rename {presentation/src/main/java/io/chthonic/weather/presentation => ui/common/src/main/java/io/chthonic/weather/ui/common}/theme/AppShapes.kt (88%) rename {presentation/src/main/java/io/chthonic/weather/presentation => ui/common/src/main/java/io/chthonic/weather/ui/common}/theme/AppTheme.kt (95%) rename {presentation/src/main/java/io/chthonic/weather/presentation => ui/common/src/main/java/io/chthonic/weather/ui/common}/theme/AppTypography.kt (98%) rename {presentation/src/main/java/io/chthonic/weather/presentation => ui/common/src/main/java/io/chthonic/weather/ui/common}/theme/Spacing.kt (87%) rename {presentation/src/main/java/io/chthonic/weather/presentation => ui/common/src/main/java/io/chthonic/weather/ui/common}/widgets/PreviewSharedAnimation.kt (83%) rename {presentation => ui/common}/src/main/res/font/outfit_black.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_bold.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_extrabold.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_extralight.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_light.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_medium.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_regular.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_semibold.ttf (100%) rename {presentation => ui/common}/src/main/res/font/outfit_thin.ttf (100%) rename {presentation => ui/common}/src/main/res/values/strings.xml (100%) diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 680e51f..ee7d32f 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -19,7 +19,10 @@ diff --git a/app/build.gradle b/app/build.gradle index 943be61..f9eae0e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,6 @@ plugins { alias(libs.plugins.androidApp) + alias(libs.plugins.compose.compiler) alias(libs.plugins.ksp) alias(libs.plugins.hilt) alias(libs.plugins.kotlin.parcelize) @@ -59,7 +60,8 @@ dependencies { implementation project(path: ':data:geocoding') implementation project(path: ':data:weather') implementation project(path: ':data:location') - implementation project(path: ':presentation') + implementation project(path: ':ui:common') + implementation project(path: ':feature:cityforecast') // di implementation libs.hilt.android @@ -68,6 +70,16 @@ dependencies { // logging implementation libs.timber + // compose + implementation platform(libs.compose.bom) + implementation libs.compose + implementation libs.compose.material3 + implementation libs.compose.icons.extended + + // navigation + implementation libs.navigation + implementation libs.navigation.compose + // testing testImplementation libs.junit androidTestImplementation libs.androidx.test.ext.junit diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d301bd1..b911d4a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,17 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.RickMortyChars" - android:usesCleartextTraffic="true" /> + android:usesCleartextTraffic="true" > + + + + + + + + + \ No newline at end of file diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/AppContainer.kt b/app/src/main/java/io/chthonic/weather/AppContainer.kt similarity index 95% rename from presentation/src/main/java/io/chthonic/weather/presentation/AppContainer.kt rename to app/src/main/java/io/chthonic/weather/AppContainer.kt index ebca267..90250de 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/AppContainer.kt +++ b/app/src/main/java/io/chthonic/weather/AppContainer.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation +package io.chthonic.weather import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.fillMaxSize @@ -18,7 +18,9 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll -import io.chthonic.weather.presentation.theme.AppColors +import io.chthonic.weather.ui.common.AppBarStyle +import io.chthonic.weather.ui.common.rememberAppContainerState +import io.chthonic.weather.ui.common.theme.AppColors @Composable @OptIn(ExperimentalMaterial3Api::class) diff --git a/app/src/main/java/io/chthonic/weather/AppContainerNav.kt b/app/src/main/java/io/chthonic/weather/AppContainerNav.kt new file mode 100644 index 0000000..98de7b7 --- /dev/null +++ b/app/src/main/java/io/chthonic/weather/AppContainerNav.kt @@ -0,0 +1,25 @@ +package io.chthonic.weather + +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.SharedTransitionLayout +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.navigation.compose.NavHost +import io.chthonic.weather.feature.cityforecast.cityForecastNavGraph +import io.chthonic.weather.feature.cityforecast.CityForecastDestination +import io.chthonic.weather.ui.common.AppContainerState + +@OptIn(ExperimentalSharedTransitionApi::class) +@Composable +fun AppContainerNavHost( + appContainerState: AppContainerState, + modifier: Modifier, +) = SharedTransitionLayout(modifier = modifier) { + NavHost( + navController = appContainerState.navController, + startDestination = CityForecastDestination.LocationList.route, + modifier = Modifier, + ) { + cityForecastNavGraph(appContainerState) + } +} \ No newline at end of file diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/MainActivity.kt b/app/src/main/java/io/chthonic/weather/MainActivity.kt similarity index 85% rename from presentation/src/main/java/io/chthonic/weather/presentation/MainActivity.kt rename to app/src/main/java/io/chthonic/weather/MainActivity.kt index 164b40f..655754a 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/MainActivity.kt +++ b/app/src/main/java/io/chthonic/weather/MainActivity.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation +package io.chthonic.weather import android.os.Bundle import androidx.activity.ComponentActivity @@ -6,7 +6,7 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.isSystemInDarkTheme import dagger.hilt.android.AndroidEntryPoint -import io.chthonic.weather.presentation.theme.AppTheme +import io.chthonic.weather.ui.common.theme.AppTheme @AndroidEntryPoint class MainActivity : ComponentActivity() { diff --git a/presentation/.gitignore b/feature/cityforecast/.gitignore similarity index 100% rename from presentation/.gitignore rename to feature/cityforecast/.gitignore diff --git a/presentation/build.gradle b/feature/cityforecast/build.gradle similarity index 84% rename from presentation/build.gradle rename to feature/cityforecast/build.gradle index c19b154..8ee3392 100644 --- a/presentation/build.gradle +++ b/feature/cityforecast/build.gradle @@ -6,7 +6,7 @@ plugins { } android { - namespace 'io.chthonic.weather.presentation' + namespace 'io.chthonic.weather.feature.cityforecast' compileSdk versions.targetSdk defaultConfig { @@ -16,17 +16,11 @@ android { consumerProguardFiles "consumer-rules.pro" } - viewBinding { - enabled = true - } - buildFeatures { - compose true - } - lint { - targetSdk 36 - } - testOptions { - targetSdk 36 + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } } } @@ -37,6 +31,7 @@ kotlin { dependencies { implementation libs.androidx.core implementation project(path: ':common') + implementation project(path: ':ui:common') implementation project(path: ':domain:presentationapi') // di diff --git a/presentation/consumer-rules.pro b/feature/cityforecast/consumer-rules.pro similarity index 100% rename from presentation/consumer-rules.pro rename to feature/cityforecast/consumer-rules.pro diff --git a/presentation/proguard-rules.pro b/feature/cityforecast/proguard-rules.pro similarity index 100% rename from presentation/proguard-rules.pro rename to feature/cityforecast/proguard-rules.pro diff --git a/feature/cityforecast/src/main/AndroidManifest.xml b/feature/cityforecast/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a5918e6 --- /dev/null +++ b/feature/cityforecast/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/AppContainerNav.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/AppContainerNav.kt new file mode 100644 index 0000000..2e1b209 --- /dev/null +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/AppContainerNav.kt @@ -0,0 +1,43 @@ +package io.chthonic.weather.feature.cityforecast + +import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import io.chthonic.weather.feature.cityforecast.screens.location.LocationDetailScreen +import io.chthonic.weather.feature.cityforecast.screens.locationlist.LocationListScreen +import io.chthonic.weather.ui.common.AppContainerState + +@OptIn(ExperimentalSharedTransitionApi::class) +fun NavGraphBuilder.cityForecastNavGraph( + appContainerState: AppContainerState, +) { + composable( + route = CityForecastDestination.LocationList.route, + ) { + LocationListScreen( + appContainerState = appContainerState, + ) + } + + composable( + route = CityForecastDestination.LocationDetail.route, + arguments = CityForecastDestination.LocationDetail.arguments, + ) { backStackEntry -> + val name = + CityForecastDestination.LocationDetail.getName(backStackEntry.arguments) + ?: return@composable + val lat = + CityForecastDestination.LocationDetail.getLat(backStackEntry.arguments) + ?: return@composable + val lon = + CityForecastDestination.LocationDetail.getLon(backStackEntry.arguments) + ?: return@composable + + LocationDetailScreen( + name = name, + lat = lat, + lon = lon, + appContainerState = appContainerState, + ) + } +} \ No newline at end of file diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/nav/Destination.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt similarity index 83% rename from presentation/src/main/java/io/chthonic/weather/presentation/nav/Destination.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt index cc54e71..042029b 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/nav/Destination.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.nav +package io.chthonic.weather.feature.cityforecast import android.net.Uri import android.os.Bundle @@ -10,12 +10,12 @@ private const val LOC_LAT_ARG: String = "lat" private const val LOC_LON_ARG: String = "lon" private const val LOC_NAME_ARG: String = "name" -sealed class Destination(val route: String, val arguments: List = emptyList()) { +sealed class CityForecastDestination(val route: String, val arguments: List = emptyList()) { - data object LocationList : Destination(route = "locations") + data object LocationList : CityForecastDestination(route = "locations") data object LocationDetail : - Destination( + CityForecastDestination( route = "location/{$LOC_NAME_ARG}/{$LOC_LAT_ARG}/{$LOC_LON_ARG}", arguments = listOf( navArgument(LOC_NAME_ARG) { type = NavType.StringType }, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/models/ListUiState.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/ListUiState.kt similarity index 65% rename from presentation/src/main/java/io/chthonic/weather/presentation/models/ListUiState.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/ListUiState.kt index 526225b..5e729e0 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/models/ListUiState.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/ListUiState.kt @@ -1,6 +1,6 @@ -package io.chthonic.weather.presentation.models +package io.chthonic.weather.feature.cityforecast.models -sealed interface ListUiState { +internal sealed interface ListUiState { data object Idle : ListUiState data object Loading : ListUiState data object Empty : ListUiState diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/models/LocationPermissionState.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/LocationPermissionState.kt similarity index 61% rename from presentation/src/main/java/io/chthonic/weather/presentation/models/LocationPermissionState.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/LocationPermissionState.kt index 1bc4081..322e4d9 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/models/LocationPermissionState.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/LocationPermissionState.kt @@ -1,6 +1,6 @@ -package io.chthonic.weather.presentation.models +package io.chthonic.weather.feature.cityforecast.models -enum class LocationPermissionState { +internal enum class LocationPermissionState { Unknown, // not yet asked Granted, Denied, // denied once, can ask again diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/models/TemperatureUnits.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/TemperatureUnits.kt similarity index 88% rename from presentation/src/main/java/io/chthonic/weather/presentation/models/TemperatureUnits.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/TemperatureUnits.kt index 3d07bce..e54dbf3 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/models/TemperatureUnits.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/TemperatureUnits.kt @@ -1,7 +1,7 @@ -package io.chthonic.weather.presentation.models +package io.chthonic.weather.feature.cityforecast.models -enum class TemperatureUnits { +internal enum class TemperatureUnits { CELSIUS, FAHRENHEIT; diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/models/WeatherCondition.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/WeatherCondition.kt similarity index 94% rename from presentation/src/main/java/io/chthonic/weather/presentation/models/WeatherCondition.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/WeatherCondition.kt index fbd5fb2..1d884e4 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/models/WeatherCondition.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/models/WeatherCondition.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.models +package io.chthonic.weather.feature.cityforecast.models import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.AcUnit @@ -12,7 +12,7 @@ import androidx.compose.material.icons.outlined.WbSunny import androidx.compose.material.icons.outlined.WbTwilight import androidx.compose.ui.graphics.vector.ImageVector -enum class WeatherCondition(val description: String) { +internal enum class WeatherCondition(val description: String) { CLEAR_SKY("Clear sky"), MAINLY_CLEAR("Mainly clear"), PARTLY_CLOUDY("Partly cloudy"), @@ -44,7 +44,7 @@ enum class WeatherCondition(val description: String) { UNKNOWN("Unknown"), } -fun Int.toWeatherCondition(): WeatherCondition = when (this) { +internal fun Int.toWeatherCondition(): WeatherCondition = when (this) { 0 -> WeatherCondition.CLEAR_SKY 1 -> WeatherCondition.MAINLY_CLEAR 2 -> WeatherCondition.PARTLY_CLOUDY @@ -76,7 +76,7 @@ fun Int.toWeatherCondition(): WeatherCondition = when (this) { else -> WeatherCondition.UNKNOWN } -fun WeatherCondition.toIcon(): ImageVector = when (this) { +internal fun WeatherCondition.toIcon(): ImageVector = when (this) { WeatherCondition.CLEAR_SKY -> Icons.Outlined.WbSunny WeatherCondition.MAINLY_CLEAR -> Icons.Outlined.WbSunny WeatherCondition.PARTLY_CLOUDY -> Icons.Outlined.WbCloudy diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/DayWeather.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/DayWeather.kt similarity index 70% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/location/DayWeather.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/DayWeather.kt index 4aac129..a085354 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/DayWeather.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/DayWeather.kt @@ -1,15 +1,15 @@ -package io.chthonic.weather.presentation.screens.location +package io.chthonic.weather.feature.cityforecast.screens.location import androidx.compose.ui.graphics.vector.ImageVector import io.chthonic.weather.common.models.DayForecast -import io.chthonic.weather.presentation.models.WeatherCondition -import io.chthonic.weather.presentation.models.toIcon -import io.chthonic.weather.presentation.models.toWeatherCondition +import io.chthonic.weather.feature.cityforecast.models.WeatherCondition +import io.chthonic.weather.feature.cityforecast.models.toIcon +import io.chthonic.weather.feature.cityforecast.models.toWeatherCondition import java.time.LocalDate import java.time.format.TextStyle import java.util.Locale -class DayWeather( +internal class DayWeather( val date: LocalDate, val weatherCondition: WeatherCondition, val minTemp: Double, @@ -32,7 +32,7 @@ class DayWeather( } } -fun DayForecast.toDayWeather(): DayWeather = DayWeather( +internal fun DayForecast.toDayWeather(): DayWeather = DayWeather( date = date, weatherCondition = weatherCode.toWeatherCondition(), minTemp = minTemp, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailScreen.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailScreen.kt similarity index 86% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailScreen.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailScreen.kt index b25e6b7..672035c 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailScreen.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailScreen.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.screens.location +package io.chthonic.weather.feature.cityforecast.screens.location import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.foundation.background @@ -34,24 +34,24 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import io.chthonic.weather.presentation.AppBarStyle -import io.chthonic.weather.presentation.AppContainerState -import io.chthonic.weather.presentation.models.ListUiState -import io.chthonic.weather.presentation.models.TemperatureUnits -import io.chthonic.weather.presentation.models.WeatherCondition -import io.chthonic.weather.presentation.nav.Destination -import io.chthonic.weather.presentation.theme.AppColors -import io.chthonic.weather.presentation.theme.LocalSpacing -import io.chthonic.weather.presentation.theme.Spacing -import io.chthonic.weather.presentation.widgets.EMPTY_CONTENT_KEY -import io.chthonic.weather.presentation.widgets.ERROR_CONTENT_KEY -import io.chthonic.weather.presentation.widgets.EmptyContent -import io.chthonic.weather.presentation.widgets.ErrorContent -import io.chthonic.weather.presentation.widgets.LOADING_CONTENT_KEY -import io.chthonic.weather.presentation.widgets.LoadingContent -import io.chthonic.weather.presentation.widgets.PreviewSharedAnimation -import io.chthonic.weather.presentation.widgets.TemperatureText -import io.chthonic.weather.presentation.widgets.TemperatureUnitsButton +import io.chthonic.weather.feature.cityforecast.CityForecastDestination +import io.chthonic.weather.feature.cityforecast.models.ListUiState +import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits +import io.chthonic.weather.feature.cityforecast.models.WeatherCondition +import io.chthonic.weather.feature.cityforecast.theme.TempColors +import io.chthonic.weather.feature.cityforecast.widgets.EMPTY_CONTENT_KEY +import io.chthonic.weather.feature.cityforecast.widgets.ERROR_CONTENT_KEY +import io.chthonic.weather.feature.cityforecast.widgets.EmptyContent +import io.chthonic.weather.feature.cityforecast.widgets.ErrorContent +import io.chthonic.weather.feature.cityforecast.widgets.LOADING_CONTENT_KEY +import io.chthonic.weather.feature.cityforecast.widgets.LoadingContent +import io.chthonic.weather.feature.cityforecast.widgets.TemperatureText +import io.chthonic.weather.feature.cityforecast.widgets.TemperatureUnitsButton +import io.chthonic.weather.ui.common.AppBarStyle +import io.chthonic.weather.ui.common.AppContainerState +import io.chthonic.weather.ui.common.theme.LocalSpacing +import io.chthonic.weather.ui.common.theme.Spacing +import io.chthonic.weather.ui.common.widgets.PreviewSharedAnimation import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -59,7 +59,7 @@ import java.time.LocalDate @Composable @OptIn(ExperimentalSharedTransitionApi::class) -fun LocationDetailScreen( +internal fun LocationDetailScreen( name: String, lat: Double, lon: Double, @@ -84,7 +84,7 @@ fun LocationDetailScreen( } } appContainerState.updateAppBarForDestination( - destination = Destination.LocationDetail, + destinationRoute = CityForecastDestination.LocationDetail.route, title = state.value.name, showNavigationIcon = true, style = AppBarStyle.Large, @@ -169,7 +169,7 @@ private fun DayItem( .padding(horizontal = spacing.m, vertical = spacing.xs), shape = MaterialTheme.shapes.large, colors = CardDefaults.cardColors( - containerColor = AppColors.temperatureCardColor(state.maxTemp, isDark), + containerColor = TempColors.temperatureCardColor(state.maxTemp, isDark), ), elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), ) { @@ -184,7 +184,7 @@ private fun DayItem( modifier = Modifier .size(48.dp) .background( - color = AppColors.temperatureIconBoxColor(state.maxTemp, isDark), + color = TempColors.temperatureIconBoxColor(state.maxTemp, isDark), shape = MaterialTheme.shapes.medium, ), ) { @@ -192,7 +192,7 @@ private fun DayItem( imageVector = state.weatherConditionIcon, contentDescription = state.weatherCondition.description, modifier = Modifier.size(28.dp), - tint = AppColors.temperatureIconTint(state.maxTemp, isDark), + tint = TempColors.temperatureIconTint(state.maxTemp, isDark), ) } }, @@ -220,7 +220,7 @@ private fun DayItem( unitsTextStyle = MaterialTheme.typography.titleSmall.copy( fontWeight = FontWeight.Medium, ), - color = AppColors.temperatureTextColor(state.maxTemp, isDark), + color = TempColors.temperatureTextColor(state.maxTemp, isDark), ) TemperatureText( temperature = state.minTemp, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailState.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailState.kt similarity index 60% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailState.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailState.kt index 5f0ed21..bb3dca8 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailState.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailState.kt @@ -1,11 +1,11 @@ -package io.chthonic.weather.presentation.screens.location +package io.chthonic.weather.feature.cityforecast.screens.location -import io.chthonic.weather.presentation.models.ListUiState -import io.chthonic.weather.presentation.models.TemperatureUnits +import io.chthonic.weather.feature.cityforecast.models.ListUiState +import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -data class LocationDetailState( +internal data class LocationDetailState( val name: String, val lat: Double, val lon: Double, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailViewModel.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailViewModel.kt similarity index 92% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailViewModel.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailViewModel.kt index 638337b..c64b3d0 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/location/LocationDetailViewModel.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailViewModel.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.screens.location +package io.chthonic.weather.feature.cityforecast.screens.location import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -8,7 +8,7 @@ import dagger.assisted.AssistedInject import dagger.hilt.android.lifecycle.HiltViewModel import io.chthonic.weather.common.models.Outcome import io.chthonic.weather.domain.presentationapi.WeatherRepo -import io.chthonic.weather.presentation.models.ListUiState +import io.chthonic.weather.feature.cityforecast.models.ListUiState import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -17,7 +17,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @HiltViewModel(assistedFactory = LocationDetailViewModel.LocationDetailViewModelFactory::class) -class LocationDetailViewModel @AssistedInject constructor( +internal class LocationDetailViewModel @AssistedInject constructor( @Assisted("name") name: String, @Assisted("lat") lat: Double, @Assisted("lon") lon: Double, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationCurrentWeather.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationCurrentWeather.kt similarity index 75% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationCurrentWeather.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationCurrentWeather.kt index 0a230fa..349f701 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationCurrentWeather.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationCurrentWeather.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.locationlist import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ErrorOutline @@ -6,10 +6,10 @@ import androidx.compose.material.icons.outlined.HourglassEmpty import androidx.compose.ui.graphics.vector.ImageVector import io.chthonic.weather.common.models.GeocodingCity import io.chthonic.weather.common.models.Location -import io.chthonic.weather.presentation.models.WeatherCondition -import io.chthonic.weather.presentation.models.toIcon +import io.chthonic.weather.feature.cityforecast.models.WeatherCondition +import io.chthonic.weather.feature.cityforecast.models.toIcon -data class LocationCurrentWeather( +internal data class LocationCurrentWeather( val location: Location, val displayName: String, val weatherCondition: WeatherCondition? = null, @@ -38,7 +38,7 @@ data class LocationCurrentWeather( ?: Icons.Outlined.HourglassEmpty } -fun GeocodingCity.toLocationCurrentWeather(): LocationCurrentWeather = LocationCurrentWeather( +internal fun GeocodingCity.toLocationCurrentWeather(): LocationCurrentWeather = LocationCurrentWeather( location = location, displayName = displayName, ) \ No newline at end of file diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListScreen.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListScreen.kt similarity index 90% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListScreen.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListScreen.kt index cda8cd0..70a895b 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListScreen.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListScreen.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.locationlist import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.ExperimentalSharedTransitionApi @@ -56,35 +56,35 @@ import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.lifecycle.compose.collectAsStateWithLifecycle import io.chthonic.weather.common.models.Location import io.chthonic.weather.common.models.Location.Companion.UNKNOWN_COORD -import io.chthonic.weather.presentation.AppBarStyle -import io.chthonic.weather.presentation.AppContainerState -import io.chthonic.weather.presentation.R -import io.chthonic.weather.presentation.models.ListUiState -import io.chthonic.weather.presentation.models.TemperatureUnits -import io.chthonic.weather.presentation.models.WeatherCondition -import io.chthonic.weather.presentation.nav.Destination -import io.chthonic.weather.presentation.theme.AppColors -import io.chthonic.weather.presentation.theme.LocalSpacing -import io.chthonic.weather.presentation.theme.Spacing -import io.chthonic.weather.presentation.widgets.EMPTY_CONTENT_KEY -import io.chthonic.weather.presentation.widgets.ERROR_CONTENT_KEY -import io.chthonic.weather.presentation.widgets.EmptyContent -import io.chthonic.weather.presentation.widgets.ErrorContent -import io.chthonic.weather.presentation.widgets.HandleLocationPermissionState -import io.chthonic.weather.presentation.widgets.IDLE_CONTENT_KEY -import io.chthonic.weather.presentation.widgets.LOADING_CONTENT_KEY -import io.chthonic.weather.presentation.widgets.LoadingContent -import io.chthonic.weather.presentation.widgets.PreviewSharedAnimation -import io.chthonic.weather.presentation.widgets.TemperatureText -import io.chthonic.weather.presentation.widgets.TemperatureUnitsButton -import io.chthonic.weather.presentation.widgets.checkLocationPermission +import io.chthonic.weather.feature.cityforecast.CityForecastDestination +import io.chthonic.weather.feature.cityforecast.models.ListUiState +import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits +import io.chthonic.weather.feature.cityforecast.models.WeatherCondition +import io.chthonic.weather.feature.cityforecast.theme.TempColors +import io.chthonic.weather.feature.cityforecast.widgets.EMPTY_CONTENT_KEY +import io.chthonic.weather.feature.cityforecast.widgets.ERROR_CONTENT_KEY +import io.chthonic.weather.feature.cityforecast.widgets.EmptyContent +import io.chthonic.weather.feature.cityforecast.widgets.ErrorContent +import io.chthonic.weather.feature.cityforecast.widgets.HandleLocationPermissionState +import io.chthonic.weather.feature.cityforecast.widgets.IDLE_CONTENT_KEY +import io.chthonic.weather.feature.cityforecast.widgets.LOADING_CONTENT_KEY +import io.chthonic.weather.feature.cityforecast.widgets.LoadingContent +import io.chthonic.weather.feature.cityforecast.widgets.TemperatureText +import io.chthonic.weather.feature.cityforecast.widgets.TemperatureUnitsButton +import io.chthonic.weather.feature.cityforecast.widgets.checkLocationPermission +import io.chthonic.weather.ui.common.AppBarStyle +import io.chthonic.weather.ui.common.AppContainerState +import io.chthonic.weather.ui.common.R +import io.chthonic.weather.ui.common.theme.LocalSpacing +import io.chthonic.weather.ui.common.theme.Spacing +import io.chthonic.weather.ui.common.widgets.PreviewSharedAnimation import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @Composable @OptIn(ExperimentalSharedTransitionApi::class) -fun LocationListScreen( +internal fun LocationListScreen( viewModel: LocationListViewModel = hiltViewModel(), appContainerState: AppContainerState, ) { @@ -101,7 +101,7 @@ fun LocationListScreen( } } appContainerState.updateAppBarForDestination( - destination = Destination.LocationList, + destinationRoute = CityForecastDestination.LocationList.route, title = context.resources.getString(R.string.app_name), showNavigationIcon = false, style = AppBarStyle.Pinned, @@ -113,7 +113,7 @@ fun LocationListScreen( when (event) { is NavigationEvent.ToLocationDetail -> { appContainerState.navController.navigate( - Destination.LocationDetail.buildUniqueRoute( + CityForecastDestination.LocationDetail.buildUniqueRoute( name = event.name, lat = event.lat, lon = event.lon, @@ -279,7 +279,7 @@ private fun WeatherLocationItem( .padding(horizontal = spacing.m, vertical = spacing.xs), shape = MaterialTheme.shapes.large, colors = CardDefaults.cardColors( - containerColor = AppColors.temperatureCardColor(state.temp, isDark), + containerColor = TempColors.temperatureCardColor(state.temp, isDark), ), elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), ) { @@ -294,7 +294,7 @@ private fun WeatherLocationItem( modifier = Modifier .size(48.dp) .background( - color = AppColors.temperatureIconBoxColor(state.temp, isDark), + color = TempColors.temperatureIconBoxColor(state.temp, isDark), shape = MaterialTheme.shapes.medium, ), ) { @@ -302,7 +302,7 @@ private fun WeatherLocationItem( state.displayIcon, contentDescription = state.weatherCondition?.description, modifier = Modifier.size(28.dp), - tint = AppColors.temperatureIconTint(state.temp, isDark), + tint = TempColors.temperatureIconTint(state.temp, isDark), ) if (isMyLocation) { @@ -349,7 +349,7 @@ private fun WeatherLocationItem( TemperatureText( temperature = state.temp, units = units, - color = AppColors.temperatureTextColor(state.temp, isDark), + color = TempColors.temperatureTextColor(state.temp, isDark), valueTextStyle = MaterialTheme.typography.displaySmall.copy( fontFamily = FontFamily.Monospace, fontFeatureSettings = "tnum", // tabular numbers diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListState.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListState.kt similarity index 60% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListState.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListState.kt index f6c8497..b5b08f5 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListState.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListState.kt @@ -1,12 +1,12 @@ -package io.chthonic.weather.presentation.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.locationlist -import io.chthonic.weather.presentation.models.ListUiState -import io.chthonic.weather.presentation.models.LocationPermissionState -import io.chthonic.weather.presentation.models.TemperatureUnits +import io.chthonic.weather.feature.cityforecast.models.ListUiState +import io.chthonic.weather.feature.cityforecast.models.LocationPermissionState +import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -data class LocationListState( +internal data class LocationListState( val listUiState: ListUiState = ListUiState.Idle, val locationPermissionState: LocationPermissionState = LocationPermissionState.Unknown, val searchText: String = "", diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListUiStateResolver.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolver.kt similarity index 75% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListUiStateResolver.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolver.kt index debd82f..1a364e8 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListUiStateResolver.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolver.kt @@ -1,10 +1,10 @@ -package io.chthonic.weather.presentation.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.locationlist import io.chthonic.weather.common.models.Outcome -import io.chthonic.weather.presentation.models.ListUiState +import io.chthonic.weather.feature.cityforecast.models.ListUiState import javax.inject.Inject -class LocationListUiStateResolver @Inject constructor() { +internal class LocationListUiStateResolver @Inject constructor() { fun resolveOnSearchAction(query: String): ListUiState = if (query.isBlank()) ListUiState.Idle else ListUiState.Loading diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListViewModel.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListViewModel.kt similarity index 97% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListViewModel.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListViewModel.kt index 2dbaccd..17ed18e 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/LocationListViewModel.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListViewModel.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.locationlist import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -9,8 +9,8 @@ import io.chthonic.weather.common.models.Outcome import io.chthonic.weather.domain.presentationapi.GeocodingRepo import io.chthonic.weather.domain.presentationapi.LocationRepo import io.chthonic.weather.domain.presentationapi.WeatherRepo -import io.chthonic.weather.presentation.models.LocationPermissionState -import io.chthonic.weather.presentation.models.toWeatherCondition +import io.chthonic.weather.feature.cityforecast.models.LocationPermissionState +import io.chthonic.weather.feature.cityforecast.models.toWeatherCondition import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -38,7 +38,7 @@ private const val MY_LOCATION_DISPLAY_NAME = "MY LOCATION" @OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @HiltViewModel -class LocationListViewModel @Inject constructor( +internal class LocationListViewModel @Inject constructor( private val geocodingRepo: GeocodingRepo, private val weatherRepo: WeatherRepo, private val locationRepo: LocationRepo, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/NavigationEvent.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/NavigationEvent.kt similarity index 54% rename from presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/NavigationEvent.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/NavigationEvent.kt index 9522956..1dc9be3 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/screens/locationlist/NavigationEvent.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/NavigationEvent.kt @@ -1,6 +1,6 @@ -package io.chthonic.weather.presentation.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.locationlist -sealed interface NavigationEvent { +internal sealed interface NavigationEvent { data class ToLocationDetail( val name: String, val lat: Double, diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TempColors.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TempColors.kt new file mode 100644 index 0000000..73679ee --- /dev/null +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TempColors.kt @@ -0,0 +1,84 @@ +package io.chthonic.weather.feature.cityforecast.theme + +import androidx.compose.ui.graphics.Color + +object TempColors { + // ───────────────────────────────────────────────────────────────────────────── + // TEMPERATURE CARD COLOR + // Call this to get the card containerColor based on celsius temperature. + // These are the exact card bg hex values from the demo. + // ───────────────────────────────────────────────────────────────────────────── + + fun temperatureCardColor(celsius: Double?, isDark: Boolean): Color = + if (isDark) { + temperatureCardColorDark(celsius) + } else { + temperatureCardColorLight(celsius) + } + + fun temperatureCardColorDark(celsius: Double?): Color = when { + celsius == null -> Color(0xFF201808) // neutral warm dark — surfaceContainerHigh + celsius < 0 -> Color(0xFF0A2A38) // deep blue — freezing + celsius < 14 -> Color(0xFF0E3028) // teal — cool (demo exact) + celsius < 24 -> Color(0xFF201808) // neutral warm — mild + celsius < 32 -> Color(0xFF4A3C14) // amber — hot (demo exact) + else -> Color(0xFF380E08) // red — extreme (demo exact) + } + + fun temperatureCardColorLight(celsius: Double?): Color = when { + celsius == null -> Color(0xFFF5EFE4) // neutral parchment + celsius < 0 -> Color(0xFFE8F0EE) // very faint teal tint + celsius < 14 -> Color(0xFFECF0EE) // faint teal + celsius < 24 -> Color(0xFFF5EFE4) // neutral — mild + celsius < 32 -> Color(0xFFF5EDE0) // faint amber tint + else -> Color(0xFFF5E8E0) // faint coral tint + } + + // Icon box colors per temperature + fun temperatureIconBoxColor(celsius: Double?, isDark: Boolean): Color = + if (isDark) { + temperatureIconBoxColorDark(celsius) + } else { + temperatureIconBoxColorLight(celsius) + } + + fun temperatureIconBoxColorDark(celsius: Double?): Color = when { + celsius == null -> Color(0xFF2A2010) // neutral, no hue + celsius < 14 -> Color(0xFF143C30) // demo: teal icon box dark + celsius < 32 -> Color(0xFF5A4818) // demo: amber icon box dark + else -> Color(0xFF481408) // demo: red icon box dark + } + + fun temperatureIconBoxColorLight(celsius: Double?): Color = when { + celsius == null -> Color(0xFFE0D8C8) // neutral — matches search bar, no hue + celsius < 14 -> Color(0xFFB8E0D4) // demo: seafoam icon box light + celsius < 32 -> Color(0xFFF0D090) // demo: golden icon box light + else -> Color(0xFFF0B898) // demo: coral icon box light + } + + // Temperature text color + fun temperatureTextColor(celsius: Double?, isDark: Boolean): Color = + if (isDark) { + temperatureTextColorDark(celsius) + } else { + temperatureTextColorLight(celsius) + } + + fun temperatureTextColorDark(celsius: Double?): Color = when { + celsius == null -> Color(0xFFA08850) // muted coords color — unobtrusive + celsius < 14 -> Color(0xFF50C0A8) // demo: teal + celsius < 32 -> Color(0xFFF0A030) // demo: amber + else -> Color(0xFFE05030) // demo: red + } + + fun temperatureTextColorLight(celsius: Double?): Color = when { + celsius == null -> Color(0xFFA08860) // muted coords color — unobtrusive + celsius < 14 -> Color(0xFF207868) // demo: deep teal + celsius < 32 -> Color(0xFFB86810) // demo: deep amber + else -> Color(0xFFC04020) // demo: deep red + } + + // Temperature Icon color + fun temperatureIconTint(celsius: Double?, isDark: Boolean): Color = + temperatureTextColor(celsius, isDark) +} \ No newline at end of file diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/HandleLocationPermissions.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/HandleLocationPermissions.kt similarity index 92% rename from presentation/src/main/java/io/chthonic/weather/presentation/widgets/HandleLocationPermissions.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/HandleLocationPermissions.kt index f28e421..012f367 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/HandleLocationPermissions.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/HandleLocationPermissions.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.widgets +package io.chthonic.weather.feature.cityforecast.widgets import android.Manifest import android.app.Activity @@ -15,9 +15,9 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import androidx.core.app.ActivityCompat -import io.chthonic.weather.presentation.models.LocationPermissionState +import io.chthonic.weather.feature.cityforecast.models.LocationPermissionState -fun Context.checkLocationPermission(onGranted: () -> Unit) { +internal fun Context.checkLocationPermission(onGranted: () -> Unit) { val granted = ActivityCompat.checkSelfPermission( this, Manifest.permission.ACCESS_FINE_LOCATION, @@ -31,7 +31,7 @@ fun Context.checkLocationPermission(onGranted: () -> Unit) { } @Composable -fun rememberLocationPermissionLauncher( +internal fun rememberLocationPermissionLauncher( onGranted: () -> Unit, onDenied: (isPermanent: Boolean) -> Unit, ): ManagedActivityResultLauncher, Map> { @@ -63,7 +63,7 @@ private val locationPermissions = arrayOf( ) @Composable -fun RequestLocationPermission( +internal fun RequestLocationPermission( permissionLauncher: ManagedActivityResultLauncher, Map>, onGranted: () -> Unit ) { @@ -87,7 +87,7 @@ fun RequestLocationPermission( } @Composable -fun HandleLocationPermissionState( +internal fun HandleLocationPermissionState( locationPermissionState: LocationPermissionState, onGranted: () -> Unit, onDenied: (isPermanent: Boolean) -> Unit, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/ListUiStasteContent.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/ListUiStasteContent.kt similarity index 87% rename from presentation/src/main/java/io/chthonic/weather/presentation/widgets/ListUiStasteContent.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/ListUiStasteContent.kt index 6227b4e..bd3dabe 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/ListUiStasteContent.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/ListUiStasteContent.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.widgets +package io.chthonic.weather.feature.cityforecast.widgets import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat @@ -24,18 +24,18 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import io.chthonic.weather.presentation.theme.Spacing +import io.chthonic.weather.ui.common.theme.Spacing -const val EMPTY_CONTENT_KEY = "EmptyContent" -const val IDLE_CONTENT_KEY = "IdleContent" -const val ERROR_CONTENT_KEY = "ErrorContent" -const val LOADING_CONTENT_KEY = "LoadingContent" +internal const val EMPTY_CONTENT_KEY = "EmptyContent" +internal const val IDLE_CONTENT_KEY = "IdleContent" +internal const val ERROR_CONTENT_KEY = "ErrorContent" +internal const val LOADING_CONTENT_KEY = "LoadingContent" @Composable -fun contentColor() = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f) +internal fun contentColor() = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.4f) @Composable -fun EmptyContent( +internal fun EmptyContent( spacing: Spacing, modifier: Modifier = Modifier, text: String = "No cities match your search.", @@ -65,7 +65,7 @@ fun EmptyContent( } @Composable -fun ErrorContent( +internal fun ErrorContent( text: String = "Error: something went wrong.", spacing: Spacing, modifier: Modifier = Modifier, @@ -94,7 +94,7 @@ fun ErrorContent( } @Composable -fun LoadingContent(spacing: Spacing, modifier: Modifier = Modifier) { +internal fun LoadingContent(spacing: Spacing, modifier: Modifier = Modifier) { Column( modifier = modifier.fillMaxWidth(), verticalArrangement = Arrangement.Center, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/PermissionDialogs.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/PermissionDialogs.kt similarity index 91% rename from presentation/src/main/java/io/chthonic/weather/presentation/widgets/PermissionDialogs.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/PermissionDialogs.kt index 1e4e121..f506617 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/PermissionDialogs.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/PermissionDialogs.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.widgets +package io.chthonic.weather.feature.cityforecast.widgets import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.width @@ -12,10 +12,10 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import io.chthonic.weather.presentation.theme.LocalSpacing +import io.chthonic.weather.ui.common.theme.LocalSpacing @Composable -fun DeniedPermissionDialog( +internal fun DeniedPermissionDialog( onRetry: () -> Unit, onDismiss: () -> Unit, ) { @@ -47,7 +47,7 @@ fun DeniedPermissionDialog( } @Composable -fun PermanentlyDeniedPermissionDialog( +internal fun PermanentlyDeniedPermissionDialog( onOpenSettings: () -> Unit, onDismiss: () -> Unit, ) { diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/TemperatureText.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/TemperatureText.kt similarity index 90% rename from presentation/src/main/java/io/chthonic/weather/presentation/widgets/TemperatureText.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/TemperatureText.kt index e945a35..77b5eb4 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/TemperatureText.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/TemperatureText.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.widgets +package io.chthonic.weather.feature.cityforecast.widgets import androidx.compose.animation.AnimatedContent import androidx.compose.animation.fadeIn @@ -14,12 +14,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle -import io.chthonic.weather.presentation.models.TemperatureUnits -import io.chthonic.weather.presentation.models.cToF +import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits +import io.chthonic.weather.feature.cityforecast.models.cToF import kotlin.math.roundToInt @Composable -fun TemperatureText( +internal fun TemperatureText( temperature: Double?, units: TemperatureUnits, color: Color, diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/TemperatureUnitsButton.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/TemperatureUnitsButton.kt similarity index 83% rename from presentation/src/main/java/io/chthonic/weather/presentation/widgets/TemperatureUnitsButton.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/TemperatureUnitsButton.kt index da009c7..cb5a38e 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/TemperatureUnitsButton.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/widgets/TemperatureUnitsButton.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.widgets +package io.chthonic.weather.feature.cityforecast.widgets import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.sizeIn @@ -10,11 +10,11 @@ import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import io.chthonic.weather.presentation.models.TemperatureUnits -import io.chthonic.weather.presentation.theme.AppColors +import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits +import io.chthonic.weather.ui.common.theme.AppColors @Composable -fun TemperatureUnitsButton( +internal fun TemperatureUnitsButton( temperatureUnits: TemperatureUnits, onToggleTemperatureUnits: () -> Unit, ) { diff --git a/presentation/src/test/java/io/chthonic/weather/presentation/screens/locationlist/LocationListUiStateResolverTest.kt b/feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolverTest.kt similarity index 99% rename from presentation/src/test/java/io/chthonic/weather/presentation/screens/locationlist/LocationListUiStateResolverTest.kt rename to feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolverTest.kt index 8df378c..b420c32 100644 --- a/presentation/src/test/java/io/chthonic/weather/presentation/screens/locationlist/LocationListUiStateResolverTest.kt +++ b/feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolverTest.kt @@ -1,8 +1,8 @@ -package io.chthonic.weather.presentation.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.locationlist import io.chthonic.weather.common.models.Location import io.chthonic.weather.common.models.Outcome -import io.chthonic.weather.presentation.models.ListUiState +import io.chthonic.weather.feature.cityforecast.models.ListUiState import junit.framework.TestCase.assertEquals import org.junit.Before import org.junit.Test diff --git a/presentation/src/main/AndroidManifest.xml b/presentation/src/main/AndroidManifest.xml deleted file mode 100644 index f9294a2..0000000 --- a/presentation/src/main/AndroidManifest.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/AppContainerNav.kt b/presentation/src/main/java/io/chthonic/weather/presentation/AppContainerNav.kt deleted file mode 100644 index 57c2c57..0000000 --- a/presentation/src/main/java/io/chthonic/weather/presentation/AppContainerNav.kt +++ /dev/null @@ -1,54 +0,0 @@ -package io.chthonic.weather.presentation - -import androidx.compose.animation.ExperimentalSharedTransitionApi -import androidx.compose.animation.SharedTransitionLayout -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import io.chthonic.weather.presentation.nav.Destination -import io.chthonic.weather.presentation.screens.location.LocationDetailScreen -import io.chthonic.weather.presentation.screens.locationlist.LocationListScreen - -@OptIn(ExperimentalSharedTransitionApi::class) -@Composable -fun AppContainerNavHost( - appContainerState: AppContainerState, - modifier: Modifier, -) = SharedTransitionLayout(modifier = modifier) { - NavHost( - navController = appContainerState.navController, - startDestination = Destination.LocationList.route, - modifier = Modifier, - ) { - composable( - route = Destination.LocationList.route, - ) { - LocationListScreen( - appContainerState = appContainerState, - ) - } - - composable( - route = Destination.LocationDetail.route, - arguments = Destination.LocationDetail.arguments, - ) { backStackEntry -> - val name = - Destination.LocationDetail.getName(backStackEntry.arguments) - ?: return@composable - val lat = - Destination.LocationDetail.getLat(backStackEntry.arguments) - ?: return@composable - val lon = - Destination.LocationDetail.getLon(backStackEntry.arguments) - ?: return@composable - - LocationDetailScreen( - name = name, - lat = lat, - lon = lon, - appContainerState = appContainerState, - ) - } - } -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 407748f..a065867 100644 --- a/settings.gradle +++ b/settings.gradle @@ -21,9 +21,12 @@ include ':data' include ':domain' include ':domain:dataapi' include ':domain:presentationapi' -include ':presentation' +include ':ui' +include ':ui:common' include ':data:common' include ':data:geocoding' include ':common' include ':data:weather' include ':data:location' +include ':feature' +include ':feature:cityforecast' diff --git a/ui/common/.gitignore b/ui/common/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/ui/common/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/ui/common/build.gradle b/ui/common/build.gradle new file mode 100644 index 0000000..9b8c0b9 --- /dev/null +++ b/ui/common/build.gradle @@ -0,0 +1,67 @@ +plugins { + alias(libs.plugins.androidLibrary) + alias(libs.plugins.compose.compiler) + alias(libs.plugins.ksp) + alias(libs.plugins.hilt) +} + +android { + namespace 'io.chthonic.weather.ui.common' + compileSdk versions.targetSdk + + defaultConfig { + minSdk versions.minSdk + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + viewBinding { + enabled = true + } + buildFeatures { + compose true + } + lint { + targetSdk versions.targetSdk + } + testOptions { + targetSdk versions.targetSdk + } +} + +kotlin { + jvmToolchain(libs.versions.jvmTarget.get().toInteger()) +} + +dependencies { + implementation libs.androidx.core + + // di + implementation libs.hilt.android + ksp libs.hilt.android.compiler + implementation libs.hilt.navigation.compose + + // compose + implementation platform(libs.compose.bom) + implementation libs.compose + implementation libs.compose.material3 + implementation libs.compose.icons.extended + implementation libs.compose.tooling.preview + debugImplementation libs.compose.tooling + implementation libs.compose.lifecycle.runtime + + // navigation + implementation libs.navigation + implementation libs.navigation.compose + + // coroutines, flow + implementation libs.coroutines.core + implementation libs.coroutines.android + + // logging + implementation libs.timber + + // testing + testImplementation libs.junit +} \ No newline at end of file diff --git a/ui/common/consumer-rules.pro b/ui/common/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/ui/common/proguard-rules.pro b/ui/common/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/ui/common/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/ui/common/src/main/AndroidManifest.xml b/ui/common/src/main/AndroidManifest.xml new file mode 100644 index 0000000..fa57d87 --- /dev/null +++ b/ui/common/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/AppContainerState.kt b/ui/common/src/main/java/io/chthonic/weather/ui/common/AppContainerState.kt similarity index 92% rename from presentation/src/main/java/io/chthonic/weather/presentation/AppContainerState.kt rename to ui/common/src/main/java/io/chthonic/weather/ui/common/AppContainerState.kt index 2c97f80..15a5d86 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/AppContainerState.kt +++ b/ui/common/src/main/java/io/chthonic/weather/ui/common/AppContainerState.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation +package io.chthonic.weather.ui.common import androidx.compose.foundation.layout.RowScope import androidx.compose.material3.SnackbarDuration @@ -13,7 +13,6 @@ import androidx.compose.runtime.setValue import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import io.chthonic.weather.presentation.nav.Destination import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -37,14 +36,14 @@ class AppContainerState( @Composable fun updateAppBarForDestination( - destination: Destination, // prevent screens/destinations fighting over state during transitions + destinationRoute: String, // prevent screens/destinations fighting over state during transitions title: String? = null, showNavigationIcon: Boolean = false, style: AppBarStyle = AppBarStyle.Pinned, actions: (@Composable RowScope.() -> Unit)? = null, ) { val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route - if (currentRoute != destination.route) return + if (currentRoute != destinationRoute) return appBarTitle = title appBarStyle = style diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppColors.kt b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppColors.kt similarity index 75% rename from presentation/src/main/java/io/chthonic/weather/presentation/theme/AppColors.kt rename to ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppColors.kt index 212c0f0..e00f745 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppColors.kt +++ b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppColors.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.theme +package io.chthonic.weather.ui.common.theme import androidx.compose.material3.ColorScheme import androidx.compose.material3.MaterialTheme @@ -124,85 +124,6 @@ object AppColors { val Scrim = Color(0xFF000000) - // ───────────────────────────────────────────────────────────────────────────── - // TEMPERATURE CARD COLOR - // Call this to get the card containerColor based on celsius temperature. - // These are the exact card bg hex values from the demo. - // ───────────────────────────────────────────────────────────────────────────── - - fun temperatureCardColor(celsius: Double?, isDark: Boolean): Color = - if (isDark) { - temperatureCardColorDark(celsius) - } else { - temperatureCardColorLight(celsius) - } - - fun temperatureCardColorDark(celsius: Double?): Color = when { - celsius == null -> Color(0xFF201808) // neutral warm dark — surfaceContainerHigh - celsius < 0 -> Color(0xFF0A2A38) // deep blue — freezing - celsius < 14 -> Color(0xFF0E3028) // teal — cool (demo exact) - celsius < 24 -> Color(0xFF201808) // neutral warm — mild - celsius < 32 -> Color(0xFF4A3C14) // amber — hot (demo exact) - else -> Color(0xFF380E08) // red — extreme (demo exact) - } - - fun temperatureCardColorLight(celsius: Double?): Color = when { - celsius == null -> Color(0xFFF5EFE4) // neutral parchment - celsius < 0 -> Color(0xFFE8F0EE) // very faint teal tint - celsius < 14 -> Color(0xFFECF0EE) // faint teal - celsius < 24 -> Color(0xFFF5EFE4) // neutral — mild - celsius < 32 -> Color(0xFFF5EDE0) // faint amber tint - else -> Color(0xFFF5E8E0) // faint coral tint - } - - // Icon box colors per temperature - fun temperatureIconBoxColor(celsius: Double?, isDark: Boolean): Color = - if (isDark) { - temperatureIconBoxColorDark(celsius) - } else { - temperatureIconBoxColorLight(celsius) - } - - fun temperatureIconBoxColorDark(celsius: Double?): Color = when { - celsius == null -> Color(0xFF2A2010) // neutral, no hue - celsius < 14 -> Color(0xFF143C30) // demo: teal icon box dark - celsius < 32 -> Color(0xFF5A4818) // demo: amber icon box dark - else -> Color(0xFF481408) // demo: red icon box dark - } - - fun temperatureIconBoxColorLight(celsius: Double?): Color = when { - celsius == null -> Color(0xFFE0D8C8) // neutral — matches search bar, no hue - celsius < 14 -> Color(0xFFB8E0D4) // demo: seafoam icon box light - celsius < 32 -> Color(0xFFF0D090) // demo: golden icon box light - else -> Color(0xFFF0B898) // demo: coral icon box light - } - - // Temperature text color - fun temperatureTextColor(celsius: Double?, isDark: Boolean): Color = - if (isDark) { - temperatureTextColorDark(celsius) - } else { - temperatureTextColorLight(celsius) - } - - fun temperatureTextColorDark(celsius: Double?): Color = when { - celsius == null -> Color(0xFFA08850) // muted coords color — unobtrusive - celsius < 14 -> Color(0xFF50C0A8) // demo: teal - celsius < 32 -> Color(0xFFF0A030) // demo: amber - else -> Color(0xFFE05030) // demo: red - } - - fun temperatureTextColorLight(celsius: Double?): Color = when { - celsius == null -> Color(0xFFA08860) // muted coords color — unobtrusive - celsius < 14 -> Color(0xFF207868) // demo: deep teal - celsius < 32 -> Color(0xFFB86810) // demo: deep amber - else -> Color(0xFFC04020) // demo: deep red - } - - // Temperature Icon color - fun temperatureIconTint(celsius: Double?, isDark: Boolean): Color = - temperatureTextColor(celsius, isDark) - @Composable fun appBarContainerColor(isDark: Boolean) = if (isDark) { MaterialTheme.colorScheme.primaryContainer diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppShapes.kt b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppShapes.kt similarity index 88% rename from presentation/src/main/java/io/chthonic/weather/presentation/theme/AppShapes.kt rename to ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppShapes.kt index b30c5a2..a6312b5 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppShapes.kt +++ b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppShapes.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.theme +package io.chthonic.weather.ui.common.theme import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Shapes diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppTheme.kt b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppTheme.kt similarity index 95% rename from presentation/src/main/java/io/chthonic/weather/presentation/theme/AppTheme.kt rename to ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppTheme.kt index b689a43..75cf37c 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppTheme.kt +++ b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppTheme.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.theme +package io.chthonic.weather.ui.common.theme import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppTypography.kt b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppTypography.kt similarity index 98% rename from presentation/src/main/java/io/chthonic/weather/presentation/theme/AppTypography.kt rename to ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppTypography.kt index 889a4ff..6b57260 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/theme/AppTypography.kt +++ b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/AppTypography.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.theme +package io.chthonic.weather.ui.common.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle @@ -6,7 +6,7 @@ import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp -import io.chthonic.weather.presentation.R +import io.chthonic.weather.ui.common.R val AppTypography: Typography by lazy { diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/theme/Spacing.kt b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/Spacing.kt similarity index 87% rename from presentation/src/main/java/io/chthonic/weather/presentation/theme/Spacing.kt rename to ui/common/src/main/java/io/chthonic/weather/ui/common/theme/Spacing.kt index f171679..2e9b1ed 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/theme/Spacing.kt +++ b/ui/common/src/main/java/io/chthonic/weather/ui/common/theme/Spacing.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.theme +package io.chthonic.weather.ui.common.theme import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.unit.Dp diff --git a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/PreviewSharedAnimation.kt b/ui/common/src/main/java/io/chthonic/weather/ui/common/widgets/PreviewSharedAnimation.kt similarity index 83% rename from presentation/src/main/java/io/chthonic/weather/presentation/widgets/PreviewSharedAnimation.kt rename to ui/common/src/main/java/io/chthonic/weather/ui/common/widgets/PreviewSharedAnimation.kt index c2c7912..2ae54c5 100644 --- a/presentation/src/main/java/io/chthonic/weather/presentation/widgets/PreviewSharedAnimation.kt +++ b/ui/common/src/main/java/io/chthonic/weather/ui/common/widgets/PreviewSharedAnimation.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.presentation.widgets +package io.chthonic.weather.ui.common.widgets import android.annotation.SuppressLint import androidx.compose.animation.AnimatedContent @@ -6,9 +6,8 @@ import androidx.compose.animation.AnimatedContentScope import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.SharedTransitionLayout import androidx.compose.animation.SharedTransitionScope -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import io.chthonic.weather.presentation.theme.AppTheme +import io.chthonic.weather.ui.common.theme.AppTheme @Composable @OptIn(ExperimentalSharedTransitionApi::class) diff --git a/presentation/src/main/res/font/outfit_black.ttf b/ui/common/src/main/res/font/outfit_black.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_black.ttf rename to ui/common/src/main/res/font/outfit_black.ttf diff --git a/presentation/src/main/res/font/outfit_bold.ttf b/ui/common/src/main/res/font/outfit_bold.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_bold.ttf rename to ui/common/src/main/res/font/outfit_bold.ttf diff --git a/presentation/src/main/res/font/outfit_extrabold.ttf b/ui/common/src/main/res/font/outfit_extrabold.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_extrabold.ttf rename to ui/common/src/main/res/font/outfit_extrabold.ttf diff --git a/presentation/src/main/res/font/outfit_extralight.ttf b/ui/common/src/main/res/font/outfit_extralight.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_extralight.ttf rename to ui/common/src/main/res/font/outfit_extralight.ttf diff --git a/presentation/src/main/res/font/outfit_light.ttf b/ui/common/src/main/res/font/outfit_light.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_light.ttf rename to ui/common/src/main/res/font/outfit_light.ttf diff --git a/presentation/src/main/res/font/outfit_medium.ttf b/ui/common/src/main/res/font/outfit_medium.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_medium.ttf rename to ui/common/src/main/res/font/outfit_medium.ttf diff --git a/presentation/src/main/res/font/outfit_regular.ttf b/ui/common/src/main/res/font/outfit_regular.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_regular.ttf rename to ui/common/src/main/res/font/outfit_regular.ttf diff --git a/presentation/src/main/res/font/outfit_semibold.ttf b/ui/common/src/main/res/font/outfit_semibold.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_semibold.ttf rename to ui/common/src/main/res/font/outfit_semibold.ttf diff --git a/presentation/src/main/res/font/outfit_thin.ttf b/ui/common/src/main/res/font/outfit_thin.ttf similarity index 100% rename from presentation/src/main/res/font/outfit_thin.ttf rename to ui/common/src/main/res/font/outfit_thin.ttf diff --git a/presentation/src/main/res/values/strings.xml b/ui/common/src/main/res/values/strings.xml similarity index 100% rename from presentation/src/main/res/values/strings.xml rename to ui/common/src/main/res/values/strings.xml From f357db96a922fdc9c8ab6bae5760a8103fb0b15c Mon Sep 17 00:00:00 2001 From: jhavatar Date: Wed, 25 Mar 2026 03:51:01 +0200 Subject: [PATCH 2/6] refactor names in feature module to better match feature --- .../io/chthonic/weather/AppContainerNav.kt | 2 +- .../cityforecast/CityForecastDestination.kt | 12 ++++--- ...ontainerNav.kt => CityForecastNavGraph.kt} | 20 +++++------ .../CityDetailScreen.kt} | 33 +++++++++-------- .../CityDetailState.kt} | 4 +-- .../CityDetailViewModel.kt} | 14 ++++---- .../{location => citydetail}/DayWeather.kt | 2 +- .../CityListScreen.kt} | 36 +++++++++---------- .../CityListState.kt} | 4 +-- .../CityListUiStateResolver.kt} | 4 +-- .../CityListViewModel.kt} | 12 +++---- .../LocationCurrentWeather.kt | 2 +- .../NavigationEvent.kt | 4 +-- .../{TempColors.kt => TemperatureColors.kt} | 2 +- ...Test.kt => CityListUiStateResolverTest.kt} | 8 +++-- 15 files changed, 83 insertions(+), 76 deletions(-) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/{AppContainerNav.kt => CityForecastNavGraph.kt} (55%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{location/LocationDetailScreen.kt => citydetail/CityDetailScreen.kt} (92%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{location/LocationDetailState.kt => citydetail/CityDetailState.kt} (82%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{location/LocationDetailViewModel.kt => citydetail/CityDetailViewModel.kt} (84%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{location => citydetail}/DayWeather.kt (94%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{locationlist/LocationListScreen.kt => citylist/CityListScreen.kt} (95%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{locationlist/LocationListState.kt => citylist/CityListState.kt} (86%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{locationlist/LocationListUiStateResolver.kt => citylist/CityListUiStateResolver.kt} (83%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{locationlist/LocationListViewModel.kt => citylist/CityListViewModel.kt} (96%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{locationlist => citylist}/LocationCurrentWeather.kt (95%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/{locationlist => citylist}/NavigationEvent.kt (58%) rename feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/{TempColors.kt => TemperatureColors.kt} (99%) rename feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/{LocationListUiStateResolverTest.kt => CityListUiStateResolverTest.kt} (97%) diff --git a/app/src/main/java/io/chthonic/weather/AppContainerNav.kt b/app/src/main/java/io/chthonic/weather/AppContainerNav.kt index 98de7b7..c0c4f32 100644 --- a/app/src/main/java/io/chthonic/weather/AppContainerNav.kt +++ b/app/src/main/java/io/chthonic/weather/AppContainerNav.kt @@ -17,7 +17,7 @@ fun AppContainerNavHost( ) = SharedTransitionLayout(modifier = modifier) { NavHost( navController = appContainerState.navController, - startDestination = CityForecastDestination.LocationList.route, + startDestination = CityForecastDestination.CityList.route, modifier = Modifier, ) { cityForecastNavGraph(appContainerState) diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt index 042029b..93a7427 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastDestination.kt @@ -10,19 +10,21 @@ private const val LOC_LAT_ARG: String = "lat" private const val LOC_LON_ARG: String = "lon" private const val LOC_NAME_ARG: String = "name" -sealed class CityForecastDestination(val route: String, val arguments: List = emptyList()) { +sealed class CityForecastDestination( + val route: String, + val arguments: List = emptyList() +) { - data object LocationList : CityForecastDestination(route = "locations") + data object CityList : CityForecastDestination(route = "locations") - data object LocationDetail : + data object CityDetail : CityForecastDestination( route = "location/{$LOC_NAME_ARG}/{$LOC_LAT_ARG}/{$LOC_LON_ARG}", arguments = listOf( navArgument(LOC_NAME_ARG) { type = NavType.StringType }, navArgument(LOC_LAT_ARG) { type = NavType.StringType }, navArgument(LOC_LON_ARG) { type = NavType.StringType }, - - ) + ) ) { fun buildUniqueRoute(name: String, lat: Double, lon: Double): String = diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/AppContainerNav.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastNavGraph.kt similarity index 55% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/AppContainerNav.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastNavGraph.kt index 2e1b209..bf1d2b7 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/AppContainerNav.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/CityForecastNavGraph.kt @@ -3,8 +3,8 @@ package io.chthonic.weather.feature.cityforecast import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable -import io.chthonic.weather.feature.cityforecast.screens.location.LocationDetailScreen -import io.chthonic.weather.feature.cityforecast.screens.locationlist.LocationListScreen +import io.chthonic.weather.feature.cityforecast.screens.citydetail.CityDetailScreen +import io.chthonic.weather.feature.cityforecast.screens.citylist.CityListScreen import io.chthonic.weather.ui.common.AppContainerState @OptIn(ExperimentalSharedTransitionApi::class) @@ -12,28 +12,28 @@ fun NavGraphBuilder.cityForecastNavGraph( appContainerState: AppContainerState, ) { composable( - route = CityForecastDestination.LocationList.route, + route = CityForecastDestination.CityList.route, ) { - LocationListScreen( + CityListScreen( appContainerState = appContainerState, ) } composable( - route = CityForecastDestination.LocationDetail.route, - arguments = CityForecastDestination.LocationDetail.arguments, + route = CityForecastDestination.CityDetail.route, + arguments = CityForecastDestination.CityDetail.arguments, ) { backStackEntry -> val name = - CityForecastDestination.LocationDetail.getName(backStackEntry.arguments) + CityForecastDestination.CityDetail.getName(backStackEntry.arguments) ?: return@composable val lat = - CityForecastDestination.LocationDetail.getLat(backStackEntry.arguments) + CityForecastDestination.CityDetail.getLat(backStackEntry.arguments) ?: return@composable val lon = - CityForecastDestination.LocationDetail.getLon(backStackEntry.arguments) + CityForecastDestination.CityDetail.getLon(backStackEntry.arguments) ?: return@composable - LocationDetailScreen( + CityDetailScreen( name = name, lat = lat, lon = lon, diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailScreen.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailScreen.kt similarity index 92% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailScreen.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailScreen.kt index 672035c..3b8a1e5 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailScreen.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailScreen.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.feature.cityforecast.screens.location +package io.chthonic.weather.feature.cityforecast.screens.citydetail import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.foundation.background @@ -38,7 +38,7 @@ import io.chthonic.weather.feature.cityforecast.CityForecastDestination import io.chthonic.weather.feature.cityforecast.models.ListUiState import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits import io.chthonic.weather.feature.cityforecast.models.WeatherCondition -import io.chthonic.weather.feature.cityforecast.theme.TempColors +import io.chthonic.weather.feature.cityforecast.theme.TemperatureColors import io.chthonic.weather.feature.cityforecast.widgets.EMPTY_CONTENT_KEY import io.chthonic.weather.feature.cityforecast.widgets.ERROR_CONTENT_KEY import io.chthonic.weather.feature.cityforecast.widgets.EmptyContent @@ -59,14 +59,14 @@ import java.time.LocalDate @Composable @OptIn(ExperimentalSharedTransitionApi::class) -internal fun LocationDetailScreen( +internal fun CityDetailScreen( name: String, lat: Double, lon: Double, appContainerState: AppContainerState, ) { val viewModel = - hiltViewModel { factory -> + hiltViewModel { factory -> factory.create( name = name, lat = lat, @@ -84,14 +84,14 @@ internal fun LocationDetailScreen( } } appContainerState.updateAppBarForDestination( - destinationRoute = CityForecastDestination.LocationDetail.route, + destinationRoute = CityForecastDestination.CityDetail.route, title = state.value.name, showNavigationIcon = true, style = AppBarStyle.Large, actions = actions, ) - LocationDetailScreenContent( + CityDetailScreenContent( state.value.dayWeatherList, state.value.listUiState, state.value.temperatureUnits, @@ -100,7 +100,7 @@ internal fun LocationDetailScreen( @Composable @OptIn(ExperimentalSharedTransitionApi::class) -private fun LocationDetailScreenContent( +private fun CityDetailScreenContent( dayWeatherList: ImmutableList, listUiState: ListUiState, units: TemperatureUnits, @@ -169,7 +169,7 @@ private fun DayItem( .padding(horizontal = spacing.m, vertical = spacing.xs), shape = MaterialTheme.shapes.large, colors = CardDefaults.cardColors( - containerColor = TempColors.temperatureCardColor(state.maxTemp, isDark), + containerColor = TemperatureColors.temperatureCardColor(state.maxTemp, isDark), ), elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), ) { @@ -184,7 +184,10 @@ private fun DayItem( modifier = Modifier .size(48.dp) .background( - color = TempColors.temperatureIconBoxColor(state.maxTemp, isDark), + color = TemperatureColors.temperatureIconBoxColor( + state.maxTemp, + isDark, + ), shape = MaterialTheme.shapes.medium, ), ) { @@ -192,7 +195,7 @@ private fun DayItem( imageVector = state.weatherConditionIcon, contentDescription = state.weatherCondition.description, modifier = Modifier.size(28.dp), - tint = TempColors.temperatureIconTint(state.maxTemp, isDark), + tint = TemperatureColors.temperatureIconTint(state.maxTemp, isDark), ) } }, @@ -220,7 +223,7 @@ private fun DayItem( unitsTextStyle = MaterialTheme.typography.titleSmall.copy( fontWeight = FontWeight.Medium, ), - color = TempColors.temperatureTextColor(state.maxTemp, isDark), + color = TemperatureColors.temperatureTextColor(state.maxTemp, isDark), ) TemperatureText( temperature = state.minTemp, @@ -245,7 +248,7 @@ private fun DayItem( @Composable private fun PreviewListContentState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationDetailScreenContent( + CityDetailScreenContent( dayWeatherList = DayWeatherPreviewProvider().values.toImmutableList(), listUiState = ListUiState.Content, units = TemperatureUnits.CELSIUS, @@ -257,7 +260,7 @@ private fun PreviewListContentState() { @Composable private fun PreviewListEmptyState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationDetailScreenContent( + CityDetailScreenContent( dayWeatherList = persistentListOf(), listUiState = ListUiState.Empty, units = TemperatureUnits.CELSIUS, @@ -269,7 +272,7 @@ private fun PreviewListEmptyState() { @Composable private fun PreviewListLoadingState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationDetailScreenContent( + CityDetailScreenContent( dayWeatherList = persistentListOf(), listUiState = ListUiState.Loading, units = TemperatureUnits.CELSIUS, @@ -282,7 +285,7 @@ private fun PreviewListLoadingState() { @Composable private fun PreviewListErrorState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationDetailScreenContent( + CityDetailScreenContent( dayWeatherList = persistentListOf(), listUiState = ListUiState.Error, units = TemperatureUnits.CELSIUS, diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailState.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailState.kt similarity index 82% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailState.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailState.kt index bb3dca8..43c9fc2 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailState.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailState.kt @@ -1,11 +1,11 @@ -package io.chthonic.weather.feature.cityforecast.screens.location +package io.chthonic.weather.feature.cityforecast.screens.citydetail import io.chthonic.weather.feature.cityforecast.models.ListUiState import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -internal data class LocationDetailState( +internal data class CityDetailState( val name: String, val lat: Double, val lon: Double, diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailViewModel.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailViewModel.kt similarity index 84% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailViewModel.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailViewModel.kt index c64b3d0..1203f57 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/LocationDetailViewModel.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/CityDetailViewModel.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.feature.cityforecast.screens.location +package io.chthonic.weather.feature.cityforecast.screens.citydetail import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -16,8 +16,8 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -@HiltViewModel(assistedFactory = LocationDetailViewModel.LocationDetailViewModelFactory::class) -internal class LocationDetailViewModel @AssistedInject constructor( +@HiltViewModel(assistedFactory = CityDetailViewModel.CityDetailViewModelFactory::class) +internal class CityDetailViewModel @AssistedInject constructor( @Assisted("name") name: String, @Assisted("lat") lat: Double, @Assisted("lon") lon: Double, @@ -25,22 +25,22 @@ internal class LocationDetailViewModel @AssistedInject constructor( ) : ViewModel() { @AssistedFactory - interface LocationDetailViewModelFactory { + interface CityDetailViewModelFactory { fun create( @Assisted("name") name: String, @Assisted("lat") lat: Double, @Assisted("lon") lon: Double, - ): LocationDetailViewModel + ): CityDetailViewModel } private val _state = MutableStateFlow( - LocationDetailState( + CityDetailState( name = name, lat = lat, lon = lon, ) ) - val state: StateFlow = _state.asStateFlow() + val state: StateFlow = _state.asStateFlow() init { viewModelScope.launch { diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/DayWeather.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/DayWeather.kt similarity index 94% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/DayWeather.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/DayWeather.kt index a085354..1effce7 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/location/DayWeather.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citydetail/DayWeather.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.feature.cityforecast.screens.location +package io.chthonic.weather.feature.cityforecast.screens.citydetail import androidx.compose.ui.graphics.vector.ImageVector import io.chthonic.weather.common.models.DayForecast diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListScreen.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListScreen.kt similarity index 95% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListScreen.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListScreen.kt index 70a895b..035fcd5 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListScreen.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListScreen.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.feature.cityforecast.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.citylist import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.ExperimentalSharedTransitionApi @@ -60,7 +60,7 @@ import io.chthonic.weather.feature.cityforecast.CityForecastDestination import io.chthonic.weather.feature.cityforecast.models.ListUiState import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits import io.chthonic.weather.feature.cityforecast.models.WeatherCondition -import io.chthonic.weather.feature.cityforecast.theme.TempColors +import io.chthonic.weather.feature.cityforecast.theme.TemperatureColors import io.chthonic.weather.feature.cityforecast.widgets.EMPTY_CONTENT_KEY import io.chthonic.weather.feature.cityforecast.widgets.ERROR_CONTENT_KEY import io.chthonic.weather.feature.cityforecast.widgets.EmptyContent @@ -84,8 +84,8 @@ import kotlinx.collections.immutable.toImmutableList @Composable @OptIn(ExperimentalSharedTransitionApi::class) -internal fun LocationListScreen( - viewModel: LocationListViewModel = hiltViewModel(), +internal fun CityListScreen( + viewModel: CityListViewModel = hiltViewModel(), appContainerState: AppContainerState, ) { val context = LocalContext.current @@ -101,7 +101,7 @@ internal fun LocationListScreen( } } appContainerState.updateAppBarForDestination( - destinationRoute = CityForecastDestination.LocationList.route, + destinationRoute = CityForecastDestination.CityList.route, title = context.resources.getString(R.string.app_name), showNavigationIcon = false, style = AppBarStyle.Pinned, @@ -111,9 +111,9 @@ internal fun LocationListScreen( LaunchedEffect(Unit) { viewModel.navigationEvent.collect { event -> when (event) { - is NavigationEvent.ToLocationDetail -> { + is NavigationEvent.ToCityDetail -> { appContainerState.navController.navigate( - CityForecastDestination.LocationDetail.buildUniqueRoute( + CityForecastDestination.CityDetail.buildUniqueRoute( name = event.name, lat = event.lat, lon = event.lon, @@ -145,7 +145,7 @@ internal fun LocationListScreen( context = context, ) - LocationListContent( + CityListContent( myLocation = state.value.myLocation, locations = state.value.searchLocations, searchText = state.value.searchText, @@ -158,7 +158,7 @@ internal fun LocationListScreen( @Composable @OptIn(ExperimentalSharedTransitionApi::class) -private fun LocationListContent( +private fun CityListContent( myLocation: LocationCurrentWeather?, locations: ImmutableList, searchText: String, @@ -279,12 +279,12 @@ private fun WeatherLocationItem( .padding(horizontal = spacing.m, vertical = spacing.xs), shape = MaterialTheme.shapes.large, colors = CardDefaults.cardColors( - containerColor = TempColors.temperatureCardColor(state.temp, isDark), + containerColor = TemperatureColors.temperatureCardColor(state.temp, isDark), ), elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), ) { ListItem( - modifier = Modifier,// .clickable(onClick = onClick), + modifier = Modifier, colors = ListItemDefaults.colors( containerColor = Color.Transparent, // let the Card background show ), @@ -294,7 +294,7 @@ private fun WeatherLocationItem( modifier = Modifier .size(48.dp) .background( - color = TempColors.temperatureIconBoxColor(state.temp, isDark), + color = TemperatureColors.temperatureIconBoxColor(state.temp, isDark), shape = MaterialTheme.shapes.medium, ), ) { @@ -302,7 +302,7 @@ private fun WeatherLocationItem( state.displayIcon, contentDescription = state.weatherCondition?.description, modifier = Modifier.size(28.dp), - tint = TempColors.temperatureIconTint(state.temp, isDark), + tint = TemperatureColors.temperatureIconTint(state.temp, isDark), ) if (isMyLocation) { @@ -349,7 +349,7 @@ private fun WeatherLocationItem( TemperatureText( temperature = state.temp, units = units, - color = TempColors.temperatureTextColor(state.temp, isDark), + color = TemperatureColors.temperatureTextColor(state.temp, isDark), valueTextStyle = MaterialTheme.typography.displaySmall.copy( fontFamily = FontFamily.Monospace, fontFeatureSettings = "tnum", // tabular numbers @@ -416,7 +416,7 @@ private fun LocationSearchBar( @Composable private fun PreviewListContentState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationListContent( + CityListContent( myLocation = LocationCurrentWeather( location = Location(12.0, 13.0), displayName = "MY LOCATION", @@ -438,7 +438,7 @@ private fun PreviewListContentState() { @Composable private fun PreviewListIdleState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationListContent( + CityListContent( myLocation = LocationCurrentWeather( location = Location(12.0, 13.0), displayName = "MY LOCATION", @@ -459,7 +459,7 @@ private fun PreviewListIdleState() { @Composable private fun PreviewListEmptyState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationListContent( + CityListContent( myLocation = LocationCurrentWeather( location = Location(12.0, 13.0), displayName = "MY LOCATION", @@ -480,7 +480,7 @@ private fun PreviewListEmptyState() { @Composable private fun PreviewListErrorState() { PreviewSharedAnimation { sharedTransitionScope, animatedContentScope -> - LocationListContent( + CityListContent( myLocation = LocationCurrentWeather( location = Location(12.0, 13.0), displayName = "MY LOCATION", diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListState.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListState.kt similarity index 86% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListState.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListState.kt index b5b08f5..aabfc5f 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListState.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListState.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.feature.cityforecast.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.citylist import io.chthonic.weather.feature.cityforecast.models.ListUiState import io.chthonic.weather.feature.cityforecast.models.LocationPermissionState @@ -6,7 +6,7 @@ import io.chthonic.weather.feature.cityforecast.models.TemperatureUnits import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -internal data class LocationListState( +internal data class CityListState( val listUiState: ListUiState = ListUiState.Idle, val locationPermissionState: LocationPermissionState = LocationPermissionState.Unknown, val searchText: String = "", diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolver.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListUiStateResolver.kt similarity index 83% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolver.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListUiStateResolver.kt index 1a364e8..f781f59 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolver.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListUiStateResolver.kt @@ -1,10 +1,10 @@ -package io.chthonic.weather.feature.cityforecast.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.citylist import io.chthonic.weather.common.models.Outcome import io.chthonic.weather.feature.cityforecast.models.ListUiState import javax.inject.Inject -internal class LocationListUiStateResolver @Inject constructor() { +internal class CityListUiStateResolver @Inject constructor() { fun resolveOnSearchAction(query: String): ListUiState = if (query.isBlank()) ListUiState.Idle else ListUiState.Loading diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListViewModel.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListViewModel.kt similarity index 96% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListViewModel.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListViewModel.kt index 17ed18e..bf882d2 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListViewModel.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/CityListViewModel.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.feature.cityforecast.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.citylist import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -38,15 +38,15 @@ private const val MY_LOCATION_DISPLAY_NAME = "MY LOCATION" @OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class) @HiltViewModel -internal class LocationListViewModel @Inject constructor( +internal class CityListViewModel @Inject constructor( private val geocodingRepo: GeocodingRepo, private val weatherRepo: WeatherRepo, private val locationRepo: LocationRepo, - private val listUiStateResolver: LocationListUiStateResolver, + private val listUiStateResolver: CityListUiStateResolver, ) : ViewModel() { - private val _state = MutableStateFlow(LocationListState()) - val state: StateFlow = _state.asStateFlow() + private val _state = MutableStateFlow(CityListState()) + val state: StateFlow = _state.asStateFlow() private val _navigationEvent = Channel(Channel.BUFFERED) val navigationEvent = _navigationEvent.receiveAsFlow() @@ -131,7 +131,7 @@ internal class LocationListViewModel @Inject constructor( fun onLocationClick(locationState: LocationCurrentWeather) { viewModelScope.launch { _navigationEvent.send( - NavigationEvent.ToLocationDetail( + NavigationEvent.ToCityDetail( name = locationState.displayName, lat = locationState.location.lat, lon = locationState.location.lon diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationCurrentWeather.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/LocationCurrentWeather.kt similarity index 95% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationCurrentWeather.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/LocationCurrentWeather.kt index 349f701..7093acb 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationCurrentWeather.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/LocationCurrentWeather.kt @@ -1,4 +1,4 @@ -package io.chthonic.weather.feature.cityforecast.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.citylist import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.ErrorOutline diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/NavigationEvent.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/NavigationEvent.kt similarity index 58% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/NavigationEvent.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/NavigationEvent.kt index 1dc9be3..db4161b 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/NavigationEvent.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/screens/citylist/NavigationEvent.kt @@ -1,7 +1,7 @@ -package io.chthonic.weather.feature.cityforecast.screens.locationlist +package io.chthonic.weather.feature.cityforecast.screens.citylist internal sealed interface NavigationEvent { - data class ToLocationDetail( + data class ToCityDetail( val name: String, val lat: Double, val lon: Double diff --git a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TempColors.kt b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TemperatureColors.kt similarity index 99% rename from feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TempColors.kt rename to feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TemperatureColors.kt index 73679ee..f1d52fe 100644 --- a/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TempColors.kt +++ b/feature/cityforecast/src/main/java/io/chthonic/weather/feature/cityforecast/theme/TemperatureColors.kt @@ -2,7 +2,7 @@ package io.chthonic.weather.feature.cityforecast.theme import androidx.compose.ui.graphics.Color -object TempColors { +internal object TemperatureColors { // ───────────────────────────────────────────────────────────────────────────── // TEMPERATURE CARD COLOR // Call this to get the card containerColor based on celsius temperature. diff --git a/feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolverTest.kt b/feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/CityListUiStateResolverTest.kt similarity index 97% rename from feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolverTest.kt rename to feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/CityListUiStateResolverTest.kt index b420c32..399d8d8 100644 --- a/feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/LocationListUiStateResolverTest.kt +++ b/feature/cityforecast/src/test/java/io/chthonic/weather/feature/cityforecast/screens/locationlist/CityListUiStateResolverTest.kt @@ -3,17 +3,19 @@ package io.chthonic.weather.feature.cityforecast.screens.locationlist import io.chthonic.weather.common.models.Location import io.chthonic.weather.common.models.Outcome import io.chthonic.weather.feature.cityforecast.models.ListUiState +import io.chthonic.weather.feature.cityforecast.screens.citylist.LocationCurrentWeather +import io.chthonic.weather.feature.cityforecast.screens.citylist.CityListUiStateResolver import junit.framework.TestCase.assertEquals import org.junit.Before import org.junit.Test -internal class LocationListUiStateResolverTest { +internal class CityListUiStateResolverTest { - private lateinit var resolver: LocationListUiStateResolver + private lateinit var resolver: CityListUiStateResolver @Before fun setup() { - resolver = LocationListUiStateResolver() + resolver = CityListUiStateResolver() } // ------------------------------------------------------------------------- From 52845bfee2a673b9b176882a3a0e5fbc9f632005 Mon Sep 17 00:00:00 2001 From: jhavatar Date: Wed, 25 Mar 2026 09:43:38 +0200 Subject: [PATCH 3/6] update yml file to use main branch instead of master --- .github/workflows/android.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 42a5a75..4ad702f 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -2,9 +2,9 @@ name: Android CI on: push: - branches: [ "master" ] + branches: [ "main" ] pull_request: - branches: [ "master" ] + branches: [ "main" ] jobs: build: From 4decd7759cf1a36c7b98bf37e5d7d854fdee728f Mon Sep 17 00:00:00 2001 From: jhavatar Date: Wed, 25 Mar 2026 12:22:45 +0200 Subject: [PATCH 4/6] Add some documentation --- .idea/misc.xml | 1 - .../java/io/chthonic/weather/AppContainer.kt | 5 +++++ .../java/io/chthonic/weather/AppContainerNav.kt | 17 ++++++++++++++++- .../cityforecast/CityForecastDestination.kt | 8 ++++++++ .../cityforecast/CityForecastNavGraph.kt | 13 +++++++++++++ .../weather/ui/common/AppContainerState.kt | 6 ++++++ 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index b85fcc4..071ae48 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ -