Skip to content

Commit

Permalink
refactor/#16 : 공통 뷰모델 설정
Browse files Browse the repository at this point in the history
- 에피소드 생성 세가지 화면 공통 뷰모델 사용 설정
  • Loading branch information
TaewoongR committed Feb 18, 2025
1 parent 92c318a commit 6838fb2
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ import com.boostcamp.mapisode.episode.state.EpisodeState
import com.boostcamp.mapisode.ui.base.RevisedBaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharedFlow
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
class EpisodeViewModel @Inject constructor() :
RevisedBaseViewModel<EpisodeIntent, EpisodeState, EpisodeEffect>(EpisodeState()) {

override suspend fun reducer(intent: SharedFlow<EpisodeIntent>) {
TODO("Not yet implemented")
}

override fun onCleared() {
super.onCleared()
Timber.e("EpisodeViewModel onCleared")
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.boostcamp.mapisode.episode.navigation

import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.boostcamp.mapisode.episode.screen.EpisodeContentScreen
import com.boostcamp.mapisode.episode.screen.EpisodeInfoScreen
import com.boostcamp.mapisode.episode.screen.EpisodePhotoScreen
import androidx.navigation.compose.currentBackStackEntryAsState
import com.boostcamp.mapisode.episode.EpisodeViewModel
import com.boostcamp.mapisode.episode.screen.EpisodeContentRoute
import com.boostcamp.mapisode.episode.screen.EpisodeInfoRoute
import com.boostcamp.mapisode.episode.screen.EpisodePhotoRoute
import com.boostcamp.mapisode.navigation.MainRoute
import com.boostcamp.mapisode.navigation.NewEpisodeRoute

Expand Down Expand Up @@ -39,29 +43,49 @@ fun NavController.popUpStackToMain(
}

fun NavGraphBuilder.addEpisodeNavGraph(
navController: NavController,
onInfoPickClick: () -> Unit,
onContentPickClick: () -> Unit,
onBack: () -> Unit,
onMainBack: () -> Unit,
) {
composable<MainRoute.Episode> {
EpisodePhotoScreen(
EpisodePhotoRoute(
onCompletePhotoPicker = onInfoPickClick,
onBackClick = onBack,
viewModel = hiltViewModel(),
)
}

@Composable
fun getParentViewModel(navController: NavController): EpisodeViewModel? {
val parentEntry = navController.currentBackStackEntryAsState().value?.let {
try {
navController.getBackStackEntry(MainRoute.Episode)
} catch (e: IllegalArgumentException) {
null
}
}
return parentEntry?.let { hiltViewModel(it) }
}

composable<NewEpisodeRoute.PickInfo> {
EpisodeInfoScreen(
onCompleteInfoPick = onContentPickClick,
onBackClick = onBack,
)
getParentViewModel(navController)?.run {
EpisodeInfoRoute(
onCompleteInfoPick = onContentPickClick,
onBackClick = onBack,
viewModel = this,
)
}
}

composable<NewEpisodeRoute.WriteContent> {
EpisodeContentScreen(
onCompleteContentClick = onMainBack,
onBackClick = onBack,
)
getParentViewModel(navController)?.run {
EpisodeContentRoute(
onCompleteContentClick = onMainBack,
onBackClick = onBack,
viewModel = this,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,61 @@ package com.boostcamp.mapisode.episode.screen

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBars
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.boostcamp.mapisode.designsystem.theme.MapisodeTheme
import com.boostcamp.mapisode.episode.EpisodeViewModel

@Composable
fun EpisodeContentScreen(
fun EpisodeContentRoute(
onCompleteContentClick: () -> Unit,
onBackClick: () -> Unit,
viewModel: EpisodeViewModel,
) {
val uiState = viewModel.state.collectAsStateWithLifecycle()

EpisodeContentScreen(
onCompleteInfoPick = onCompleteContentClick,
onBackClick = onBackClick,
)
}

@Composable
fun EpisodeContentScreen(
onCompleteInfoPick: () -> Unit,
onBackClick: () -> Unit,
) {
Scaffold(
modifier = Modifier.fillMaxSize(),
modifier = Modifier.fillMaxSize()
.padding(
top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding(),
bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding(),
),
topBar = { EpisodeTopBar(title = "내용 입력", onBackClick = onBackClick) },
containerColor = MapisodeTheme.colorScheme.scaffoldBackground,
) {
Column(
modifier = Modifier.fillMaxSize().padding(it.calculateTopPadding()),
modifier = Modifier
.fillMaxSize()
.padding(it.calculateTopPadding()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Button(
onClick = onCompleteContentClick,
onClick = onCompleteInfoPick,
) {
Text(text = "onCompleteContentClick")
Text(text = "onCompleteInfoPick")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,55 @@ package com.boostcamp.mapisode.episode.screen

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBars
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.boostcamp.mapisode.designsystem.theme.MapisodeTheme
import com.boostcamp.mapisode.episode.EpisodeViewModel

@Composable
fun EpisodeInfoRoute(
onCompleteInfoPick: () -> Unit,
onBackClick: () -> Unit,
viewModel: EpisodeViewModel,
) {
val uiState = viewModel.state.collectAsStateWithLifecycle()

EpisodeInfoScreen(
onCompleteInfoPick = onCompleteInfoPick,
onBackClick = onBackClick,
)
}

@Composable
fun EpisodeInfoScreen(
onCompleteInfoPick: () -> Unit,
onBackClick: () -> Unit,
) {
Scaffold(
modifier = Modifier.fillMaxSize(),
modifier = Modifier
.fillMaxSize()
.padding(
top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding(),
bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding(),
),
topBar = { EpisodeTopBar(title = "위치 및 그룹 선택", onBackClick = onBackClick) },
containerColor = MapisodeTheme.colorScheme.scaffoldBackground,
) {
Column(
modifier = Modifier.fillMaxSize().padding(it.calculateTopPadding()),
modifier = Modifier
.fillMaxSize()
.padding(it.calculateTopPadding()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,52 @@ package com.boostcamp.mapisode.episode.screen

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBars
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import com.boostcamp.mapisode.designsystem.theme.MapisodeTheme
import com.boostcamp.mapisode.episode.EpisodeViewModel

@Composable
fun EpisodePhotoRoute(
onBackClick: () -> Unit,
onCompletePhotoPicker: () -> Unit,
viewModel: EpisodeViewModel,
) {
EpisodePhotoScreen(
onBackClick = onBackClick,
onCompletePhotoPicker = onCompletePhotoPicker,
)
}

@Composable
fun EpisodePhotoScreen(
onBackClick: () -> Unit,
onCompletePhotoPicker: () -> Unit,
) {
Scaffold(
modifier = Modifier.fillMaxSize(),
modifier = Modifier
.fillMaxSize()
.padding(
top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding(),
bottom = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding(),
),
topBar = { EpisodeTopBar(title = "사진 선택", onBackClick = onBackClick) },
containerColor = MapisodeTheme.colorScheme.scaffoldBackground,
) {
Column(
modifier = Modifier.fillMaxSize().padding(it.calculateTopPadding()),
modifier = Modifier
.fillMaxSize()
.padding(it.calculateTopPadding()),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.boostcamp.mapisode.episode.screen

import androidx.compose.runtime.Composable
import com.boostcamp.mapisode.designsystem.R
import com.boostcamp.mapisode.designsystem.compose.MapisodeIcon
import com.boostcamp.mapisode.designsystem.compose.MapisodeIconButton
import com.boostcamp.mapisode.designsystem.compose.topbar.TopAppBar

@Composable
fun EpisodeTopBar(
title: String,
onBackClick: () -> Unit,
) {
TopAppBar(
title = title,
navigationIcon = {
MapisodeIconButton(
onClick = { onBackClick() },
) {
MapisodeIcon(
id = R.drawable.ic_arrow_back_ios,
)
}
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.boostcamp.mapisode.main

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hasRoute
import androidx.navigation.NavGraph.Companion.findStartDestination
Expand Down Expand Up @@ -58,6 +57,8 @@ internal class MainNavigator(
}
}

fun provideNavController(): NavHostController = navController

fun navigateToLogin() {
navController.navigate(startDestination) {
popUpTo(startDestination) { inclusive = true }
Expand Down Expand Up @@ -92,13 +93,6 @@ internal class MainNavigator(
navController.navigateEpisodeEdit(episodeId)
}

fun getEpisodeBackStackEntry(): NavBackStackEntry =
navController.getBackStackEntry(startDestination)

fun popBackEpisodeToMain() {
navController.popBackStack(Route.Auth, inclusive = false)
}

fun navigateGroupJoin() {
navController.navigateGroupJoin()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ internal fun MainNavHost(
navigateToMain = navigator::navigateToMain,
)
addEpisodeNavGraph(
navController = navigator.provideNavController(),
onInfoPickClick = navigator::navigateToEpisodeInfo,
onContentPickClick = navigator::navigateToEpisodeContent,
onBack = navigator::popBackStackIfNotHome,
Expand Down

0 comments on commit 6838fb2

Please sign in to comment.