diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/reply/CreatorChannelCommunityReplyActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/reply/CreatorChannelCommunityReplyActivity.kt index 1d4ac89d..e5d0b910 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/reply/CreatorChannelCommunityReplyActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/reply/CreatorChannelCommunityReplyActivity.kt @@ -3,11 +3,9 @@ package kr.co.vividnext.sodalive.v2.creator.channel.community.detail.reply import android.app.Activity import android.content.Context import android.content.Intent -import android.text.InputType import android.text.method.ScrollingMovementMethod -import android.widget.EditText +import android.view.inputmethod.InputMethodManager import android.widget.Toast -import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.core.widget.doAfterTextChanged import androidx.recyclerview.widget.LinearLayoutManager @@ -15,6 +13,7 @@ import androidx.recyclerview.widget.RecyclerView import kr.co.vividnext.sodalive.R import kr.co.vividnext.sodalive.base.BaseActivity import kr.co.vividnext.sodalive.databinding.ActivityCreatorChannelCommunityReplyBinding +import kr.co.vividnext.sodalive.v2.components.modal.V2ModalDialog import kr.co.vividnext.sodalive.v2.creator.channel.community.detail.CreatorChannelCommunityCommentUiModel import kr.co.vividnext.sodalive.v2.creator.channel.community.detail.reply.ui.CreatorChannelCommunityReplyAdapter import kr.co.vividnext.sodalive.v2.creator.channel.community.detail.ui.CreatorChannelCommunityCommentAdapter @@ -26,10 +25,11 @@ class CreatorChannelCommunityReplyActivity : BaseActivity showModifyReplyDialog(reply.replyId, reply.comment) }, + onModifyClick = { reply -> viewModel.startReplyEdit(reply.replyId, reply.comment) }, onDeleteClick = { reply -> showDeleteReplyDialog(reply.replyId) } ) private var postId: Long = 0L + private var renderedEditingTarget: CreatorChannelCommunityReplyEditTarget? = null override fun setupView() { postId = intent.getLongExtra(EXTRA_POST_ID, 0L) @@ -57,17 +57,26 @@ class CreatorChannelCommunityReplyActivity : BaseActivity render(state) } + viewModel.replyWrittenEventLiveData.observe(this) { written -> + if (written == true) { + hideReplyKeyboard() + viewModel.consumeReplyWrittenEvent() + } + } viewModel.replyChangedEventLiveData.observe(this) { changed -> if (changed == true) { setResult(Activity.RESULT_OK) + hideReplyKeyboard() viewModel.consumeReplyChangedEvent() } } viewModel.parentCommentChangedEventLiveData.observe(this) { changed -> if (changed == true) { setResult(Activity.RESULT_OK) + hideReplyKeyboard() viewModel.consumeParentCommentChangedEvent() } } @@ -98,7 +107,7 @@ class CreatorChannelCommunityReplyActivity : BaseActivity showModifyParentCommentDialog(comment.comment) }, + onModifyClick = { comment -> viewModel.startParentCommentEdit(comment.comment) }, onDeleteClick = { showDeleteParentCommentDialog() } ) layoutCreatorChannelCommunityReplyParent.layoutCreatorChannelCommunityCommentLatestReply.isVisible = false @@ -107,69 +116,36 @@ class CreatorChannelCommunityReplyActivity : BaseActivity - val modifiedComment = editText.text?.toString().orEmpty() - if (modifiedComment.trim() == comment.trim()) { - Toast.makeText(this, R.string.audio_content_comment_no_change, Toast.LENGTH_SHORT).show() - } else { - viewModel.modifyReply(replyId, modifiedComment) - } - } - .show() - } - - private fun showModifyParentCommentDialog(comment: String) { - val editText = EditText(this).apply { - inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE - minLines = 3 - setText(comment) - setSelection(comment.length) - } - AlertDialog.Builder(this) - .setTitle(R.string.menu_modify_action) - .setView(editText) - .setNegativeButton(R.string.cancel, null) - .setPositiveButton(R.string.confirm) { _, _ -> - val modifiedComment = editText.text?.toString().orEmpty() - if (modifiedComment.trim() == comment.trim()) { - Toast.makeText(this, R.string.audio_content_comment_no_change, Toast.LENGTH_SHORT).show() - } else { - viewModel.modifyParentComment(modifiedComment) - } - } - .show() - } - private fun showDeleteParentCommentDialog() { - AlertDialog.Builder(this) - .setTitle(R.string.confirm_delete_title) - .setMessage(R.string.confirm_delete_message) - .setNegativeButton(R.string.cancel, null) - .setPositiveButton(R.string.confirm) { _, _ -> viewModel.deleteParentComment() } - .show() + V2ModalDialog( + activity = this, + layoutInflater = layoutInflater, + title = getString(R.string.confirm_delete_title), + desc = getString(R.string.confirm_delete_message), + confirmButtonTitle = getString(R.string.confirm), + confirmButtonClick = { viewModel.deleteParentComment() }, + cancelButtonTitle = getString(R.string.cancel) + ).show(screenWidth) } private fun showDeleteReplyDialog(replyId: Long) { - AlertDialog.Builder(this) - .setTitle(R.string.confirm_delete_title) - .setMessage(R.string.confirm_delete_message) - .setNegativeButton(R.string.cancel, null) - .setPositiveButton(R.string.confirm) { _, _ -> viewModel.deleteReply(replyId) } - .show() + V2ModalDialog( + activity = this, + layoutInflater = layoutInflater, + title = getString(R.string.confirm_delete_title), + desc = getString(R.string.confirm_delete_message), + confirmButtonTitle = getString(R.string.confirm), + confirmButtonClick = { viewModel.deleteReply(replyId) }, + cancelButtonTitle = getString(R.string.cancel) + ).show(screenWidth) } private fun updateSendButton(enabled: Boolean) = with(binding.btnCreatorChannelCommunityReplySend) { @@ -184,6 +160,22 @@ class CreatorChannelCommunityReplyActivity : BaseActivity modifyParentCommentFromInput(content, comment) + is CreatorChannelCommunityReplyEditTarget.Reply -> modifyReplyFromInput(content, target.replyId, comment) + } + } + + private fun modifyReplyFromInput( + content: CreatorChannelCommunityReplyUiState.Content, + replyId: Long, + comment: String + ) { + isModifyingReply = true + _replyStateLiveData.value = content.copy(isSendingReply = true) + compositeDisposable.add( + legacyRepository.modifyComment(ModifyCommentRequest(commentId = replyId, comment = comment), authToken()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { response -> + isModifyingReply = false + val current = _replyStateLiveData.value as? CreatorChannelCommunityReplyUiState.Content + ?: return@subscribe + if (response.success) { + _replyChangedEventLiveData.value = true + _replyStateLiveData.value = current.copy( + replyInput = "", + isSendingReply = false, + editingTarget = null + ) + loadReplyPage(page = FIRST_PAGE, append = false) + } else { + showMutationFailureToast(response.message) + _replyStateLiveData.value = current.copy(isSendingReply = false) + } + }, + { + isModifyingReply = false + val current = _replyStateLiveData.value as? CreatorChannelCommunityReplyUiState.Content + ?: return@subscribe + showMutationFailureToast() + _replyStateLiveData.value = current.copy(isSendingReply = false) + } + ) + ) + } + + private fun modifyParentCommentFromInput( + content: CreatorChannelCommunityReplyUiState.Content, + comment: String + ) { + val parentComment = parentComment ?: return + isModifyingReply = true + _replyStateLiveData.value = content.copy(isSendingReply = true) + compositeDisposable.add( + legacyRepository.modifyComment( + ModifyCommentRequest(commentId = parentComment.commentId, comment = comment), + authToken() + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + { response -> + isModifyingReply = false + val current = _replyStateLiveData.value as? CreatorChannelCommunityReplyUiState.Content + ?: return@subscribe + if (response.success) { + val updatedParent = parentComment.copy(comment = comment) + this.parentComment = updatedParent + _replyStateLiveData.value = current.copy( + parentComment = updatedParent, + replyInput = "", + isSendingReply = false, + editingTarget = null + ) + _parentCommentChangedEventLiveData.value = true + } else { + showMutationFailureToast(response.message) + _replyStateLiveData.value = current.copy(isSendingReply = false) + } + }, + { + isModifyingReply = false + val current = _replyStateLiveData.value as? CreatorChannelCommunityReplyUiState.Content + ?: return@subscribe + showMutationFailureToast() + _replyStateLiveData.value = current.copy(isSendingReply = false) + } + ) + ) + } + private fun modifyParentComment(parentComment: CreatorChannelCommunityCommentUiModel, comment: String) { isModifyingReply = true compositeDisposable.add( @@ -337,6 +473,12 @@ class CreatorChannelCommunityReplyViewModel( ) } + private fun showNoChangeToast() { + _toastLiveData.value = CreatorChannelEvent( + ToastMessage(resId = R.string.audio_content_comment_no_change) + ) + } + private fun CreatorChannelCommunityReplyResponse.toUiModel() = CreatorChannelCommunityReplyUiModel( replyId = commentId, commentId = parentComment?.commentId ?: 0L, @@ -360,6 +502,19 @@ class CreatorChannelCommunityReplyViewModel( } } +sealed interface CreatorChannelCommunityReplyEditTarget { + val originalComment: String + + data class ParentComment( + override val originalComment: String + ) : CreatorChannelCommunityReplyEditTarget + + data class Reply( + val replyId: Long, + override val originalComment: String + ) : CreatorChannelCommunityReplyEditTarget +} + sealed interface CreatorChannelCommunityReplyUiState { data class Content( val parentComment: CreatorChannelCommunityCommentUiModel, @@ -368,6 +523,7 @@ sealed interface CreatorChannelCommunityReplyUiState { val hasNextReply: Boolean, val isLoadingReplies: Boolean = false, val replyInput: String = "", - val isSendingReply: Boolean = false + val isSendingReply: Boolean = false, + val editingTarget: CreatorChannelCommunityReplyEditTarget? = null ) : CreatorChannelCommunityReplyUiState } diff --git a/app/src/main/res/layout/activity_creator_channel_community_reply.xml b/app/src/main/res/layout/activity_creator_channel_community_reply.xml index 18603f72..8bf03c48 100644 --- a/app/src/main/res/layout/activity_creator_channel_community_reply.xml +++ b/app/src/main/res/layout/activity_creator_channel_community_reply.xml @@ -25,18 +25,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - + +