From 5f82d5111ba7a7df3aa63d690e4f658f7c2a1a57 Mon Sep 17 00:00:00 2001 From: Ju Yungyeom Date: Tue, 9 Dec 2025 17:15:47 +0900 Subject: [PATCH 1/2] #706 [feature] Add post create state --- .../presentation/screen/post/PostScreen.kt | 33 +++++++++++++++---- .../view/dialog/CommentBottomSheetDialog.kt | 29 +++++++++++++--- .../presentation/viewmodel/PostViewModel.kt | 20 ++++++----- 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/post/PostScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/post/PostScreen.kt index 18468f4d..8c4b2796 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/post/PostScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/post/PostScreen.kt @@ -99,7 +99,7 @@ fun PostScreen( val commentState = postViewModel.postComments.observeAsState() val commentText = remember { mutableStateOf(TextFieldValue("")) } val showMentionSearchView = remember { mutableStateOf(false) } - val commentFocusRequester = FocusRequester() + val commentFocusRequester = remember { FocusRequester() } // comment option val onClickCommentDelete: (Long) -> Unit = { commentId -> @@ -180,11 +180,30 @@ fun PostScreen( val onClickCancelReply: () -> Unit = { clearComment() } - val postCommentCreateSuccess by postViewModel.postCommentCreateSuccess.observeAsState(Event(false)) - if (postCommentCreateSuccess.getContentIfNotHandled() == true) { - clearComment() - keyboardController?.hide() - postViewModel.requestPostComment(postId) + + val postCommentCreateState by postViewModel.postCommentCreateState.observeAsState() + LaunchedEffect(postCommentCreateState) { + postCommentCreateState?.status?.let { state -> + when (state) { + Status.LOADING -> { + coroutineScope.launch { + snackBarHostState.showSnackbar(context.getString(R.string.loading_default_message)) + } + } + + Status.SUCCESS -> { + clearComment() + keyboardController?.hide() + postViewModel.requestPostComment(postId) + } + + Status.ERROR -> { + coroutineScope.launch { + snackBarHostState.showSnackbar(context.getString(R.string.network_error_dialog_default_message)) + } + } + } + } } BackHandler(enabled = loadingVisible) {} @@ -454,7 +473,7 @@ private fun PreviewPostScreen() { userSearchKeyword = userSearchKeyword, showMentionSearchView = showMentionSearchView, userResults = userResults, - commentFocusRequester = FocusRequester(), + commentFocusRequester = remember { FocusRequester() }, onClickPostComment = { }, onClickProfile = { }, onClickPost = { }, diff --git a/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt b/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt index 3984e606..119f8970 100644 --- a/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt +++ b/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt @@ -168,11 +168,30 @@ fun CommentBottomSheetDialog( val onClickCancelReply: () -> Unit = { clearComment() } - val postCommentCreateSuccess by postViewModel.postCommentCreateSuccess.observeAsState(Event(false)) - if (postCommentCreateSuccess.getContentIfNotHandled() == true) { - clearComment() - keyboardController?.hide() - postViewModel.requestPostComment(postId) + + val postCommentCreateState by postViewModel.postCommentCreateState.observeAsState() + LaunchedEffect(postCommentCreateState) { + postCommentCreateState?.status?.let { state -> + when (state) { + Status.LOADING -> { + coroutineScope.launch { + snackBarHostState.showSnackbar(context.getString(R.string.loading_default_message)) + } + } + + Status.SUCCESS -> { + clearComment() + keyboardController?.hide() + postViewModel.requestPostComment(postId) + } + + Status.ERROR -> { + coroutineScope.launch { + snackBarHostState.showSnackbar(context.getString(R.string.network_error_dialog_default_message)) + } + } + } + } } Surface( diff --git a/presentation/src/main/java/daily/dayo/presentation/viewmodel/PostViewModel.kt b/presentation/src/main/java/daily/dayo/presentation/viewmodel/PostViewModel.kt index 8c5a5aff..e0fccb7e 100644 --- a/presentation/src/main/java/daily/dayo/presentation/viewmodel/PostViewModel.kt +++ b/presentation/src/main/java/daily/dayo/presentation/viewmodel/PostViewModel.kt @@ -66,8 +66,8 @@ class PostViewModel @Inject constructor( private val _postDeleteSuccess = MutableSharedFlow() val postDeleteSuccess = _postDeleteSuccess.asSharedFlow() - private val _postCommentCreateSuccess = MutableLiveData>() - val postCommentCreateSuccess get() = _postCommentCreateSuccess + private val _postCommentCreateState = MutableLiveData>() + val postCommentCreateState: LiveData> get() = _postCommentCreateState private val _postCommentDeleteSuccess = MutableLiveData>() val postCommentDeleteSuccess get() = _postCommentDeleteSuccess @@ -241,17 +241,19 @@ class PostViewModel @Inject constructor( } fun requestCreatePostComment(contents: String, postId: Long, mentionedUser: List) { - if (contents.isEmpty()) return + if (contents.isEmpty() || _postCommentCreateState.value?.status == Status.LOADING) return + viewModelScope.launch { + _postCommentCreateState.postValue(Resource.loading(null)) val mentionList = getMentionList(contents, mentionedUser) requestCreatePostCommentUseCase(contents = contents, postId = postId, mentionList = mentionList).let { response -> when (response) { is NetworkResponse.Success -> { - _postCommentCreateSuccess.postValue(Event(true)) + _postCommentCreateState.postValue(Resource.success(true)) } else -> { - _postCommentCreateSuccess.postValue(Event(false)) + _postCommentCreateState.postValue(Resource.error("댓글 작성 실패", false)) } } } @@ -259,19 +261,21 @@ class PostViewModel @Inject constructor( } fun requestCreatePostCommentReply(reply: Pair, contents: String, postId: Long, mentionedUser: List) { - if (contents.isEmpty()) return + if (contents.isEmpty() || _postCommentCreateState.value?.status == Status.LOADING) return + viewModelScope.launch { + _postCommentCreateState.postValue(Resource.loading(null)) val mentionList = getMentionList(contents, mentionedUser).toMutableList() val (parentCommentId, comment) = reply mentionList.add(MentionUser(comment.memberId, comment.nickname)) // 언급된 유저 리스트에 원본 댓글 유저 추가 (팔로우하지 않아도 답글 가능하므로 따로 추가) requestCreatePostCommentReplyUseCase(commentId = parentCommentId, contents = contents, postId = postId, mentionList = mentionList).let { response -> when (response) { is NetworkResponse.Success -> { - _postCommentCreateSuccess.postValue(Event(true)) + _postCommentCreateState.postValue(Resource.success(true)) } else -> { - _postCommentCreateSuccess.postValue(Event(false)) + _postCommentCreateState.postValue(Resource.error("답글 작성 실패", false)) } } } From 71b81c9811a82264cb70fb0a73f180ce2e83fc8f Mon Sep 17 00:00:00 2001 From: Ju Yungyeom Date: Tue, 9 Dec 2025 18:01:01 +0900 Subject: [PATCH 2/2] #706 [feature] Display snackbar when bottom sheet is visible --- .../dayo/presentation/screen/main/MainScreen.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt index 6b6f7ed0..1241bd57 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt @@ -112,10 +112,9 @@ internal fun MainScreen( SharedTransitionLayout { Scaffold( snackbarHost = { - SnackbarHost( - hostState = snackBarHostState, - modifier = Modifier.navigationBarsPadding() - ) + if (!bottomSheetController.isVisible) { + SnackbarHost(hostState = snackBarHostState) + } } ) { Box { @@ -295,7 +294,13 @@ internal fun MainScreen( sheetState = bottomSheetState, dragHandle = null ) { - bottomSheetController.sheetContent() + Box { + bottomSheetController.sheetContent() + SnackbarHost( + hostState = snackBarHostState, + modifier = Modifier.align(Alignment.BottomCenter) + ) + } } } }