diff --git a/app/build.gradle b/app/build.gradle index 0de3b36f..0b8eeb55 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,6 +102,8 @@ dependencies { //Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.11' + //Moshi + implementation "com.squareup.retrofit2:converter-moshi:2.9.0" //Convertor factory by Gson implementation 'com.squareup.retrofit2:converter-gson:2.9.0' diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/location/DefaultLocationTracker.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/location/DefaultLocationTracker.kt index 00bad114..f997fe35 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/location/DefaultLocationTracker.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/location/DefaultLocationTracker.kt @@ -1,4 +1,4 @@ -package com.abanoub.weather.data.location +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.location import android.Manifest import android.app.Application @@ -7,14 +7,12 @@ import android.content.pm.PackageManager import android.location.Location import android.location.LocationManager import androidx.core.content.ContextCompat -import com.abanoub.weather.domain.location.LocationTracker +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.location.LocationTracker import com.google.android.gms.location.FusedLocationProviderClient -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.suspendCancellableCoroutine import javax.inject.Inject import kotlin.coroutines.resume -@OptIn(ExperimentalCoroutinesApi::class) class DefaultLocationTracker @Inject constructor( private val locationClient: FusedLocationProviderClient, private val application: Application diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/mappers/WeatherMappers.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/mappers/WeatherMappers.kt index dd00be29..0ba62c3f 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/mappers/WeatherMappers.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/mappers/WeatherMappers.kt @@ -1,12 +1,10 @@ -package com.abanoub.weather.data.mappers +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.mappers -import android.os.Build -import androidx.annotation.RequiresApi -import com.abanoub.weather.data.remote.WeatherDataDto -import com.abanoub.weather.data.remote.WeatherDto -import com.abanoub.weather.domain.weather.WeatherData -import com.abanoub.weather.domain.weather.WeatherInfo -import com.abanoub.weather.domain.weather.WeatherType +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather.WeatherData +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather.WeatherInfo +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather.WeatherType +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote.WeatherDataDto +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote.WeatherDto import java.time.LocalDateTime import java.time.format.DateTimeFormatter @@ -15,7 +13,6 @@ private data class IndexedWeatherData( val data: WeatherData ) -@RequiresApi(Build.VERSION_CODES.O) fun WeatherDataDto.toWeatherDataMap(): Map> { return time.mapIndexed { index, time -> val temperature = temperatures[index] @@ -41,7 +38,6 @@ fun WeatherDataDto.toWeatherDataMap(): Map> { } } -@RequiresApi(Build.VERSION_CODES.O) fun WeatherDto.toWeatherInfo(): WeatherInfo { val weatherDataMap = weatherData.toWeatherDataMap() val now = LocalDateTime.now() diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/Constant.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/Constant.kt new file mode 100644 index 00000000..1e5442aa --- /dev/null +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/Constant.kt @@ -0,0 +1,7 @@ +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote + +object Constant { + const val END_POINT_WEATHER_API = + "v1/forecast?hourly=temperature_2m,weathercode,relativehumidity_2m,windspeed_10m,pressure_msl" + const val BASE_URL_WEATHER_API = "https://api.open-meteo.com/" +} \ No newline at end of file diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherApi.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherApi.kt index 57c4310e..d8aa8efa 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherApi.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherApi.kt @@ -1,11 +1,12 @@ -package com.abanoub.weather.data.remote +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote.Constant.END_POINT_WEATHER_API import retrofit2.http.GET import retrofit2.http.Query interface WeatherApi { - @GET("v1/forecast?hourly=temperature_2m,weathercode,relativehumidity_2m,windspeed_10m,pressure_msl") + @GET(END_POINT_WEATHER_API) suspend fun getWeather( @Query("latitude") latitude: Double, @Query("longitude") longitude: Double, diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDataDto.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDataDto.kt index c540a143..9d6345bb 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDataDto.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDataDto.kt @@ -1,4 +1,4 @@ -package com.abanoub.weather.data.remote +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote import com.squareup.moshi.Json diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDto.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDto.kt index 8b403536..71dc4686 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDto.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/remote/WeatherDto.kt @@ -1,5 +1,6 @@ -package com.abanoub.weather.data.remote +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote.WeatherDataDto import com.squareup.moshi.Json data class WeatherDto( diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/repository/WeatherRepositoryImpl.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/repository/WeatherRepositoryImpl.kt index ac8f355f..23003604 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/repository/WeatherRepositoryImpl.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/data/repository/WeatherRepositoryImpl.kt @@ -1,19 +1,16 @@ -package com.abanoub.weather.data.repository +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.repository -import android.os.Build -import androidx.annotation.RequiresApi -import com.abanoub.weather.data.mappers.toWeatherInfo -import com.abanoub.weather.data.remote.WeatherApi -import com.abanoub.weather.domain.repository.WeatherRepository -import com.abanoub.weather.domain.util.Resource -import com.abanoub.weather.domain.weather.WeatherInfo +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.mappers.toWeatherInfo +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.repository.WeatherRepository +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.util.Resource +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather.WeatherInfo +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote.WeatherApi import javax.inject.Inject class WeatherRepositoryImpl @Inject constructor( private val api: WeatherApi ) : WeatherRepository { - @RequiresApi(Build.VERSION_CODES.O) override suspend fun getWeatherData(lat: Double, long: Double): Resource { return try { Resource.Success( diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/AppModule.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/AppModule.kt new file mode 100644 index 00000000..aec949da --- /dev/null +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/AppModule.kt @@ -0,0 +1,36 @@ +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.di + +import android.app.Application +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote.Constant.BASE_URL_WEATHER_API +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.remote.WeatherApi +import com.google.android.gms.location.FusedLocationProviderClient +import com.google.android.gms.location.LocationServices +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import retrofit2.Retrofit +import retrofit2.converter.moshi.MoshiConverterFactory +import retrofit2.create +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object AppModule { + + @Provides + @Singleton + fun provideWeatherApi(): WeatherApi { + return Retrofit.Builder() + .baseUrl(BASE_URL_WEATHER_API) + .addConverterFactory(MoshiConverterFactory.create()) + .build() + .create() + } + + @Provides + @Singleton + fun provideFusedLocationProviderClient(application: Application): FusedLocationProviderClient { + return LocationServices.getFusedLocationProviderClient(application) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/LocationModule.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/LocationModule.kt new file mode 100644 index 00000000..af288842 --- /dev/null +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/LocationModule.kt @@ -0,0 +1,20 @@ +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.di + +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.location.DefaultLocationTracker +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.location.LocationTracker +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +abstract class LocationModule { + + @Binds + @Singleton + abstract fun bindLocationTracker( + defaultLocationTracker: DefaultLocationTracker + ): LocationTracker +} \ No newline at end of file diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/RepositoryModule.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/RepositoryModule.kt new file mode 100644 index 00000000..462086e6 --- /dev/null +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/di/RepositoryModule.kt @@ -0,0 +1,20 @@ +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.di + +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.data.repository.WeatherRepositoryImpl +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.repository.WeatherRepository +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +abstract class RepositoryModule { + + @Binds + @Singleton + abstract fun bindWeatherRepository( + weatherRepositoryImpl: WeatherRepositoryImpl + ): WeatherRepository +} \ No newline at end of file diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/location/LocationTracker.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/location/LocationTracker.kt index dbab2a36..b4f19e75 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/location/LocationTracker.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/location/LocationTracker.kt @@ -1,4 +1,4 @@ -package com.abanoub.weather.domain.location +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.location import android.location.Location diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/repository/WeatherRepository.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/repository/WeatherRepository.kt index 77f026e9..26b6bf4b 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/repository/WeatherRepository.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/repository/WeatherRepository.kt @@ -1,7 +1,7 @@ -package com.abanoub.weather.domain.repository +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.repository -import com.abanoub.weather.domain.util.Resource -import com.abanoub.weather.domain.weather.WeatherInfo +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.util.Resource +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather.WeatherInfo interface WeatherRepository { suspend fun getWeatherData(lat: Double, long: Double): Resource diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/util/Resource.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/util/Resource.kt index 8136b8c9..0fb5dbd8 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/util/Resource.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/util/Resource.kt @@ -1,4 +1,4 @@ -package com.abanoub.weather.domain.util +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.util sealed class Resource(val data: T? = null, val message: String? = null) { class Success(data: T?) : Resource(data) diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherData.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherData.kt index 3731a0da..6097cdeb 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherData.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherData.kt @@ -1,4 +1,4 @@ -package com.abanoub.weather.domain.weather +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather import java.time.LocalDateTime diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherInfo.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherInfo.kt index 22f911f3..71c46133 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherInfo.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherInfo.kt @@ -1,4 +1,4 @@ -package com.abanoub.weather.domain.weather +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather data class WeatherInfo( val weatherDataPerDay: Map>, diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherType.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherType.kt index bcbbe13f..d102fca4 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherType.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/domain/weather/WeatherType.kt @@ -1,7 +1,7 @@ -package com.abanoub.weather.domain.weather +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather import androidx.annotation.DrawableRes -import com.abanoub.weather.R +import com.example.jetpack_compose_all_in_one.R sealed class WeatherType( val weatherDesc: String, diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/HourlyWeatherDisplay.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/HourlyWeatherDisplay.kt index d568c963..19e0d942 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/HourlyWeatherDisplay.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/HourlyWeatherDisplay.kt @@ -1,7 +1,5 @@ -package com.abanoub.weather.presentation +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation -import android.os.Build -import androidx.annotation.RequiresApi import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -15,10 +13,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp -import com.abanoub.weather.domain.weather.WeatherData +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather.WeatherData import java.time.format.DateTimeFormatter -@RequiresApi(Build.VERSION_CODES.O) @Composable fun HourlyWeatherDisplay( weatherData: WeatherData, diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherCard.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherCard.kt index ea25694b..b86297ff 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherCard.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherCard.kt @@ -1,12 +1,18 @@ -package com.abanoub.weather.presentation +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation -import android.os.Build -import androidx.annotation.RequiresApi import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Card -import androidx.compose.material.Text +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -17,11 +23,11 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation.WeatherState +import com.example.jetpack_compose_all_in_one.R +import com.example.jetpack_compose_all_in_one.ui.theme.dp_15 import java.time.format.DateTimeFormatter import kotlin.math.roundToInt -@RequiresApi(Build.VERSION_CODES.O) @Composable fun WeatherCard( state: WeatherState, @@ -30,9 +36,9 @@ fun WeatherCard( ) { state.weatherInfo?.currentWeatherData?.let { data -> Card( - backgroundColor = backgroundColor, - shape = RoundedCornerShape(10.dp), - modifier = modifier.padding(16.dp) + modifier = modifier.then(Modifier.padding(dp_15)), + shape = RoundedCornerShape(dp_15), + elevation = CardDefaults.cardElevation(dp_15), ) { Column( modifier = Modifier diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherDataDisplay.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherDataDisplay.kt index f2050e8f..830bf450 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherDataDisplay.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherDataDisplay.kt @@ -1,4 +1,4 @@ -package com.abanoub.weather.presentation +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherForecast.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherForecast.kt index 0ef74bfb..d8278407 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherForecast.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherForecast.kt @@ -1,18 +1,19 @@ -package com.abanoub.weather.presentation +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation -import android.os.Build -import androidx.annotation.RequiresApi -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.material.Text +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation.WeatherState -@RequiresApi(Build.VERSION_CODES.O) @Composable fun WeatherForecast( state: WeatherState, diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherScreen.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherScreen.kt new file mode 100644 index 00000000..f5791d1e --- /dev/null +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherScreen.kt @@ -0,0 +1,49 @@ +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp + + +@Composable +fun WeatherScreen() { + Box( + modifier = Modifier.fillMaxSize() + ) { + Column( + modifier = Modifier + .fillMaxSize() + .background(DarkBlue) + ) { + WeatherCard( + state = viewModel.state, + backgroundColor = DeepBlue + ) + Spacer(modifier = Modifier.height(16.dp)) + WeatherForecast(state = viewModel.state) + } + if (viewModel.state.isLoading) { + CircularProgressIndicator( + modifier = Modifier.align(Alignment.Center) + ) + } + viewModel.state.error?.let { error -> + Text( + text = error, + color = Color.White, + textAlign = TextAlign.Center, + modifier = Modifier.align(Alignment.Center) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherState.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherState.kt index 8c0eee07..19a63a30 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherState.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherState.kt @@ -1,5 +1,7 @@ package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.weather.WeatherInfo + data class WeatherState( val weatherInfo: WeatherInfo? = null, diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherViewModel.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherViewModel.kt index 187a937d..3a42c13b 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherViewModel.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/android_architectures/clean_code_with_mvi_mvvm/presentation/WeatherViewModel.kt @@ -1,14 +1,13 @@ -package com.abanoub.weather.presentation +package com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.abanoub.weather.domain.location.LocationTracker -import com.abanoub.weather.domain.repository.WeatherRepository -import com.abanoub.weather.domain.util.Resource -import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.presentation.WeatherState +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.location.LocationTracker +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.repository.WeatherRepository +import com.example.jetpack_compose_all_in_one.android_architectures.clean_code_with_mvi_mvvm.domain.util.Resource import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject @@ -39,6 +38,7 @@ class WeatherViewModel @Inject constructor( error = null ) } + is Resource.Error -> { state = state.copy( weatherInfo = null, @@ -55,5 +55,4 @@ class WeatherViewModel @Inject constructor( } } } - } \ No newline at end of file diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/features/weather_sample/view/WeatherSample.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/features/weather_sample/view/WeatherSample.kt index 5478f77d..f23a1589 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/features/weather_sample/view/WeatherSample.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/features/weather_sample/view/WeatherSample.kt @@ -2,7 +2,6 @@ package com.example.jetpack_compose_all_in_one.features.weather_sample.view import android.location.Location -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/ui/components/MainContainerOfApp.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/ui/components/MainContainerOfApp.kt index acf0012f..32ca7671 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/ui/components/MainContainerOfApp.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/ui/components/MainContainerOfApp.kt @@ -449,6 +449,11 @@ fun MainContainerOfApp( composable(NavDes.CleanCode.route()) { DogApiMainPage() } + + composable(NavDes.CleanCodeWithMVI.route()) { + DogApiMainPage() + } + composable(NavDes.SharedPrefDemo.route()){ SharedPrefDemoScreen(context = context) } diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavConstants.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavConstants.kt index 87d52543..4f7a36c3 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavConstants.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavConstants.kt @@ -190,6 +190,10 @@ object NavConstants { const val CLEAN_CODE = "CLEAN_CODE" const val CLEAN_CODE_ABOUT = "Clean Code" + + const val CLEAN_CODE_WITH_MVI = "CLEAN_CODE_MVI" + const val CLEAN_CODE_ABOUT_WITH_MVI = "Clean Code + MVI + MVVM" + const val CONTENT_PROVIDER = "CONTENT_PROVIDER" const val CONTENT_PROVIDER_ABOUT = "Content Provider" diff --git a/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavDes.kt b/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavDes.kt index 53154d62..edd32a14 100644 --- a/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavDes.kt +++ b/app/src/main/java/com/example/jetpack_compose_all_in_one/utils/navigation/NavDes.kt @@ -18,6 +18,8 @@ import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.CHAT import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.CHAT_DEMO_UI_ABOUT import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.CLEAN_CODE import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.CLEAN_CODE_ABOUT +import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.CLEAN_CODE_ABOUT_WITH_MVI +import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.CLEAN_CODE_WITH_MVI import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.COLLAPSABLE import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.COLLAPSABLE_ABOUT import com.example.jetpack_compose_all_in_one.utils.navigation.NavConstants.CONTENT_PROVIDER @@ -217,7 +219,7 @@ sealed class NavDes(val data: INavigationDrawerItem, val customAppBarStringId: I NavDes(NavigationDrawerData(LESSON_12_WEBVIEW, LESSON_12_WEBVIEW_ABOUT)) object Lesson13Localization : - NavDes(NavigationDrawerData(LESSON_13_LOCALIAZATION , LESSON_13_LOCALIAZATION_ABOUT)) + NavDes(NavigationDrawerData(LESSON_13_LOCALIAZATION, LESSON_13_LOCALIAZATION_ABOUT)) object QuoteSwipe : NavDes(NavigationDrawerData(QUOTE_2, QUOTE_2_ABOUT)) @@ -329,6 +331,8 @@ sealed class NavDes(val data: INavigationDrawerItem, val customAppBarStringId: I object Mvvm : NavDes(NavigationDrawerData(MVVM, MVVM_ABOUT)) object Mvi : NavDes(NavigationDrawerData(MVI, MVI_ABOUT)) object CleanCode : NavDes(NavigationDrawerData(CLEAN_CODE, CLEAN_CODE_ABOUT)) + object CleanCodeWithMVI : + NavDes(NavigationDrawerData(CLEAN_CODE_WITH_MVI, CLEAN_CODE_ABOUT_WITH_MVI)) object AndroidArchitectures : NavDes( @@ -337,7 +341,8 @@ sealed class NavDes(val data: INavigationDrawerItem, val customAppBarStringId: I Mvp, Mvvm, Mvi, - CleanCode + CleanCode, + CleanCodeWithMVI ), ANDROID_ARCHITECTURES ) ) diff --git a/app/src/main/res/drawable/ic_cloudy.xml b/app/src/main/res/drawable/ic_cloudy.xml new file mode 100644 index 00000000..b1fa9a3d --- /dev/null +++ b/app/src/main/res/drawable/ic_cloudy.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_drop.xml b/app/src/main/res/drawable/ic_drop.xml new file mode 100644 index 00000000..d1aa6a34 --- /dev/null +++ b/app/src/main/res/drawable/ic_drop.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_heavysnow.xml b/app/src/main/res/drawable/ic_heavysnow.xml new file mode 100644 index 00000000..7a979a98 --- /dev/null +++ b/app/src/main/res/drawable/ic_heavysnow.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_pressure.xml b/app/src/main/res/drawable/ic_pressure.xml new file mode 100644 index 00000000..a9b1300b --- /dev/null +++ b/app/src/main/res/drawable/ic_pressure.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_rainshower.xml b/app/src/main/res/drawable/ic_rainshower.xml new file mode 100644 index 00000000..bdbefab6 --- /dev/null +++ b/app/src/main/res/drawable/ic_rainshower.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_rainy.xml b/app/src/main/res/drawable/ic_rainy.xml new file mode 100644 index 00000000..b31d1058 --- /dev/null +++ b/app/src/main/res/drawable/ic_rainy.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_rainythunder.xml b/app/src/main/res/drawable/ic_rainythunder.xml new file mode 100644 index 00000000..187e16a6 --- /dev/null +++ b/app/src/main/res/drawable/ic_rainythunder.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_snowy.xml b/app/src/main/res/drawable/ic_snowy.xml new file mode 100644 index 00000000..2f3c7c77 --- /dev/null +++ b/app/src/main/res/drawable/ic_snowy.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_snowyrainy.xml b/app/src/main/res/drawable/ic_snowyrainy.xml new file mode 100644 index 00000000..0b976d80 --- /dev/null +++ b/app/src/main/res/drawable/ic_snowyrainy.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_sunny.xml b/app/src/main/res/drawable/ic_sunny.xml new file mode 100644 index 00000000..1ca0d3d1 --- /dev/null +++ b/app/src/main/res/drawable/ic_sunny.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_sunnycloudy.xml b/app/src/main/res/drawable/ic_sunnycloudy.xml new file mode 100644 index 00000000..3f307d6c --- /dev/null +++ b/app/src/main/res/drawable/ic_sunnycloudy.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_sunnyrainy.xml b/app/src/main/res/drawable/ic_sunnyrainy.xml new file mode 100644 index 00000000..b1706cd5 --- /dev/null +++ b/app/src/main/res/drawable/ic_sunnyrainy.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_thunder.xml b/app/src/main/res/drawable/ic_thunder.xml new file mode 100644 index 00000000..6dc0fbb1 --- /dev/null +++ b/app/src/main/res/drawable/ic_thunder.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_very_cloudy.xml b/app/src/main/res/drawable/ic_very_cloudy.xml new file mode 100644 index 00000000..8da59ab1 --- /dev/null +++ b/app/src/main/res/drawable/ic_very_cloudy.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_wind.xml b/app/src/main/res/drawable/ic_wind.xml new file mode 100644 index 00000000..45604f00 --- /dev/null +++ b/app/src/main/res/drawable/ic_wind.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_windy.xml b/app/src/main/res/drawable/ic_windy.xml new file mode 100644 index 00000000..8a4ef7b1 --- /dev/null +++ b/app/src/main/res/drawable/ic_windy.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + \ No newline at end of file