From 9be872fbb817edb8f3f66145dd26aed73abcfd93 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Thu, 20 Jul 2023 01:33:00 +0900 Subject: [PATCH 01/13] Change page that doesn't need to be StateFlow but just variable --- .../main/java/com/jik/feature/popular/PopularViewModel.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt b/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt index f5ab9e8..0b1f68c 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt @@ -7,7 +7,6 @@ import com.jik.core.model.Movie import com.jik.core.ui.state.UiState import com.jik.core.ui.state.getUiStateFlow import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow import javax.inject.Inject @HiltViewModel @@ -15,13 +14,13 @@ class PopularViewModel @Inject constructor( private val movieRepository: MovieRepository ) : ViewModel() { - private val page = MutableStateFlow(FIRST_PAGE) + private var page = FIRST_PAGE val popularUiStates = mutableStateListOf() suspend fun getPopularMovies() { - getUiStateFlow { movieRepository.getPopularMovies(page.value) } + getUiStateFlow { movieRepository.getPopularMovies(page) } .collect { uiState -> when (uiState) { is UiState.Loading -> { @@ -32,7 +31,7 @@ class PopularViewModel @Inject constructor( } is UiState.Success -> { popularUiStates.addAll(uiState.data.map { PopularUiState.Data(it) }) - page.value++ + page++ } } } From db68eedcc8c78b1a6c633fe7bb100b986248eb9d Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Thu, 20 Jul 2023 01:33:42 +0900 Subject: [PATCH 02/13] Fix Poster can't Double Click --- .../jik/core/designsystem/component/Card.kt | 6 ++--- .../core/ui/util/modifier/clickableSingle.kt | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt index f09752a..7c39c99 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt @@ -2,7 +2,6 @@ package com.jik.core.designsystem.component import android.widget.Toast import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size @@ -24,6 +23,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import coil.compose.AsyncImage import com.jik.core.designsystem.theme.MovieTheme +import com.jik.core.ui.util.modifier.clickableSingle @Composable fun PosterCard( @@ -47,7 +47,7 @@ fun PosterCard( contentDescription = contentDescription, modifier = Modifier .fillMaxSize() - .clickable(enabled = clickable) { onClick() }, + .clickableSingle(enabled = clickable) { onClick() }, placeholder = placeholder, alignment = alignment, contentScale = contentScale @@ -79,7 +79,7 @@ fun GradientPosterCard( contentDescription = contentDescription, modifier = Modifier .fillMaxSize() - .clickable(enabled = clickable) { onClick() }, + .clickableSingle(enabled = clickable) { onClick() }, placeholder = placeholder, alignment = alignment, contentScale = contentScale diff --git a/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt b/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt new file mode 100644 index 0000000..814b461 --- /dev/null +++ b/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt @@ -0,0 +1,24 @@ +package com.jik.core.ui.util.modifier + +import androidx.compose.foundation.clickable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.composed + +fun Modifier.clickableSingle( + enabled: Boolean = true, + onClick: () -> Unit +): Modifier = composed { + + var lastClickTime by remember { mutableStateOf(0L) } + + this.clickable(enabled = enabled) { + if (System.currentTimeMillis() - lastClickTime > 1000L) { + lastClickTime = System.currentTimeMillis() + onClick() + } + } +} From ffdede1800f2a7cbe60092393e737c2b48bde2ac Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Tue, 25 Jul 2023 14:00:48 +0900 Subject: [PATCH 03/13] Remove PopularUiState(Sealed interface) --- .../com/jik/feature/popular/PopularScreen.kt | 15 ++++++++------ .../jik/feature/popular/PopularViewModel.kt | 20 +++++-------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt b/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt index 7085722..a1239df 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt @@ -17,7 +17,9 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.jik.core.designsystem.component.* +import com.jik.core.model.Movie import com.jik.core.ui.pagination.Pageable +import com.jik.core.ui.state.UiState import kotlinx.coroutines.launch @@ -33,6 +35,7 @@ fun PopularScreen( Column(modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) { PopularScreenTopBar(scrollBehavior = scrollBehavior) + PopularScreenContent( popularUiStates = popularViewModel.popularUiStates, onLoadMore = popularViewModel::getPopularMovies, @@ -57,7 +60,7 @@ fun PopularScreenTopBar(scrollBehavior: TopAppBarScrollBehavior) { @Composable fun PopularScreenContent( - popularUiStates: List, + popularUiStates: List>, onLoadMore: suspend () -> Unit, onRetry: suspend () -> Unit, onPosterClick: (Long) -> Unit, @@ -81,18 +84,18 @@ fun PopularScreenContent( ) { popularUiStates.forEachIndexed { index, uiState -> when (uiState) { - is PopularUiState.Data -> { + is UiState.Success -> { item { PosterCard( - posterPath = uiState.movie.getPosterUrl(), + posterPath = uiState.data.getPosterUrl(), modifier = Modifier .sizeIn(minWidth = 160.dp, minHeight = 240.dp) .aspectRatio(2f / 3f), - onClick = { onPosterClick(uiState.movie.id) } + onClick = { onPosterClick(uiState.data.id) } ) } } - is PopularUiState.Loading -> { + is UiState.Loading -> { if (index != popularUiStates.size - 1) return@forEachIndexed item(span = { GridItemSpan(maxLineSpan) }) { @@ -101,7 +104,7 @@ fun PopularScreenContent( } } } - is PopularUiState.Error -> { + is UiState.Error -> { if (index != popularUiStates.size - 1) return@forEachIndexed item(span = { GridItemSpan(maxLineSpan) }) { diff --git a/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt b/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt index 0b1f68c..dca1dd9 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt @@ -16,7 +16,7 @@ class PopularViewModel @Inject constructor( private var page = FIRST_PAGE - val popularUiStates = mutableStateListOf() + val popularUiStates = mutableStateListOf>() suspend fun getPopularMovies() { @@ -24,13 +24,13 @@ class PopularViewModel @Inject constructor( .collect { uiState -> when (uiState) { is UiState.Loading -> { - popularUiStates.add(PopularUiState.Loading) + popularUiStates.add(uiState) } is UiState.Error -> { - popularUiStates.add(PopularUiState.Error(uiState.throwable)) + popularUiStates.add(uiState) } is UiState.Success -> { - popularUiStates.addAll(uiState.data.map { PopularUiState.Data(it) }) + popularUiStates.addAll(uiState.data.map { UiState.Success(it) }) page++ } } @@ -40,14 +40,4 @@ class PopularViewModel @Inject constructor( companion object { private const val FIRST_PAGE = 1 } -} - - -sealed interface PopularUiState { - - object Loading : PopularUiState - - data class Data(val movie: Movie) : PopularUiState - - data class Error(val throwable: Throwable) : PopularUiState -} +} \ No newline at end of file From 5ca63b6c418942fced3b310474a62d0994a2771e Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Tue, 25 Jul 2023 14:02:50 +0900 Subject: [PATCH 04/13] Apply fold, Remove flowOn --- .../java/com/jik/core/ui/state/UiState.kt | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/core-ui/src/main/java/com/jik/core/ui/state/UiState.kt b/core-ui/src/main/java/com/jik/core/ui/state/UiState.kt index bb77627..ef5e16d 100644 --- a/core-ui/src/main/java/com/jik/core/ui/state/UiState.kt +++ b/core-ui/src/main/java/com/jik/core/ui/state/UiState.kt @@ -1,9 +1,6 @@ package com.jik.core.ui.state -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.onStart sealed interface UiState { @@ -14,17 +11,18 @@ sealed interface UiState { fun Result.toUiState(): UiState { - onSuccess { - return UiState.Success(it) - }.onFailure { - return UiState.Error(it) - } - return UiState.Loading + return fold( + onSuccess = { + UiState.Success(it) + }, + onFailure = { + UiState.Error(it) + } + ) } fun getUiStateFlow( - dispatcher: CoroutineDispatcher = Dispatchers.IO, block: suspend () -> Result, ) = flow { emit(block().toUiState()) -}.onStart { emit(UiState.Loading) }.flowOn(dispatcher) \ No newline at end of file +}.onStart { emit(UiState.Loading) } \ No newline at end of file From b026a277b8af878f5c6bbfabbdb59d3ab8d67e9b Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Fri, 28 Jul 2023 21:11:44 +0900 Subject: [PATCH 05/13] Remove unused code --- .../movie/navigation/TopLevelDestination.kt | 13 +---- .../main/java/com/jik/movie/ui/MovieApp.kt | 8 +-- .../java/com/jik/movie/ui/MovieAppState.kt | 6 -- .../data/repository/MovieRepositoryMock.kt | 55 ------------------- .../jik/core/designsystem/component/Card.kt | 4 +- .../core/designsystem/component/TopAppBar.kt | 4 +- .../com/jik/core/designsystem/theme/Theme.kt | 2 +- 7 files changed, 9 insertions(+), 83 deletions(-) delete mode 100644 core-data/src/main/java/com/jik/core/data/repository/MovieRepositoryMock.kt diff --git a/app/src/main/java/com/jik/movie/navigation/TopLevelDestination.kt b/app/src/main/java/com/jik/movie/navigation/TopLevelDestination.kt index 765e044..8fb069a 100644 --- a/app/src/main/java/com/jik/movie/navigation/TopLevelDestination.kt +++ b/app/src/main/java/com/jik/movie/navigation/TopLevelDestination.kt @@ -2,7 +2,6 @@ package com.jik.movie.navigation import androidx.compose.ui.graphics.vector.ImageVector import com.jik.core.designsystem.icon.MovieIcons -import com.jik.core.ui.R import com.jik.feature.home.navigation.HomeNavigation import com.jik.feature.popular.navigation.PopularNavigation import com.jik.feature.home.R as homeR @@ -11,23 +10,17 @@ import com.jik.feature.popular.R as popularR enum class TopLevelDestination( val route: String, - val selectedIcon: ImageVector, - val unselectedIcon: ImageVector, + val icon: ImageVector, val iconTextId: Int, - val titleTextId: Int, ) { HOME( route = HomeNavigation.route, - selectedIcon = MovieIcons.HomeRounded, - unselectedIcon = MovieIcons.HomeRounded, + icon = MovieIcons.HomeRounded, iconTextId = homeR.string.home, - titleTextId = R.string.app_name ), POPULAR( route = PopularNavigation.route, - selectedIcon = MovieIcons.LocalFireDepartmentRounded, - unselectedIcon = MovieIcons.LocalFireDepartmentRounded, + icon = MovieIcons.LocalFireDepartmentRounded, iconTextId = popularR.string.popular, - titleTextId = popularR.string.popular ) } \ No newline at end of file diff --git a/app/src/main/java/com/jik/movie/ui/MovieApp.kt b/app/src/main/java/com/jik/movie/ui/MovieApp.kt index 1ba4116..b82a14c 100644 --- a/app/src/main/java/com/jik/movie/ui/MovieApp.kt +++ b/app/src/main/java/com/jik/movie/ui/MovieApp.kt @@ -15,9 +15,7 @@ import com.jik.movie.navigation.TopLevelDestination @Composable fun MovieApp() { - MovieTheme( - dynamicColor = false - ) { + MovieTheme { val appState = rememberMovieAppState() val destination = appState.currentTopLevelDestination @@ -63,8 +61,8 @@ fun MovieBottomBar( MovieNavigationBarItem( selected = selected, onClick = { onNavigateToDestination(destination) }, - iconImageVector = destination.selectedIcon, - selectedIconImageVector = destination.selectedIcon, + iconImageVector = destination.icon, + selectedIconImageVector = destination.icon, labelTextId = destination.iconTextId, ) } diff --git a/app/src/main/java/com/jik/movie/ui/MovieAppState.kt b/app/src/main/java/com/jik/movie/ui/MovieAppState.kt index a9a2302..30cf11e 100644 --- a/app/src/main/java/com/jik/movie/ui/MovieAppState.kt +++ b/app/src/main/java/com/jik/movie/ui/MovieAppState.kt @@ -1,7 +1,5 @@ package com.jik.movie.ui -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import androidx.compose.runtime.remember @@ -33,10 +31,6 @@ class MovieAppState( val navController: NavHostController, ) { - @OptIn(ExperimentalMaterial3Api::class) - val topAppBarScrollBehavior - @Composable get() = TopAppBarDefaults.enterAlwaysScrollBehavior() - private val currentDestination: NavDestination? @Composable get() = navController.currentBackStackEntryAsState().value?.destination diff --git a/core-data/src/main/java/com/jik/core/data/repository/MovieRepositoryMock.kt b/core-data/src/main/java/com/jik/core/data/repository/MovieRepositoryMock.kt deleted file mode 100644 index c604030..0000000 --- a/core-data/src/main/java/com/jik/core/data/repository/MovieRepositoryMock.kt +++ /dev/null @@ -1,55 +0,0 @@ -//package com.jik.core.data.repository -// -//import com.jik.core.model.Movie -//import com.jik.core.model.MovieInfo -// -//class MovieRepositoryMock() : MovieRepository { -// -// override fun getPopularMovies(): List { -// return listOf( -// Movie( -// id = 502356, -// title = "The Super Mario Bros. Movie", -// posterPath = "/qNBAXBIQlnOThrVvA6mA2B5ggV6.jpg" -// ), -// Movie( -// id = 677179, -// title = "Creed III", -// posterPath = "/vJU3rXSP9hwUuLeq8IpfsJShLOk.jpg" -// ), -// Movie( -// id = 76600, -// title = "Avatar: The Way of Water", -// posterPath = "/t6HIqrRAclMCA60NsSmeqe9RmNV.jpg" -// ), -// Movie( -// id = 638974, -// title = "Murder Mystery 2", -// posterPath = "/wdffZv8gIiWy6xr4t7hWBWtUwpl.jpg" -// ), -// ) -// } -// -// override fun getMovieInfo(id: Int): MovieInfo = -// MovieInfo( -// id = 76600, -// title = "Avatar: The Way of Water", -// genres = listOf( -// MovieInfo.Genre( -// id = 878, -// name = "Science Fiction" -// ), -// MovieInfo.Genre( -// id = 12, -// name = "Adventure" -// ), -// MovieInfo.Genre( -// id = 28, -// name = "Action" -// ) -// ), -// overview = "", -// posterPath = "", -// rating = 0.0 -// ) -//} \ No newline at end of file diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt index 7c39c99..d838bde 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/component/Card.kt @@ -128,9 +128,7 @@ enum class GradientArea { @Preview @Composable fun PosterCardPreview() { - MovieTheme( - dynamicColor = false - ) { + MovieTheme { val context = LocalContext.current PosterCard( posterPath = "https://image.tmdb.org/t/p/w500/qNBAXBIQlnOThrVvA6mA2B5ggV6.jpg", diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt index 4a9bf84..ddbe551 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt @@ -43,9 +43,7 @@ fun MovieTopAppBar( @ThemePreviews @Composable private fun TopAppBarPreview() { - MovieTheme( - dynamicColor = false - ) { + MovieTheme { MovieTopAppBar( titleRes = android.R.string.untitled, scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt index 6bec33c..5e2a7ca 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt @@ -73,7 +73,7 @@ private val isSdkHigher31 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S fun MovieTheme( darkTheme: Boolean = isSystemInDarkTheme(), // Dynamic color is available on Android 12+ - dynamicColor: Boolean = isSdkHigher31, + dynamicColor: Boolean = false, content: @Composable () -> Unit ) { val colorScheme = when { From 7f6a4c1e2e199a254afd5d3a96099599935d4dd3 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Sat, 29 Jul 2023 02:06:56 +0900 Subject: [PATCH 06/13] Update Type --- .../core/designsystem/component/TopAppBar.kt | 9 +- .../com/jik/core/designsystem/theme/Font.kt | 16 +++ .../com/jik/core/designsystem/theme/Theme.kt | 2 +- .../com/jik/core/designsystem/theme/Type.kt | 104 +++++++++++++----- .../java/com/jik/feature/home/HomeScreen.kt | 5 +- 5 files changed, 103 insertions(+), 33 deletions(-) create mode 100644 core-designsystem/src/main/java/com/jik/core/designsystem/theme/Font.kt diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt index ddbe551..5ff4c75 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/component/TopAppBar.kt @@ -5,8 +5,9 @@ import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.jik.core.designsystem.theme.MovieTheme import com.jik.core.ui.preview.ThemePreviews @@ -22,7 +23,8 @@ fun MovieTopAppBar( ), scrollBehavior: TopAppBarScrollBehavior? = null, titleFontFamily: FontFamily? = null, - titleFontSize: TextUnit = TextUnit.Unspecified, + titleStyle: TextStyle = MaterialTheme.typography.titleLarge, + titleWeight: FontWeight = FontWeight.Bold, ) { TopAppBar( title = { @@ -30,7 +32,8 @@ fun MovieTopAppBar( text = stringResource(id = titleRes), color = MaterialTheme.colorScheme.primary, fontFamily = titleFontFamily, - fontSize = titleFontSize + fontWeight = titleWeight, + style = titleStyle ) }, colors = colors, diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Font.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Font.kt new file mode 100644 index 0000000..b64a72c --- /dev/null +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Font.kt @@ -0,0 +1,16 @@ +package com.jik.core.designsystem.theme + +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import com.jik.core.designsystem.R + +object MovieFontFamily { + + val Sansita = FontFamily( + Font(R.font.sansita_blackitalic), + ) + + val LilitaOne = FontFamily( + Font(R.font.lilita_one), + ) +} \ No newline at end of file diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt index 5e2a7ca..279c599 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Theme.kt @@ -99,7 +99,7 @@ fun MovieTheme( MaterialTheme( colorScheme = colorScheme, - typography = Typography, + typography = MovieTypography, content = content ) } \ No newline at end of file diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Type.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Type.kt index 8354d11..a5feb05 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Type.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Type.kt @@ -2,46 +2,98 @@ package com.jik.core.designsystem.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp -import com.jik.core.designsystem.R -// Set of Material typography styles to start with -val Typography = Typography( - titleLarge = TextStyle( - fontWeight = FontWeight.Bold, +internal val MovieTypography = Typography( + displayLarge = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 57.sp, + lineHeight = 64.sp, + letterSpacing = (-0.25).sp, + ), + displayMedium = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 45.sp, + lineHeight = 52.sp, + letterSpacing = 0.sp, + ), + displaySmall = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 36.sp, + lineHeight = 44.sp, + letterSpacing = 0.sp, + ), + headlineLarge = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 32.sp, + lineHeight = 40.sp, + letterSpacing = 0.sp, + ), + headlineMedium = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 28.sp, + lineHeight = 36.sp, + letterSpacing = 0.sp, + ), + headlineSmall = TextStyle( + fontWeight = FontWeight.Normal, fontSize = 24.sp, + lineHeight = 32.sp, + letterSpacing = 0.sp, + ), + titleLarge = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 22.sp, lineHeight = 28.sp, - letterSpacing = 0.sp + letterSpacing = 0.sp, ), titleMedium = TextStyle( fontWeight = FontWeight.Bold, fontSize = 18.sp, lineHeight = 24.sp, - letterSpacing = 0.1.sp + letterSpacing = 0.1.sp, ), - bodyMedium = TextStyle( + titleSmall = TextStyle( fontWeight = FontWeight.Medium, fontSize = 14.sp, - lineHeight = 18.sp, - letterSpacing = 0.1.sp + lineHeight = 20.sp, + letterSpacing = 0.1.sp, ), - labelMedium = TextStyle( + bodyLarge = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp, + ), + bodyMedium = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.25.sp, + ), + bodySmall = TextStyle( + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.4.sp, + ), + labelLarge = TextStyle( fontWeight = FontWeight.Medium, fontSize = 14.sp, lineHeight = 20.sp, - letterSpacing = 0.1.sp - ) -) - - -object MovieFontFamily { - val Sansita = FontFamily( - Font(R.font.sansita_blackitalic), - ) - val LilitaOne = FontFamily( - Font(R.font.lilita_one), - ) -} \ No newline at end of file + letterSpacing = 0.1.sp, + ), + labelMedium = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp, + ), + labelSmall = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 10.sp, + lineHeight = 16.sp, + letterSpacing = 0.sp, + ), +) \ No newline at end of file diff --git a/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt b/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt index ef3cd76..c7611fe 100644 --- a/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt +++ b/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt @@ -13,7 +13,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.jik.core.designsystem.component.* @@ -166,14 +165,14 @@ fun HomeScreenTopBar( modifier: Modifier = Modifier, ) { MovieTopAppBar( - modifier = modifier, titleRes = com.jik.core.ui.R.string.logo, + modifier = modifier, colors = TopAppBarDefaults.topAppBarColors( containerColor = MaterialTheme.colorScheme.background.copy( alpha = 0.0f ) ), + titleStyle = MaterialTheme.typography.displayMedium, titleFontFamily = MovieFontFamily.LilitaOne, - titleFontSize = 40.sp ) } \ No newline at end of file From e2bd1d2e56e7ff8a7aadf11e7326362cf0b37ac2 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Sat, 29 Jul 2023 02:28:25 +0900 Subject: [PATCH 07/13] Refactor Minor Elements --- .../core/designsystem/component/Navigation.kt | 25 +++++++++---------- .../jik/core/designsystem/icon/MovieIcons.kt | 13 ++++------ .../com/jik/core/designsystem/theme/Color.kt | 3 --- .../source/MovieRemoteDataSourceImpl.kt | 1 + .../main/java/com/jik/core/ui/util/Toast.kt | 8 ------ .../core/ui/util/modifier/clickableSingle.kt | 4 ++- .../com/jik/feature/detail/DetailScreen.kt | 2 +- .../com/jik/feature/popular/PopularScreen.kt | 4 +-- .../jik/feature/popular/PopularViewModel.kt | 1 - 9 files changed, 23 insertions(+), 38 deletions(-) delete mode 100644 core-ui/src/main/java/com/jik/core/ui/util/Toast.kt diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/component/Navigation.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/component/Navigation.kt index f508a86..d9b9394 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/component/Navigation.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/component/Navigation.kt @@ -101,6 +101,18 @@ fun RowScope.MovieNavigationBarItem( } } +@Composable +private fun MovieNavigationBarItemIcon( + selected: Boolean, + iconImageVector: ImageVector, + selectedIconImageVector: ImageVector, +) { + Icon( + imageVector = if (selected) selectedIconImageVector else iconImageVector, + tint = if (selected) selectedIconColor() else unselectedIconColor(), + contentDescription = null + ) +} @Composable private fun MovieNavigationBarItemLabelAndIcon( @@ -128,19 +140,6 @@ private fun MovieNavigationBarItemLabelAndIcon( } } -@Composable -private fun MovieNavigationBarItemIcon( - selected: Boolean, - iconImageVector: ImageVector, - selectedIconImageVector: ImageVector, -) { - Icon( - imageVector = if (selected) selectedIconImageVector else iconImageVector, - tint = if (selected) selectedIconColor() else unselectedIconColor(), - contentDescription = null - ) -} - private object MovieNavigationBarItemDefaults { @Composable fun selectedIconColor() = MaterialTheme.colorScheme.onSurface diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/icon/MovieIcons.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/icon/MovieIcons.kt index 5a2f5cd..20c7ae7 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/icon/MovieIcons.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/icon/MovieIcons.kt @@ -1,23 +1,20 @@ package com.jik.core.designsystem.icon import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Home -import androidx.compose.material.icons.filled.LocalFireDepartment import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Star -import androidx.compose.material.icons.outlined.Home -import androidx.compose.material.icons.outlined.LocalFireDepartment import androidx.compose.material.icons.rounded.Home import androidx.compose.material.icons.rounded.LocalFireDepartment +import androidx.compose.ui.graphics.Color object MovieIcons { val Refresh = Icons.Filled.Refresh val Star = Icons.Filled.Star - val Home = Icons.Filled.Home val HomeRounded = Icons.Rounded.Home - val HomeOutlined = Icons.Outlined.Home - val LocalFireDepartment = Icons.Filled.LocalFireDepartment val LocalFireDepartmentRounded = Icons.Rounded.LocalFireDepartment - val LocalFireDepartmentOutlined = Icons.Outlined.LocalFireDepartment +} + +object IconColor { + val Star = Color(0xFFFFC72F) } \ No newline at end of file diff --git a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Color.kt b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Color.kt index d030fee..fcd6ba0 100644 --- a/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Color.kt +++ b/core-designsystem/src/main/java/com/jik/core/designsystem/theme/Color.kt @@ -2,9 +2,6 @@ package com.jik.core.designsystem.theme import androidx.compose.ui.graphics.Color -object IconColor { - val Star = Color(0xFFFFC72F) -} internal val md_theme_light_primary = Color(0xFFE21111) internal val md_theme_light_onPrimary = Color(0xFFFFFFFF) diff --git a/core-network/src/main/java/com/jik/core/network/source/MovieRemoteDataSourceImpl.kt b/core-network/src/main/java/com/jik/core/network/source/MovieRemoteDataSourceImpl.kt index d84265a..8962531 100644 --- a/core-network/src/main/java/com/jik/core/network/source/MovieRemoteDataSourceImpl.kt +++ b/core-network/src/main/java/com/jik/core/network/source/MovieRemoteDataSourceImpl.kt @@ -8,6 +8,7 @@ import javax.inject.Inject class MovieRemoteDataSourceImpl @Inject constructor( private val movieService: MovieService ) : MovieRemoteDataSource { + override suspend fun getPopularMovies(page: Int): Result> { return movieService.getPopularMovieList(page).mapCatching { it.results diff --git a/core-ui/src/main/java/com/jik/core/ui/util/Toast.kt b/core-ui/src/main/java/com/jik/core/ui/util/Toast.kt deleted file mode 100644 index d675db1..0000000 --- a/core-ui/src/main/java/com/jik/core/ui/util/Toast.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.jik.core.ui.util - -import android.content.Context -import android.widget.Toast - -fun toast(context: Context, message: String) { - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() -} \ No newline at end of file diff --git a/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt b/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt index 814b461..1953cb3 100644 --- a/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt +++ b/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt @@ -16,9 +16,11 @@ fun Modifier.clickableSingle( var lastClickTime by remember { mutableStateOf(0L) } this.clickable(enabled = enabled) { - if (System.currentTimeMillis() - lastClickTime > 1000L) { + if (System.currentTimeMillis() - lastClickTime > LAST_CLICK_TERM) { lastClickTime = System.currentTimeMillis() onClick() } } } + +private const val LAST_CLICK_TERM = 1000L \ No newline at end of file diff --git a/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt b/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt index 42f904a..3c8b59e 100644 --- a/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt +++ b/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt @@ -21,8 +21,8 @@ import com.jik.core.designsystem.component.GradientArea import com.jik.core.designsystem.component.GradientPosterCard import com.jik.core.designsystem.component.LoadingWheel import com.jik.core.designsystem.component.Refresh +import com.jik.core.designsystem.icon.IconColor import com.jik.core.designsystem.icon.MovieIcons -import com.jik.core.designsystem.theme.IconColor import com.jik.core.model.MovieInfo import com.jik.core.ui.state.UiState import com.jik.core.ui.util.MovieGenreUtils diff --git a/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt b/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt index a1239df..564f4c7 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt @@ -108,9 +108,7 @@ fun PopularScreenContent( if (index != popularUiStates.size - 1) return@forEachIndexed item(span = { GridItemSpan(maxLineSpan) }) { - Box( - modifier = Modifier.height(popularScreenHeight) - ) { + Box(modifier = Modifier.height(popularScreenHeight)) { Refresh( modifier = Modifier.align(Alignment.Center), onClick = { diff --git a/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt b/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt index dca1dd9..c6ca3ec 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/PopularViewModel.kt @@ -18,7 +18,6 @@ class PopularViewModel @Inject constructor( val popularUiStates = mutableStateListOf>() - suspend fun getPopularMovies() { getUiStateFlow { movieRepository.getPopularMovies(page) } .collect { uiState -> From 850255f182893eca6c1e65172a6ec621bd3c4d09 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Sat, 29 Jul 2023 22:47:02 +0900 Subject: [PATCH 08/13] Refactor Pageable --- .../java/com/jik/core/ui/pagination/Base.kt | 18 ++-------------- .../java/com/jik/core/ui/pagination/Grid.kt | 21 +++++++++---------- .../java/com/jik/core/ui/pagination/List.kt | 20 +++++++++--------- 3 files changed, 22 insertions(+), 37 deletions(-) diff --git a/core-ui/src/main/java/com/jik/core/ui/pagination/Base.kt b/core-ui/src/main/java/com/jik/core/ui/pagination/Base.kt index c855c80..da39249 100644 --- a/core-ui/src/main/java/com/jik/core/ui/pagination/Base.kt +++ b/core-ui/src/main/java/com/jik/core/ui/pagination/Base.kt @@ -1,14 +1,11 @@ package com.jik.core.ui.pagination -import androidx.compose.foundation.lazy.LazyListLayoutInfo -import androidx.compose.foundation.lazy.grid.LazyGridLayoutInfo import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.remember - -internal object Base { +internal object BasePageable { @Composable fun Operate(calculateShouldLoadMore: () -> Boolean, onLoadMore: suspend () -> Unit) { @@ -26,18 +23,7 @@ internal object Base { } // means that if the last visible item is 'threshold' or less from the end of the list, return true - fun calculateShouldLoadMore(layoutInfo: T, threshold: Int): Boolean { - val itemCount = when (layoutInfo) { - is LazyGridLayoutInfo -> layoutInfo.totalItemsCount - is LazyListLayoutInfo -> layoutInfo.totalItemsCount - else -> throw IllegalArgumentException("Unsupported layoutInfo type") - } - val lastVisibleItem = when (layoutInfo) { - is LazyGridLayoutInfo -> layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 - is LazyListLayoutInfo -> layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0 - else -> throw IllegalArgumentException("Unsupported layoutInfo type") - } - + fun calculateShouldLoadMore(itemCount: Int, lastVisibleItem: Int, threshold: Int): Boolean { return lastVisibleItem >= itemCount - threshold } } \ No newline at end of file diff --git a/core-ui/src/main/java/com/jik/core/ui/pagination/Grid.kt b/core-ui/src/main/java/com/jik/core/ui/pagination/Grid.kt index 42bb018..f34f473 100644 --- a/core-ui/src/main/java/com/jik/core/ui/pagination/Grid.kt +++ b/core-ui/src/main/java/com/jik/core/ui/pagination/Grid.kt @@ -2,9 +2,6 @@ package com.jik.core.ui.pagination import androidx.compose.foundation.lazy.grid.LazyGridState import androidx.compose.runtime.Composable -import com.jik.core.ui.pagination.Base.Operate -import com.jik.core.ui.pagination.Base.calculateShouldLoadMore - @Composable fun LazyGridState.Pageable( @@ -12,13 +9,15 @@ fun LazyGridState.Pageable( threshold: Int = 4 ) { - Operate( - onLoadMore = onLoadMore, - calculateShouldLoadMore = { - calculateShouldLoadMore( - layoutInfo = this.layoutInfo, - threshold = threshold - ) - } + val calculateShouldLoadMore = + BasePageable.calculateShouldLoadMore( + itemCount = layoutInfo.totalItemsCount, + lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0, + threshold = threshold + ) + + BasePageable.Operate( + calculateShouldLoadMore = { calculateShouldLoadMore }, + onLoadMore = onLoadMore ) } \ No newline at end of file diff --git a/core-ui/src/main/java/com/jik/core/ui/pagination/List.kt b/core-ui/src/main/java/com/jik/core/ui/pagination/List.kt index cb95a5e..b3ca8c4 100644 --- a/core-ui/src/main/java/com/jik/core/ui/pagination/List.kt +++ b/core-ui/src/main/java/com/jik/core/ui/pagination/List.kt @@ -2,8 +2,6 @@ package com.jik.core.ui.pagination import androidx.compose.foundation.lazy.LazyListState import androidx.compose.runtime.Composable -import com.jik.core.ui.pagination.Base.Operate -import com.jik.core.ui.pagination.Base.calculateShouldLoadMore @Composable fun LazyListState.Pageable( @@ -11,13 +9,15 @@ fun LazyListState.Pageable( threshold: Int = 4 ) { - Operate( - onLoadMore = onLoadMore, - calculateShouldLoadMore = { - calculateShouldLoadMore( - layoutInfo = this.layoutInfo, - threshold = threshold - ) - } + val calculateShouldLoadMore = + BasePageable.calculateShouldLoadMore( + itemCount = layoutInfo.totalItemsCount, + lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0, + threshold = threshold + ) + + BasePageable.Operate( + calculateShouldLoadMore = { calculateShouldLoadMore }, + onLoadMore = onLoadMore ) } \ No newline at end of file From d4ba9e5f97325b99649d6af27ea836abe6e10ad6 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Sat, 29 Jul 2023 22:49:49 +0900 Subject: [PATCH 09/13] Move navigate function from each Screen to NavHost so, Delete dependency between screen --- .../main/java/com/jik/movie/navigation/MovieNavHost.kt | 9 +++++++-- feature-home/build.gradle.kts | 1 - .../com/jik/feature/home/navigation/HomeNavigation.kt | 7 ++----- feature-popular/build.gradle.kts | 1 - .../jik/feature/popular/navigation/PopularNavigation.kt | 7 ++----- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt b/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt index fcf7b52..1cf1e0b 100644 --- a/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt +++ b/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt @@ -5,6 +5,7 @@ import androidx.compose.ui.Modifier import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import com.jik.feature.detail.navigation.DetailNavigation.installDetailScreen +import com.jik.feature.detail.navigation.DetailNavigation.navigateDetail import com.jik.feature.home.navigation.HomeNavigation import com.jik.feature.home.navigation.HomeNavigation.installHomeScreen import com.jik.feature.popular.navigation.PopularNavigation.installPopularScreen @@ -20,8 +21,12 @@ fun MovieNavHost( startDestination = startDestination, modifier = modifier ) { - installHomeScreen(navController) - installPopularScreen(navController) + installHomeScreen( + onPosterClick = { movieId -> navController.navigateDetail(movieId) } + ) + installPopularScreen( + onPosterClick = { movieId -> navController.navigateDetail(movieId) } + ) installDetailScreen() } } \ No newline at end of file diff --git a/feature-home/build.gradle.kts b/feature-home/build.gradle.kts index ee67b17..3d82807 100644 --- a/feature-home/build.gradle.kts +++ b/feature-home/build.gradle.kts @@ -50,7 +50,6 @@ dependencies { implementation(projects.coreUi) implementation(projects.coreModel) implementation(projects.coreData) - implementation(projects.featureDetail) implementation(libs.androidx.ktx) implementation(libs.androidx.runtime.ktx) diff --git a/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt b/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt index f1aa963..9cba917 100644 --- a/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt +++ b/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt @@ -6,7 +6,6 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import com.jik.core.ui.util.StatusBarColor -import com.jik.feature.detail.navigation.DetailNavigation.navigateDetail import com.jik.feature.home.HomeScreen object HomeNavigation { @@ -18,15 +17,13 @@ object HomeNavigation { } fun NavGraphBuilder.installHomeScreen( - navController: NavController + onPosterClick: (Long) -> Unit ) { composable( route = HomeNavigation.route ) { StatusBarColor(color = Color.Transparent) - HomeScreen( - onPosterClick = { movieId -> navController.navigateDetail(movieId) } - ) + HomeScreen(onPosterClick = onPosterClick) } } } \ No newline at end of file diff --git a/feature-popular/build.gradle.kts b/feature-popular/build.gradle.kts index 55b0f1a..66051c0 100644 --- a/feature-popular/build.gradle.kts +++ b/feature-popular/build.gradle.kts @@ -48,7 +48,6 @@ dependencies { implementation(projects.coreUi) implementation(projects.coreModel) implementation(projects.coreData) - implementation(projects.featureDetail) implementation(libs.androidx.ktx) implementation(libs.androidx.runtime.ktx) diff --git a/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt b/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt index 3cb7c60..b9b7f75 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt @@ -4,7 +4,6 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable -import com.jik.feature.detail.navigation.DetailNavigation.navigateDetail import com.jik.feature.popular.PopularScreen @@ -16,14 +15,12 @@ object PopularNavigation { } fun NavGraphBuilder.installPopularScreen( - navController: NavController, + onPosterClick: (Long) -> Unit ) { composable( route = PopularNavigation.route ) { - PopularScreen( - onPosterClick = { movieId -> navController.navigateDetail(movieId) }, - ) + PopularScreen(onPosterClick = onPosterClick) } } } \ No newline at end of file From c682008dc2753109bf0c2aeb81f6ec3eb7cf4bd0 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Sat, 29 Jul 2023 22:51:16 +0900 Subject: [PATCH 10/13] Change variable, function name --- app/src/main/java/com/jik/movie/MainActivity.kt | 5 ++--- .../java/com/jik/movie/splash/SplashScreen.kt | 9 ++++++--- .../java/com/jik/core/ui/util/DimensionUtils.kt | 4 ---- .../java/com/jik/feature/detail/DetailScreen.kt | 7 +++---- .../main/java/com/jik/feature/home/HomeScreen.kt | 16 ++++++++-------- .../com/jik/feature/popular/PopularScreen.kt | 8 ++++---- 6 files changed, 23 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/jik/movie/MainActivity.kt b/app/src/main/java/com/jik/movie/MainActivity.kt index 7e57c61..e4e3700 100644 --- a/app/src/main/java/com/jik/movie/MainActivity.kt +++ b/app/src/main/java/com/jik/movie/MainActivity.kt @@ -4,15 +4,14 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.core.view.WindowCompat -import com.jik.movie.splash.createSplashScreen +import com.jik.movie.splash.showSplashScreenWithDelay import com.jik.movie.ui.MovieApp import dagger.hilt.android.AndroidEntryPoint -import kotlin.time.Duration.Companion.seconds @AndroidEntryPoint class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { - createSplashScreen(delay = 1.2.seconds) + showSplashScreenWithDelay() super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/jik/movie/splash/SplashScreen.kt b/app/src/main/java/com/jik/movie/splash/SplashScreen.kt index 53258b2..d1e36fa 100644 --- a/app/src/main/java/com/jik/movie/splash/SplashScreen.kt +++ b/app/src/main/java/com/jik/movie/splash/SplashScreen.kt @@ -2,13 +2,16 @@ package com.jik.movie.splash import android.app.Activity import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.launch import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds -fun Activity.createSplashScreen(delay: Duration) { +fun Activity.showSplashScreenWithDelay(delay: Duration = 1.2.seconds) { installSplashScreen().setKeepOnScreenCondition { - runBlocking { + CoroutineScope(Dispatchers.Main).launch { delay(duration = delay) } false diff --git a/core-ui/src/main/java/com/jik/core/ui/util/DimensionUtils.kt b/core-ui/src/main/java/com/jik/core/ui/util/DimensionUtils.kt index 7a38e56..8293a37 100644 --- a/core-ui/src/main/java/com/jik/core/ui/util/DimensionUtils.kt +++ b/core-ui/src/main/java/com/jik/core/ui/util/DimensionUtils.kt @@ -2,10 +2,6 @@ package com.jik.core.ui.util import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.Dp - -@Composable -fun Dp.dpToPx() = with(LocalDensity.current) { this@dpToPx.toPx() } @Composable fun Int.pxToDp() = with(LocalDensity.current) { this@pxToDp.toDp() } \ No newline at end of file diff --git a/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt b/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt index 3c8b59e..df37ed0 100644 --- a/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt +++ b/feature-detail/src/main/java/com/jik/feature/detail/DetailScreen.kt @@ -47,7 +47,7 @@ fun DetailScreen( } } is UiState.Success -> { - DetailScreenContent( + Content( movieInfo = detailUiState.data, modifier = modifier ) @@ -66,7 +66,7 @@ fun DetailScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable -fun DetailScreenContent( +private fun Content( movieInfo: MovieInfo, modifier: Modifier = Modifier ) { @@ -167,8 +167,7 @@ private fun Genres(movieInfo: MovieInfo) { ) { Text( text = genre.name, - modifier = Modifier - .align(Alignment.Center), + modifier = Modifier.align(Alignment.Center), color = Color.White, style = MaterialTheme.typography.labelMedium, ) diff --git a/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt b/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt index c7611fe..dbbf333 100644 --- a/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt +++ b/feature-home/src/main/java/com/jik/feature/home/HomeScreen.kt @@ -32,7 +32,7 @@ fun HomeScreen( val mainMovie = homeViewModel.mainMovie.collectAsStateWithLifecycle().value Box(modifier = modifier) { - HomeScreenContent( + Content( modifier = Modifier .fillMaxSize() .verticalScroll(rememberScrollState()), @@ -43,12 +43,12 @@ fun HomeScreen( onRetry = homeViewModel::getPopularMovies, onPosterClick = onPosterClick ) - HomeScreenTopBar() + TopBar() } } @Composable -fun HomeScreenContent( +private fun Content( modifier: Modifier = Modifier, homeUiState: UiState, mainMovie: Movie, @@ -60,11 +60,11 @@ fun HomeScreenContent( val coroutineScope = rememberCoroutineScope() Column(modifier) { - HomeScreenTopContent( + TopContent( mainMovie = mainMovie, onPosterClick = onPosterClick, ) - HomeScreenPopularContent( + PopularContent( popularMovies = popularMovies, onLoadMore = onLoadMore, onPosterClick = onPosterClick @@ -94,7 +94,7 @@ fun HomeScreenContent( @Composable -fun HomeScreenTopContent( +private fun TopContent( mainMovie: Movie, modifier: Modifier = Modifier, onPosterClick: (Long) -> Unit, @@ -116,7 +116,7 @@ fun HomeScreenTopContent( @Composable -fun HomeScreenPopularContent( +fun PopularContent( modifier: Modifier = Modifier, popularMovies: List, onLoadMore: suspend () -> Unit, @@ -161,7 +161,7 @@ fun HomeScreenPopularContent( @OptIn(ExperimentalMaterial3Api::class) @Composable -fun HomeScreenTopBar( +private fun TopBar( modifier: Modifier = Modifier, ) { MovieTopAppBar( diff --git a/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt b/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt index 564f4c7..cceb714 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/PopularScreen.kt @@ -34,9 +34,9 @@ fun PopularScreen( val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() Column(modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) { - PopularScreenTopBar(scrollBehavior = scrollBehavior) + TopBar(scrollBehavior = scrollBehavior) - PopularScreenContent( + Content( popularUiStates = popularViewModel.popularUiStates, onLoadMore = popularViewModel::getPopularMovies, onRetry = popularViewModel::getPopularMovies, @@ -51,7 +51,7 @@ fun PopularScreen( @OptIn(ExperimentalMaterial3Api::class) @Composable -fun PopularScreenTopBar(scrollBehavior: TopAppBarScrollBehavior) { +private fun TopBar(scrollBehavior: TopAppBarScrollBehavior) { MovieTopAppBar( titleRes = R.string.popular, scrollBehavior = scrollBehavior @@ -59,7 +59,7 @@ fun PopularScreenTopBar(scrollBehavior: TopAppBarScrollBehavior) { } @Composable -fun PopularScreenContent( +private fun Content( popularUiStates: List>, onLoadMore: suspend () -> Unit, onRetry: suspend () -> Unit, From 618d40d1e59f005d49451c95b8daf13a4fa0653f Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Mon, 31 Jul 2023 21:57:35 +0900 Subject: [PATCH 11/13] Apply Detail Screen navigate Animation --- .../java/com/jik/movie/navigation/MovieNavHost.kt | 7 ++++++- .../jik/feature/detail/navigation/DetailNavigation.kt | 11 +++++++++-- .../com/jik/feature/home/navigation/HomeNavigation.kt | 2 ++ .../feature/popular/navigation/PopularNavigation.kt | 2 ++ gradle/libs.versions.toml | 2 +- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt b/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt index 1cf1e0b..7805fe4 100644 --- a/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt +++ b/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt @@ -1,5 +1,7 @@ package com.jik.movie.navigation +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.NavHostController @@ -27,6 +29,9 @@ fun MovieNavHost( installPopularScreen( onPosterClick = { movieId -> navController.navigateDetail(movieId) } ) - installDetailScreen() + installDetailScreen( + enterTransition = slideInHorizontally { it }, + exitTransition = slideOutHorizontally { it } + ) } } \ No newline at end of file diff --git a/feature-detail/src/main/java/com/jik/feature/detail/navigation/DetailNavigation.kt b/feature-detail/src/main/java/com/jik/feature/detail/navigation/DetailNavigation.kt index 33763f3..e6ef624 100644 --- a/feature-detail/src/main/java/com/jik/feature/detail/navigation/DetailNavigation.kt +++ b/feature-detail/src/main/java/com/jik/feature/detail/navigation/DetailNavigation.kt @@ -1,5 +1,6 @@ package com.jik.feature.detail.navigation +import androidx.compose.animation.* import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -28,10 +29,16 @@ object DetailNavigation { navigate("${route}/$movieId") } - fun NavGraphBuilder.installDetailScreen() { + @OptIn(ExperimentalAnimationApi::class) + fun NavGraphBuilder.installDetailScreen( + enterTransition: EnterTransition, + exitTransition: ExitTransition + ) { composable( route = routeWithArgs, - arguments = arguments + arguments = arguments, + enterTransition = { enterTransition }, + exitTransition = { exitTransition } ) { StatusBarColor(color = Color.Transparent) DetailScreen( diff --git a/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt b/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt index 9cba917..285442f 100644 --- a/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt +++ b/feature-home/src/main/java/com/jik/feature/home/navigation/HomeNavigation.kt @@ -1,5 +1,6 @@ package com.jik.feature.home.navigation +import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.ui.graphics.Color import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder @@ -16,6 +17,7 @@ object HomeNavigation { navigate(route, navOptions) } + @OptIn(ExperimentalAnimationApi::class) fun NavGraphBuilder.installHomeScreen( onPosterClick: (Long) -> Unit ) { diff --git a/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt b/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt index b9b7f75..25dc855 100644 --- a/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt +++ b/feature-popular/src/main/java/com/jik/feature/popular/navigation/PopularNavigation.kt @@ -1,5 +1,6 @@ package com.jik.feature.popular.navigation +import androidx.compose.animation.ExperimentalAnimationApi import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -14,6 +15,7 @@ object PopularNavigation { navigate(route, navOptions) } + @OptIn(ExperimentalAnimationApi::class) fun NavGraphBuilder.installPopularScreen( onPosterClick: (Long) -> Unit ) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 22864f4..9aa5eac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ ktx = "1.9.0" runtime-ktx = "2.6.1" compose = "1.4.3" compose-activity = "1.7.0" -compose-navigation = "2.6.0" +compose-navigation = "2.7.0-alpha01" accompanist = "0.30.1" material3 = "1.1.0-beta01" junit = "4.13.2" From e088fe788ca65fef2b82c1a0ff7e59180c3e81e7 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Mon, 31 Jul 2023 22:27:32 +0900 Subject: [PATCH 12/13] Apply bottomBar AnimatedVisibility --- .../com/jik/movie/navigation/MovieNavHost.kt | 8 +-- .../main/java/com/jik/movie/ui/MovieApp.kt | 66 +++++++++++-------- ...{clickableSingle.kt => ClickableSingle.kt} | 0 .../jik/core/ui/util/modifier/Condition.kt | 7 ++ 4 files changed, 50 insertions(+), 31 deletions(-) rename core-ui/src/main/java/com/jik/core/ui/util/modifier/{clickableSingle.kt => ClickableSingle.kt} (100%) create mode 100644 core-ui/src/main/java/com/jik/core/ui/util/modifier/Condition.kt diff --git a/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt b/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt index 7805fe4..550e3d5 100644 --- a/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt +++ b/app/src/main/java/com/jik/movie/navigation/MovieNavHost.kt @@ -1,7 +1,7 @@ package com.jik.movie.navigation -import androidx.compose.animation.slideInHorizontally -import androidx.compose.animation.slideOutHorizontally +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.NavHostController @@ -30,8 +30,8 @@ fun MovieNavHost( onPosterClick = { movieId -> navController.navigateDetail(movieId) } ) installDetailScreen( - enterTransition = slideInHorizontally { it }, - exitTransition = slideOutHorizontally { it } + enterTransition = slideInVertically { it }, + exitTransition = slideOutVertically { it } ) } } \ No newline at end of file diff --git a/app/src/main/java/com/jik/movie/ui/MovieApp.kt b/app/src/main/java/com/jik/movie/ui/MovieApp.kt index b82a14c..8c3d470 100644 --- a/app/src/main/java/com/jik/movie/ui/MovieApp.kt +++ b/app/src/main/java/com/jik/movie/ui/MovieApp.kt @@ -1,5 +1,8 @@ package com.jik.movie.ui +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold @@ -10,6 +13,7 @@ import com.jik.core.designsystem.component.MovieNavigationBar import com.jik.core.designsystem.component.MovieNavigationBarItem import com.jik.core.designsystem.component.NavigationBarCornerSize import com.jik.core.designsystem.theme.MovieTheme +import com.jik.core.ui.util.modifier.conditional import com.jik.movie.navigation.MovieNavHost import com.jik.movie.navigation.TopLevelDestination @@ -21,13 +25,12 @@ fun MovieApp() { Scaffold( bottomBar = { - if (destination != null) { - MovieBottomBar( - topLevelDestination = appState.topLevelDestinations, - currentDestination = destination, - onNavigateToDestination = appState::navigateToDestination, - ) - } + MovieBottomBar( + visible = destination != null, + topLevelDestination = appState.topLevelDestinations, + currentDestination = destination, + onNavigateToDestination = appState::navigateToDestination, + ) }, contentWindowInsets = WindowInsets(0.dp) ) { @@ -36,11 +39,13 @@ fun MovieApp() { MovieNavHost( navController = appState.navController, - modifier = Modifier.padding( - top = topPadding, - bottom = if (destination != null && bottomPadding > 0.dp) bottomPadding - NavigationBarCornerSize - else bottomPadding - ) + modifier = Modifier.conditional(destination != null) { + padding( + top = topPadding, + bottom = if (destination != null && bottomPadding > 0.dp) bottomPadding - NavigationBarCornerSize + else bottomPadding + ) + } ) } } @@ -48,24 +53,31 @@ fun MovieApp() { @Composable fun MovieBottomBar( + visible: Boolean, topLevelDestination: List, - currentDestination: TopLevelDestination, + currentDestination: TopLevelDestination?, modifier: Modifier = Modifier, onNavigateToDestination: (TopLevelDestination) -> Unit, ) { - MovieNavigationBar( - modifier = modifier, - content = { - topLevelDestination.forEach { destination -> - val selected = destination.route == currentDestination.route - MovieNavigationBarItem( - selected = selected, - onClick = { onNavigateToDestination(destination) }, - iconImageVector = destination.icon, - selectedIconImageVector = destination.icon, - labelTextId = destination.iconTextId, - ) + AnimatedVisibility( + visible = visible, + enter = slideInVertically { it }, + exit = slideOutVertically { it } + ) { + MovieNavigationBar( + modifier = modifier, + content = { + topLevelDestination.forEach { destination -> + val selected = destination.route == currentDestination?.route + MovieNavigationBarItem( + selected = selected, + onClick = { onNavigateToDestination(destination) }, + iconImageVector = destination.icon, + selectedIconImageVector = destination.icon, + labelTextId = destination.iconTextId, + ) + } } - } - ) + ) + } } \ No newline at end of file diff --git a/core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt b/core-ui/src/main/java/com/jik/core/ui/util/modifier/ClickableSingle.kt similarity index 100% rename from core-ui/src/main/java/com/jik/core/ui/util/modifier/clickableSingle.kt rename to core-ui/src/main/java/com/jik/core/ui/util/modifier/ClickableSingle.kt diff --git a/core-ui/src/main/java/com/jik/core/ui/util/modifier/Condition.kt b/core-ui/src/main/java/com/jik/core/ui/util/modifier/Condition.kt new file mode 100644 index 0000000..dc81e7b --- /dev/null +++ b/core-ui/src/main/java/com/jik/core/ui/util/modifier/Condition.kt @@ -0,0 +1,7 @@ +package com.jik.core.ui.util.modifier + +import androidx.compose.ui.Modifier + + +fun Modifier.conditional(condition: Boolean, modifier: Modifier.() -> Modifier): Modifier = + if (condition) this.modifier() else this \ No newline at end of file From 50ce51e9599d6019c5a0e781fb54017245a1cac4 Mon Sep 17 00:00:00 2001 From: jhg3410 <80373033+jhg3410@users.noreply.github.com> Date: Thu, 10 Aug 2023 22:13:28 +0900 Subject: [PATCH 13/13] Fix not Apply Delay on Splash --- .../main/java/com/jik/movie/splash/SplashScreen.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/jik/movie/splash/SplashScreen.kt b/app/src/main/java/com/jik/movie/splash/SplashScreen.kt index d1e36fa..5f0939f 100644 --- a/app/src/main/java/com/jik/movie/splash/SplashScreen.kt +++ b/app/src/main/java/com/jik/movie/splash/SplashScreen.kt @@ -10,10 +10,14 @@ import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds fun Activity.showSplashScreenWithDelay(delay: Duration = 1.2.seconds) { + var splashOut = true + + CoroutineScope(Dispatchers.Main).launch { + delay(delay) + splashOut = false + } + installSplashScreen().setKeepOnScreenCondition { - CoroutineScope(Dispatchers.Main).launch { - delay(duration = delay) - } - false + splashOut } } \ No newline at end of file