diff --git a/presentation/src/main/java/com/example/presentation/component/ImagePager.kt b/presentation/src/main/java/com/example/presentation/component/ImagePager.kt index e86ee26..0ba9441 100644 --- a/presentation/src/main/java/com/example/presentation/component/ImagePager.kt +++ b/presentation/src/main/java/com/example/presentation/component/ImagePager.kt @@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -34,32 +33,34 @@ fun ImagePager( modifier = modifier, ) { HorizontalPager( - state = pagerState) { index -> + state = pagerState, + ) { index -> val image = images[index] Image( modifier = Modifier.fillMaxSize(), painter = rememberAsyncImagePainter(model = image), contentDescription = "", - contentScale = ContentScale.Crop + contentScale = ContentScale.Crop, ) } - - Box(modifier = Modifier - .align(Alignment.TopEnd) - .padding(8.dp) - .background(MaterialTheme.colorScheme.primary, shape = RoundedCornerShape(8.dp))) { + + Box( + modifier = + Modifier + .align(Alignment.TopEnd) + .padding(8.dp) + .background(MaterialTheme.colorScheme.primary, shape = RoundedCornerShape(8.dp)), + ) { Text( modifier = Modifier.padding(horizontal = 4.dp, vertical = 2.dp), text = "${pagerState.currentPage + 1} / ${images.size}", style = MaterialTheme.typography.labelSmall, - color = Color.White + color = Color.White, ) } } - } - @OptIn(ExperimentalFoundationApi::class) @Preview @Composable @@ -68,9 +69,10 @@ private fun ImagePagerPreview() { ImagePager( modifier = Modifier, images = listOf(), - pagerState = rememberPagerState( - pageCount = { 10 } - ) + pagerState = + rememberPagerState( + pageCount = { 10 }, + ), ) } } diff --git a/presentation/src/main/java/com/example/presentation/main/writing/ImageSelectScreen.kt b/presentation/src/main/java/com/example/presentation/main/writing/ImageSelectScreen.kt index 32d03da..a66e33e 100644 --- a/presentation/src/main/java/com/example/presentation/main/writing/ImageSelectScreen.kt +++ b/presentation/src/main/java/com/example/presentation/main/writing/ImageSelectScreen.kt @@ -40,8 +40,8 @@ import org.orbitmvi.orbit.compose.collectAsState fun ImageSelectScreen( viewModel: WritingViewModel, onBackClick: () -> Unit, - onNextClick: () -> Unit - ) { + onNextClick: () -> Unit, +) { val state = viewModel.collectAsState().value ImageSelectScreen( diff --git a/presentation/src/main/java/com/example/presentation/main/writing/WritingActivity.kt b/presentation/src/main/java/com/example/presentation/main/writing/WritingActivity.kt index 5126650..5cde1b3 100644 --- a/presentation/src/main/java/com/example/presentation/main/writing/WritingActivity.kt +++ b/presentation/src/main/java/com/example/presentation/main/writing/WritingActivity.kt @@ -10,7 +10,7 @@ import dagger.hilt.android.AndroidEntryPoint class WritingActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - + setContent { SnsProjectTheme { WritingNavHost(onFinish = { finish() }) diff --git a/presentation/src/main/java/com/example/presentation/main/writing/WritingNavHost.kt b/presentation/src/main/java/com/example/presentation/main/writing/WritingNavHost.kt index ea638e2..c03f16d 100644 --- a/presentation/src/main/java/com/example/presentation/main/writing/WritingNavHost.kt +++ b/presentation/src/main/java/com/example/presentation/main/writing/WritingNavHost.kt @@ -7,21 +7,19 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @Composable -fun WritingNavHost( - onFinish: () -> Unit -) { +fun WritingNavHost(onFinish: () -> Unit) { val navController = rememberNavController() val sharedViewModel: WritingViewModel = viewModel() - + NavHost(navController = navController, startDestination = WritingRoute.IMAGE_SELECT_SCREEN.route) { composable(WritingRoute.IMAGE_SELECT_SCREEN.route) { ImageSelectScreen(viewModel = sharedViewModel, onNextClick = { navController.navigate(WritingRoute.WRITING_SCREEN.route) }, onBackClick = onFinish) } - + composable(WritingRoute.WRITING_SCREEN.route) { - WritingScreen(viewModel = sharedViewModel,onBackClick = { navController.navigateUp() }, onPostClick = {}) + WritingScreen(viewModel = sharedViewModel, onBackClick = { navController.navigateUp() }, onPostClick = {}) } } } diff --git a/presentation/src/main/java/com/example/presentation/main/writing/WritingScreen.kt b/presentation/src/main/java/com/example/presentation/main/writing/WritingScreen.kt index fb31955..5433c62 100644 --- a/presentation/src/main/java/com/example/presentation/main/writing/WritingScreen.kt +++ b/presentation/src/main/java/com/example/presentation/main/writing/WritingScreen.kt @@ -35,11 +35,12 @@ fun WritingScreen( onPostClick: () -> Unit, ) { val state = viewModel.collectAsState().value - val pageState = rememberPagerState( - initialPage = 0, - pageCount = { state.images.size }, - ) - + val pageState = + rememberPagerState( + initialPage = 0, + pageCount = { state.images.size }, + ) + WritingScreen( images = state.images.map { it.uri }, text = state.text, @@ -58,47 +59,55 @@ fun WritingScreen( text: String, onTextChange: (String) -> Unit, onBackClick: () -> Unit, - onPostClick: () -> Unit + onPostClick: () -> Unit, ) { Surface { Scaffold( topBar = - { - CenterAlignedTopAppBar( - title = { - Text(text = "새 게시물", style = MaterialTheme.typography.headlineSmall) - }, - navigationIcon = { - IconButton(onClick = onBackClick) { - Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "뒤로가기") - } - }, - actions = { - TextButton(onClick = onPostClick) { - Text(text = "다음", style = MaterialTheme.typography.bodyMedium, color = Color.Black) - } - }, - ) - }, + { + CenterAlignedTopAppBar( + title = { + Text(text = "새 게시물", style = MaterialTheme.typography.headlineSmall) + }, + navigationIcon = { + IconButton(onClick = onBackClick) { + Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "뒤로가기") + } + }, + actions = { + TextButton(onClick = onPostClick) { + Text(text = "다음", style = MaterialTheme.typography.bodyMedium, color = Color.Black) + } + }, + ) + }, content = { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { - ImagePager(modifier = Modifier - .fillMaxWidth() - .weight(2f), images = images, pagerState = pagerState) - + ImagePager( + modifier = + Modifier + .fillMaxWidth() + .weight(2f), + images = images, + pagerState = pagerState, + ) + HorizontalDivider() - - LoginTextField(modifier = Modifier - .fillMaxWidth() - .weight(3f), value = text, onValueString = onTextChange) + + LoginTextField( + modifier = + Modifier + .fillMaxWidth() + .weight(3f), + value = text, + onValueString = onTextChange, + ) } }, - - ) + ) } } - @OptIn(ExperimentalFoundationApi::class) @Preview @Composable @@ -110,7 +119,7 @@ private fun WritingScreenPreview() { onTextChange = {}, pagerState = rememberPagerState(pageCount = { 10 }), onBackClick = {}, - onPostClick = {} + onPostClick = {}, ) } } diff --git a/presentation/src/main/java/com/example/presentation/main/writing/WritingViewModel.kt b/presentation/src/main/java/com/example/presentation/main/writing/WritingViewModel.kt index 71d80b7..de77897 100644 --- a/presentation/src/main/java/com/example/presentation/main/writing/WritingViewModel.kt +++ b/presentation/src/main/java/com/example/presentation/main/writing/WritingViewModel.kt @@ -17,67 +17,69 @@ import org.orbitmvi.orbit.viewmodel.container @HiltViewModel class WritingViewModel -@Inject -constructor( - private val getImageListUseCase: GetImageListUseCase, -) : ViewModel(), ContainerHost { - override val container: Container = - container( - initialState = WritingState(), - buildSettings = { - this.exceptionHandler = - CoroutineExceptionHandler { _, throwable -> - intent { - postSideEffect(WritingSideEffect.Toast(throwable.message.orEmpty())) + @Inject + constructor( + private val getImageListUseCase: GetImageListUseCase, + ) : ViewModel(), ContainerHost { + override val container: Container = + container( + initialState = WritingState(), + buildSettings = { + this.exceptionHandler = + CoroutineExceptionHandler { _, throwable -> + intent { + postSideEffect(WritingSideEffect.Toast(throwable.message.orEmpty())) + } } + }, + ) + + init { + load() + } + + private fun load() = + intent { + val images = getImageListUseCase() + reduce { + state.copy( + selectedImages = images.firstOrNull()?.let { listOf(it) } ?: listOf(), + images = images, + ) + } + } + + fun onItemClick(image: Image) = + intent { + reduce { + if (state.selectedImages.contains(image)) { + state.copy(selectedImages = state.selectedImages - image) + } else { + state.copy(selectedImages = state.selectedImages + image) } - }, - ) - - init { - load() - } - - private fun load() = - intent { - val images = getImageListUseCase() - reduce { - state.copy( - selectedImages = images.firstOrNull()?.let { listOf(it) } ?: listOf(), - images = images, - ) + } } - } - - fun onItemClick(image: Image) = - intent { - reduce { - if (state.selectedImages.contains(image)) { - state.copy(selectedImages = state.selectedImages - image) - } else { - state.copy(selectedImages = state.selectedImages + image) + + fun onTextChange(text: String) = + blockingIntent { + reduce { + state.copy(text = text) } } - } - - fun onTextChange(text: String) = blockingIntent { - reduce { - state.copy(text = text) - } - } - - fun onPostClick() = intent { + + fun onPostClick() = + intent { // val writingState = state // - //TODO: 업로드 기능 구현 + // TODO: 업로드 기능 구현 + } } -} @Immutable data class WritingState( val selectedImages: List = listOf(), val images: List = listOf(), - val text: String = "" + val text: String = "", ) sealed interface WritingSideEffect {