diff --git a/app/build.gradle b/app/build.gradle index 33436acd9..61957382d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,17 +4,21 @@ plugins { id "kotlin-kapt" id 'dagger.hilt.android.plugin' id 'androidx.navigation.safeargs' + id 'com.google.gms.google-services' + id 'com.google.firebase.crashlytics' + id 'com.google.firebase.firebase-perf' } def localProperties = new Properties() localProperties.load(new FileInputStream(rootProject.file("local.properties"))) android { - compileSdk 32 + namespace "com.karrar.movieapp" + compileSdk 36 defaultConfig { applicationId "com.karrar.movieapp" - minSdk 21 + minSdk 23 targetSdk 32 versionCode 1 versionName "1.0" @@ -37,13 +41,14 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } buildFeatures { + buildConfig true dataBinding true viewBinding true } @@ -52,69 +57,71 @@ android { dependencies { - implementation 'androidx.core:core-ktx:1.7.0' - implementation 'androidx.appcompat:appcompat:1.5.1' - implementation 'com.google.android.material:material:1.6.1' - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'androidx.core:core-ktx:1.17.0' + implementation 'androidx.appcompat:appcompat:1.7.1' + implementation 'com.google.android.material:material:1.13.0' + implementation 'androidx.constraintlayout:constraintlayout:2.2.1' testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + androidTestImplementation 'androidx.test.ext:junit:1.3.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0' //Test - testImplementation "org.junit.jupiter:junit-jupiter-api:5.8.2" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.8.2" - testImplementation "org.junit.jupiter:junit-jupiter-params:5.8.2" + testImplementation "org.junit.jupiter:junit-jupiter-api:5.13.4" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.13.4" + testImplementation "org.junit.jupiter:junit-jupiter-params:5.13.4" - implementation 'com.squareup.retrofit2:retrofit:2.9.0' - implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.squareup.retrofit2:retrofit:3.0.0' + implementation 'com.squareup.retrofit2:converter-gson:3.0.0' - implementation "com.squareup.okhttp3:okhttp:4.9.1" + implementation "com.squareup.okhttp3:okhttp:5.1.0" //viewModel - implementation 'androidx.fragment:fragment-ktx:1.5.2' - implementation 'androidx.activity:activity-ktx:1.5.1' - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1' + implementation 'androidx.fragment:fragment-ktx:1.8.9' + implementation 'androidx.activity:activity-ktx:1.10.1' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.9.3' implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" - implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2' - implementation 'androidx.navigation:navigation-ui-ktx:2.5.2' + implementation 'androidx.navigation:navigation-fragment-ktx:2.9.3' + implementation 'androidx.navigation:navigation-ui-ktx:2.9.3' - implementation "androidx.recyclerview:recyclerview:1.2.0" + implementation "androidx.recyclerview:recyclerview:1.4.0" //picasso implementation 'com.squareup.picasso:picasso:2.71828' // room dependency - def room_version = "2.4.3" + def room_version = "2.7.2" implementation("androidx.room:room-runtime:$room_version") kapt("androidx.room:room-compiler:$room_version") implementation("androidx.room:room-ktx:$room_version") - implementation "com.google.dagger:hilt-android:2.42" - kapt "com.google.dagger:hilt-compiler:2.42" + implementation "com.google.dagger:hilt-android:2.57.1" + kapt "com.google.dagger:hilt-compiler:2.57.1" - implementation "androidx.compose.material3:material3:1.0.0-alpha14" - implementation "androidx.compose.material3:material3-window-size-class:1.0.0-alpha14" + implementation "androidx.compose.material3:material3:1.3.2" + implementation "androidx.compose.material3:material3-window-size-class:1.3.2" //data store preferences - implementation "androidx.datastore:datastore-preferences:1.0.0" + implementation "androidx.datastore:datastore-preferences:1.1.7" - implementation 'androidx.core:core-splashscreen:1.0.0' - - implementation 'androidx.appcompat:appcompat:1.0.0-alpha1' - implementation 'com.google.android.material:material:1.0.0-alpha1' + implementation 'androidx.core:core-splashscreen:1.0.1' // Lottie - implementation 'com.airbnb.android:lottie:5.2.0' + implementation 'com.airbnb.android:lottie:6.6.7' //Coil - implementation 'io.coil-kt:coil:2.2.2' + implementation 'io.coil-kt:coil:2.7.0' - implementation 'io.github.glailton.expandabletextview:expandabletextview:1.0.2' + implementation 'io.github.glailton.expandabletextview:expandabletextview:1.0.4' - implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:11.1.0' + implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:12.1.2' // paging - implementation "androidx.paging:paging-runtime:3.1.1" - implementation "androidx.paging:paging-runtime-ktx:3.1.1" + implementation "androidx.paging:paging-runtime-ktx:3.3.6" + + // firebase + implementation platform('com.google.firebase:firebase-bom:34.2.0') + implementation 'com.google.firebase:firebase-analytics' + implementation 'com.google.firebase:firebase-crashlytics' + implementation 'com.google.firebase:firebase-perf' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 84503d082..c498b0dee 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> diff --git a/app/src/main/java/com/karrar/movieapp/data/local/database/MovieDataBase.kt b/app/src/main/java/com/karrar/movieapp/data/local/database/MovieDataBase.kt index b2b020bdb..24c443653 100644 --- a/app/src/main/java/com/karrar/movieapp/data/local/database/MovieDataBase.kt +++ b/app/src/main/java/com/karrar/movieapp/data/local/database/MovieDataBase.kt @@ -13,7 +13,8 @@ import com.karrar.movieapp.data.local.database.entity.series.* ActorEntity::class, TrendingMovieEntity::class, NowStreamingMovieEntity::class,UpcomingMovieEntity::class, MysteryMovieEntity::class,AdventureMovieEntity::class, AiringTodaySeriesEntity::class, OnTheAirSeriesEntity::class,TopRatedSeriesEntity::class], - version = 1 + version = 1, + exportSchema = false ) @TypeConverters(Converters::class) abstract class MovieDataBase : RoomDatabase() { diff --git a/app/src/main/java/com/karrar/movieapp/data/remote/response/movie/MovieDetailsDto.kt b/app/src/main/java/com/karrar/movieapp/data/remote/response/movie/MovieDetailsDto.kt index ce734b717..8ce8da68d 100644 --- a/app/src/main/java/com/karrar/movieapp/data/remote/response/movie/MovieDetailsDto.kt +++ b/app/src/main/java/com/karrar/movieapp/data/remote/response/movie/MovieDetailsDto.kt @@ -36,7 +36,7 @@ data class MovieDetailsDto( @SerializedName("release_date") val releaseDate: Date? = null, @SerializedName("revenue") - val revenue: Int? = null, + val revenue: Long? = null, @SerializedName("runtime") val runtime: Int? = null, @SerializedName("spoken_languages") diff --git a/app/src/main/java/com/karrar/movieapp/ui/adapters/CollectionsAdapter.kt b/app/src/main/java/com/karrar/movieapp/ui/adapters/CollectionsAdapter.kt new file mode 100644 index 000000000..0764bc577 --- /dev/null +++ b/app/src/main/java/com/karrar/movieapp/ui/adapters/CollectionsAdapter.kt @@ -0,0 +1,20 @@ +package com.karrar.movieapp.ui.adapters + +import com.karrar.movieapp.R +import com.karrar.movieapp.ui.base.BaseAdapter +import com.karrar.movieapp.ui.base.BaseInteractionListener +import com.karrar.movieapp.ui.models.CollectionUiState + +class CollectionAdapter( + items: List, + val listener: CollectionInteractionListener +) : + BaseAdapter(items, listener) { + override val layoutID: Int = R.layout.item_collection +} + +interface CollectionInteractionListener : BaseInteractionListener { + fun onCollectionClick(collectionId: Int) + fun onClickSeeAllCollection() +} + diff --git a/app/src/main/java/com/karrar/movieapp/ui/adapters/MediaAdapter.kt b/app/src/main/java/com/karrar/movieapp/ui/adapters/MediaAdapter.kt index 5b76f5143..2e9bd8079 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/adapters/MediaAdapter.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/adapters/MediaAdapter.kt @@ -1,13 +1,13 @@ package com.karrar.movieapp.ui.adapters -import com.karrar.movieapp.domain.models.Media +import com.karrar.movieapp.R import com.karrar.movieapp.ui.base.BaseAdapter import com.karrar.movieapp.ui.base.BaseInteractionListener -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi -class MediaAdapter(items: List, layout: Int, listener: MediaInteractionListener) : - BaseAdapter(items, listener) { - override val layoutID: Int = layout +class MediaAdapter(items: List, listener: MediaInteractionListener,val title:String) : + BaseAdapter(items, listener) { + override val layoutID: Int = R.layout.item_media_card } interface MediaInteractionListener : BaseInteractionListener { diff --git a/app/src/main/java/com/karrar/movieapp/ui/adapters/MovieAdapter.kt b/app/src/main/java/com/karrar/movieapp/ui/adapters/MovieAdapter.kt index 255967768..c6ef586bf 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/adapters/MovieAdapter.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/adapters/MovieAdapter.kt @@ -2,18 +2,16 @@ package com.karrar.movieapp.ui.adapters import com.karrar.movieapp.R import com.karrar.movieapp.domain.enums.HomeItemsType -import com.karrar.movieapp.domain.models.Media import com.karrar.movieapp.ui.base.BaseAdapter import com.karrar.movieapp.ui.base.BaseInteractionListener -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi -class MovieAdapter(items: List,val listener: MovieInteractionListener) : - BaseAdapter(items, listener) { +class MovieAdapter(items: List, val listener: MovieInteractionListener) : + BaseAdapter(items, listener) { override val layoutID: Int = R.layout.item_movie } interface MovieInteractionListener : BaseInteractionListener { fun onClickMovie(movieId: Int) fun onClickSeeAllMovie(homeItemsType: HomeItemsType) -} - +} \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaAdapter.kt b/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaAdapter.kt index 7d7bd5eb9..4fb4517b9 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaAdapter.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaAdapter.kt @@ -4,18 +4,18 @@ import androidx.recyclerview.widget.DiffUtil import com.karrar.movieapp.R import com.karrar.movieapp.ui.adapters.MediaInteractionListener import com.karrar.movieapp.ui.base.BasePagingAdapter -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi open class AllMediaAdapter(listener: MediaInteractionListener) : - BasePagingAdapter(MediaComparator, listener) { + BasePagingAdapter(MediaComparator, listener) { override val layoutID: Int = R.layout.item_media - object MediaComparator : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: MediaUiState, newItem: MediaUiState) = + object MediaComparator : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: MediaUi, newItem: MediaUi) = oldItem.id == newItem.id - override fun areContentsTheSame(oldItem: MediaUiState, newItem: MediaUiState) = + override fun areContentsTheSame(oldItem: MediaUi, newItem: MediaUi) = oldItem == newItem } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaUiState.kt b/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaUiState.kt index b91150297..e06889519 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaUiState.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMediaUiState.kt @@ -1,12 +1,12 @@ package com.karrar.movieapp.ui.allMedia import androidx.paging.PagingData -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow data class AllMediaUiState( - val allMedia : Flow> = emptyFlow(), + val allMedia : Flow> = emptyFlow(), val isLoading : Boolean = false, val error : List = emptyList(), ) diff --git a/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMovieFragment.kt b/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMovieFragment.kt index ac5a3db7e..fb8919734 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMovieFragment.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/allMedia/AllMovieFragment.kt @@ -11,7 +11,7 @@ import com.karrar.movieapp.databinding.FragmentAllMovieBinding import com.karrar.movieapp.domain.enums.AllMediaType import com.karrar.movieapp.ui.adapters.LoadUIStateAdapter import com.karrar.movieapp.ui.base.BaseFragment -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi import com.karrar.movieapp.utilities.collect import com.karrar.movieapp.utilities.collectLast import com.karrar.movieapp.utilities.setSpanSize @@ -46,7 +46,7 @@ class AllMovieFragment : BaseFragment() { } - private suspend fun setAllMedia(itemsPagingData: PagingData) { + private suspend fun setAllMedia(itemsPagingData: PagingData) { allMediaAdapter.submitData(itemsPagingData) } diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/HomeFragment.kt b/app/src/main/java/com/karrar/movieapp/ui/home/HomeFragment.kt index 6718f35f4..88b693874 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/HomeFragment.kt @@ -35,15 +35,14 @@ class HomeFragment : BaseFragment() { homeAdapter.setItems( mutableListOf( it.popularMovies, - it.tvShowsSeries, - it.onTheAiringSeries, - it.airingTodaySeries, + it.recentlyReleased, + it.whatShouldIWatch, it.upcomingMovies, - it.nowStreamingMovies, - it.mysteryMovies, - it.adventureMovies, - it.trendingMovies, - it.actors, + it.matchesYourVibe, + it.topRatedTVShows, + it.recentlyViewed, + it.collections, + it.needMoreWatch, ) ) } @@ -68,30 +67,39 @@ class HomeFragment : BaseFragment() { event.actorID ) } + is HomeUIEvent.ClickMovieEvent -> { HomeFragmentDirections.actionHomeFragmentToMovieDetailFragment( event.movieID ) } + HomeUIEvent.ClickSeeAllActorEvent -> { HomeFragmentDirections.actionHomeFragmentToActorsFragment() } + is HomeUIEvent.ClickSeeAllMovieEvent -> { HomeFragmentDirections.actionHomeFragmentToAllMovieFragment( -1, event.mediaType ) } + is HomeUIEvent.ClickSeeAllTVShowsEvent -> { HomeFragmentDirections.actionHomeFragmentToAllMovieFragment( -1, event.mediaType ) } + is HomeUIEvent.ClickSeriesEvent -> { HomeFragmentDirections.actionHomeFragmentToTvShowDetailsFragment( event.seriesID ) } + + HomeUIEvent.ClickWhatShouldIWatchEvent -> TODO() + + HomeUIEvent.ClickNeedMoreToWatchEvent -> TODO() } findNavController().navigate(action) } diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/HomeInteractionListener.kt b/app/src/main/java/com/karrar/movieapp/ui/home/HomeInteractionListener.kt index 0e95f5d1c..3034a45cf 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/HomeInteractionListener.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/HomeInteractionListener.kt @@ -4,4 +4,5 @@ import com.karrar.movieapp.ui.base.BaseInteractionListener interface HomeInteractionListener : BaseInteractionListener { fun onClickSeeAllActors() + fun onClickWhatShouldIWatch() } \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/HomeItem.kt b/app/src/main/java/com/karrar/movieapp/ui/home/HomeItem.kt index c0d424f23..8de94933f 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/HomeItem.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/HomeItem.kt @@ -1,30 +1,25 @@ package com.karrar.movieapp.ui.home -import com.karrar.movieapp.domain.enums.HomeItemsType -import com.karrar.movieapp.ui.models.ActorUiState import com.karrar.movieapp.ui.home.homeUiState.PopularUiState -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.CollectionUiState +import com.karrar.movieapp.ui.models.MediaUi sealed class HomeItem(val priority: Int) { - data class Slider(val items: List) : HomeItem(0) - - data class TvShows(val items: List) : HomeItem(1) - - data class OnTheAiring(val items: List, val type: HomeItemsType = HomeItemsType.ON_THE_AIR) : HomeItem(2) - - data class Trending(val items: List, val type: HomeItemsType = HomeItemsType.TRENDING) : HomeItem(3) - - data class AiringToday(val items: List) : HomeItem(4) - - data class NowStreaming(val items: List, val type: HomeItemsType = HomeItemsType.NOW_STREAMING) : HomeItem(5) - - data class Upcoming(val items: List, val type: HomeItemsType = HomeItemsType.UPCOMING) : HomeItem(6) - - data class Mystery(val items: List, val type: HomeItemsType = HomeItemsType.MYSTERY) : HomeItem(7) - - data class Adventure(val items: List, val type: HomeItemsType = HomeItemsType.ADVENTURE) : HomeItem(8) - - data class Actor(val items: List) : HomeItem(9) - + data class RecentlyReleased(val items: List) : HomeItem(1) + data class WhatShouldIWatch( + val mainTitle: String, + val secondaryTitle: String, + val infoTitle: String + ) : HomeItem(2) + data class UpcomingMovies(val items: List) : HomeItem(3) + data class MatchesYourVibe(val items: List) : HomeItem(4) + data class TopRatedTVShows(val items: List) : HomeItem(5) + data class RecentlyViewed(val items: List) : HomeItem(6) + data class Collections(val items: List) : HomeItem(8) + data class NeedMoreWatch( + val mainTitle: String, + val secondaryTitle: String, + val infoTitle: String + ) : HomeItem(9) } \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/HomeViewModel.kt b/app/src/main/java/com/karrar/movieapp/ui/home/HomeViewModel.kt index be2da0910..1a9858991 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/HomeViewModel.kt @@ -1,12 +1,11 @@ package com.karrar.movieapp.ui.home -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope -import com.karrar.movieapp.domain.RequestStatus import com.karrar.movieapp.domain.enums.AllMediaType import com.karrar.movieapp.domain.enums.HomeItemsType import com.karrar.movieapp.domain.usecase.home.HomeUseCasesContainer import com.karrar.movieapp.ui.adapters.ActorsInteractionListener +import com.karrar.movieapp.ui.adapters.CollectionInteractionListener import com.karrar.movieapp.ui.adapters.MediaInteractionListener import com.karrar.movieapp.ui.adapters.MovieInteractionListener import com.karrar.movieapp.ui.base.BaseViewModel @@ -30,7 +29,7 @@ class HomeViewModel @Inject constructor( private val actorUiMapper: ActorUiMapper, private val popularUiMapper: PopularUiMapper, ) : BaseViewModel(), HomeInteractionListener, ActorsInteractionListener, MovieInteractionListener, - MediaInteractionListener, TVShowInteractionListener { + MediaInteractionListener, TVShowInteractionListener, CollectionInteractionListener { private val _homeUiState = MutableStateFlow(HomeUiState()) val homeUiState = _homeUiState.asStateFlow() @@ -46,15 +45,18 @@ class HomeViewModel @Inject constructor( private fun getHomeData() { _homeUiState.update { it.copy(isLoading = true) } getTrending() - getNowStreaming() - getUpcoming() - getTopRatedTvShow() getOnTheAir() getAiringToday() getPopularMovies() getMystery() getAdventure() getActors() + + + getNowStreaming() + getTopRatedTvShow() + getUpcoming() + } override fun getData() { @@ -70,8 +72,10 @@ class HomeViewModel @Inject constructor( if (list.isNotEmpty()) { val items = list.map(popularUiMapper::map) _homeUiState.update { - it.copy(popularMovies = HomeItem.Slider(items), - isLoading = false) + it.copy( + popularMovies = HomeItem.Slider(items), + isLoading = false + ) } } } @@ -81,6 +85,7 @@ class HomeViewModel @Inject constructor( } } + private fun onError(message: String) { val errors = _homeUiState.value.error.toMutableList() errors.add(message) @@ -93,10 +98,9 @@ class HomeViewModel @Inject constructor( homeUseCasesContainer.getTrendingMoviesUseCase().collect { list -> if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) - _homeUiState.update { - it.copy(trendingMovies = HomeItem.Trending(items), - isLoading = false) - } + /*_homeUiState.update { + it.copy(trendingMovies = HomeItem.Trending(items), isLoading = false) + }*/ } } } catch (th: Throwable) { @@ -112,10 +116,10 @@ class HomeViewModel @Inject constructor( homeUseCasesContainer.getTrendingActorsUseCase().collect { list -> if (list.isNotEmpty()) { val items = list.map(actorUiMapper::map) - _homeUiState.update { + /*_homeUiState.update { it.copy(actors = HomeItem.Actor(items), isLoading = false) - } + }*/ } } } catch (th: Throwable) { @@ -132,7 +136,7 @@ class HomeViewModel @Inject constructor( if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) _homeUiState.update { - it.copy(upcomingMovies = HomeItem.Upcoming(items), + it.copy(upcomingMovies = HomeItem.UpcomingMovies(items), isLoading = false) } } @@ -152,7 +156,7 @@ class HomeViewModel @Inject constructor( if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) _homeUiState.update { - it.copy(nowStreamingMovies = HomeItem.NowStreaming(items), + it.copy(recentlyReleased = HomeItem.RecentlyReleased(items), isLoading = false) } } @@ -171,7 +175,7 @@ class HomeViewModel @Inject constructor( if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) _homeUiState.update { - it.copy(tvShowsSeries = HomeItem.TvShows(items), + it.copy(topRatedTVShows = HomeItem.TopRatedTVShows(items), isLoading = false) } } @@ -186,10 +190,10 @@ class HomeViewModel @Inject constructor( homeUseCasesContainer.getOnTheAirUseCase().collect { list -> if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) - _homeUiState.update { + /*_homeUiState.update { it.copy(onTheAiringSeries = HomeItem.OnTheAiring(items), isLoading = false) - } + }*/ } } } catch (th: Throwable) { @@ -205,10 +209,10 @@ class HomeViewModel @Inject constructor( homeUseCasesContainer.getAiringTodayUseCase().collect { list -> if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) - _homeUiState.update { + /*_homeUiState.update { it.copy(airingTodaySeries = HomeItem.AiringToday(items), isLoading = false) - } + }*/ } } } catch (th: Throwable) { @@ -225,10 +229,10 @@ class HomeViewModel @Inject constructor( homeUseCasesContainer.getMysteryMoviesUseCase().collect { list -> if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) - _homeUiState.update { + /*_homeUiState.update { it.copy(mysteryMovies = HomeItem.Mystery(items), isLoading = false) - } + }*/ } } } catch (th: Throwable) { @@ -244,10 +248,10 @@ class HomeViewModel @Inject constructor( homeUseCasesContainer.getAdventureMoviesUseCase().collect { list -> if (list.isNotEmpty()) { val items = list.map(mediaUiMapper::map) - _homeUiState.update { + /*_homeUiState.update { it.copy(adventureMovies = HomeItem.Adventure(items), isLoading = false) - } + }*/ } } } catch (th: Throwable) { @@ -283,6 +287,10 @@ class HomeViewModel @Inject constructor( } + override fun onClickWhatShouldIWatch() { + _homeUIEvent.update { Event(HomeUIEvent.ClickWhatShouldIWatchEvent) } + } + override fun onClickMedia(mediaId: Int) { _homeUIEvent.update { Event(HomeUIEvent.ClickSeriesEvent(mediaId)) } } @@ -295,5 +303,7 @@ class HomeViewModel @Inject constructor( _homeUIEvent.update { Event(HomeUIEvent.ClickSeeAllTVShowsEvent(type)) } } + override fun onCollectionClick(collectionId: Int) {} + override fun onClickSeeAllCollection() {} } \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/PopularUiMapper.kt b/app/src/main/java/com/karrar/movieapp/ui/home/PopularUiMapper.kt index d3a4afa8a..2a97dac85 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/PopularUiMapper.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/PopularUiMapper.kt @@ -3,16 +3,19 @@ package com.karrar.movieapp.ui.home import com.karrar.movieapp.domain.mappers.Mapper import com.karrar.movieapp.domain.models.PopularMovie import com.karrar.movieapp.ui.home.homeUiState.PopularUiState +import java.util.Locale.getDefault import javax.inject.Inject class PopularUiMapper @Inject constructor() : Mapper { override fun map(input: PopularMovie): PopularUiState { + val formattedRate = String.format(getDefault(), "%.1f", input.movieRate) + return PopularUiState( input.movieID, input.title, input.imageUrl, - input.movieRate, + formattedRate, input.genre ) } diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/adapter/HomeAdapter.kt b/app/src/main/java/com/karrar/movieapp/ui/home/adapter/HomeAdapter.kt index bcf42dd00..3c988a702 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/adapter/HomeAdapter.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/adapter/HomeAdapter.kt @@ -1,18 +1,27 @@ package com.karrar.movieapp.ui.home.adapter +import android.os.Handler +import android.os.Looper import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.databinding.DataBindingUtil +import androidx.viewpager2.widget.ViewPager2 import com.karrar.movieapp.BR import com.karrar.movieapp.R +import com.karrar.movieapp.databinding.ItemPopularMovieBinding import com.karrar.movieapp.domain.enums.HomeItemsType -import com.karrar.movieapp.ui.adapters.* +import com.karrar.movieapp.ui.adapters.CollectionAdapter +import com.karrar.movieapp.ui.adapters.CollectionInteractionListener +import com.karrar.movieapp.ui.adapters.MediaAdapter +import com.karrar.movieapp.ui.adapters.MediaInteractionListener +import com.karrar.movieapp.ui.adapters.MovieAdapter +import com.karrar.movieapp.ui.adapters.MovieInteractionListener import com.karrar.movieapp.ui.base.BaseAdapter import com.karrar.movieapp.ui.base.BaseInteractionListener import com.karrar.movieapp.ui.home.HomeInteractionListener import com.karrar.movieapp.ui.home.HomeItem -import com.karrar.movieapp.ui.models.MediaUiState -import com.karrar.movieapp.utilities.Constants +import com.karrar.movieapp.ui.models.MediaUi class HomeAdapter( private var homeItems: MutableList, @@ -45,84 +54,117 @@ class HomeAdapter( if (position != -1) when (val currentItem = homeItems[position]) { is HomeItem.Slider -> { - holder.binding.setVariable( - BR.adapterRecycler, + val adapter = PopularMovieAdapter(currentItem.items, listener as HomeInteractionListener) - ) - } + val viewPager = + holder.binding.root.findViewById(R.id.viewPagerPopular) + viewPager.adapter = adapter + + setupPageTransformer(viewPager) + setupAutoScroll(viewPager, adapter) - is HomeItem.TvShows -> { - holder.binding.run { - if (currentItem.items.isNotEmpty()) { - setVariable(BR.topRated, currentItem.items.first()) - setVariable(BR.popular, currentItem.items[1]) - setVariable(BR.latest, currentItem.items.last()) - setVariable(BR.listener, listener as TVShowInteractionListener) - } - } } - is HomeItem.Actor -> { + is HomeItem.RecentlyReleased -> { holder.binding.run { setVariable( - BR.adapterRecycler, ActorAdapter( + BR.adapterRecycler, + MediaAdapter( currentItem.items, - R.layout.item_actor_home, - listener as ActorsInteractionListener + listener as MediaInteractionListener, + "Recently Released" ) ) - setVariable(BR.listener, listener as HomeInteractionListener) } + } + is HomeItem.WhatShouldIWatch -> { + holder.binding.run { + setVariable(BR.mainTitle, currentItem.mainTitle) + setVariable(BR.secondaryTitle, currentItem.secondaryTitle) + setVariable(BR.infoTitle, currentItem.infoTitle) + setVariable( + BR.listener, + listener as HomeInteractionListener + ) + } } - is HomeItem.AiringToday -> { + is HomeItem.UpcomingMovies -> { holder.binding.run { setVariable( BR.adapterRecycler, MediaAdapter( - currentItem.items.take(Constants.MAX_NUMBER_AIRING_TODAY), - R.layout.item_airing_today, - listener as MediaInteractionListener + currentItem.items, + listener as MediaInteractionListener, + "Upcoming Movies" ) ) - setVariable(BR.count, currentItem.items.size) } } - is HomeItem.Adventure -> { - bindMovie(holder, currentItem.items, currentItem.type) - } - - is HomeItem.Mystery -> { - bindMovie(holder, currentItem.items, currentItem.type) + is HomeItem.MatchesYourVibe -> { + holder.binding.run { + setVariable( + BR.adapterRecycler, + MediaAdapter( + currentItem.items, + listener as MediaInteractionListener, + "Matches your Vibe" + ) + ) + } } - is HomeItem.NowStreaming -> { - bindMovie(holder, currentItem.items, currentItem.type) + is HomeItem.TopRatedTVShows -> { + holder.binding.run { + setVariable( + BR.adapterRecycler, + MediaAdapter( + currentItem.items, + listener as MediaInteractionListener, + "Top Rated TV Shows" + ) + ) + } } - is HomeItem.OnTheAiring -> { + is HomeItem.RecentlyViewed -> { holder.binding.run { setVariable( BR.adapterRecycler, - TVShowAdapter(currentItem.items, listener as TVShowInteractionListener) + MediaAdapter( + currentItem.items, + listener as MediaInteractionListener, + "Recently Viewed" + ) ) - setVariable(BR.movieType, currentItem.type) } } - is HomeItem.Trending -> { - bindMovie(holder, currentItem.items, currentItem.type) + is HomeItem.Collections -> { + holder.binding.run { + setVariable( + BR.adapterRecycler, + CollectionAdapter( + currentItem.items, + listener as CollectionInteractionListener + ) + ) + } } - is HomeItem.Upcoming -> { - bindMovie(holder, currentItem.items, currentItem.type) + is HomeItem.NeedMoreWatch -> { + holder.binding.run { + setVariable(BR.mainTitle, currentItem.mainTitle) + setVariable(BR.secondaryTitle, currentItem.secondaryTitle) + setVariable(BR.infoTitle, currentItem.infoTitle) + } } } } - private fun bindMovie(holder: ItemViewHolder, items: List, type: HomeItemsType) { + private fun bindMovie(holder: ItemViewHolder, items: List, type: HomeItemsType) { holder.binding.run { setVariable( BR.adapterRecycler, @@ -151,20 +193,63 @@ class HomeAdapter( override fun getItemViewType(position: Int): Int { if (homeItems.isNotEmpty()) { return when (homeItems[position]) { - is HomeItem.Actor -> R.layout.list_actor - is HomeItem.TvShows -> R.layout.list_tv_shows is HomeItem.Slider -> R.layout.list_popular - is HomeItem.AiringToday -> R.layout.list_airing_today - is HomeItem.OnTheAiring -> R.layout.list_tvshow - is HomeItem.Adventure, - is HomeItem.Mystery, - is HomeItem.NowStreaming, - is HomeItem.Trending, - is HomeItem.Upcoming, - -> R.layout.list_movie + is HomeItem.RecentlyReleased, + is HomeItem.WhatShouldIWatch -> R.layout.item_suggestion + is HomeItem.UpcomingMovies, + is HomeItem.MatchesYourVibe, + is HomeItem.TopRatedTVShows, + is HomeItem.RecentlyViewed, + -> R.layout.list_media + is HomeItem.Collections -> R.layout.list_collection + is HomeItem.NeedMoreWatch -> R.layout.item_suggestion } } return -1 } + private fun setupPageTransformer(viewPager: ViewPager2) { + viewPager.offscreenPageLimit = 3 + val sideScale = 1.1f + val sideTranslationY = 100f + val sideOffset = -60f + + viewPager.setPageTransformer { page, position -> + val binding = DataBindingUtil.getBinding(page) + binding?.apply { + if (position in -0.5f..0.5f) { + root.scaleY = 1f + root.translationY = 0f + root.translationZ = 1f + root.translationX = 0f + textMovieTitle.visibility = View.VISIBLE + textRate.visibility = View.VISIBLE + textCategory.visibility = View.VISIBLE + } else { + root.scaleY = sideScale + root.translationY = sideTranslationY + root.translationZ = 0f + root.translationX = position * sideOffset + textMovieTitle.visibility = View.GONE + textRate.visibility = View.GONE + textCategory.visibility = View.GONE + } + } + } + } + + private fun setupAutoScroll(viewPager: ViewPager2, adapter: PopularMovieAdapter) { + val handler = Handler(Looper.getMainLooper()) + val runnable = object : Runnable { + override fun run() { + val current = viewPager.currentItem + val next = if (current + 1 < adapter.itemCount) current + 1 else 0 + viewPager.setCurrentItem(next, true) + handler.postDelayed(this, 3000) + } + } + handler.postDelayed(runnable, 3000) + } + + } \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/adapter/TVShowAdapter.kt b/app/src/main/java/com/karrar/movieapp/ui/home/adapter/TVShowAdapter.kt index b38722519..52da30b8b 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/adapter/TVShowAdapter.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/adapter/TVShowAdapter.kt @@ -5,10 +5,10 @@ import com.karrar.movieapp.domain.enums.AllMediaType import com.karrar.movieapp.domain.models.Media import com.karrar.movieapp.ui.base.BaseAdapter import com.karrar.movieapp.ui.base.BaseInteractionListener -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi -class TVShowAdapter(items: List,val listener: TVShowInteractionListener) : - BaseAdapter(items, listener) { +class TVShowAdapter(items: List,val listener: TVShowInteractionListener) : + BaseAdapter(items, listener) { override val layoutID: Int = R.layout.item_tvshow } diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUIEvent.kt b/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUIEvent.kt index 13fd1005e..d03c1d608 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUIEvent.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUIEvent.kt @@ -4,6 +4,8 @@ import com.karrar.movieapp.domain.enums.AllMediaType sealed interface HomeUIEvent { object ClickSeeAllActorEvent : HomeUIEvent + object ClickWhatShouldIWatchEvent : HomeUIEvent + object ClickNeedMoreToWatchEvent : HomeUIEvent data class ClickMovieEvent(val movieID: Int) : HomeUIEvent data class ClickActorEvent(val actorID: Int) : HomeUIEvent data class ClickSeriesEvent(val seriesID: Int) : HomeUIEvent diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUiState.kt b/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUiState.kt index f86783407..8439dd55f 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUiState.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/HomeUiState.kt @@ -1,18 +1,28 @@ package com.karrar.movieapp.ui.home.homeUiState import com.karrar.movieapp.ui.home.HomeItem +import com.karrar.movieapp.ui.models.CollectionUiState -data class HomeUiState ( +data class HomeUiState( val popularMovies: HomeItem = HomeItem.Slider(emptyList()), - val trendingMovies: HomeItem = HomeItem.Trending(emptyList()), - val nowStreamingMovies: HomeItem = HomeItem.NowStreaming(emptyList()), - val adventureMovies: HomeItem = HomeItem.Adventure(emptyList()), - val mysteryMovies: HomeItem = HomeItem.Mystery(emptyList()), - val upcomingMovies: HomeItem = HomeItem.Upcoming(emptyList()), - val onTheAiringSeries: HomeItem = HomeItem.OnTheAiring(emptyList()), - val airingTodaySeries: HomeItem = HomeItem.AiringToday(emptyList()), - val tvShowsSeries: HomeItem = HomeItem.TvShows(emptyList()), - val actors: HomeItem = HomeItem.Actor(emptyList()), - val isLoading:Boolean = false, - val error : List = emptyList(), + val recentlyReleased: HomeItem = HomeItem.RecentlyReleased(emptyList()), + val whatShouldIWatch: HomeItem = HomeItem.WhatShouldIWatch("", "", ""), + val needMoreWatch: HomeItem = HomeItem.NeedMoreWatch("", "", ""), + val upcomingMovies: HomeItem = HomeItem.UpcomingMovies(emptyList()), + val matchesYourVibe: HomeItem = HomeItem.MatchesYourVibe(emptyList()), + val topRatedTVShows: HomeItem = HomeItem.TopRatedTVShows(emptyList()), + val recentlyViewed: HomeItem = HomeItem.RecentlyViewed(emptyList()), + val collections: HomeItem = HomeItem.Collections( + listOf( + CollectionUiState(0, "My Favorite TV Shows", "5 shows"), + CollectionUiState(0, "My Favorite TV Shows", "5 shows"), + CollectionUiState(0, "My Favorite TV Shows", "5 shows"), + CollectionUiState(0, "My Favorite TV Shows", "5 shows"), + CollectionUiState(0, "My Favorite TV Shows", "5 shows"), + CollectionUiState(0, "My Favorite TV Shows", "5 shows"), + CollectionUiState(0, "My Favorite TV Shows", "5 shows"), + ) + ), + val isLoading: Boolean = false, + val error: List = emptyList(), ) \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/PopularUiState.kt b/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/PopularUiState.kt index c810022c4..65e22fbcb 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/PopularUiState.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/home/homeUiState/PopularUiState.kt @@ -4,6 +4,6 @@ data class PopularUiState( val movieID: Int, val title: String, val imageUrl: String, - val movieRate:Double, + val movieRate: String, val genre: List ) \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/mappers/MediaUiMapper.kt b/app/src/main/java/com/karrar/movieapp/ui/mappers/MediaUiMapper.kt index 44bbba3d4..e7f8f9d97 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/mappers/MediaUiMapper.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/mappers/MediaUiMapper.kt @@ -3,14 +3,16 @@ package com.karrar.movieapp.ui.mappers import com.karrar.movieapp.domain.mappers.Mapper import com.karrar.movieapp.domain.models.Media -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi import javax.inject.Inject -class MediaUiMapper @Inject constructor() : Mapper { - override fun map(input: Media): MediaUiState { - return MediaUiState( - input.mediaID, - input.mediaImage, +class MediaUiMapper @Inject constructor() : Mapper { + override fun map(input: Media): MediaUi { + return MediaUi( + id= input.mediaID, + title = input.mediaName, + imageUrl = input.mediaImage, + rate = input.mediaRate.toString() ) } } \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/models/CollectionUiState.kt b/app/src/main/java/com/karrar/movieapp/ui/models/CollectionUiState.kt new file mode 100644 index 000000000..b948f2020 --- /dev/null +++ b/app/src/main/java/com/karrar/movieapp/ui/models/CollectionUiState.kt @@ -0,0 +1,7 @@ +package com.karrar.movieapp.ui.models + +data class CollectionUiState( + val id: Int = 0, + val title: String = "", + val subtitle: String = "", +) \ No newline at end of file diff --git a/app/src/main/java/com/karrar/movieapp/ui/models/MediaUi.kt b/app/src/main/java/com/karrar/movieapp/ui/models/MediaUi.kt index c40d8d08f..f576e947d 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/models/MediaUi.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/models/MediaUi.kt @@ -1,6 +1,8 @@ package com.karrar.movieapp.ui.models -data class MediaUiState( +data class MediaUi( val id: Int = 0, - val imageUrl: String = "" + val title: String = "", + val imageUrl: String = "", + val rate: String = "0.0" ) diff --git a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/DetailItem.kt b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/DetailItem.kt index 122a31b20..827e29550 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/DetailItem.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/DetailItem.kt @@ -3,7 +3,6 @@ package com.karrar.movieapp.ui.movieDetails import androidx.lifecycle.ViewModel import com.karrar.movieapp.domain.models.* import com.karrar.movieapp.ui.models.ActorUiState -import com.karrar.movieapp.ui.models.MediaUiState //sealed class DetailItem(val priority: Int) { diff --git a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/MovieDetailsViewModel.kt b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/MovieDetailsViewModel.kt index 1b8230357..77c9edb12 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/MovieDetailsViewModel.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/MovieDetailsViewModel.kt @@ -115,13 +115,13 @@ class MovieDetailsViewModel @Inject constructor( viewModelScope.launch { try { val result = getMovieDetailsUseCase.getSimilarMovie(movieId) - _uiState.update { + /*_uiState.update { it.copy( similarMoviesResult = result.map { media -> mediaUIStateMapper.map(media) }, isLoading = false ) - } + }*/ onAddMovieDetailsItemOfNestedView( DetailItemUIState.SimilarMovies(_uiState.value.similarMoviesResult) ) diff --git a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/mapper/MediaUIStateMapper.kt b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/mapper/MediaUIStateMapper.kt index f4b17464f..d287dfa3e 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/mapper/MediaUIStateMapper.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/mapper/MediaUIStateMapper.kt @@ -2,12 +2,12 @@ package com.karrar.movieapp.ui.movieDetails.mapper import com.karrar.movieapp.domain.mappers.Mapper import com.karrar.movieapp.domain.models.Media -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi import javax.inject.Inject -class MediaUIStateMapper @Inject constructor() : Mapper { - override fun map(input: Media): MediaUiState { - return MediaUiState( +class MediaUIStateMapper @Inject constructor() : Mapper { + override fun map(input: Media): MediaUi { + return MediaUi( id = input.mediaID, imageUrl = input.mediaImage, ) diff --git a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/DetailItemUIState.kt b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/DetailItemUIState.kt index 4b508e627..326d51051 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/DetailItemUIState.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/DetailItemUIState.kt @@ -2,7 +2,7 @@ package com.karrar.movieapp.ui.movieDetails.movieDetailsUIState import androidx.lifecycle.ViewModel import com.karrar.movieapp.ui.models.ActorUiState -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi sealed class DetailItemUIState(val priority: Int) { @@ -10,7 +10,7 @@ sealed class DetailItemUIState(val priority: Int) { class Cast(val data: List) : DetailItemUIState(1) - class SimilarMovies(val data: List) : DetailItemUIState(2) + class SimilarMovies(val data: List) : DetailItemUIState(2) class Comment(val data: ReviewUIState) : DetailItemUIState(6) diff --git a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/MovieUIState.kt b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/MovieUIState.kt index de41d9039..6ba14e0dc 100644 --- a/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/MovieUIState.kt +++ b/app/src/main/java/com/karrar/movieapp/ui/movieDetails/movieDetailsUIState/MovieUIState.kt @@ -1,12 +1,12 @@ package com.karrar.movieapp.ui.movieDetails.movieDetailsUIState import com.karrar.movieapp.ui.models.ActorUiState -import com.karrar.movieapp.ui.models.MediaUiState +import com.karrar.movieapp.ui.models.MediaUi data class MovieUIState( val movieDetailsResult: MovieDetailsUIState = MovieDetailsUIState(), val movieCastResult: List = emptyList(), - val similarMoviesResult: List = emptyList(), + val similarMoviesResult: List = emptyList(), val movieReview: List = emptyList(), val detailItemResult: List = mutableListOf(), val ratingValue: Float = 0F, diff --git a/app/src/main/java/com/karrar/movieapp/utilities/Event.kt b/app/src/main/java/com/karrar/movieapp/utilities/Event.kt index 81163d780..0b319780d 100644 --- a/app/src/main/java/com/karrar/movieapp/utilities/Event.kt +++ b/app/src/main/java/com/karrar/movieapp/utilities/Event.kt @@ -19,11 +19,10 @@ open class Event(private val content: T) { fun peekContent(): T = content } -class EventObserve(private val onEventUnhandledContent:(T) ->Unit) - : Observer> { - override fun onChanged(event: Event?) { - event?.getContentIfNotHandled()?.let { +class EventObserve(private val onEventUnhandledContent: (T) -> Unit) : Observer> { + override fun onChanged(event: Event) { + event.getContentIfNotHandled()?.let { onEventUnhandledContent(it) } } -} \ No newline at end of file +} diff --git a/app/src/main/res/drawable/cast_card_shape.xml b/app/src/main/res/drawable/cast_card_shape.xml new file mode 100644 index 000000000..96affdb23 --- /dev/null +++ b/app/src/main/res/drawable/cast_card_shape.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/collection_card_background.xml b/app/src/main/res/drawable/collection_card_background.xml new file mode 100644 index 000000000..d5fffa173 --- /dev/null +++ b/app/src/main/res/drawable/collection_card_background.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/due_tone_folder.xml b/app/src/main/res/drawable/due_tone_folder.xml new file mode 100644 index 000000000..3265afe26 --- /dev/null +++ b/app/src/main/res/drawable/due_tone_folder.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/drawable/gradient_overlay.xml b/app/src/main/res/drawable/gradient_overlay.xml new file mode 100644 index 000000000..0d8c8f37c --- /dev/null +++ b/app/src/main/res/drawable/gradient_overlay.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_magic_stick.xml b/app/src/main/res/drawable/ic_magic_stick.xml new file mode 100644 index 000000000..1912aed39 --- /dev/null +++ b/app/src/main/res/drawable/ic_magic_stick.xml @@ -0,0 +1,29 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_star.xml b/app/src/main/res/drawable/ic_star.xml new file mode 100644 index 000000000..d80b15ea1 --- /dev/null +++ b/app/src/main/res/drawable/ic_star.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/item_featued_collection_background.xml b/app/src/main/res/drawable/item_featued_collection_background.xml new file mode 100644 index 000000000..a10ae4b24 --- /dev/null +++ b/app/src/main/res/drawable/item_featued_collection_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/app/src/main/res/drawable/outline_alt_arrow_right.xml b/app/src/main/res/drawable/outline_alt_arrow_right.xml new file mode 100644 index 000000000..810db12d8 --- /dev/null +++ b/app/src/main/res/drawable/outline_alt_arrow_right.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/poster.png b/app/src/main/res/drawable/poster.png new file mode 100644 index 000000000..a172e24b5 Binary files /dev/null and b/app/src/main/res/drawable/poster.png differ diff --git a/app/src/main/res/drawable/rating_background.xml b/app/src/main/res/drawable/rating_background.xml new file mode 100644 index 000000000..0f79ab346 --- /dev/null +++ b/app/src/main/res/drawable/rating_background.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_corners.xml b/app/src/main/res/drawable/rounded_corners.xml index 5c531c62e..d77dcdaac 100644 --- a/app/src/main/res/drawable/rounded_corners.xml +++ b/app/src/main/res/drawable/rounded_corners.xml @@ -1,4 +1,6 @@ - + + \ No newline at end of file diff --git a/app/src/main/res/drawable/star.xml b/app/src/main/res/drawable/star.xml new file mode 100644 index 000000000..92ec8734f --- /dev/null +++ b/app/src/main/res/drawable/star.xml @@ -0,0 +1,14 @@ + + + + diff --git a/app/src/main/res/font/manrope.xml b/app/src/main/res/font/manrope.xml new file mode 100644 index 000000000..5a11420e4 --- /dev/null +++ b/app/src/main/res/font/manrope.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/font/manrope_bold.ttf b/app/src/main/res/font/manrope_bold.ttf new file mode 100644 index 000000000..62a618393 Binary files /dev/null and b/app/src/main/res/font/manrope_bold.ttf differ diff --git a/app/src/main/res/font/manrope_extra_bold.ttf b/app/src/main/res/font/manrope_extra_bold.ttf new file mode 100644 index 000000000..2fa671c21 Binary files /dev/null and b/app/src/main/res/font/manrope_extra_bold.ttf differ diff --git a/app/src/main/res/font/manrope_extra_light.ttf b/app/src/main/res/font/manrope_extra_light.ttf new file mode 100644 index 000000000..c55745a49 Binary files /dev/null and b/app/src/main/res/font/manrope_extra_light.ttf differ diff --git a/app/src/main/res/font/manrope_light.ttf b/app/src/main/res/font/manrope_light.ttf new file mode 100644 index 000000000..8a771c26e Binary files /dev/null and b/app/src/main/res/font/manrope_light.ttf differ diff --git a/app/src/main/res/font/manrope_medium.ttf b/app/src/main/res/font/manrope_medium.ttf new file mode 100644 index 000000000..c6d28def6 Binary files /dev/null and b/app/src/main/res/font/manrope_medium.ttf differ diff --git a/app/src/main/res/font/manrope_regular.ttf b/app/src/main/res/font/manrope_regular.ttf new file mode 100644 index 000000000..9a108f1ce Binary files /dev/null and b/app/src/main/res/font/manrope_regular.ttf differ diff --git a/app/src/main/res/font/manrope_semibold.ttf b/app/src/main/res/font/manrope_semibold.ttf new file mode 100644 index 000000000..46a13d619 Binary files /dev/null and b/app/src/main/res/font/manrope_semibold.ttf differ diff --git a/app/src/main/res/layout/empty.xml b/app/src/main/res/layout/empty.xml index 10191a15f..2b3a3c167 100644 --- a/app/src/main/res/layout/empty.xml +++ b/app/src/main/res/layout/empty.xml @@ -26,7 +26,7 @@ app:lottie_rawRes="@raw/no_data" /> + app:layout_constraintTop_toBottomOf="@+id/secondary_title" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_list_details.xml b/app/src/main/res/layout/fragment_list_details.xml index d19182e2d..1df4db58c 100644 --- a/app/src/main/res/layout/fragment_list_details.xml +++ b/app/src/main/res/layout/fragment_list_details.xml @@ -57,7 +57,7 @@ app:lottie_rawRes="@raw/no_data" /> + app:layout_constraintTop_toBottomOf="@+id/secondary_title" /> diff --git a/app/src/main/res/layout/fragment_movie_details.xml b/app/src/main/res/layout/fragment_movie_details.xml index 8f849c68f..4a55757c1 100644 --- a/app/src/main/res/layout/fragment_movie_details.xml +++ b/app/src/main/res/layout/fragment_movie_details.xml @@ -18,7 +18,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/background_color" + android:background="@color/background_screen" android:overScrollMode="never" android:scrollbars="none" app:doneLoading="@{viewModel.uiState.loading}" diff --git a/app/src/main/res/layout/fragment_my_lists.xml b/app/src/main/res/layout/fragment_my_lists.xml index 89dde81dc..4b0058336 100644 --- a/app/src/main/res/layout/fragment_my_lists.xml +++ b/app/src/main/res/layout/fragment_my_lists.xml @@ -191,7 +191,7 @@ app:lottie_rawRes="@raw/no_data" /> + app:layout_constraintTop_toBottomOf="@+id/secondary_title" /> diff --git a/app/src/main/res/layout/fragment_tv_show_details.xml b/app/src/main/res/layout/fragment_tv_show_details.xml index 477248c84..974489e65 100644 --- a/app/src/main/res/layout/fragment_tv_show_details.xml +++ b/app/src/main/res/layout/fragment_tv_show_details.xml @@ -18,7 +18,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/background_color" + android:background="@color/background_screen" android:overScrollMode="never" app:doneLoading="@{viewModel.stateFlow.loading}" app:errorNotEmpty="@{viewModel.stateFlow.errorUIState}" diff --git a/app/src/main/res/layout/item_airing_today.xml b/app/src/main/res/layout/item_airing_today.xml index 23096a586..05b4c0ebd 100644 --- a/app/src/main/res/layout/item_airing_today.xml +++ b/app/src/main/res/layout/item_airing_today.xml @@ -13,7 +13,7 @@ + type="com.karrar.movieapp.ui.models.MediaUi" /> diff --git a/app/src/main/res/layout/item_cast.xml b/app/src/main/res/layout/item_cast.xml index cdd7594a9..be466c88c 100644 --- a/app/src/main/res/layout/item_cast.xml +++ b/app/src/main/res/layout/item_cast.xml @@ -15,43 +15,59 @@ + android:layout_width="200dp" + android:layout_marginHorizontal="6dp" + android:layout_marginVertical="6dp" + android:layout_height="64dp" + android:background="@drawable/cast_card_shape" + android:onClick="@{() -> listener.onClickActor(item.id)}"> + app:shapeAppearanceOverlay="@style/CastImgCorners" + tools:srcCompat="@drawable/image" /> + + + + android:textAlignment="textStart" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="@+id/cast_name" + app:layout_constraintTop_toBottomOf="@+id/cast_name" + tools:text="Bruce Wayne" /> - \ No newline at end of file + diff --git a/app/src/main/res/layout/item_collection.xml b/app/src/main/res/layout/item_collection.xml new file mode 100644 index 000000000..8cf5b3c09 --- /dev/null +++ b/app/src/main/res/layout/item_collection.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_featured_collection.xml b/app/src/main/res/layout/item_featured_collection.xml new file mode 100644 index 000000000..10ab7b6b5 --- /dev/null +++ b/app/src/main/res/layout/item_featured_collection.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_media.xml b/app/src/main/res/layout/item_media.xml index 7de55aeb9..807bded31 100644 --- a/app/src/main/res/layout/item_media.xml +++ b/app/src/main/res/layout/item_media.xml @@ -10,7 +10,7 @@ + type="com.karrar.movieapp.ui.models.MediaUi" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_movie.xml b/app/src/main/res/layout/item_movie.xml index 925c45393..fceb491d5 100644 --- a/app/src/main/res/layout/item_movie.xml +++ b/app/src/main/res/layout/item_movie.xml @@ -11,7 +11,7 @@ + type="com.karrar.movieapp.ui.models.MediaUi" /> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -14,81 +15,88 @@ + android:layout_height="match_parent" + android:paddingTop="@dimen/spacing_medium"> + - + app:layout_constraintVertical_bias="1.0" + app:shapeAppearanceOverlay="@style/CardCorners.Medium" /> + android:textColor="@color/shade_primary" + app:layout_constraintEnd_toEndOf="@+id/image_movie" + app:layout_constraintStart_toStartOf="@+id/image_movie" + app:layout_constraintTop_toBottomOf="@+id/image_movie" + tools:text="Until Dawn" /> + android:textColor="@color/shade_primary" + app:drawableEndCompat="@drawable/ic_star" + android:drawablePadding="@dimen/spacing_too_small" + app:layout_constraintEnd_toEndOf="@+id/image_movie" + app:layout_constraintTop_toTopOf="@+id/image_movie" + tools:text="7.5" /> + app:layout_constraintEnd_toEndOf="@+id/image_movie" + app:layout_constraintStart_toStartOf="@+id/image_movie" + app:layout_constraintTop_toBottomOf="@+id/text_movie_title" + tools:text="Mystery, Horror, Science Fiction" /> - + \ No newline at end of file diff --git a/app/src/main/res/layout/item_rating.xml b/app/src/main/res/layout/item_rating.xml index 493e8fa95..7de6042e1 100644 --- a/app/src/main/res/layout/item_rating.xml +++ b/app/src/main/res/layout/item_rating.xml @@ -15,7 +15,7 @@ android:layout_height="wrap_content"> + app:layout_constraintTop_toBottomOf="@+id/main_title" /> diff --git a/app/src/main/res/layout/item_suggestion.xml b/app/src/main/res/layout/item_suggestion.xml new file mode 100644 index 000000000..891674b26 --- /dev/null +++ b/app/src/main/res/layout/item_suggestion.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_tvshow.xml b/app/src/main/res/layout/item_tvshow.xml index 1053791f4..da68a29da 100644 --- a/app/src/main/res/layout/item_tvshow.xml +++ b/app/src/main/res/layout/item_tvshow.xml @@ -10,7 +10,7 @@ + type="com.karrar.movieapp.ui.models.MediaUi" /> + app:layout_constraintTop_toBottomOf="@+id/main_title" /> diff --git a/app/src/main/res/layout/list_cast.xml b/app/src/main/res/layout/list_cast.xml index 1c4802322..ad7348555 100644 --- a/app/src/main/res/layout/list_cast.xml +++ b/app/src/main/res/layout/list_cast.xml @@ -31,15 +31,16 @@ android:id="@+id/cast_adapter" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_small" - android:orientation="horizontal" + android:layout_marginTop="6dp" + android:adapter="@{adapterRecycler}" android:clipToPadding="false" + android:orientation="horizontal" android:paddingHorizontal="@dimen/spacing_small" - android:adapter="@{adapterRecycler}" - app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/cast" + app:spanCount="2" tools:listitem="@layout/item_cast" /> diff --git a/app/src/main/res/layout/list_collection.xml b/app/src/main/res/layout/list_collection.xml new file mode 100644 index 000000000..7d55a1d7f --- /dev/null +++ b/app/src/main/res/layout/list_collection.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/list_media.xml b/app/src/main/res/layout/list_media.xml new file mode 100644 index 000000000..e05229d35 --- /dev/null +++ b/app/src/main/res/layout/list_media.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/list_popular.xml b/app/src/main/res/layout/list_popular.xml index c03ced088..f6cca7b5a 100644 --- a/app/src/main/res/layout/list_popular.xml +++ b/app/src/main/res/layout/list_popular.xml @@ -11,19 +11,14 @@ - + tools:listitem="@layout/item_popular_movie"/> \ No newline at end of file diff --git a/app/src/main/res/layout/list_tv_shows.xml b/app/src/main/res/layout/list_tv_shows.xml deleted file mode 100644 index 7594a48c0..000000000 --- a/app/src/main/res/layout/list_tv_shows.xml +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 79f9a54d4..03aa3121c 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -16,4 +16,35 @@ #80737373 #99FFFFFF + + #132132 + #1B1C2A + #1B1C2A + #242533 + #E1E1E3 + #A4A4AA + #72727B + #2D2E3B + #242533 + #8C9EFF + #464D7B + #24263B + #8C9EFF + #24263B + #242533 + #1B1C2A + #E1E1E3 + #8C9EFF + #72727B + #24263B + #121321 + #121321 + #FF6B6B + #00E676 + #FFD600 + #2C202D + #232A31 + #2D2927 + + \ No newline at end of file diff --git a/app/src/main/res/values-night/strings.xml b/app/src/main/res/values-night/strings.xml new file mode 100644 index 000000000..697f601db --- /dev/null +++ b/app/src/main/res/values-night/strings.xml @@ -0,0 +1,4 @@ + + + Recently Released + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a3c7a39d1..37bd67079 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -23,5 +23,34 @@ #33737373 #9903050A + #F7F7F7 + #FFFFFF + #FFFFFF + #F6F6F6 + #313131 + #717171 + #A5A5A5 + #ECECEC + #F6F6F6 + #536DFE + #BEC8FF + #F1F3FF + #536DFE + #F1F3FF + #E5E5E5 + #FFFFFF + #313131 + #A5A5A5 + #536DFE + #ECECEC + #FFFFFF + #FFFFFF + #EF4444 + #22C55E + #FACC15 + #EBEEEE + #EEF5EF + #FFFAEB + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index f11c481fd..755f3d0a4 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -7,6 +7,10 @@ 8dp 4dp 88dp + 200dp + 48dp + 6dp + 12dp 72dp @@ -15,9 +19,10 @@ 350dp 20sp - 14sp + 16sp 12sp + 24dp 16dp @@ -27,4 +32,28 @@ 32dp + 40sp + 24sp + 20sp + 18sp + 16sp + + 16sp + 14sp + 12sp + + 12sp + + 2dp + 4dp + 8dp + 10dp + 12dp + 16dp + 20dp + 24dp + 28dp + 32dp + 1000dp + \ No newline at end of file diff --git a/app/src/main/res/values/font_certs.xml b/app/src/main/res/values/font_certs.xml new file mode 100644 index 000000000..d2226ac01 --- /dev/null +++ b/app/src/main/res/values/font_certs.xml @@ -0,0 +1,17 @@ + + + + @array/com_google_android_gms_fonts_certs_dev + @array/com_google_android_gms_fonts_certs_prod + + + + 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 + + + diff --git a/app/src/main/res/values/preloaded_fonts.xml b/app/src/main/res/values/preloaded_fonts.xml new file mode 100644 index 000000000..e79cd3f98 --- /dev/null +++ b/app/src/main/res/values/preloaded_fonts.xml @@ -0,0 +1,9 @@ + + + + @font/manrope + @font/manrope_bold + @font/manrope_medium + @font/manrope_semibold + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6f19e245..b8f149932 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -52,7 +52,7 @@ %1$d Minutes (%1$s reviews) Overview - Cast + Star Cast Similar Movies Rate The Movie Reviews @@ -102,4 +102,12 @@ No lists found %1$d. %2$s (%1$s Seasons) + Upcoming Movies + Your Collections + Show More + Recently Released + Let Us Choose For You! + We’ll help you skip the scroll and go straight to the good stuff. + image_card + Night forest background \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 6b0d8e04a..f164a38d6 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -79,7 +79,6 @@ @color/shade_ternary_color - @@ -130,6 +129,15 @@ 50% + + + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index 0287e7e3a..705978db1 100644 --- a/build.gradle +++ b/build.gradle @@ -3,17 +3,22 @@ buildscript { dependencies { - classpath 'com.google.dagger:hilt-android-gradle-plugin:2.42' + classpath 'com.google.gms:google-services:4.4.3' + classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.6' + classpath 'com.google.firebase:perf-plugin:2.0.1' + + + classpath 'com.google.dagger:hilt-android-gradle-plugin:2.57.1' //navigation - def nav_version = '2.4.1' + def nav_version = '2.9.3' classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" } } plugins { - id 'com.android.application' version '7.2.1' apply false - id 'com.android.library' version '7.2.1' apply false - id 'org.jetbrains.kotlin.android' version '1.7.10' apply false + id 'com.android.application' version '8.10.1' apply false + id 'com.android.library' version '8.10.1' apply false + id 'org.jetbrains.kotlin.android' version '2.2.10' apply false } task clean(type: Delete) { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5834dd9a6..be0a136de 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Sat Sep 24 00:18:55 TRT 2022 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME