Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<string name="add_memo">메모 추가</string>
<string name="common_dot_separator">•</string>
<string name="common_retry">다시 시도</string>
<string name="common_all">전체</string>

<!-- Transport Segment -->
<string name="transport_segment_format">약 %1$s • %2$s</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import com.yapp.ndgl.core.base.UiIntent
import com.yapp.ndgl.core.base.UiSideEffect
import com.yapp.ndgl.core.base.UiState
import com.yapp.ndgl.data.travel.model.PlaceCategory
import com.yapp.ndgl.data.travel.model.ProgramType
import com.yapp.ndgl.feature.home.model.TravelContent
import com.yapp.ndgl.feature.home.model.TravelProgramTab
import java.time.LocalDate

@Stable
Expand Down Expand Up @@ -60,25 +60,17 @@ data class HomeState(
popularTravelsByProgram[selectedTab.programId] ?: emptyList()
}
}

sealed interface TravelProgramTab {
data object All : TravelProgramTab

data class Custom(
val programId: Long,
val name: String,
val type: ProgramType,
) : TravelProgramTab
}
}

sealed interface HomeIntent : UiIntent {
data object ClickSearchTravelTemplate : HomeIntent
data class SelectPopularTravelTab(val index: Int) : HomeIntent
data class ClickTravel(val travelId: Long) : HomeIntent
data object ClickTravelMore : HomeIntent
}

sealed interface HomeSideEffect : UiSideEffect {
data object NavigateToSearchTravelTemplate : HomeSideEffect
data class NavigateToFollowTravel(val travelId: Long, val days: Int) : HomeSideEffect
data object NavigateToTravelMore : HomeSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ import com.yapp.ndgl.core.ui.theme.NDGLTheme
import com.yapp.ndgl.data.travel.model.PlaceCategory
import com.yapp.ndgl.data.travel.model.ProgramType
import com.yapp.ndgl.feature.home.model.TravelContent
import com.yapp.ndgl.feature.home.model.TravelProgramTab
import java.time.LocalDate

@Composable
internal fun HomeRoute(
viewModel: HomeViewModel = hiltViewModel(),
navigateToTemplateSearch: () -> Unit,
navigateToFollowTravel: (Long, Int) -> Unit,
navigateToPopularTravelList: () -> Unit,
) {
val state by viewModel.collectAsState()

Expand All @@ -43,12 +45,16 @@ internal fun HomeRoute(
onTravelClick = { travelId ->
viewModel.onIntent(HomeIntent.ClickTravel(travelId))
},
onTravelMoreClick = {
viewModel.onIntent(HomeIntent.ClickTravelMore)
},
)

viewModel.collectSideEffect { sideEffect ->
when (sideEffect) {
HomeSideEffect.NavigateToSearchTravelTemplate -> navigateToTemplateSearch()
is HomeSideEffect.NavigateToFollowTravel -> navigateToFollowTravel(sideEffect.travelId, sideEffect.days)
HomeSideEffect.NavigateToTravelMore -> navigateToPopularTravelList()
}
}
}
Expand All @@ -59,6 +65,7 @@ private fun HomeScreen(
onSearchClick: () -> Unit,
onTabSelected: (Int) -> Unit,
onTravelClick: (Long) -> Unit,
onTravelMoreClick: () -> Unit,
) {
Scaffold(
topBar = {
Expand Down Expand Up @@ -104,6 +111,7 @@ private fun HomeScreen(
travels = state.filteredPopularTravels,
onTabSelected = onTabSelected,
onTravelClick = onTravelClick,
onTravelMoreClick = onTravelMoreClick,
)
}
}
Expand Down Expand Up @@ -176,18 +184,18 @@ private fun HomeScreenPreview() {
),
),
travelProgramTabs = listOf(
HomeState.TravelProgramTab.All,
HomeState.TravelProgramTab.Custom(
TravelProgramTab.All,
TravelProgramTab.Custom(
programId = 1,
name = "빠니보틀",
type = ProgramType.YOUTUBE,
),
HomeState.TravelProgramTab.Custom(
TravelProgramTab.Custom(
programId = 2,
name = "곽튜브",
type = ProgramType.YOUTUBE,
),
HomeState.TravelProgramTab.Custom(
TravelProgramTab.Custom(
programId = 3,
name = "콩콩팡팡",
type = ProgramType.TV,
Expand All @@ -198,6 +206,7 @@ private fun HomeScreenPreview() {
onSearchClick = {},
onTabSelected = {},
onTravelClick = {},
onTravelMoreClick = {},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.yapp.ndgl.data.travel.repository.TravelProgramRepository
import com.yapp.ndgl.data.travel.repository.TravelTemplateRepository
import com.yapp.ndgl.data.travel.repository.UserTravelRepository
import com.yapp.ndgl.feature.home.model.TravelContent
import com.yapp.ndgl.feature.home.model.TravelProgramTab
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
Expand Down Expand Up @@ -124,10 +125,10 @@ class HomeViewModel @Inject constructor(
}

val tabs = buildList {
add(HomeState.TravelProgramTab.All)
add(TravelProgramTab.All)
programs.forEach { program ->
add(
HomeState.TravelProgramTab.Custom(
TravelProgramTab.Custom(
programId = program.id,
name = program.name,
type = program.type,
Expand Down Expand Up @@ -190,6 +191,7 @@ class HomeViewModel @Inject constructor(
}

is HomeIntent.ClickTravel -> postNavigateToTravelTemplate(travelId = intent.travelId)
HomeIntent.ClickTravelMore -> postNavigateToTravelMore()
}
}

Expand All @@ -201,6 +203,10 @@ class HomeViewModel @Inject constructor(
postSideEffect(HomeSideEffect.NavigateToFollowTravel(travelId = travelId, days = 1))
}

private fun postNavigateToTravelMore() {
postSideEffect(HomeSideEffect.NavigateToTravelMore)
}

companion object {
private const val MAX_POPULAR_TRAVEL_COUNT = 9
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ import com.yapp.ndgl.data.travel.model.ProgramType
import com.yapp.ndgl.feature.home.R
import com.yapp.ndgl.feature.home.component.TravelTemplate
import com.yapp.ndgl.feature.home.model.TravelContent
import com.yapp.ndgl.feature.home.model.TravelProgramTab
import com.yapp.ndgl.feature.home.util.toIconRes
import kotlinx.collections.immutable.toPersistentList
import com.yapp.ndgl.core.ui.R as CoreR

private const val COLUMN_ITEM_COUNT = 3

@Composable
internal fun PopularTravelSection(
tabs: List<HomeState.TravelProgramTab>,
tabs: List<TravelProgramTab>,
selectedTabIndex: Int,
travels: List<TravelContent>,
onTabSelected: (Int) -> Unit,
onTravelClick: (Long) -> Unit,
onTravelMoreClick: () -> Unit,
) {
Column(
modifier = Modifier.fillMaxWidth(),
Expand All @@ -61,7 +64,7 @@ internal fun PopularTravelSection(
NDGLOutlinedButton(
status = NDGLOutlinedButtonAttr.Status.ACTIVE,
label = stringResource(R.string.home_popular_travel_more_button),
onClick = {},
onClick = onTravelMoreClick,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp),
Expand All @@ -71,7 +74,7 @@ internal fun PopularTravelSection(

@Composable
private fun HorizontalCardSection(
tabs: List<HomeState.TravelProgramTab>,
tabs: List<TravelProgramTab>,
selectedTabIndex: Int,
travels: List<TravelContent>,
onTabSelected: (Int) -> Unit,
Expand All @@ -87,11 +90,12 @@ private fun HorizontalCardSection(
NDGLChipTab(
tabs = tabs.map { tab ->
when (tab) {
HomeState.TravelProgramTab.All -> NDGLChipTabAttr.Tab(
TravelProgramTab.All -> NDGLChipTabAttr.Tab(
tag = "All",
name = "전체",
name = stringResource(CoreR.string.common_all),
)
is HomeState.TravelProgramTab.Custom -> NDGLChipTabAttr.Tab(

is TravelProgramTab.Custom -> NDGLChipTabAttr.Tab(
tag = tab.programId.toString(),
name = tab.name,
leadingIcon = tab.type.toIconRes(),
Expand Down Expand Up @@ -185,13 +189,13 @@ private fun PopularTravelSectionPreview() {
NDGLTheme {
PopularTravelSection(
tabs = listOf(
HomeState.TravelProgramTab.All,
HomeState.TravelProgramTab.Custom(
TravelProgramTab.All,
TravelProgramTab.Custom(
programId = 1,
name = "빠니보틀",
type = ProgramType.YOUTUBE,
),
HomeState.TravelProgramTab.Custom(
TravelProgramTab.Custom(
programId = 2,
name = "곽튜브",
type = ProgramType.TV,
Expand All @@ -201,6 +205,7 @@ private fun PopularTravelSectionPreview() {
travels = sampleTravels,
onTabSelected = {},
onTravelClick = {},
onTravelMoreClick = {},
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.yapp.ndgl.feature.home.model

import com.yapp.ndgl.data.travel.model.ProgramType

sealed interface TravelProgramTab {
data object All : TravelProgramTab

data class Custom(
val programId: Long,
val name: String,
val type: ProgramType,
) : TravelProgramTab
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.yapp.ndgl.feature.home.navigation
import androidx.navigation3.runtime.EntryProviderScope
import androidx.navigation3.runtime.NavKey
import com.yapp.ndgl.feature.home.main.HomeRoute
import com.yapp.ndgl.feature.home.popular.PopularTravelListRoute
import com.yapp.ndgl.feature.home.search.TemplateSearchRoute
import com.yapp.ndgl.navigation.Navigator
import com.yapp.ndgl.navigation.Route
Expand All @@ -18,6 +19,9 @@ fun EntryProviderScope<NavKey>.homeEntry(
navigateToFollowTravel = { travelId, days ->
navigator.navigate(Route.FollowTravel(travelId = travelId, days = days))
},
navigateToPopularTravelList = {
navigator.navigate(Route.PopularTravelList)
},
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
entry<Route.TemplateSearch> {
Expand All @@ -30,4 +34,17 @@ fun EntryProviderScope<NavKey>.homeEntry(
},
)
}
entry<Route.PopularTravelList> {
PopularTravelListRoute(
goBack = {
navigator.goBack()
},
navigateToTemplateSearch = {
navigator.navigate(Route.TemplateSearch)
},
navigateToFollowTravel = { travelId, days ->
navigator.navigate(Route.FollowTravel(travelId = travelId, days = days))
},
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.yapp.ndgl.feature.home.popular

import androidx.compose.runtime.Immutable
import com.yapp.ndgl.core.base.UiIntent
import com.yapp.ndgl.core.base.UiSideEffect
import com.yapp.ndgl.core.base.UiState
import com.yapp.ndgl.feature.home.model.TravelContent
import com.yapp.ndgl.feature.home.model.TravelProgramTab
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentMapOf

@Immutable
data class PopularTravelListState(
val travelProgramTabs: ImmutableList<TravelProgramTab> = persistentListOf(),
val selectedTabIndex: Int = 0,
val allPopularTravels: ImmutableList<TravelContent> = persistentListOf(),
val popularTravelsByProgram: ImmutableMap<Long, ImmutableList<TravelContent>> = persistentMapOf(),
) : UiState {
val selectedProgramTravels: ImmutableList<TravelContent> by lazy {
val selectTab = travelProgramTabs.getOrElse(selectedTabIndex) { TravelProgramTab.All }

when (selectTab) {
TravelProgramTab.All -> allPopularTravels
is TravelProgramTab.Custom -> popularTravelsByProgram.getOrDefault(
selectTab.programId,
persistentListOf(),
)
}
}
}

sealed interface PopularTravelListIntent : UiIntent {
data object ClickSearchTravelTemplate : PopularTravelListIntent
data class SelectPopularTravelTab(val index: Int) : PopularTravelListIntent
data class ClickTravel(val travelId: Long) : PopularTravelListIntent
}

sealed interface PopularTravelListSideEffect : UiSideEffect {
data object NavigateToSearchTravelTemplate : PopularTravelListSideEffect
data class NavigateToFollowTravel(
val travelId: Long,
val days: Int,
) : PopularTravelListSideEffect
}
Loading