From ee695da0c711fb0e20a716c1dd755f53dce2f868 Mon Sep 17 00:00:00 2001 From: Eric Ampire Date: Sat, 4 Sep 2021 23:27:50 +0200 Subject: [PATCH] Refactoring --- .../android/androidstudycase/MainActivity.kt | 5 +- .../androidstudycase/app/AppNavigation.kt | 3 +- .../screen/explore/business/ExploreEffect.kt | 3 - .../explore/business/ExploreViewModel.kt | 40 +++------- .../explore/business/ExploreViewState.kt | 3 +- .../screen/explore/ui/ExploreScreen.kt | 80 ++++++++++++------- .../presentation/screen/main/ui/MainScreen.kt | 1 + app/src/main/res/values/strings.xml | 1 - .../domain/entity/Lottiefile.kt | 18 ++--- 9 files changed, 77 insertions(+), 77 deletions(-) diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/MainActivity.kt b/app/src/main/java/com/ericampire/android/androidstudycase/MainActivity.kt index 3a41ced..f98078e 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/MainActivity.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/MainActivity.kt @@ -3,11 +3,9 @@ package com.ericampire.android.androidstudycase import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.tooling.preview.Preview import com.ericampire.android.androidstudycase.presentation.screen.main.ui.MainScreen import com.ericampire.android.androidstudycase.presentation.theme.AndroidStudyCaseTheme import com.google.accompanist.pager.ExperimentalPagerApi @@ -15,6 +13,7 @@ import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { + @ExperimentalMaterialApi @ExperimentalPagerApi override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/app/AppNavigation.kt b/app/src/main/java/com/ericampire/android/androidstudycase/app/AppNavigation.kt index acb36c9..7b1f435 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/app/AppNavigation.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/app/AppNavigation.kt @@ -1,11 +1,11 @@ package com.ericampire.android.androidstudycase.app +import androidx.compose.material.ExperimentalMaterialApi import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import com.ericampire.android.androidstudycase.presentation.screen.explore.ui.ExploreScreen -import com.ericampire.android.androidstudycase.presentation.screen.home.business.HomeViewModel import com.ericampire.android.androidstudycase.presentation.screen.home.ui.HomeScreen import com.ericampire.android.androidstudycase.presentation.screen.preview.ui.PreviewScreen import com.ericampire.android.androidstudycase.util.Destination @@ -20,6 +20,7 @@ fun NavGraphBuilder.addHomeScreen(navController: NavController) { } } +@ExperimentalMaterialApi @ExperimentalPagerApi fun NavGraphBuilder.addExploreScreen(navController: NavController) { composable(Destination.Explore.route) { diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreEffect.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreEffect.kt index 87724ba..36a85fb 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreEffect.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreEffect.kt @@ -2,7 +2,4 @@ package com.ericampire.android.androidstudycase.presentation.screen.explore.busi sealed interface ExploreEffect { data class ShowErrorMessage(val message: String) : ExploreEffect - object Loading : ExploreEffect - object Success : ExploreEffect - object Idle : ExploreEffect } \ No newline at end of file diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt index e352ec0..7f97673 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewModel.kt @@ -32,48 +32,30 @@ class ExploreViewModel @Inject constructor( init { viewModelScope.launch { pendingAction.collectLatest { action -> - when(action) { - ExploreAction.FindFeaturedFile -> findFeaturedFile() - ExploreAction.FindPopularFile -> findPopularFile() - ExploreAction.FindRecentFile -> findRecentFile() + when (action) { + ExploreAction.FindFeaturedFile -> findFeaturedLottieFileUseCase(Unit).fetchData() + ExploreAction.FindPopularFile -> findPopularLottieFileUseCase(Unit).fetchData() + ExploreAction.FindRecentFile -> findRecentLottieFileUseCase(Unit).fetchData() } } } } - private fun Flow>>.fetchData() = intent { + private fun Flow>>.fetchData() = intent(registerIdling = false) { collect { result -> - when(result) { + when (result) { is Result.Error -> { val errorMessage = result.exception.localizedMessage ?: "Unknown Error" + reduce { state.copy(isLoading = false) } postSideEffect(ExploreEffect.ShowErrorMessage(errorMessage)) } - Result.Loading -> { - postSideEffect(ExploreEffect.Loading) + Result.Loading -> reduce { + state.copy(isLoading = true) } - is Result.Success -> { - postSideEffect(ExploreEffect.Success) - reduce { state.copy(files = result.data) } + is Result.Success -> reduce { + state.copy(files = result.data, isLoading = false) } } } } - - private fun findRecentFile() { - viewModelScope.launch { - findRecentLottieFileUseCase(Unit).fetchData() - } - } - - private fun findPopularFile() { - viewModelScope.launch { - findPopularLottieFileUseCase(Unit).fetchData() - } - } - - private fun findFeaturedFile() { - viewModelScope.launch { - findFeaturedLottieFileUseCase(Unit).fetchData() - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewState.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewState.kt index 3406c77..af0a64e 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewState.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/business/ExploreViewState.kt @@ -3,5 +3,6 @@ package com.ericampire.android.androidstudycase.presentation.screen.explore.busi import com.ericampire.android.androidstudycase.domain.entity.Lottiefile data class ExploreViewState( - val files: List = emptyList() + val files: List = emptyList(), + val isLoading: Boolean = false ) diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt index 1345bc4..357c471 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/explore/ui/ExploreScreen.kt @@ -1,8 +1,10 @@ package com.ericampire.android.androidstudycase.presentation.screen.explore.ui -import androidx.compose.animation.Crossfade +import android.widget.Toast import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.runtime.* @@ -10,27 +12,27 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringArrayResource -import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.navigation.NavController import com.ericampire.android.androidstudycase.R +import com.ericampire.android.androidstudycase.domain.entity.Lottiefile +import com.ericampire.android.androidstudycase.presentation.custom.LoadingView import com.ericampire.android.androidstudycase.presentation.custom.TopActionBar import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreAction import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreEffect import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreViewModel import com.ericampire.android.androidstudycase.presentation.theme.AppColor -import com.google.accompanist.insets.navigationBarsPadding -import com.google.accompanist.insets.statusBarsPadding import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.pagerTabIndicatorOffset import com.google.accompanist.pager.rememberPagerState import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import timber.log.Timber +@ExperimentalMaterialApi @ExperimentalPagerApi @Composable fun ExploreScreen( @@ -38,12 +40,22 @@ fun ExploreScreen( viewModel: ExploreViewModel ) { - val effects by viewModel.container.sideEffectFlow.collectAsState(ExploreEffect.Idle) + val coroutineScope = rememberCoroutineScope() val state by viewModel.container.stateFlow.collectAsState() + val context = LocalContext.current val tabItems = stringArrayResource(id = R.array.explore_item) val pagerState = rememberPagerState(pageCount = tabItems.size) - val coroutineScope = rememberCoroutineScope() + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { + when (it) { + is ExploreEffect.ShowErrorMessage -> { + Toast.makeText(context, it.message, Toast.LENGTH_LONG).show() + } + } + } + } LaunchedEffect(viewModel) { viewModel.submitAction(ExploreAction.FindRecentFile) @@ -62,7 +74,9 @@ fun ExploreScreen( Scaffold( topBar = { Column( - modifier = Modifier.fillMaxWidth().background(color = AppColor.Black001), + modifier = Modifier + .fillMaxWidth() + .background(color = AppColor.Black001), content = { TopActionBar() TabRow( @@ -108,27 +122,37 @@ fun ExploreScreen( ) }, content = { contentPadding -> - Crossfade(modifier = Modifier.padding(contentPadding), targetState = effects) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center, - content = { - when(it) { - ExploreEffect.Idle -> { - Timber.e("Idel") - } - ExploreEffect.Loading -> { - - } - is ExploreEffect.ShowErrorMessage -> { - - } - ExploreEffect.Success -> { - val data = state.files - Timber.e(data.toString()) - } - } + Box( + modifier = Modifier + .padding(contentPadding) + .fillMaxSize(), + contentAlignment = Alignment.Center, + content = { + if (state.isLoading) { + LoadingView() } + if (state.files.isNotEmpty()) { + ExploreContent(files = state.files) + } + } + ) + } + ) +} + +@ExperimentalMaterialApi +@Composable +fun ExploreContent( + modifier: Modifier = Modifier, + files: List +) { + LazyColumn( + modifier = modifier.fillMaxSize(), + content = { + items(items = files, key = { it.toString() }) { lottieFile -> + LottieFileItemView( + lottiefile = lottieFile, + onClick = {} ) } } diff --git a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/main/ui/MainScreen.kt b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/main/ui/MainScreen.kt index 4d1aff6..86937f8 100644 --- a/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/main/ui/MainScreen.kt +++ b/app/src/main/java/com/ericampire/android/androidstudycase/presentation/screen/main/ui/MainScreen.kt @@ -25,6 +25,7 @@ import com.google.accompanist.insets.navigationBarsPadding import com.google.accompanist.insets.statusBarsPadding import com.google.accompanist.pager.ExperimentalPagerApi +@ExperimentalMaterialApi @ExperimentalPagerApi @Composable fun MainScreen() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78cd624..e5f8fdc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,2 @@ - Android Study Case \ No newline at end of file diff --git a/domain/src/main/java/com/ericampire/android/androidstudycase/domain/entity/Lottiefile.kt b/domain/src/main/java/com/ericampire/android/androidstudycase/domain/entity/Lottiefile.kt index 3f4635b..9348c18 100644 --- a/domain/src/main/java/com/ericampire/android/androidstudycase/domain/entity/Lottiefile.kt +++ b/domain/src/main/java/com/ericampire/android/androidstudycase/domain/entity/Lottiefile.kt @@ -1,14 +1,10 @@ package com.ericampire.android.androidstudycase.domain.entity -import androidx.room.* -import com.ericampire.android.androidstudycase.domain.util.DateSerializer -import com.ericampire.android.androidstudycase.util.room.DateConverter -import kotlinx.serialization.Contextual -import kotlinx.serialization.ExperimentalSerializationApi -import java.util.* +import androidx.room.Entity +import androidx.room.Ignore +import androidx.room.PrimaryKey import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonNames @Serializable data class LottieFilesApiResponse( @@ -37,13 +33,13 @@ data class LottieFilesPage( @Serializable @Entity -class Lottiefile( +data class Lottiefile( @PrimaryKey var id: Long? = null, var bgColor: String = "", var lottieUrl: String = "", - var gifUrl: String = "", - var videoUrl: String = "", - var imageUrl: String = "", + var gifUrl: String? = "", + var videoUrl: String? = "", + var imageUrl: String? = "", var name: String = "", // @TypeConverters(DateConverter::class) // @Serializable(with = DateSerializer::class)