diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/layoutManager/CenterSmoothScroller.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/layoutManager/CenterSmoothScroller.kt deleted file mode 100644 index 7aa83f849..000000000 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/layoutManager/CenterSmoothScroller.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.emmsale.presentation.common.layoutManager - -import android.content.Context -import androidx.recyclerview.widget.LinearSmoothScroller -import dagger.hilt.android.qualifiers.ApplicationContext -import javax.inject.Inject - -class CenterSmoothScroller @Inject constructor( - @ApplicationContext context: Context, -) : LinearSmoothScroller(context) { - - override fun calculateDtToFit( - viewStart: Int, - viewEnd: Int, - boxStart: Int, - boxEnd: Int, - snapPreference: Int, - ): Int = (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2) -} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/layoutManager/EndSmoothScroller.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/layoutManager/EndSmoothScroller.kt deleted file mode 100644 index 85118711b..000000000 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/layoutManager/EndSmoothScroller.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.emmsale.presentation.common.layoutManager - -import android.content.Context -import androidx.recyclerview.widget.LinearSmoothScroller -import dagger.hilt.android.qualifiers.ApplicationContext -import javax.inject.Inject - -class EndSmoothScroller @Inject constructor( - @ApplicationContext context: Context, -) : LinearSmoothScroller(context) { - - override fun getVerticalSnapPreference(): Int = SNAP_TO_END -} diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/views/SubTextInputWindow.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/views/SubTextInputWindow.kt index a50fa1b2a..fd7cb1664 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/views/SubTextInputWindow.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/common/views/SubTextInputWindow.kt @@ -46,7 +46,6 @@ class SubTextInputWindow @JvmOverloads constructor( init { applyStyledAttributes(attrs) addView(binding.root) - isClickable = true background = context.getColor(R.color.white).toDrawable() elevation = 5f.dp } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsActivity.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsActivity.kt index a8b5770e5..533193ed0 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsActivity.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsActivity.kt @@ -7,7 +7,6 @@ import android.os.Bundle import androidx.activity.OnBackPressedCallback import androidx.activity.viewModels import androidx.core.view.isVisible -import androidx.lifecycle.lifecycleScope import com.emmsale.R import com.emmsale.data.model.Comment import com.emmsale.databinding.ActivityChildCommentsBinding @@ -15,8 +14,6 @@ import com.emmsale.presentation.base.NetworkActivity import com.emmsale.presentation.common.extension.hideKeyboard import com.emmsale.presentation.common.extension.showKeyboard import com.emmsale.presentation.common.extension.showSnackBar -import com.emmsale.presentation.common.layoutManager.CenterSmoothScroller -import com.emmsale.presentation.common.layoutManager.EndSmoothScroller import com.emmsale.presentation.common.recyclerView.DividerItemDecoration import com.emmsale.presentation.common.views.InfoDialog import com.emmsale.presentation.common.views.WarningDialog @@ -27,11 +24,9 @@ import com.emmsale.presentation.ui.childCommentList.ChildCommentsViewModel.Compa import com.emmsale.presentation.ui.childCommentList.recyclerView.CommentsAdapter import com.emmsale.presentation.ui.childCommentList.uiState.ChildCommentsUiEvent import com.emmsale.presentation.ui.feedDetail.FeedDetailActivity +import com.emmsale.presentation.ui.feedDetail.uiState.CommentsUiState import com.emmsale.presentation.ui.profile.ProfileActivity import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import javax.inject.Inject @AndroidEntryPoint class ChildCommentsActivity : @@ -39,14 +34,8 @@ class ChildCommentsActivity : override val viewModel: ChildCommentsViewModel by viewModels() - @Inject - lateinit var centerSmoothScroller: CenterSmoothScroller - - @Inject - lateinit var endSmoothScroller: EndSmoothScroller - private val commentsAdapter: CommentsAdapter = CommentsAdapter( - onCommentClick = { }, + onCommentClick = { comment -> viewModel.unhighlight(comment.id) }, onAuthorImageClick = { authorId -> ProfileActivity.startActivity(this, authorId) }, onCommentMenuClick = ::showCommentMenuDialog, ) @@ -74,21 +63,9 @@ class ChildCommentsActivity : private fun BottomMenuDialog.addCommentUpdateButton(commentId: Long) { addMenuItemBelow(context.getString(R.string.all_update_button_label)) { - viewModel.startEditComment(commentId) + viewModel.setEditMode(true, commentId) binding.stiwCommentUpdate.requestFocusOnEditText() showKeyboard() - startToEditComment(commentId) - } - } - - private fun startToEditComment(commentId: Long) { - val position = viewModel.comments.value.getPosition(commentId) - - lifecycleScope.launch { - delay(KEYBOARD_SHOW_WAITING_TIME) - binding.rvChildcommentsChildcomments - .layoutManager - ?.startSmoothScroll(endSmoothScroller.apply { targetPosition = position }) } } @@ -153,12 +130,12 @@ class ChildCommentsActivity : hideKeyboard() } binding.onCommentUpdateCancelButtonClick = { - viewModel.cancelEditComment() + viewModel.setEditMode(false) hideKeyboard() } binding.onUpdatedCommentSubmitButtonClick = { - val comment = viewModel.editingComment.value - if (comment != null) viewModel.updateComment(comment.id, it) + val commentId = viewModel.editingCommentId.value + if (commentId != null) viewModel.updateComment(commentId, it) hideKeyboard() } } @@ -195,31 +172,23 @@ class ChildCommentsActivity : private fun observeComments() { viewModel.comments.observe(this) { - commentsAdapter.submitList(it.commentUiStates) { handleHighlightComment() } + commentsAdapter.submitList(it.commentUiStates) { scrollToIfFirstFetch(it) } } } - private fun handleHighlightComment() { - if (highlightCommentId == INVALID_COMMENT_ID || isNotRealFirstEnter()) return - - viewModel.isAlreadyFirstFetched = true - viewModel.highlightCommentOnFirstEnter(highlightCommentId) - highlightCommentOnFirstEnter() - } - - private fun isNotRealFirstEnter(): Boolean = - viewModel.isAlreadyFirstFetched || viewModel.comments.value.commentUiStates.isEmpty() - - private fun highlightCommentOnFirstEnter() { - val position = viewModel.comments.value.getPosition(highlightCommentId) + private fun scrollToIfFirstFetch(commentUiState: CommentsUiState) { + fun cantScroll(): Boolean = + viewModel.isAlreadyFirstFetched || commentUiState.commentUiStates.isEmpty() + if (highlightCommentId == INVALID_COMMENT_ID || cantScroll()) return + val position = viewModel.comments.value.commentUiStates + .indexOfFirst { + it.comment.id == highlightCommentId + } binding.rvChildcommentsChildcomments.scrollToPosition(position) - lifecycleScope.launch { - delay(100L) // 버그 때문에 - binding.rvChildcommentsChildcomments - .layoutManager - ?.startSmoothScroll(centerSmoothScroller.apply { targetPosition = position }) - } + + viewModel.highlight(highlightCommentId) + viewModel.isAlreadyFirstFetched = true } private fun observeUiEvent() { @@ -273,7 +242,6 @@ class ChildCommentsActivity : private const val KEY_HIGHLIGHT_COMMENT_ID = "KEY_HIGHLIGHT_COMMENT_ID" private const val KEY_FROM_POST_DETAIL = "KEY_FROM_POST_DETAIL" private const val INVALID_COMMENT_ID: Long = -1 - private const val KEYBOARD_SHOW_WAITING_TIME = 300L fun startActivity( context: Context, diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsViewModel.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsViewModel.kt index d3eff880c..023431030 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsViewModel.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/childCommentList/ChildCommentsViewModel.kt @@ -4,8 +4,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.map -import androidx.lifecycle.viewModelScope -import com.emmsale.data.model.Comment import com.emmsale.data.repository.interfaces.CommentRepository import com.emmsale.data.repository.interfaces.TokenRepository import com.emmsale.presentation.base.RefreshableViewModel @@ -16,8 +14,6 @@ import com.emmsale.presentation.ui.childCommentList.uiState.ChildCommentsUiEvent import com.emmsale.presentation.ui.feedDetail.uiState.CommentsUiState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.properties.Delegates.vetoable @@ -40,16 +36,16 @@ class ChildCommentsViewModel @Inject constructor( private val _comments = NotNullMutableLiveData(CommentsUiState()) val comments: NotNullLiveData = _comments - private val _editingComment = MutableLiveData() - val editingComment: LiveData = _editingComment + private val _editingCommentId = MutableLiveData() + val editingCommentId: LiveData = _editingCommentId - val isEditingComment: LiveData = _editingComment.map { it != null } + val editingCommentContent: LiveData = _editingCommentId.map { commentId -> + if (commentId == null) null else _comments.value[commentId]?.comment?.content + } private val _canSubmitComment = NotNullMutableLiveData(true) val canSubmitComment: NotNullLiveData = _canSubmitComment - private var unhighlightJob: Job? = null - private val _uiEvent = SingleLiveEvent() val uiEvent: LiveData = _uiEvent @@ -73,7 +69,7 @@ class ChildCommentsViewModel @Inject constructor( fun updateComment(commentId: Long, content: String): Job = commandAndRefresh( command = { commentRepository.updateComment(commentId, content) }, - onSuccess = { _editingComment.value = null }, + onSuccess = { _editingCommentId.value = null }, onFailure = { _, _ -> _uiEvent.value = ChildCommentsUiEvent.CommentUpdateFail }, onStart = { _canSubmitComment.value = false }, onFinish = { _canSubmitComment.value = true }, @@ -84,26 +80,8 @@ class ChildCommentsViewModel @Inject constructor( onFailure = { _, _ -> _uiEvent.value = ChildCommentsUiEvent.CommentDeleteFail }, ) - fun startEditComment(commentId: Long) { - _editingComment.value = comments.value.commentUiStates - .find { it.comment.id == commentId } - ?.comment - ?: return - unhighlightJob?.cancel() - _comments.value = _comments.value.highlight(commentId) - } - - fun cancelEditComment() { - _editingComment.value = null - _comments.value = _comments.value.unhighlight() - } - - fun highlightCommentOnFirstEnter(commentId: Long) { - _comments.value = _comments.value.highlight(commentId) - unhighlightJob = viewModelScope.launch { - delay(COMMENT_HIGHLIGHTING_DURATION_ON_FIRST_ENTER) - _comments.value = _comments.value.unhighlight() - } + fun setEditMode(isEditMode: Boolean, commentId: Long = INVALID_COMMENT_ID) { + _editingCommentId.value = if (isEditMode) commentId else null } fun reportComment(commentId: Long): Job = command( @@ -128,12 +106,24 @@ class ChildCommentsViewModel @Inject constructor( onSuccess = { _comments.value = CommentsUiState(uid, it) }, ) + fun highlight(commentId: Long) { + val comment = _comments.value.commentUiStates.find { it.comment.id == commentId } ?: return + if (comment.isHighlight) return + _comments.value = _comments.value.highlight(commentId) + } + + fun unhighlight(commentId: Long) { + val comment = _comments.value.commentUiStates.find { it.comment.id == commentId } ?: return + if (!comment.isHighlight) return + _comments.value = _comments.value.unhighlight() + } + companion object { const val KEY_FEED_ID = "KEY_FEED_ID" const val KEY_PARENT_COMMENT_ID = "KEY_PARENT_COMMENT_ID" - private const val REPORT_DUPLICATE_ERROR_CODE = 400 + private const val INVALID_COMMENT_ID: Long = -1 - private const val COMMENT_HIGHLIGHTING_DURATION_ON_FIRST_ENTER = 2000L + private const val REPORT_DUPLICATE_ERROR_CODE = 400 } } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailActivity.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailActivity.kt index dff03f39b..8308b5c0c 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailActivity.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailActivity.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.os.Bundle import androidx.activity.viewModels import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearSmoothScroller import com.emmsale.R import com.emmsale.data.model.Comment import com.emmsale.databinding.ActivityFeedDetailBinding @@ -12,8 +13,6 @@ import com.emmsale.presentation.base.NetworkActivity import com.emmsale.presentation.common.extension.hideKeyboard import com.emmsale.presentation.common.extension.showKeyboard import com.emmsale.presentation.common.extension.showSnackBar -import com.emmsale.presentation.common.layoutManager.CenterSmoothScroller -import com.emmsale.presentation.common.layoutManager.EndSmoothScroller import com.emmsale.presentation.common.recyclerView.DividerItemDecoration import com.emmsale.presentation.common.views.InfoDialog import com.emmsale.presentation.common.views.WarningDialog @@ -27,7 +26,6 @@ import com.emmsale.presentation.ui.profile.ProfileActivity import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import javax.inject.Inject @AndroidEntryPoint class FeedDetailActivity : @@ -39,12 +37,6 @@ class FeedDetailActivity : override val viewModel: FeedDetailViewModel by viewModels() - @Inject - lateinit var centerSmoothScroller: CenterSmoothScroller - - @Inject - lateinit var endSmoothScroller: EndSmoothScroller - private val bottomMenuDialog: BottomMenuDialog by lazy { BottomMenuDialog(this) } private val feedAndCommentsAdapter = FeedAndCommentsAdapter( @@ -79,21 +71,9 @@ class FeedDetailActivity : private fun BottomMenuDialog.addCommentUpdateButton(commentId: Long) { addMenuItemBelow(context.getString(R.string.all_update_button_label)) { + viewModel.startEditComment(commentId) binding.stiwCommentUpdate.requestFocusOnEditText() showKeyboard() - viewModel.startEditComment(commentId) - startToEditComment(commentId) - } - } - - private fun startToEditComment(commentId: Long) { - val position = viewModel.feedDetailUiState.value.getCommentPosition(commentId) - - lifecycleScope.launch { - delay(KEYBOARD_SHOW_WAITING_TIME) - binding.rvFeedAndComments - .layoutManager - ?.startSmoothScroll(endSmoothScroller.apply { targetPosition = position }) } } @@ -162,8 +142,8 @@ class FeedDetailActivity : hideKeyboard() } binding.onUpdatedCommentSubmitButtonClick = { - val comment = viewModel.editingComment.value - if (comment != null) viewModel.updateComment(comment.id, it) + val commentId = viewModel.editingCommentId.value + if (commentId != null) viewModel.updateComment(commentId, it) hideKeyboard() } } @@ -232,33 +212,17 @@ class FeedDetailActivity : private fun observeFeedDetail() { viewModel.feedDetailUiState.observe(this) { val feedAndComments = listOf(it.feedUiState) + it.commentsUiState.commentUiStates - feedAndCommentsAdapter.submitList(feedAndComments) { handleHighlightComment() } + feedAndCommentsAdapter.submitList(feedAndComments) { + if (highlightCommentId == INVALID_COMMENT_ID || isNotRealFirstFetch()) return@submitList + viewModel.highlightComment(highlightCommentId) + viewModel.isAlreadyFirstFetched = true + } } } - private fun handleHighlightComment() { - if (highlightCommentId == INVALID_COMMENT_ID || isNotRealFirstEnter()) return - - viewModel.isAlreadyFirstFetched = true - viewModel.highlightCommentOnFirstEnter(highlightCommentId) - highlightCommentOnFirstEnter() - } - - private fun isNotRealFirstEnter(): Boolean = + private fun isNotRealFirstFetch(): Boolean = viewModel.isAlreadyFirstFetched || viewModel.commentUiStates.isEmpty() - private fun highlightCommentOnFirstEnter() { - val position = viewModel.feedDetailUiState.value.getCommentPosition(highlightCommentId) - - binding.rvFeedAndComments.scrollToPosition(position) - lifecycleScope.launch { - delay(100L) // 버그 때문에 - binding.rvFeedAndComments - .layoutManager - ?.startSmoothScroll(centerSmoothScroller.apply { targetPosition = position }) - } - } - private fun observeUiEvent() { viewModel.uiEvent.observe(this, ::handleUiEvent) } @@ -310,6 +274,8 @@ class FeedDetailActivity : binding.btiwCommentPost.clearText() scrollToLastPosition() } + + is FeedDetailUiEvent.CommentHighlight -> highlightComment(uiEvent.commentId) } } @@ -318,10 +284,26 @@ class FeedDetailActivity : binding.rvFeedAndComments.smoothScrollToPosition(commentsCount) } + private fun highlightComment(commentId: Long) { + val position = viewModel.commentUiStates + .indexOfFirst { + it.comment.id == commentId + } + + binding.rvFeedAndComments.scrollToPosition(position + 1) + lifecycleScope.launch { + delay(200L) + binding.rvFeedAndComments.layoutManager?.startSmoothScroll( + object : LinearSmoothScroller(this@FeedDetailActivity) { + override fun getVerticalSnapPreference(): Int = SNAP_TO_START + }.apply { targetPosition = position + 1 }, + ) + } + } + companion object { private const val KEY_HIGHLIGHT_COMMENT_ID = "KEY_HIGHLIGHT_COMMENT_ID" private const val INVALID_COMMENT_ID: Long = -1 - private const val KEYBOARD_SHOW_WAITING_TIME = 300L fun startActivity( context: Context, diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailViewModel.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailViewModel.kt index b21267f2f..255506ea8 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailViewModel.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/FeedDetailViewModel.kt @@ -28,7 +28,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.delay import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.properties.Delegates @@ -61,16 +60,15 @@ class FeedDetailViewModel @Inject constructor( val isFeedDetailWrittenByLoginUser: Boolean get() = feed.writer.id == uid - private val _editingComment = MutableLiveData() - val editingComment: LiveData = _editingComment - - val isEditingComment: LiveData = _editingComment.map { it != null } + private val _editingCommentId = MutableLiveData() + val editingCommentId: LiveData = _editingCommentId + val editingCommentContent: LiveData = _editingCommentId.map { commentId -> + if (commentId == null) null else commentUiStates.find { it.comment.id == commentId }?.comment?.content + } private val _canSubmitComment = NotNullMutableLiveData(true) val canSubmitComment: NotNullLiveData = _canSubmitComment - private var unhighlightJob: Job? = null - private val _uiEvent = SingleLiveEvent() val uiEvent: LiveData = _uiEvent @@ -187,7 +185,7 @@ class FeedDetailViewModel @Inject constructor( fun updateComment(commentId: Long, content: String): Job = commandAndRefresh( command = { commentRepository.updateComment(commentId, content) }, - onSuccess = { _editingComment.value = null }, + onSuccess = { _editingCommentId.value = null }, onFailure = { _, _ -> _uiEvent.value = FeedDetailUiEvent.CommentUpdateFail }, onStart = { _canSubmitComment.value = false }, onFinish = { _canSubmitComment.value = true }, @@ -199,25 +197,13 @@ class FeedDetailViewModel @Inject constructor( ) fun startEditComment(commentId: Long) { - _editingComment.value = commentUiStates - .find { it.comment.id == commentId } - ?.comment - ?: return - unhighlightJob?.cancel() - _feedDetailUiState.value = _feedDetailUiState.value.highlightComment(commentId) + _editingCommentId.value = commentId + highlightComment(commentId) } fun cancelEditComment() { - _editingComment.value = null - _feedDetailUiState.value = _feedDetailUiState.value.unhighlightComment() - } - - fun highlightCommentOnFirstEnter(commentId: Long) { - _feedDetailUiState.value = _feedDetailUiState.value.highlightComment(commentId) - unhighlightJob = viewModelScope.launch { - delay(COMMENT_HIGHLIGHTING_DURATION_ON_FIRST_ENTER) - _feedDetailUiState.value = _feedDetailUiState.value.unhighlightComment() - } + _editingCommentId.value = null + unhighlightComment() } fun reportComment(commentId: Long): Job = command( @@ -237,13 +223,20 @@ class FeedDetailViewModel @Inject constructor( }, ) + fun highlightComment(commentId: Long) { + _feedDetailUiState.value = _feedDetailUiState.value.highlightComment(commentId) + _uiEvent.value = FeedDetailUiEvent.CommentHighlight(commentId) + } + + private fun unhighlightComment() { + _feedDetailUiState.value = _feedDetailUiState.value.unhighlightComment() + } + companion object { const val KEY_FEED_ID: String = "KEY_FEED_ID" private const val DEFAULT_FEED_ID: Long = -1 private const val DELETED_FEED_FETCH_ERROR_CODE = 403 private const val REPORT_DUPLICATE_ERROR_CODE = 400 - - private const val COMMENT_HIGHLIGHTING_DURATION_ON_FIRST_ENTER = 2000L } } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentUiState.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentUiState.kt index e2c379680..d51e2f19e 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentUiState.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentUiState.kt @@ -8,12 +8,6 @@ data class CommentUiState( val comment: Comment, ) : FeedOrCommentUiState { - constructor(uid: Long, comment: Comment, isHighlight: Boolean = false) : this( - isWrittenByLoginUser = uid == comment.writer.id, - isHighlight = isHighlight, - comment = comment, - ) - override val id: Long = comment.id override val viewType: Int = VIEW_TYPE @@ -28,5 +22,12 @@ data class CommentUiState( companion object { const val VIEW_TYPE = 1 + + fun create(uid: Long, comment: Comment, isHighlight: Boolean = false): CommentUiState = + CommentUiState( + isWrittenByLoginUser = uid == comment.writer.id, + isHighlight = isHighlight, + comment = comment, + ) } } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentsUiState.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentsUiState.kt index 05598bd40..320f4ba95 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentsUiState.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/CommentsUiState.kt @@ -6,14 +6,16 @@ data class CommentsUiState(val commentUiStates: List = emptyList constructor(uid: Long, comments: List) : this( comments.flatMap { comment -> - listOf(CommentUiState(uid, comment)) + - comment.childComments.map { childComment -> CommentUiState(uid, childComment) } + listOf(CommentUiState.create(uid, comment)) + + comment.childComments.map { childComment -> + CommentUiState.create(uid, childComment) + } }, ) constructor(uid: Long, comment: Comment) : this( - listOf(CommentUiState(uid, comment)) + - comment.childComments.map { childComment -> CommentUiState(uid, childComment) }, + listOf(CommentUiState.create(uid, comment)) + + comment.childComments.map { childComment -> CommentUiState.create(uid, childComment) }, ) val size: Int = commentUiStates.size @@ -21,9 +23,6 @@ data class CommentsUiState(val commentUiStates: List = emptyList operator fun get(commentId: Long): CommentUiState? = commentUiStates.find { it.comment.id == commentId } - fun getPosition(commentId: Long): Int = - commentUiStates.indexOfFirst { it.comment.id == commentId } - fun highlight(commentId: Long) = copy( commentUiStates = commentUiStates.map { if (it.comment.id == commentId) it.highlight() else it.unhighlight() }, ) diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiEvent.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiEvent.kt index 5194643c2..a25ff414b 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiEvent.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiEvent.kt @@ -11,4 +11,5 @@ sealed interface FeedDetailUiEvent { object CommentReportFail : FeedDetailUiEvent object CommentReportComplete : FeedDetailUiEvent object CommentPostComplete : FeedDetailUiEvent + data class CommentHighlight(val commentId: Long) : FeedDetailUiEvent } diff --git a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiState.kt b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiState.kt index f4b29aadf..5d8beb5c9 100644 --- a/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiState.kt +++ b/android/2023-emmsale/app/src/main/java/com/emmsale/presentation/ui/feedDetail/uiState/FeedDetailUiState.kt @@ -12,8 +12,6 @@ data class FeedDetailUiState( commentsUiState = CommentsUiState(uid, comments), ) - fun getCommentPosition(commentId: Long): Int = commentsUiState.getPosition(commentId) + 1 - fun highlightComment(commentId: Long): FeedDetailUiState = copy(commentsUiState = commentsUiState.highlight(commentId)) diff --git a/android/2023-emmsale/app/src/main/res/layout/activity_child_comments.xml b/android/2023-emmsale/app/src/main/res/layout/activity_child_comments.xml index 519f72838..e33fcdc78 100644 --- a/android/2023-emmsale/app/src/main/res/layout/activity_child_comments.xml +++ b/android/2023-emmsale/app/src/main/res/layout/activity_child_comments.xml @@ -52,65 +52,68 @@ app:swipeRefreshColor="@{@color/primary_color}" android:layout_width="0dp" android:layout_height="0dp" - app:layout_constraintBottom_toTopOf="@id/barrier_input_windows" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tb_childcomments_toolbar"> + + - - - - - - - - + + + + + + + + + @@ -74,7 +74,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:hint="@string/comments_edit_comment_hint" - app:visible="@{!vm.isEditingComment}" app:onSubmit="@{(content) -> onCommentSubmitButtonClick.invoke(content)}" app:isSubmitEnabled="@{vm.canSubmitComment}" app:submitButtonLabel="@string/comments_comment_submit_button_label" /> @@ -86,21 +85,14 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent" - app:text="@{vm.editingComment.content}" - app:visible="@{vm.isEditingComment}" + app:text="@{vm.editingCommentContent}" + app:visible="@{vm.editingCommentId != null}" app:isSubmitEnabled="@{vm.canSubmitComment}" app:submitButtonLabel="@string/all_update_button_label" app:cancelButtonLabel="@string/all_cancel" app:onCancel="@{() -> onCommentUpdateCancelButtonClick.invoke()}" app:onSubmit="@{(content) -> onUpdatedCommentSubmitButtonClick.invoke(content)}" /> - -