Refactoring

This commit is contained in:
2021-09-04 23:27:50 +02:00
parent f4a61138ee
commit ee695da0c7
9 changed files with 77 additions and 77 deletions
@@ -3,11 +3,9 @@ package com.ericampire.android.androidstudycase
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface 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.screen.main.ui.MainScreen
import com.ericampire.android.androidstudycase.presentation.theme.AndroidStudyCaseTheme import com.ericampire.android.androidstudycase.presentation.theme.AndroidStudyCaseTheme
import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.ExperimentalPagerApi
@@ -15,6 +13,7 @@ import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@ExperimentalMaterialApi
@ExperimentalPagerApi @ExperimentalPagerApi
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -1,11 +1,11 @@
package com.ericampire.android.androidstudycase.app package com.ericampire.android.androidstudycase.app
import androidx.compose.material.ExperimentalMaterialApi
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
import com.ericampire.android.androidstudycase.presentation.screen.explore.ui.ExploreScreen 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.home.ui.HomeScreen
import com.ericampire.android.androidstudycase.presentation.screen.preview.ui.PreviewScreen import com.ericampire.android.androidstudycase.presentation.screen.preview.ui.PreviewScreen
import com.ericampire.android.androidstudycase.util.Destination import com.ericampire.android.androidstudycase.util.Destination
@@ -20,6 +20,7 @@ fun NavGraphBuilder.addHomeScreen(navController: NavController) {
} }
} }
@ExperimentalMaterialApi
@ExperimentalPagerApi @ExperimentalPagerApi
fun NavGraphBuilder.addExploreScreen(navController: NavController) { fun NavGraphBuilder.addExploreScreen(navController: NavController) {
composable(Destination.Explore.route) { composable(Destination.Explore.route) {
@@ -2,7 +2,4 @@ package com.ericampire.android.androidstudycase.presentation.screen.explore.busi
sealed interface ExploreEffect { sealed interface ExploreEffect {
data class ShowErrorMessage(val message: String) : ExploreEffect data class ShowErrorMessage(val message: String) : ExploreEffect
object Loading : ExploreEffect
object Success : ExploreEffect
object Idle : ExploreEffect
} }
@@ -33,47 +33,29 @@ class ExploreViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
pendingAction.collectLatest { action -> pendingAction.collectLatest { action ->
when (action) { when (action) {
ExploreAction.FindFeaturedFile -> findFeaturedFile() ExploreAction.FindFeaturedFile -> findFeaturedLottieFileUseCase(Unit).fetchData()
ExploreAction.FindPopularFile -> findPopularFile() ExploreAction.FindPopularFile -> findPopularLottieFileUseCase(Unit).fetchData()
ExploreAction.FindRecentFile -> findRecentFile() ExploreAction.FindRecentFile -> findRecentLottieFileUseCase(Unit).fetchData()
} }
} }
} }
} }
private fun Flow<Result<List<Lottiefile>>>.fetchData() = intent { private fun Flow<Result<List<Lottiefile>>>.fetchData() = intent(registerIdling = false) {
collect { result -> collect { result ->
when (result) { when (result) {
is Result.Error -> { is Result.Error -> {
val errorMessage = result.exception.localizedMessage ?: "Unknown Error" val errorMessage = result.exception.localizedMessage ?: "Unknown Error"
reduce { state.copy(isLoading = false) }
postSideEffect(ExploreEffect.ShowErrorMessage(errorMessage)) postSideEffect(ExploreEffect.ShowErrorMessage(errorMessage))
} }
Result.Loading -> { Result.Loading -> reduce {
postSideEffect(ExploreEffect.Loading) state.copy(isLoading = true)
} }
is Result.Success -> { is Result.Success -> reduce {
postSideEffect(ExploreEffect.Success) state.copy(files = result.data, isLoading = false)
reduce { state.copy(files = result.data) }
} }
} }
} }
} }
private fun findRecentFile() {
viewModelScope.launch {
findRecentLottieFileUseCase(Unit).fetchData()
}
}
private fun findPopularFile() {
viewModelScope.launch {
findPopularLottieFileUseCase(Unit).fetchData()
}
}
private fun findFeaturedFile() {
viewModelScope.launch {
findFeaturedLottieFileUseCase(Unit).fetchData()
}
}
} }
@@ -3,5 +3,6 @@ package com.ericampire.android.androidstudycase.presentation.screen.explore.busi
import com.ericampire.android.androidstudycase.domain.entity.Lottiefile import com.ericampire.android.androidstudycase.domain.entity.Lottiefile
data class ExploreViewState( data class ExploreViewState(
val files: List<Lottiefile> = emptyList() val files: List<Lottiefile> = emptyList(),
val isLoading: Boolean = false
) )
@@ -1,8 +1,10 @@
package com.ericampire.android.androidstudycase.presentation.screen.explore.ui 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.background
import androidx.compose.foundation.layout.* 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.foundation.shape.RoundedCornerShape
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
@@ -10,27 +12,27 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.ericampire.android.androidstudycase.R 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.custom.TopActionBar
import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreAction 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.ExploreEffect
import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreViewModel import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreViewModel
import com.ericampire.android.androidstudycase.presentation.theme.AppColor 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.ExperimentalPagerApi
import com.google.accompanist.pager.pagerTabIndicatorOffset import com.google.accompanist.pager.pagerTabIndicatorOffset
import com.google.accompanist.pager.rememberPagerState import com.google.accompanist.pager.rememberPagerState
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber
@ExperimentalMaterialApi
@ExperimentalPagerApi @ExperimentalPagerApi
@Composable @Composable
fun ExploreScreen( fun ExploreScreen(
@@ -38,12 +40,22 @@ fun ExploreScreen(
viewModel: ExploreViewModel viewModel: ExploreViewModel
) { ) {
val effects by viewModel.container.sideEffectFlow.collectAsState(ExploreEffect.Idle) val coroutineScope = rememberCoroutineScope()
val state by viewModel.container.stateFlow.collectAsState() val state by viewModel.container.stateFlow.collectAsState()
val context = LocalContext.current
val tabItems = stringArrayResource(id = R.array.explore_item) val tabItems = stringArrayResource(id = R.array.explore_item)
val pagerState = rememberPagerState(pageCount = tabItems.size) 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) { LaunchedEffect(viewModel) {
viewModel.submitAction(ExploreAction.FindRecentFile) viewModel.submitAction(ExploreAction.FindRecentFile)
@@ -62,7 +74,9 @@ fun ExploreScreen(
Scaffold( Scaffold(
topBar = { topBar = {
Column( Column(
modifier = Modifier.fillMaxWidth().background(color = AppColor.Black001), modifier = Modifier
.fillMaxWidth()
.background(color = AppColor.Black001),
content = { content = {
TopActionBar() TopActionBar()
TabRow( TabRow(
@@ -108,27 +122,37 @@ fun ExploreScreen(
) )
}, },
content = { contentPadding -> content = { contentPadding ->
Crossfade(modifier = Modifier.padding(contentPadding), targetState = effects) {
Box( Box(
modifier = Modifier.fillMaxSize(), modifier = Modifier
.padding(contentPadding)
.fillMaxSize(),
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
content = { content = {
when(it) { if (state.isLoading) {
ExploreEffect.Idle -> { LoadingView()
Timber.e("Idel") }
if (state.files.isNotEmpty()) {
ExploreContent(files = state.files)
}
}
)
}
)
} }
ExploreEffect.Loading -> {
} @ExperimentalMaterialApi
is ExploreEffect.ShowErrorMessage -> { @Composable
fun ExploreContent(
} modifier: Modifier = Modifier,
ExploreEffect.Success -> { files: List<Lottiefile>
val data = state.files ) {
Timber.e(data.toString()) LazyColumn(
} modifier = modifier.fillMaxSize(),
} content = {
} items(items = files, key = { it.toString() }) { lottieFile ->
LottieFileItemView(
lottiefile = lottieFile,
onClick = {}
) )
} }
} }
@@ -25,6 +25,7 @@ import com.google.accompanist.insets.navigationBarsPadding
import com.google.accompanist.insets.statusBarsPadding import com.google.accompanist.insets.statusBarsPadding
import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.ExperimentalPagerApi
@ExperimentalMaterialApi
@ExperimentalPagerApi @ExperimentalPagerApi
@Composable @Composable
fun MainScreen() { fun MainScreen() {
-1
View File
@@ -1,3 +1,2 @@
<resources> <resources>
<string name="app_name">Android Study Case</string>
</resources> </resources>
@@ -1,14 +1,10 @@
package com.ericampire.android.androidstudycase.domain.entity package com.ericampire.android.androidstudycase.domain.entity
import androidx.room.* import androidx.room.Entity
import com.ericampire.android.androidstudycase.domain.util.DateSerializer import androidx.room.Ignore
import com.ericampire.android.androidstudycase.util.room.DateConverter import androidx.room.PrimaryKey
import kotlinx.serialization.Contextual
import kotlinx.serialization.ExperimentalSerializationApi
import java.util.*
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
@Serializable @Serializable
data class LottieFilesApiResponse( data class LottieFilesApiResponse(
@@ -37,13 +33,13 @@ data class LottieFilesPage(
@Serializable @Serializable
@Entity @Entity
class Lottiefile( data class Lottiefile(
@PrimaryKey var id: Long? = null, @PrimaryKey var id: Long? = null,
var bgColor: String = "", var bgColor: String = "",
var lottieUrl: String = "", var lottieUrl: String = "",
var gifUrl: String = "", var gifUrl: String? = "",
var videoUrl: String = "", var videoUrl: String? = "",
var imageUrl: String = "", var imageUrl: String? = "",
var name: String = "", var name: String = "",
// @TypeConverters(DateConverter::class) // @TypeConverters(DateConverter::class)
// @Serializable(with = DateSerializer::class) // @Serializable(with = DateSerializer::class)