Skip to content

Commit 7916501

Browse files
authored
Merge pull request #713 from Daily-DAYO/bug/issue-706
Prevent duplicate reply submissions
2 parents b12c869 + 71b81c9 commit 7916501

4 files changed

Lines changed: 72 additions & 25 deletions

File tree

presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,9 @@ internal fun MainScreen(
112112
SharedTransitionLayout {
113113
Scaffold(
114114
snackbarHost = {
115-
SnackbarHost(
116-
hostState = snackBarHostState,
117-
modifier = Modifier.navigationBarsPadding()
118-
)
115+
if (!bottomSheetController.isVisible) {
116+
SnackbarHost(hostState = snackBarHostState)
117+
}
119118
}
120119
) {
121120
Box {
@@ -295,7 +294,13 @@ internal fun MainScreen(
295294
sheetState = bottomSheetState,
296295
dragHandle = null
297296
) {
298-
bottomSheetController.sheetContent()
297+
Box {
298+
bottomSheetController.sheetContent()
299+
SnackbarHost(
300+
hostState = snackBarHostState,
301+
modifier = Modifier.align(Alignment.BottomCenter)
302+
)
303+
}
299304
}
300305
}
301306
}

presentation/src/main/java/daily/dayo/presentation/screen/post/PostScreen.kt

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ fun PostScreen(
9999
val commentState = postViewModel.postComments.observeAsState()
100100
val commentText = remember { mutableStateOf(TextFieldValue("")) }
101101
val showMentionSearchView = remember { mutableStateOf(false) }
102-
val commentFocusRequester = FocusRequester()
102+
val commentFocusRequester = remember { FocusRequester() }
103103

104104
// comment option
105105
val onClickCommentDelete: (Long) -> Unit = { commentId ->
@@ -180,11 +180,30 @@ fun PostScreen(
180180
val onClickCancelReply: () -> Unit = {
181181
clearComment()
182182
}
183-
val postCommentCreateSuccess by postViewModel.postCommentCreateSuccess.observeAsState(Event(false))
184-
if (postCommentCreateSuccess.getContentIfNotHandled() == true) {
185-
clearComment()
186-
keyboardController?.hide()
187-
postViewModel.requestPostComment(postId)
183+
184+
val postCommentCreateState by postViewModel.postCommentCreateState.observeAsState()
185+
LaunchedEffect(postCommentCreateState) {
186+
postCommentCreateState?.status?.let { state ->
187+
when (state) {
188+
Status.LOADING -> {
189+
coroutineScope.launch {
190+
snackBarHostState.showSnackbar(context.getString(R.string.loading_default_message))
191+
}
192+
}
193+
194+
Status.SUCCESS -> {
195+
clearComment()
196+
keyboardController?.hide()
197+
postViewModel.requestPostComment(postId)
198+
}
199+
200+
Status.ERROR -> {
201+
coroutineScope.launch {
202+
snackBarHostState.showSnackbar(context.getString(R.string.network_error_dialog_default_message))
203+
}
204+
}
205+
}
206+
}
188207
}
189208

190209
BackHandler(enabled = loadingVisible) {}
@@ -454,7 +473,7 @@ private fun PreviewPostScreen() {
454473
userSearchKeyword = userSearchKeyword,
455474
showMentionSearchView = showMentionSearchView,
456475
userResults = userResults,
457-
commentFocusRequester = FocusRequester(),
476+
commentFocusRequester = remember { FocusRequester() },
458477
onClickPostComment = { },
459478
onClickProfile = { },
460479
onClickPost = { },

presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,30 @@ fun CommentBottomSheetDialog(
168168
val onClickCancelReply: () -> Unit = {
169169
clearComment()
170170
}
171-
val postCommentCreateSuccess by postViewModel.postCommentCreateSuccess.observeAsState(Event(false))
172-
if (postCommentCreateSuccess.getContentIfNotHandled() == true) {
173-
clearComment()
174-
keyboardController?.hide()
175-
postViewModel.requestPostComment(postId)
171+
172+
val postCommentCreateState by postViewModel.postCommentCreateState.observeAsState()
173+
LaunchedEffect(postCommentCreateState) {
174+
postCommentCreateState?.status?.let { state ->
175+
when (state) {
176+
Status.LOADING -> {
177+
coroutineScope.launch {
178+
snackBarHostState.showSnackbar(context.getString(R.string.loading_default_message))
179+
}
180+
}
181+
182+
Status.SUCCESS -> {
183+
clearComment()
184+
keyboardController?.hide()
185+
postViewModel.requestPostComment(postId)
186+
}
187+
188+
Status.ERROR -> {
189+
coroutineScope.launch {
190+
snackBarHostState.showSnackbar(context.getString(R.string.network_error_dialog_default_message))
191+
}
192+
}
193+
}
194+
}
176195
}
177196

178197
Surface(

presentation/src/main/java/daily/dayo/presentation/viewmodel/PostViewModel.kt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ class PostViewModel @Inject constructor(
6666
private val _postDeleteSuccess = MutableSharedFlow<Status>()
6767
val postDeleteSuccess = _postDeleteSuccess.asSharedFlow()
6868

69-
private val _postCommentCreateSuccess = MutableLiveData<Event<Boolean>>()
70-
val postCommentCreateSuccess get() = _postCommentCreateSuccess
69+
private val _postCommentCreateState = MutableLiveData<Resource<Boolean>>()
70+
val postCommentCreateState: LiveData<Resource<Boolean>> get() = _postCommentCreateState
7171

7272
private val _postCommentDeleteSuccess = MutableLiveData<Event<Boolean>>()
7373
val postCommentDeleteSuccess get() = _postCommentDeleteSuccess
@@ -241,37 +241,41 @@ class PostViewModel @Inject constructor(
241241
}
242242

243243
fun requestCreatePostComment(contents: String, postId: Long, mentionedUser: List<SearchUser>) {
244-
if (contents.isEmpty()) return
244+
if (contents.isEmpty() || _postCommentCreateState.value?.status == Status.LOADING) return
245+
245246
viewModelScope.launch {
247+
_postCommentCreateState.postValue(Resource.loading(null))
246248
val mentionList = getMentionList(contents, mentionedUser)
247249
requestCreatePostCommentUseCase(contents = contents, postId = postId, mentionList = mentionList).let { response ->
248250
when (response) {
249251
is NetworkResponse.Success -> {
250-
_postCommentCreateSuccess.postValue(Event(true))
252+
_postCommentCreateState.postValue(Resource.success(true))
251253
}
252254

253255
else -> {
254-
_postCommentCreateSuccess.postValue(Event(false))
256+
_postCommentCreateState.postValue(Resource.error("댓글 작성 실패", false))
255257
}
256258
}
257259
}
258260
}
259261
}
260262

261263
fun requestCreatePostCommentReply(reply: Pair<Long, Comment>, contents: String, postId: Long, mentionedUser: List<SearchUser>) {
262-
if (contents.isEmpty()) return
264+
if (contents.isEmpty() || _postCommentCreateState.value?.status == Status.LOADING) return
265+
263266
viewModelScope.launch {
267+
_postCommentCreateState.postValue(Resource.loading(null))
264268
val mentionList = getMentionList(contents, mentionedUser).toMutableList()
265269
val (parentCommentId, comment) = reply
266270
mentionList.add(MentionUser(comment.memberId, comment.nickname)) // 언급된 유저 리스트에 원본 댓글 유저 추가 (팔로우하지 않아도 답글 가능하므로 따로 추가)
267271
requestCreatePostCommentReplyUseCase(commentId = parentCommentId, contents = contents, postId = postId, mentionList = mentionList).let { response ->
268272
when (response) {
269273
is NetworkResponse.Success -> {
270-
_postCommentCreateSuccess.postValue(Event(true))
274+
_postCommentCreateState.postValue(Resource.success(true))
271275
}
272276

273277
else -> {
274-
_postCommentCreateSuccess.postValue(Event(false))
278+
_postCommentCreateState.postValue(Resource.error("답글 작성 실패", false))
275279
}
276280
}
277281
}

0 commit comments

Comments
 (0)