From c244855152e46a8255921ff771e56ac0a7744614 Mon Sep 17 00:00:00 2001 From: taehwan Date: Tue, 21 May 2024 20:35:44 +0900 Subject: [PATCH 1/3] =?UTF-8?q?(FEAT)[#294]=20UI=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/core/designsystem/res/Painter.kt | 3 +- .../app/feature/bookmark/BookmarkScreen.kt | 6 ++ .../app/feature/bookmark/BookmarkViewModel.kt | 21 ++++-- .../bookmark/{ => component}/BookmarkCard.kt | 2 +- .../bookmark/{ => component}/BookmarkItem.kt | 12 +++- .../{ => component}/BookmarkTimeline.kt | 3 +- .../{ => model}/BookmarkItemUiState.kt | 3 +- .../bookmark/{ => model}/BookmarkUiState.kt | 6 +- .../contributor/ContributorScreenTest.kt | 1 + .../feature/contributor/ContributorScreen.kt | 21 +++--- .../contributor/ContributorViewModel.kt | 11 ++-- .../{ => model}/ContributorsUiState.kt | 6 +- .../contributor/ContributorViewModelTest.kt | 1 + .../app/feature/home/SponsorScreenTest.kt | 2 + .../app/feature/home/HomeScreen.kt | 21 ++++++ .../app/feature/home/HomeViewModel.kt | 39 ++++++----- .../app/feature/home/SponsorsUiState.kt | 35 ---------- .../home/{ => component}/ContributorCard.kt | 3 +- .../home/{ => component}/SessionCard.kt | 3 +- .../home/{ => component}/SponsorCard.kt | 30 +++++---- .../app/feature/home/model/SponsorsUiState.kt | 39 +++++++++++ ...SponsorsUiStatePreviewParameterProvider.kt | 6 +- .../app/feature/home/HomeViewModelTest.kt | 3 +- .../app/feature/main/MainScreen.kt | 2 +- .../feature/session/SessionDetailScreen.kt | 5 ++ .../feature/session/SessionDetailViewModel.kt | 36 +++++----- .../app/feature/session/SessionScreen.kt | 15 +++-- .../app/feature/session/SessionUiState.kt | 14 ---- .../app/feature/session/SessionViewModel.kt | 47 ++++++------- .../session/{ => component}/SessionCard.kt | 3 +- .../session/{ => component}/SessionChip.kt | 5 +- .../SessionDetailBookmarkStatePopup.kt | 3 +- .../{ => component}/SessionTopAppBar.kt | 4 +- .../{ => model}/SessionDetailEffect.kt | 2 +- .../{ => model}/SessionDetailUiState.kt | 2 +- .../session/{ => model}/SessionState.kt | 13 ++-- .../feature/session/model/SessionUiState.kt | 19 ++++++ .../session/SessionDetailViewModelTest.kt | 1 + .../feature/session/SessionViewModelTest.kt | 1 + .../app/feature/setting/SettingScreen.kt | 9 +-- .../setting/component/OpenSourceCard.kt | 66 +++++++++++++++++++ .../setting/opensource/OpenSourceCard.kt | 55 ---------------- 42 files changed, 347 insertions(+), 232 deletions(-) rename feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/{ => component}/BookmarkCard.kt (98%) rename feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/{ => component}/BookmarkItem.kt (90%) rename feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/{ => component}/BookmarkTimeline.kt (96%) rename feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/{ => model}/BookmarkItemUiState.kt (91%) rename feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/{ => model}/BookmarkUiState.kt (55%) rename feature/contributor/src/main/java/com/droidknights/app/feature/contributor/{ => model}/ContributorsUiState.kt (66%) delete mode 100644 feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiState.kt rename feature/home/src/main/java/com/droidknights/app/feature/home/{ => component}/ContributorCard.kt (96%) rename feature/home/src/main/java/com/droidknights/app/feature/home/{ => component}/SessionCard.kt (96%) rename feature/home/src/main/java/com/droidknights/app/feature/home/{ => component}/SponsorCard.kt (91%) create mode 100644 feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiState.kt rename feature/home/src/main/java/com/droidknights/app/feature/home/{ => model}/SponsorsUiStatePreviewParameterProvider.kt (89%) delete mode 100644 feature/session/src/main/java/com/droidknights/app/feature/session/SessionUiState.kt rename feature/session/src/main/java/com/droidknights/app/feature/session/{ => component}/SessionCard.kt (98%) rename feature/session/src/main/java/com/droidknights/app/feature/session/{ => component}/SessionChip.kt (92%) rename feature/session/src/main/java/com/droidknights/app/feature/session/{ => component}/SessionDetailBookmarkStatePopup.kt (94%) rename feature/session/src/main/java/com/droidknights/app/feature/session/{ => component}/SessionTopAppBar.kt (97%) rename feature/session/src/main/java/com/droidknights/app/feature/session/{ => model}/SessionDetailEffect.kt (85%) rename feature/session/src/main/java/com/droidknights/app/feature/session/{ => model}/SessionDetailUiState.kt (87%) rename feature/session/src/main/java/com/droidknights/app/feature/session/{ => model}/SessionState.kt (91%) create mode 100644 feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionUiState.kt create mode 100644 feature/setting/src/main/java/com/droidknights/app/feature/setting/component/OpenSourceCard.kt delete mode 100644 feature/setting/src/main/java/com/droidknights/app/feature/setting/opensource/OpenSourceCard.kt diff --git a/core/designsystem/src/main/java/com/droidknights/app/core/designsystem/res/Painter.kt b/core/designsystem/src/main/java/com/droidknights/app/core/designsystem/res/Painter.kt index 07ddd09c..3ebf2562 100644 --- a/core/designsystem/src/main/java/com/droidknights/app/core/designsystem/res/Painter.kt +++ b/core/designsystem/src/main/java/com/droidknights/app/core/designsystem/res/Painter.kt @@ -10,4 +10,5 @@ import com.droidknights.app.core.designsystem.theme.LocalDarkTheme fun rememberPainterResource( @DrawableRes lightId: Int, @DrawableRes darkId: Int = lightId, -): Painter = painterResource(id = if (LocalDarkTheme.current) darkId else lightId) +): Painter = + painterResource(id = if (LocalDarkTheme.current) darkId else lightId) diff --git a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkScreen.kt b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkScreen.kt index 5019489a..5aeaf5f0 100644 --- a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkScreen.kt +++ b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkScreen.kt @@ -31,6 +31,11 @@ import com.droidknights.app.core.designsystem.theme.DuskGray import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.designsystem.theme.PaleGray import com.droidknights.app.core.designsystem.theme.Purple01 +import com.droidknights.app.feature.bookmark.component.BookmarkCard +import com.droidknights.app.feature.bookmark.component.BookmarkItem +import com.droidknights.app.feature.bookmark.component.BookmarkTimelineItem +import com.droidknights.app.feature.bookmark.model.BookmarkItemUiState +import com.droidknights.app.feature.bookmark.model.BookmarkUiState import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.flow.collectLatest @@ -109,6 +114,7 @@ private fun BookmarkScreen( items = bookmarkItems, key = { item -> item.session.id } ) { itemState -> + /** 편집모드 나타내는 Trailing 컨텐츠를 이곳에 구현하세요 */ BookmarkItem( leadingContent = @Composable { BookmarkTimelineItem( diff --git a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkViewModel.kt b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkViewModel.kt index 22bfa120..3c1e0398 100644 --- a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkViewModel.kt +++ b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkViewModel.kt @@ -3,15 +3,18 @@ package com.droidknights.app.feature.bookmark import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.droidknights.app.core.domain.usecase.GetBookmarkedSessionsUseCase +import com.droidknights.app.feature.bookmark.model.BookmarkItemUiState +import com.droidknights.app.feature.bookmark.model.BookmarkUiState import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject +import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch +import javax.inject.Inject @HiltViewModel class BookmarkViewModel @Inject constructor( @@ -19,10 +22,10 @@ class BookmarkViewModel @Inject constructor( ) : ViewModel() { private val _errorFlow = MutableSharedFlow() - val errorFlow: SharedFlow get() = _errorFlow + val errorFlow = _errorFlow.asSharedFlow() private val _bookmarkUiState = MutableStateFlow(BookmarkUiState.Loading) - val bookmarkUiState: StateFlow = _bookmarkUiState + val bookmarkUiState = _bookmarkUiState.asStateFlow() init { viewModelScope.launch { @@ -42,6 +45,7 @@ class BookmarkViewModel @Inject constructor( isEditMode = false ) } + .toPersistentList() ) } @@ -55,6 +59,7 @@ class BookmarkViewModel @Inject constructor( isEditMode = bookmarkUiState.isEditButtonSelected ) } + .toPersistentList() ) } } @@ -72,7 +77,11 @@ class BookmarkViewModel @Inject constructor( _bookmarkUiState.value = state.copy( isEditButtonSelected = state.isEditButtonSelected.not(), - bookmarks = state.bookmarks.map { it.copy(isEditMode = !it.isEditMode.not()) } + bookmarks = state.bookmarks + .map { + it.copy(isEditMode = !it.isEditMode.not()) + } + .toPersistentList() ) } } diff --git a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkCard.kt b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkCard.kt similarity index 98% rename from feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkCard.kt rename to feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkCard.kt index 0fbe68a4..735df7d2 100644 --- a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkCard.kt +++ b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkCard.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.bookmark +package com.droidknights.app.feature.bookmark.component import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement diff --git a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkItem.kt b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkItem.kt similarity index 90% rename from feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkItem.kt rename to feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkItem.kt index 16d9b04f..84820a6c 100644 --- a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkItem.kt +++ b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkItem.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.bookmark +package com.droidknights.app.feature.bookmark.component import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize @@ -47,13 +47,19 @@ internal fun BookmarkItem( drawLine( color = LightGray, start = Offset(x = leadingContentWidth.toPx() / 2, y = 0F), - end = Offset(x = leadingContentWidth.toPx() / 2, y = (this.size.height / 2) - (leadingContentHeight.toPx() / 2)), + end = Offset( + x = leadingContentWidth.toPx() / 2, + y = (this.size.height / 2) - (leadingContentHeight.toPx() / 2) + ), strokeWidth = 1.dp.toPx() ) drawLine( color = LightGray, - start = Offset(x = leadingContentWidth.toPx() / 2, y = (this.size.height / 2) + (leadingContentHeight.toPx() / 2)), + start = Offset( + x = leadingContentWidth.toPx() / 2, + y = (this.size.height / 2) + (leadingContentHeight.toPx() / 2) + ), end = Offset(x = leadingContentWidth.toPx() / 2, y = this.size.height), strokeWidth = 1.dp.toPx() ) diff --git a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkTimeline.kt b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkTimeline.kt similarity index 96% rename from feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkTimeline.kt rename to feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkTimeline.kt index e9ade2c5..7739b0b3 100644 --- a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkTimeline.kt +++ b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/component/BookmarkTimeline.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.bookmark +package com.droidknights.app.feature.bookmark.component import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box @@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.designsystem.theme.Purple01 import com.droidknights.app.core.designsystem.theme.White +import com.droidknights.app.feature.bookmark.R import java.time.LocalTime import java.time.format.DateTimeFormatter diff --git a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkItemUiState.kt b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/model/BookmarkItemUiState.kt similarity index 91% rename from feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkItemUiState.kt rename to feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/model/BookmarkItemUiState.kt index b344d0b5..3bf737b4 100644 --- a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkItemUiState.kt +++ b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/model/BookmarkItemUiState.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.bookmark +package com.droidknights.app.feature.bookmark.model import com.droidknights.app.core.model.Session import java.time.LocalTime @@ -11,6 +11,7 @@ data class BookmarkItemUiState( val session: Session, val isEditMode: Boolean, ) { + val sequence: Int get() = index + 1 diff --git a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkUiState.kt b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/model/BookmarkUiState.kt similarity index 55% rename from feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkUiState.kt rename to feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/model/BookmarkUiState.kt index 06a03444..ee533d50 100644 --- a/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/BookmarkUiState.kt +++ b/feature/bookmark/src/main/java/com/droidknights/app/feature/bookmark/model/BookmarkUiState.kt @@ -1,7 +1,9 @@ -package com.droidknights.app.feature.bookmark +package com.droidknights.app.feature.bookmark.model import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf @Stable sealed interface BookmarkUiState { @@ -12,6 +14,6 @@ sealed interface BookmarkUiState { @Immutable data class Success( val isEditButtonSelected: Boolean = false, - val bookmarks: List = listOf(), + val bookmarks: ImmutableList = persistentListOf(), ) : BookmarkUiState } diff --git a/feature/contributor/src/androidTest/java/com/droidknights/app/feature/contributor/ContributorScreenTest.kt b/feature/contributor/src/androidTest/java/com/droidknights/app/feature/contributor/ContributorScreenTest.kt index 03b7afcb..9df82dbe 100644 --- a/feature/contributor/src/androidTest/java/com/droidknights/app/feature/contributor/ContributorScreenTest.kt +++ b/feature/contributor/src/androidTest/java/com/droidknights/app/feature/contributor/ContributorScreenTest.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText import com.droidknights.app.core.model.Contributor +import com.droidknights.app.feature.contributor.model.ContributorsUiState import kotlinx.collections.immutable.persistentListOf import org.junit.Before import org.junit.Rule diff --git a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt index 766967e7..174fa608 100644 --- a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt +++ b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt @@ -46,6 +46,7 @@ import com.droidknights.app.core.designsystem.theme.LocalDarkTheme import com.droidknights.app.core.designsystem.theme.Neon01 import com.droidknights.app.core.designsystem.theme.Neon05 import com.droidknights.app.core.model.Contributor +import com.droidknights.app.feature.contributor.model.ContributorsUiState import com.valentinilk.shimmer.shimmer import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.collectLatest @@ -161,6 +162,7 @@ private fun ContributorList( item { TopBanner() } + when (uiState) { ContributorsUiState.Loading -> { items(SHIMMERING_ITEM_COUNT) { @@ -181,6 +183,7 @@ private fun ContributorList( } } } + item { Footer(modifier = Modifier.padding(bottom = 16.dp)) } @@ -193,15 +196,15 @@ private fun ContributorItem( modifier: Modifier = Modifier, ) { val uriHandler = LocalUriHandler.current - val shimmerModifier = - if (contributor == null) { - Modifier - .clip(RoundedCornerShape(10.dp)) - .shimmer() - .background(color = MaterialTheme.colorScheme.outline) - } else { - Modifier - } + val shimmerModifier = if (contributor == null) { + Modifier + .clip(RoundedCornerShape(10.dp)) + .shimmer() + .background(color = MaterialTheme.colorScheme.outline) + } else { + Modifier + } + val placeholder = rememberPainterResource( lightId = R.drawable.ic_contributor_placeholder_lightmode, darkId = R.drawable.ic_contributor_placeholder_darkmode, diff --git a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorViewModel.kt b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorViewModel.kt index 2c65338a..98d2d40c 100644 --- a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorViewModel.kt +++ b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorViewModel.kt @@ -3,17 +3,18 @@ package com.droidknights.app.feature.contributor import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.droidknights.app.core.domain.usecase.GetContributorsUseCase +import com.droidknights.app.feature.contributor.model.ContributorsUiState import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn +import javax.inject.Inject @HiltViewModel class ContributorViewModel @Inject constructor( @@ -21,12 +22,14 @@ class ContributorViewModel @Inject constructor( ) : ViewModel() { private val _errorFlow = MutableSharedFlow() - val errorFlow: SharedFlow get() = _errorFlow + val errorFlow = _errorFlow.asSharedFlow() val uiState: StateFlow = flow { emit(getContributorsUseCase().toPersistentList()) } .map(ContributorsUiState::Contributors) - .catch { throwable -> _errorFlow.emit(throwable) } + .catch { throwable -> + _errorFlow.emit(throwable) + } .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), diff --git a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorsUiState.kt b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/model/ContributorsUiState.kt similarity index 66% rename from feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorsUiState.kt rename to feature/contributor/src/main/java/com/droidknights/app/feature/contributor/model/ContributorsUiState.kt index 10c47dcd..d21fedc6 100644 --- a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorsUiState.kt +++ b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/model/ContributorsUiState.kt @@ -1,9 +1,9 @@ -package com.droidknights.app.feature.contributor +package com.droidknights.app.feature.contributor.model import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import com.droidknights.app.core.model.Contributor -import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.ImmutableList @Stable sealed interface ContributorsUiState { @@ -13,6 +13,6 @@ sealed interface ContributorsUiState { @Immutable data class Contributors( - val contributors: PersistentList, + val contributors: ImmutableList, ) : ContributorsUiState } diff --git a/feature/contributor/src/test/java/com/droidknights/app/feature/contributor/ContributorViewModelTest.kt b/feature/contributor/src/test/java/com/droidknights/app/feature/contributor/ContributorViewModelTest.kt index c40e17a7..7f989cc4 100644 --- a/feature/contributor/src/test/java/com/droidknights/app/feature/contributor/ContributorViewModelTest.kt +++ b/feature/contributor/src/test/java/com/droidknights/app/feature/contributor/ContributorViewModelTest.kt @@ -4,6 +4,7 @@ import app.cash.turbine.test import com.droidknights.app.core.domain.usecase.GetContributorsUseCase import com.droidknights.app.core.model.Contributor import com.droidknights.app.core.testing.rule.MainDispatcherRule +import com.droidknights.app.feature.contributor.model.ContributorsUiState import io.mockk.coEvery import io.mockk.mockk import kotlin.test.assertIs diff --git a/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt b/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt index 3086e3fa..0414ca9d 100644 --- a/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt +++ b/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt @@ -5,6 +5,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithText import com.droidknights.app.core.model.Sponsor +import com.droidknights.app.feature.home.component.SponsorCard +import com.droidknights.app.feature.home.model.SponsorsUiState import org.junit.Before import org.junit.Rule import org.junit.Test diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt index af1c635e..396ad539 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt @@ -10,9 +10,16 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.droidknights.app.feature.home.component.ContributorCard +import com.droidknights.app.feature.home.component.SessionCard +import com.droidknights.app.feature.home.component.SponsorCard +import com.droidknights.app.feature.home.model.SponsorsUiState +import com.droidknights.app.feature.home.model.SponsorsUiStatePreviewParameterProvider import kotlinx.coroutines.flow.collectLatest @Composable @@ -58,3 +65,17 @@ private fun HomeScreen( SponsorCard(uiState = sponsorsUiState) } } + +@Preview +@Composable +private fun PreviewHomeScreen( + @PreviewParameter(SponsorsUiStatePreviewParameterProvider::class) + sponsorsUiState: SponsorsUiState, +) { + HomeScreen( + padding = PaddingValues(), + sponsorsUiState = sponsorsUiState, + onSessionClick = {}, + onContributorClick = {}, + ) +} \ No newline at end of file diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/HomeViewModel.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/HomeViewModel.kt index 66b35ad2..8bbd1c47 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/HomeViewModel.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/HomeViewModel.kt @@ -3,16 +3,18 @@ package com.droidknights.app.feature.home import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.droidknights.app.core.domain.usecase.GetSponsorsUseCase +import com.droidknights.app.feature.home.model.SponsorsUiState import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject +import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn +import javax.inject.Inject @HiltViewModel class HomeViewModel @Inject constructor( @@ -20,22 +22,23 @@ class HomeViewModel @Inject constructor( ) : ViewModel() { private val _errorFlow = MutableSharedFlow() - val errorFlow: SharedFlow get() = _errorFlow + val errorFlow get() = _errorFlow.asSharedFlow() - val sponsorsUiState: StateFlow = flow { emit(getSponsorsUseCase()) } - .map { sponsors -> - if (sponsors.isNotEmpty()) { - SponsorsUiState.Sponsors(sponsors) - } else { - SponsorsUiState.Empty + val sponsorsUiState: StateFlow = + flow { emit(getSponsorsUseCase()) } + .map { sponsors -> + if (sponsors.isNotEmpty()) { + SponsorsUiState.Sponsors(sponsors.toPersistentList()) + } else { + SponsorsUiState.Empty + } + } + .catch { throwable -> + _errorFlow.emit(throwable) } - } - .catch { throwable -> - _errorFlow.emit(throwable) - } - .stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5_000), - initialValue = SponsorsUiState.Loading, - ) + .stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = SponsorsUiState.Loading, + ) } diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiState.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiState.kt deleted file mode 100644 index 68cf8e03..00000000 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiState.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.droidknights.app.feature.home - -import androidx.compose.runtime.Immutable -import androidx.compose.runtime.Stable -import com.droidknights.app.core.model.Sponsor -import kotlinx.collections.immutable.PersistentList -import kotlinx.collections.immutable.toPersistentList - -@Stable -sealed interface SponsorsUiState { - - @Immutable - data object Loading : SponsorsUiState - - @Immutable - data object Empty : SponsorsUiState - - @Immutable - data class Sponsors( - val sponsors: List, - ) : SponsorsUiState { - - val platinumCount: Int = sponsors.count { it.grade == Sponsor.Grade.PLATINUM } - - val goldCount: Int = sponsors.count { it.grade == Sponsor.Grade.GOLD } - - val silverCount: Int = sponsors.count { it.grade == Sponsor.Grade.SILVER } - - val groupedSponsorsByGrade: PersistentList> = sponsors - .groupBy { it.grade } - .toSortedMap(compareBy { it.priority }) - .values - .toPersistentList() - } -} diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/ContributorCard.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/component/ContributorCard.kt similarity index 96% rename from feature/home/src/main/java/com/droidknights/app/feature/home/ContributorCard.kt rename to feature/home/src/main/java/com/droidknights/app/feature/home/component/ContributorCard.kt index 435852ce..5568a2eb 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/ContributorCard.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/component/ContributorCard.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.home +package com.droidknights.app.feature.home.component import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box @@ -18,6 +18,7 @@ import com.droidknights.app.core.designsystem.theme.Black import com.droidknights.app.core.designsystem.theme.Green03 import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.designsystem.theme.Neon05 +import com.droidknights.app.feature.home.R @Composable internal fun ContributorCard( diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/SessionCard.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/component/SessionCard.kt similarity index 96% rename from feature/home/src/main/java/com/droidknights/app/feature/home/SessionCard.kt rename to feature/home/src/main/java/com/droidknights/app/feature/home/component/SessionCard.kt index 932d96e3..151f70d3 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/SessionCard.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/component/SessionCard.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.home +package com.droidknights.app.feature.home.component import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -20,6 +20,7 @@ import com.droidknights.app.core.designsystem.theme.Black import com.droidknights.app.core.designsystem.theme.Graphite import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.designsystem.theme.White +import com.droidknights.app.feature.home.R @Composable internal fun SessionCard( diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorCard.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/component/SponsorCard.kt similarity index 91% rename from feature/home/src/main/java/com/droidknights/app/feature/home/SponsorCard.kt rename to feature/home/src/main/java/com/droidknights/app/feature/home/component/SponsorCard.kt index dc421e8c..3d8bd717 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorCard.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/component/SponsorCard.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.home +package com.droidknights.app.feature.home.component import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items @@ -22,11 +21,10 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.painter.ColorPainter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.painterResource @@ -39,11 +37,12 @@ import com.droidknights.app.core.designsystem.component.NetworkImage import com.droidknights.app.core.designsystem.theme.DuskGray import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.designsystem.theme.LightGray -import com.droidknights.app.core.designsystem.theme.PaleGray import com.droidknights.app.core.model.Sponsor +import com.droidknights.app.feature.home.R +import com.droidknights.app.feature.home.model.SponsorsUiState +import com.droidknights.app.feature.home.model.SponsorsUiStatePreviewParameterProvider import com.valentinilk.shimmer.shimmer -import kotlinx.collections.immutable.PersistentList -import kotlinx.collections.immutable.toPersistentList +import kotlinx.collections.immutable.ImmutableList @Composable internal fun SponsorCard(uiState: SponsorsUiState) { @@ -86,7 +85,7 @@ private fun SponsorCardContents(uiState: SponsorsUiState.Sponsors) { @Composable private fun SponsorGroup( - groupedSponsorsByGrade: PersistentList>, + groupedSponsorsByGrade: ImmutableList>, ) { Column( modifier = Modifier @@ -140,11 +139,14 @@ private fun SponsorLogo( sponsor: Sponsor, onClick: () -> Unit, ) { - val gradeIcon = when (sponsor.grade) { - Sponsor.Grade.GOLD -> R.drawable.ic_crown_gold - Sponsor.Grade.PLATINUM -> R.drawable.ic_crown_platinum - Sponsor.Grade.SILVER -> R.drawable.ic_crown_silver - } + val gradeIcon by rememberUpdatedState( + when (sponsor.grade) { + Sponsor.Grade.GOLD -> R.drawable.ic_crown_gold + Sponsor.Grade.PLATINUM -> R.drawable.ic_crown_platinum + Sponsor.Grade.SILVER -> R.drawable.ic_crown_silver + } + ) + Box( modifier = Modifier .padding(horizontal = 1.dp) diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiState.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiState.kt new file mode 100644 index 00000000..9c23d70d --- /dev/null +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiState.kt @@ -0,0 +1,39 @@ +package com.droidknights.app.feature.home.model + +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import com.droidknights.app.core.model.Sponsor +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toPersistentList + +@Stable +sealed interface SponsorsUiState { + + @Immutable + data object Loading : SponsorsUiState + + @Immutable + data object Empty : SponsorsUiState + + @Immutable + data class Sponsors( + val sponsors: ImmutableList, + ) : SponsorsUiState { + + val platinumCount: Int = + sponsors.count { it.grade == Sponsor.Grade.PLATINUM } + + val goldCount: Int = + sponsors.count { it.grade == Sponsor.Grade.GOLD } + + val silverCount: Int = + sponsors.count { it.grade == Sponsor.Grade.SILVER } + + val groupedSponsorsByGrade: ImmutableList> = + sponsors + .groupBy { it.grade } + .toSortedMap(compareBy { it.priority }) + .values + .toPersistentList() + } +} diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiStatePreviewParameterProvider.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiStatePreviewParameterProvider.kt similarity index 89% rename from feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiStatePreviewParameterProvider.kt rename to feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiStatePreviewParameterProvider.kt index 35382b5f..26c78c0c 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiStatePreviewParameterProvider.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiStatePreviewParameterProvider.kt @@ -1,13 +1,15 @@ -package com.droidknights.app.feature.home +package com.droidknights.app.feature.home.model import androidx.compose.ui.tooling.preview.PreviewParameterProvider import com.droidknights.app.core.model.Sponsor +import kotlinx.collections.immutable.persistentListOf internal class SponsorsUiStatePreviewParameterProvider : PreviewParameterProvider { + override val values: Sequence = sequenceOf( SponsorsUiState.Loading, SponsorsUiState.Sponsors( - sponsors = listOf( + sponsors = persistentListOf( Sponsor( name = "Sponsor1", homepage = "https://www.instagram.com/droid_knights", diff --git a/feature/home/src/test/java/com/droidknights/app/feature/home/HomeViewModelTest.kt b/feature/home/src/test/java/com/droidknights/app/feature/home/HomeViewModelTest.kt index acbce4e4..37c877ef 100644 --- a/feature/home/src/test/java/com/droidknights/app/feature/home/HomeViewModelTest.kt +++ b/feature/home/src/test/java/com/droidknights/app/feature/home/HomeViewModelTest.kt @@ -4,12 +4,13 @@ import app.cash.turbine.test import com.droidknights.app.core.domain.usecase.GetSponsorsUseCase import com.droidknights.app.core.model.Sponsor import com.droidknights.app.core.testing.rule.MainDispatcherRule +import com.droidknights.app.feature.home.model.SponsorsUiState import io.mockk.coEvery import io.mockk.mockk -import kotlin.test.assertIs import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test +import kotlin.test.assertIs internal class HomeViewModelTest { @get:Rule diff --git a/feature/main/src/main/java/com/droidknights/app/feature/main/MainScreen.kt b/feature/main/src/main/java/com/droidknights/app/feature/main/MainScreen.kt index 6015a738..6a90fcf3 100644 --- a/feature/main/src/main/java/com/droidknights/app/feature/main/MainScreen.kt +++ b/feature/main/src/main/java/com/droidknights/app/feature/main/MainScreen.kt @@ -42,10 +42,10 @@ import com.droidknights.app.feature.contributor.navigation.contributorNavGraph import com.droidknights.app.feature.home.navigation.homeNavGraph import com.droidknights.app.feature.session.navigation.sessionNavGraph import com.droidknights.app.feature.setting.navigation.settingNavGraph -import java.net.UnknownHostException import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.launch +import java.net.UnknownHostException @Composable internal fun MainScreen( diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailScreen.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailScreen.kt index f26f9335..a70e9610 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailScreen.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailScreen.kt @@ -49,6 +49,11 @@ import com.droidknights.app.core.model.Room import com.droidknights.app.core.model.Session import com.droidknights.app.core.model.Speaker import com.droidknights.app.core.model.Tag +import com.droidknights.app.feature.session.component.SessionDetailBookmarkStatePopup +import com.droidknights.app.feature.session.component.TimeChip +import com.droidknights.app.feature.session.component.TrackChip +import com.droidknights.app.feature.session.model.SessionDetailEffect +import com.droidknights.app.feature.session.model.SessionDetailUiState import com.droidknights.app.widget.sendWidgetUpdateCommand import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailViewModel.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailViewModel.kt index f840e333..67df83ec 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailViewModel.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailViewModel.kt @@ -5,41 +5,45 @@ import androidx.lifecycle.viewModelScope import com.droidknights.app.core.domain.usecase.BookmarkSessionUseCase import com.droidknights.app.core.domain.usecase.GetBookmarkedSessionIdsUseCase import com.droidknights.app.core.domain.usecase.GetSessionUseCase +import com.droidknights.app.feature.session.model.SessionDetailEffect +import com.droidknights.app.feature.session.model.SessionDetailUiState import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import javax.inject.Inject @HiltViewModel class SessionDetailViewModel @Inject constructor( private val getSessionUseCase: GetSessionUseCase, - private val getBookmarkedSessionIdsUseCase: GetBookmarkedSessionIdsUseCase, + getBookmarkedSessionIdsUseCase: GetBookmarkedSessionIdsUseCase, private val bookmarkSessionUseCase: BookmarkSessionUseCase, ) : ViewModel() { private val _sessionUiState = MutableStateFlow(SessionDetailUiState.Loading) - val sessionUiState: StateFlow = _sessionUiState + val sessionUiState = _sessionUiState.asStateFlow() private val _sessionUiEffect = MutableStateFlow(SessionDetailEffect.Idle) - val sessionUiEffect: StateFlow = _sessionUiEffect + val sessionUiEffect = _sessionUiEffect.asStateFlow() init { - viewModelScope.launch { - combine( - sessionUiState, - getBookmarkedSessionIdsUseCase(), - ) { sessionUiState, bookmarkIds -> - when (sessionUiState) { - is SessionDetailUiState.Loading -> sessionUiState - is SessionDetailUiState.Success -> { - sessionUiState.copy(bookmarked = bookmarkIds.contains(sessionUiState.session.id)) - } + combine( + sessionUiState, + getBookmarkedSessionIdsUseCase(), + ) { sessionUiState, bookmarkIds -> + when (sessionUiState) { + is SessionDetailUiState.Loading -> sessionUiState + is SessionDetailUiState.Success -> { + sessionUiState.copy(bookmarked = bookmarkIds.contains(sessionUiState.session.id)) } - }.collect { _sessionUiState.value = it } + } } + .onEach { _sessionUiState.value = it } + .launchIn(viewModelScope) } fun fetchSession(sessionId: String) { diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionScreen.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionScreen.kt index 116eb922..c48653cc 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionScreen.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionScreen.kt @@ -26,6 +26,11 @@ import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.model.Room import com.droidknights.app.core.model.Session import com.droidknights.app.core.ui.RoomText +import com.droidknights.app.feature.session.component.SessionCard +import com.droidknights.app.feature.session.component.SessionTopAppBar +import com.droidknights.app.feature.session.model.SessionState +import com.droidknights.app.feature.session.model.SessionUiState +import com.droidknights.app.feature.session.model.rememberSessionState import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.flow.collectLatest @@ -38,11 +43,13 @@ internal fun SessionScreen( sessionViewModel: SessionViewModel = hiltViewModel(), ) { val sessionUiState by sessionViewModel.uiState.collectAsStateWithLifecycle() - val sessionState = (sessionUiState as? SessionUiState.Sessions)?.sessions?.let { sessions -> - rememberSessionState(sessions = sessions) // SessionUiState.Sessions - } ?: rememberSessionState(sessions = persistentListOf()) // SessionUiState.Loading, SessionUiState.Error + val sessionState = (sessionUiState as? SessionUiState.Sessions)?.sessions + ?.let { sessions -> + rememberSessionState(sessions = sessions) // SessionUiState.Sessions + } + ?: rememberSessionState(sessions = persistentListOf()) // SessionUiState.Loading, SessionUiState.Error - LaunchedEffect(true) { + LaunchedEffect(Unit) { sessionViewModel.errorFlow.collectLatest { throwable -> onShowErrorSnackBar(throwable) } } diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionUiState.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionUiState.kt deleted file mode 100644 index ffafb975..00000000 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionUiState.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.droidknights.app.feature.session - -import com.droidknights.app.core.model.Session -import kotlinx.collections.immutable.PersistentList -import kotlinx.collections.immutable.persistentListOf - -sealed interface SessionUiState { - - data object Loading : SessionUiState - - data class Sessions( - val sessions: PersistentList = persistentListOf(), - ) : SessionUiState -} diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionViewModel.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionViewModel.kt index c7508b03..0a2de6dc 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionViewModel.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/SessionViewModel.kt @@ -4,47 +4,50 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.droidknights.app.core.domain.usecase.GetBookmarkedSessionIdsUseCase import com.droidknights.app.core.domain.usecase.GetSessionsUseCase +import com.droidknights.app.feature.session.model.SessionUiState import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import javax.inject.Inject @HiltViewModel class SessionViewModel @Inject constructor( - private val getSessionsUseCase: GetSessionsUseCase, - private val getBookmarkedSessionIdsUseCase: GetBookmarkedSessionIdsUseCase, + getSessionsUseCase: GetSessionsUseCase, + getBookmarkedSessionIdsUseCase: GetBookmarkedSessionIdsUseCase, ) : ViewModel() { private val _errorFlow = MutableSharedFlow() - val errorFlow: SharedFlow get() = _errorFlow + val errorFlow = _errorFlow.asSharedFlow() private val _uiState = MutableStateFlow(SessionUiState.Loading) - val uiState: StateFlow = _uiState.asStateFlow() + val uiState = _uiState.asStateFlow() init { - viewModelScope.launch { - val sessionsFlow = getSessionsUseCase() - val bookmarkedIdsFlow = getBookmarkedSessionIdsUseCase() - - sessionsFlow.combine(bookmarkedIdsFlow) { sessions, bookmarkedIds -> - val enhancedSessions = sessions.map { session -> - session.copy(isBookmarked = bookmarkedIds.contains(session.id)) - } - SessionUiState.Sessions( - sessions = enhancedSessions.toPersistentList() - ) - }.catch { throwable -> + combine( + getSessionsUseCase(), + getBookmarkedSessionIdsUseCase() + ) { sessions, bookmarkedIds -> + SessionUiState.Sessions( + sessions = sessions + .map { session -> + session.copy(isBookmarked = bookmarkedIds.contains(session.id)) + } + .toPersistentList() + ) + } + .catch { throwable -> _errorFlow.emit(throwable) - }.collect { combinedUiState -> + } + .onEach { combinedUiState -> _uiState.value = combinedUiState } - } + .launchIn(viewModelScope) } } diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionCard.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionCard.kt similarity index 98% rename from feature/session/src/main/java/com/droidknights/app/feature/session/SessionCard.kt rename to feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionCard.kt index 93aefe03..afd69a48 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionCard.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionCard.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.session +package com.droidknights.app.feature.session.component import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Box @@ -32,6 +32,7 @@ import com.droidknights.app.core.model.Room import com.droidknights.app.core.model.Session import com.droidknights.app.core.model.Speaker import com.droidknights.app.core.model.Tag +import com.droidknights.app.feature.session.R import kotlinx.datetime.LocalDateTime @Composable diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionChip.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionChip.kt similarity index 92% rename from feature/session/src/main/java/com/droidknights/app/feature/session/SessionChip.kt rename to feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionChip.kt index 687c2596..00ecb905 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionChip.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionChip.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.session +package com.droidknights.app.feature.session.component import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable @@ -7,9 +7,10 @@ import androidx.compose.ui.res.stringResource import com.droidknights.app.core.designsystem.component.TextChip import com.droidknights.app.core.model.Room import com.droidknights.app.core.ui.textRes -import java.time.format.DateTimeFormatter +import com.droidknights.app.feature.session.R import kotlinx.datetime.LocalDateTime import kotlinx.datetime.toJavaLocalDateTime +import java.time.format.DateTimeFormatter @Composable internal fun TrackChip(room: Room) { diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailBookmarkStatePopup.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionDetailBookmarkStatePopup.kt similarity index 94% rename from feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailBookmarkStatePopup.kt rename to feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionDetailBookmarkStatePopup.kt index 4dae8b7b..e3212ef3 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailBookmarkStatePopup.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionDetailBookmarkStatePopup.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.session +package com.droidknights.app.feature.session.component import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth @@ -16,6 +16,7 @@ import androidx.compose.ui.unit.dp import com.droidknights.app.core.designsystem.theme.Graphite import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.designsystem.theme.Purple01 +import com.droidknights.app.feature.session.R @Composable internal fun SessionDetailBookmarkStatePopup(bookmarked: Boolean) { diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionTopAppBar.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionTopAppBar.kt similarity index 97% rename from feature/session/src/main/java/com/droidknights/app/feature/session/SessionTopAppBar.kt rename to feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionTopAppBar.kt index a7d2f9de..bb2d35dc 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionTopAppBar.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/component/SessionTopAppBar.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.session +package com.droidknights.app.feature.session.component import android.content.res.Configuration import androidx.compose.animation.AnimatedVisibility @@ -42,6 +42,8 @@ import com.droidknights.app.core.designsystem.component.TopAppBarNavigationType import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.model.Room import com.droidknights.app.core.ui.RoomText +import com.droidknights.app.feature.session.R +import com.droidknights.app.feature.session.model.SessionState import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.launch diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailEffect.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionDetailEffect.kt similarity index 85% rename from feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailEffect.kt rename to feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionDetailEffect.kt index 1838d0a3..492e0946 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailEffect.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionDetailEffect.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.session +package com.droidknights.app.feature.session.model import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailUiState.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionDetailUiState.kt similarity index 87% rename from feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailUiState.kt rename to feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionDetailUiState.kt index daeff442..81fb0555 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionDetailUiState.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionDetailUiState.kt @@ -1,4 +1,4 @@ -package com.droidknights.app.feature.session +package com.droidknights.app.feature.session.model import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionState.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionState.kt similarity index 91% rename from feature/session/src/main/java/com/droidknights/app/feature/session/SessionState.kt rename to feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionState.kt index 85ecb4f2..205a2689 100644 --- a/feature/session/src/main/java/com/droidknights/app/feature/session/SessionState.kt +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionState.kt @@ -1,8 +1,9 @@ -package com.droidknights.app.feature.session +package com.droidknights.app.feature.session.model import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable import androidx.compose.runtime.derivedStateOf @@ -14,11 +15,13 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import com.droidknights.app.core.model.Room import com.droidknights.app.core.model.Session +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.mapNotNull +@Immutable data class SessionGroup( val room: Room, val sessions: PersistentList, @@ -26,10 +29,11 @@ data class SessionGroup( @Stable class SessionState( - private val sessions: PersistentList, + private val sessions: ImmutableList, val listState: LazyListState, selectedRoom: Room? = sessions.map { it.room }.firstOrNull(), ) { + val groups: List = sessions .groupBy { it.room } .map { (room, sessions) -> SessionGroup(room, sessions.toPersistentList()) } @@ -70,8 +74,9 @@ class SessionState( } companion object { + fun Saver( - sessions: PersistentList, + sessions: ImmutableList, listState: LazyListState, ): Saver = Saver( save = { it.selectedRoom }, @@ -88,7 +93,7 @@ class SessionState( @Composable internal fun rememberSessionState( - sessions: PersistentList, + sessions: ImmutableList, listState: LazyListState = rememberLazyListState(), ): SessionState { val state = rememberSaveable( diff --git a/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionUiState.kt b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionUiState.kt new file mode 100644 index 00000000..2873c18c --- /dev/null +++ b/feature/session/src/main/java/com/droidknights/app/feature/session/model/SessionUiState.kt @@ -0,0 +1,19 @@ +package com.droidknights.app.feature.session.model + +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import com.droidknights.app.core.model.Session +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +@Stable +sealed interface SessionUiState { + + @Immutable + data object Loading : SessionUiState + + @Immutable + data class Sessions( + val sessions: ImmutableList = persistentListOf(), + ) : SessionUiState +} diff --git a/feature/session/src/test/java/com/droidknights/app/feature/session/SessionDetailViewModelTest.kt b/feature/session/src/test/java/com/droidknights/app/feature/session/SessionDetailViewModelTest.kt index 6cd2f15a..041a38a0 100644 --- a/feature/session/src/test/java/com/droidknights/app/feature/session/SessionDetailViewModelTest.kt +++ b/feature/session/src/test/java/com/droidknights/app/feature/session/SessionDetailViewModelTest.kt @@ -7,6 +7,7 @@ import com.droidknights.app.core.domain.usecase.GetSessionUseCase import com.droidknights.app.core.model.Room import com.droidknights.app.core.model.Session import com.droidknights.app.core.testing.rule.MainDispatcherRule +import com.droidknights.app.feature.session.model.SessionDetailUiState import io.mockk.coEvery import io.mockk.mockk import kotlin.test.assertIs diff --git a/feature/session/src/test/java/com/droidknights/app/feature/session/SessionViewModelTest.kt b/feature/session/src/test/java/com/droidknights/app/feature/session/SessionViewModelTest.kt index 72942595..0dd28af6 100644 --- a/feature/session/src/test/java/com/droidknights/app/feature/session/SessionViewModelTest.kt +++ b/feature/session/src/test/java/com/droidknights/app/feature/session/SessionViewModelTest.kt @@ -6,6 +6,7 @@ import com.droidknights.app.core.domain.usecase.GetSessionsUseCase import com.droidknights.app.core.model.Room import com.droidknights.app.core.model.Session import com.droidknights.app.core.testing.rule.MainDispatcherRule +import com.droidknights.app.feature.session.model.SessionUiState import io.mockk.coEvery import io.mockk.mockk import kotlin.test.assertEquals diff --git a/feature/setting/src/main/java/com/droidknights/app/feature/setting/SettingScreen.kt b/feature/setting/src/main/java/com/droidknights/app/feature/setting/SettingScreen.kt index b28d75b6..81ae84f2 100644 --- a/feature/setting/src/main/java/com/droidknights/app/feature/setting/SettingScreen.kt +++ b/feature/setting/src/main/java/com/droidknights/app/feature/setting/SettingScreen.kt @@ -25,7 +25,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -33,7 +32,7 @@ import androidx.compose.ui.unit.dp import com.droidknights.app.core.designsystem.component.KnightsCard import com.droidknights.app.core.designsystem.theme.KnightsTheme import com.droidknights.app.core.designsystem.theme.LocalDarkTheme -import com.droidknights.app.feature.setting.opensource.OpenSourceCard +import com.droidknights.app.feature.setting.component.OpenSourceCard @Composable internal fun SettingScreen( @@ -48,9 +47,7 @@ internal fun SettingScreen( .padding(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), ) { - OpenSourceCard( - context = LocalContext.current, - ) + OpenSourceCard() LightDarkThemeCard( onChangeDarkTheme = onChangeDarkTheme ) @@ -80,7 +77,7 @@ private fun LightDarkThemeCard( ) { val cardModifier = Modifier.weight(1f) ThemeCard( - selected = !darkTheme, + selected = darkTheme.not(), titleRes = R.string.light_mode, imageRes = R.drawable.img_light_mode, onClick = { onChangeDarkTheme(false) }, diff --git a/feature/setting/src/main/java/com/droidknights/app/feature/setting/component/OpenSourceCard.kt b/feature/setting/src/main/java/com/droidknights/app/feature/setting/component/OpenSourceCard.kt new file mode 100644 index 00000000..242b6315 --- /dev/null +++ b/feature/setting/src/main/java/com/droidknights/app/feature/setting/component/OpenSourceCard.kt @@ -0,0 +1,66 @@ +package com.droidknights.app.feature.setting.component + +import android.content.Intent +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.droidknights.app.core.designsystem.component.KnightsCard +import com.droidknights.app.core.designsystem.theme.KnightsTheme +import com.droidknights.app.feature.setting.R +import com.google.android.gms.oss.licenses.OssLicensesMenuActivity + +@Composable +internal fun OpenSourceCard( + modifier: Modifier = Modifier, +) { + val titleText = stringResource(id = R.string.oss_license_title) + val arrowPainter = painterResource(id = R.drawable.icon_arrow_right_yellow01) + val context = LocalContext.current + + CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onPrimaryContainer) { + KnightsCard( + modifier = modifier, + onClick = { + context.startActivity(Intent(context, OssLicensesMenuActivity::class.java)) + } + ) { + Column { + Text( + text = titleText, + style = KnightsTheme.typography.headlineSmallBL, + modifier = Modifier + .padding(top = 24.dp, start = 24.dp) + ) + + Spacer(modifier = Modifier.padding(top = 39.dp)) + + Image( + painter = arrowPainter, + contentDescription = null, + modifier = Modifier + .align(alignment = Alignment.End) + .padding(end = 24.dp, bottom = 24.dp) + ) + } + } + } +} + +@Preview +@Composable +private fun PreviewOpenSourceCard() { + OpenSourceCard() +} \ No newline at end of file diff --git a/feature/setting/src/main/java/com/droidknights/app/feature/setting/opensource/OpenSourceCard.kt b/feature/setting/src/main/java/com/droidknights/app/feature/setting/opensource/OpenSourceCard.kt deleted file mode 100644 index 3fd0c817..00000000 --- a/feature/setting/src/main/java/com/droidknights/app/feature/setting/opensource/OpenSourceCard.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.droidknights.app.feature.setting.opensource - -import android.content.Context -import android.content.Intent -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import com.droidknights.app.core.designsystem.component.KnightsCard -import com.droidknights.app.core.designsystem.theme.Graphite -import com.droidknights.app.core.designsystem.theme.KnightsTheme -import com.droidknights.app.feature.setting.R -import com.google.android.gms.oss.licenses.OssLicensesMenuActivity - -@Composable -internal fun OpenSourceCard( - modifier: Modifier = Modifier, - context: Context, -) { - val titleText = stringResource(id = R.string.oss_license_title) - val arrowPainter = painterResource(id = R.drawable.icon_arrow_right_yellow01) - - KnightsCard( - color = Graphite, - modifier = modifier, - onClick = { - context.startActivity(Intent(context, OssLicensesMenuActivity::class.java)) - } - ) { - Column { - Text( - text = titleText, - style = KnightsTheme.typography.headlineSmallBL, - modifier = Modifier.padding(top = 24.dp, start = 24.dp), - color = Color.White - ) - Spacer(modifier = Modifier.padding(top = 39.dp)) - Image( - painter = arrowPainter, - contentDescription = null, - modifier = Modifier - .align(alignment = Alignment.End) - .padding(end = 24.dp, bottom = 24.dp) - ) - } - } -} From 93edea94af40c01d9cd773154f1386af61fdf3d8 Mon Sep 17 00:00:00 2001 From: taehwan Date: Tue, 21 May 2024 20:37:02 +0900 Subject: [PATCH 2/3] =?UTF-8?q?detekt=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../droidknights/app/feature/contributor/ContributorScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt index 174fa608..eb896f08 100644 --- a/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt +++ b/feature/contributor/src/main/java/com/droidknights/app/feature/contributor/ContributorScreen.kt @@ -204,7 +204,7 @@ private fun ContributorItem( } else { Modifier } - + val placeholder = rememberPainterResource( lightId = R.drawable.ic_contributor_placeholder_lightmode, darkId = R.drawable.ic_contributor_placeholder_darkmode, From 5c859ddea90be175b3a47dfc3e2dd5eaca185e06 Mon Sep 17 00:00:00 2001 From: taehwan Date: Wed, 22 May 2024 18:38:20 +0900 Subject: [PATCH 3/3] =?UTF-8?q?#295=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/droidknights/app/feature/home/SponsorScreenTest.kt | 3 ++- .../main/java/com/droidknights/app/feature/home/HomeScreen.kt | 3 +-- .../{model => }/SponsorsUiStatePreviewParameterProvider.kt | 3 ++- .../com/droidknights/app/feature/home/component/SponsorCard.kt | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) rename feature/home/src/main/java/com/droidknights/app/feature/home/{model => }/SponsorsUiStatePreviewParameterProvider.kt (92%) diff --git a/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt b/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt index 0414ca9d..3bf14b6b 100644 --- a/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt +++ b/feature/home/src/androidTest/java/com/droidknights/app/feature/home/SponsorScreenTest.kt @@ -7,6 +7,7 @@ import androidx.compose.ui.test.onNodeWithText import com.droidknights.app.core.model.Sponsor import com.droidknights.app.feature.home.component.SponsorCard import com.droidknights.app.feature.home.model.SponsorsUiState +import kotlinx.collections.immutable.persistentListOf import org.junit.Before import org.junit.Rule import org.junit.Test @@ -62,7 +63,7 @@ class SponsorScreenTest { companion object { private val sponsors = - listOf( + persistentListOf( Sponsor( name = "Sponsor1", homepage = "https://www.instagram.com/droid_knights", diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt index 396ad539..97a7ec79 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/HomeScreen.kt @@ -19,7 +19,6 @@ import com.droidknights.app.feature.home.component.ContributorCard import com.droidknights.app.feature.home.component.SessionCard import com.droidknights.app.feature.home.component.SponsorCard import com.droidknights.app.feature.home.model.SponsorsUiState -import com.droidknights.app.feature.home.model.SponsorsUiStatePreviewParameterProvider import kotlinx.coroutines.flow.collectLatest @Composable @@ -78,4 +77,4 @@ private fun PreviewHomeScreen( onSessionClick = {}, onContributorClick = {}, ) -} \ No newline at end of file +} diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiStatePreviewParameterProvider.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiStatePreviewParameterProvider.kt similarity index 92% rename from feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiStatePreviewParameterProvider.kt rename to feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiStatePreviewParameterProvider.kt index 26c78c0c..50ee04cd 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/model/SponsorsUiStatePreviewParameterProvider.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/SponsorsUiStatePreviewParameterProvider.kt @@ -1,7 +1,8 @@ -package com.droidknights.app.feature.home.model +package com.droidknights.app.feature.home import androidx.compose.ui.tooling.preview.PreviewParameterProvider import com.droidknights.app.core.model.Sponsor +import com.droidknights.app.feature.home.model.SponsorsUiState import kotlinx.collections.immutable.persistentListOf internal class SponsorsUiStatePreviewParameterProvider : PreviewParameterProvider { diff --git a/feature/home/src/main/java/com/droidknights/app/feature/home/component/SponsorCard.kt b/feature/home/src/main/java/com/droidknights/app/feature/home/component/SponsorCard.kt index 3d8bd717..2574d38d 100644 --- a/feature/home/src/main/java/com/droidknights/app/feature/home/component/SponsorCard.kt +++ b/feature/home/src/main/java/com/droidknights/app/feature/home/component/SponsorCard.kt @@ -40,7 +40,7 @@ import com.droidknights.app.core.designsystem.theme.LightGray import com.droidknights.app.core.model.Sponsor import com.droidknights.app.feature.home.R import com.droidknights.app.feature.home.model.SponsorsUiState -import com.droidknights.app.feature.home.model.SponsorsUiStatePreviewParameterProvider +import com.droidknights.app.feature.home.SponsorsUiStatePreviewParameterProvider import com.valentinilk.shimmer.shimmer import kotlinx.collections.immutable.ImmutableList