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
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class AuthRepository @Inject constructor(
private val localAuthDataSource: LocalAuthDataSource,
) {
suspend fun initSession(): Boolean {
val uuid = localAuthDataSource.getUuid()
val uuid = getIdentifierCode()
var isFirstUser = false
val response = if (uuid.isNotEmpty()) {
suspendRunCatching {
Expand Down Expand Up @@ -65,4 +65,6 @@ class AuthRepository @Inject constructor(
throw IllegalStateException("Failed to get FCM token", e)
}
}

suspend fun getIdentifierCode(): String = localAuthDataSource.getUuid()
}
1 change: 1 addition & 0 deletions feature/home/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ android {
}

dependencies {
implementation(project(":data:auth"))
implementation(project(":data:travel"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,15 @@ data class HomeState(

sealed interface HomeIntent : UiIntent {
data object ClickSearchTravelTemplate : HomeIntent
data object ClickSettings : 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 object NavigateToSettings : 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 @@ -29,6 +29,7 @@ import java.time.LocalDate
internal fun HomeRoute(
viewModel: HomeViewModel = hiltViewModel(),
navigateToTemplateSearch: () -> Unit,
navigateToSettings: () -> Unit,
navigateToFollowTravel: (Long, Int) -> Unit,
navigateToPopularTravelList: () -> Unit,
) {
Expand All @@ -39,6 +40,9 @@ internal fun HomeRoute(
onSearchClick = {
viewModel.onIntent(HomeIntent.ClickSearchTravelTemplate)
},
onSettingsClick = {
viewModel.onIntent(HomeIntent.ClickSettings)
},
onTabSelected = { index ->
viewModel.onIntent(HomeIntent.SelectPopularTravelTab(index))
},
Expand All @@ -53,6 +57,7 @@ internal fun HomeRoute(
viewModel.collectSideEffect { sideEffect ->
when (sideEffect) {
HomeSideEffect.NavigateToSearchTravelTemplate -> navigateToTemplateSearch()
HomeSideEffect.NavigateToSettings -> navigateToSettings()
is HomeSideEffect.NavigateToFollowTravel -> navigateToFollowTravel(sideEffect.travelId, sideEffect.days)
HomeSideEffect.NavigateToTravelMore -> navigateToPopularTravelList()
}
Expand All @@ -63,6 +68,7 @@ internal fun HomeRoute(
private fun HomeScreen(
state: HomeState,
onSearchClick: () -> Unit,
onSettingsClick: () -> Unit,
onTabSelected: (Int) -> Unit,
onTravelClick: (Long) -> Unit,
onTravelMoreClick: () -> Unit,
Expand All @@ -82,7 +88,7 @@ private fun HomeScreen(
)
NDGLNavigationIcon(
icon = R.drawable.ic_28_settings,
onClick = { /* FIXME: 설정 */ },
onClick = onSettingsClick,
)
},
)
Expand Down Expand Up @@ -204,6 +210,7 @@ private fun HomeScreenPreview() {
allPopularTravels = sampleTravels,
),
onSearchClick = {},
onSettingsClick = {},
onTabSelected = {},
onTravelClick = {},
onTravelMoreClick = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,10 @@ class HomeViewModel @Inject constructor(
override suspend fun handleIntent(intent: HomeIntent) {
when (intent) {
HomeIntent.ClickSearchTravelTemplate -> postNavigateToSearchTravelTemplate()

HomeIntent.ClickSettings -> postNavigateToSettings()
is HomeIntent.SelectPopularTravelTab -> {
reduce { copy(popularTravelSelectedTabIndex = intent.index) }
}

is HomeIntent.ClickTravel -> postNavigateToTravelTemplate(travelId = intent.travelId)
HomeIntent.ClickTravelMore -> postNavigateToTravelMore()
}
Expand All @@ -187,6 +186,10 @@ class HomeViewModel @Inject constructor(
postSideEffect(HomeSideEffect.NavigateToSearchTravelTemplate)
}

private fun postNavigateToSettings() {
postSideEffect(HomeSideEffect.NavigateToSettings)
}

private fun postNavigateToTravelTemplate(travelId: Long) {
postSideEffect(HomeSideEffect.NavigateToFollowTravel(travelId = travelId, days = 1))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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.feature.home.settings.SettingsRoute
import com.yapp.ndgl.navigation.Navigator
import com.yapp.ndgl.navigation.Route

Expand All @@ -16,6 +17,9 @@ fun EntryProviderScope<NavKey>.homeEntry(
navigateToTemplateSearch = {
navigator.navigate(Route.TemplateSearch)
},
navigateToSettings = {
navigator.navigate(Route.Settings)
},
navigateToFollowTravel = { travelId, days ->
navigator.navigate(Route.FollowTravel(travelId = travelId, days = days))
},
Expand Down Expand Up @@ -47,4 +51,11 @@ fun EntryProviderScope<NavKey>.homeEntry(
},
)
}
entry<Route.Settings> {
SettingsRoute(
goBack = {
navigator.goBack()
},
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.yapp.ndgl.feature.home.settings

import androidx.annotation.StringRes
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
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.R
import com.yapp.ndgl.feature.home.settings.SettingsState.UrlMenu
import kotlinx.collections.immutable.ImmutableList

@Immutable
data class SettingsState(
val menuItems: ImmutableList<SettingsMenu>,
) : UiState {
@Stable
sealed interface SettingsMenu {
@get:StringRes
val labelRes: Int

data class OpenUrl(
val menu: UrlMenu,
) : SettingsMenu {
override val labelRes = menu.labelRes
}

data object CopyIdentifierCode : SettingsMenu {
override val labelRes = R.string.home_settings_identification_code
}

data class AppVersion(
val versionName: String,
) : SettingsMenu {
override val labelRes = R.string.home_settings_version_info
}
}

enum class UrlMenu(
@get:StringRes val labelRes: Int,
val url: String,
) {
FAQ(
labelRes = R.string.home_settings_faq,
url = "https://repeated-tapir-33f.notion.site/FAQ-30ccbdc5a38380d6af4af7b7c412921e?source=copy_link",
),
RECOMMEND_LINK(
labelRes = R.string.home_settings_recommend_link,
url = "https://forms.gle/3q1uhQVeeKRrz11y5",
),
TERMS_OF_SERVICE(
labelRes = R.string.home_settings_terms_of_service,
url = "https://repeated-tapir-33f.notion.site/2c8cbdc5a3838070a8d8ccdcd0631c9a?source=copy_link",
),
PRIVACY_POLICY(
labelRes = R.string.home_settings_privacy_policy,
url = "https://repeated-tapir-33f.notion.site/30ccbdc5a38380e3a50ace64a9b0f398?source=copy_link",
),
}
}

sealed interface SettingsIntent : UiIntent {
data class ClickUrlMenu(val menu: UrlMenu) : SettingsIntent
data object ClickCopyIdentifierCodeMenu : SettingsIntent
}

sealed interface SettingsSideEffect : UiSideEffect {
data class OpenUrl(val url: String) : SettingsSideEffect
data class CopyIdentifierCode(val code: String) : SettingsSideEffect
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package com.yapp.ndgl.feature.home.settings

import android.content.ClipData
import android.content.ClipboardManager
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
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.statusBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.yapp.ndgl.core.ui.designsystem.NDGLNavigationBar
import com.yapp.ndgl.core.ui.designsystem.NDGLNavigationBarAttr
import com.yapp.ndgl.core.ui.theme.NDGLTheme
import com.yapp.ndgl.core.ui.util.launchBrowser
import com.yapp.ndgl.feature.home.R
import com.yapp.ndgl.feature.home.settings.SettingsState.SettingsMenu
import kotlinx.collections.immutable.ImmutableList
import com.yapp.ndgl.core.ui.R as CoreR

@Composable
internal fun SettingsRoute(
viewModel: SettingsViewModel = hiltViewModel(),
goBack: () -> Unit,
) {
val context = LocalContext.current

val state by viewModel.collectAsState()

SettingsScreen(
menuItems = state.menuItems,
goBack = goBack,
onUrlItemClick = {
viewModel.onIntent(SettingsIntent.ClickUrlMenu(it))
},
onCopyIdentifierCodeClick = {
viewModel.onIntent(SettingsIntent.ClickCopyIdentifierCodeMenu)
},
)

viewModel.collectSideEffect { sideEffect ->
when (sideEffect) {
is SettingsSideEffect.OpenUrl -> context.launchBrowser(sideEffect.url)
is SettingsSideEffect.CopyIdentifierCode -> {
val clipboard = context.getSystemService(ClipboardManager::class.java)
val clip = ClipData.newPlainText(
context.getString(R.string.home_settings_identification_code),
sideEffect.code,
)
clipboard?.setPrimaryClip(clip)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}
}

@Composable
private fun SettingsScreen(
menuItems: ImmutableList<SettingsMenu>,
goBack: () -> Unit,
onUrlItemClick: (SettingsState.UrlMenu) -> Unit,
onCopyIdentifierCodeClick: () -> Unit,
) {
Scaffold(
topBar = {
NDGLNavigationBar(
textAlignType = NDGLNavigationBarAttr.TextAlignType.CENTER,
modifier = Modifier
.fillMaxWidth()
.background(color = NDGLTheme.colors.white)
.statusBarsPadding(),
headline = stringResource(R.string.home_settings_title),
leadingIcon = CoreR.drawable.ic_28_chevron_left,
onLeadingIconClick = goBack,
)
},
) { innerPadding ->
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
contentPadding = PaddingValues(24.dp),
) {
items(
items = menuItems,
key = { item -> item.labelRes },
) { item ->
when (item) {
is SettingsMenu.OpenUrl -> SettingsMenuItem(
text = stringResource(item.labelRes),
onClick = { onUrlItemClick(item.menu) },
)

SettingsMenu.CopyIdentifierCode -> SettingsMenuItem(
text = stringResource(item.labelRes),
onClick = onCopyIdentifierCodeClick,
)

is SettingsMenu.AppVersion -> VersionItem(versionName = item.versionName)
}
}
}
}
}

@Composable
private fun SettingsMenuItem(
text: String,
onClick: () -> Unit,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(horizontal = 8.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = text,
style = NDGLTheme.typography.bodyLgRegular,
color = NDGLTheme.colors.black700,
modifier = Modifier.weight(1f),
)
Icon(
imageVector = ImageVector.vectorResource(CoreR.drawable.ic_24_chevron_right),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = NDGLTheme.colors.black600,
)
}
HorizontalDivider(color = NDGLTheme.colors.black50)
}

@Composable
private fun VersionItem(
versionName: String,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = stringResource(R.string.home_settings_version_info),
style = NDGLTheme.typography.bodyLgRegular,
color = NDGLTheme.colors.black700,
modifier = Modifier.weight(1f),
)
Text(
text = versionName,
style = NDGLTheme.typography.bodyLgRegular,
color = NDGLTheme.colors.black400,
)
}
HorizontalDivider(color = NDGLTheme.colors.black50)
}
Loading