diff --git a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditAdapter.kt b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditAdapter.kt index 0afe2201..2e332803 100644 --- a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditAdapter.kt +++ b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditAdapter.kt @@ -9,15 +9,11 @@ import org.sopt.ui.view.ItemDiffCallback class ClipEditAdapter( private val itemClick: (Long, String, Long, String) -> Unit, - private val deleteClip: (Long) -> Unit, - private val onLongClick: (Long) -> Unit, - private val onLongClick2: (Long) -> Unit, -) : ListAdapter(DiffUtil), ItemTouchHelperListener { +) : ListAdapter(DiffUtil) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ClipEditViewHolder { return ClipEditViewHolder( ItemClipEditClipBinding.inflate(LayoutInflater.from(parent.context), parent, false), itemClick, - onLongClick, ) } @@ -25,29 +21,21 @@ class ClipEditAdapter( holder.onBind(getItem(position)) } + fun moveItem(fromPosition: Int, toPosition: Int) { + val currentList = currentList.toMutableList() + val item = currentList.removeAt(fromPosition) + currentList.add(toPosition, item) + submitList(currentList) + } + + fun getCategoryId(position: Int): Long? { + return currentList[position].categoryId + } + companion object { private val DiffUtil = ItemDiffCallback( onItemsTheSame = { old, new -> old.categoryId == new.categoryId }, onContentsTheSame = { old, new -> old == new }, ) } - - override fun onItemMove(from: Int, to: Int) { - val item: Category? = currentList[from] - val newList = ArrayList() - newList.addAll(currentList) - newList.removeAt(from) - if (item != null) { - newList.add(to, item) - } - notifyItemMoved(from, to) - onLongClick2(to.toLong()) - } - - override fun onItemSwipe(position: Int) { - val newList = ArrayList(currentList) - deleteClip(newList[position].categoryId ?: 0) - newList.removeAt(position) - notifyItemRemoved(position) - } } diff --git a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditFragment.kt b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditFragment.kt index 66591c37..2acab12e 100644 --- a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditFragment.kt +++ b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditFragment.kt @@ -24,48 +24,33 @@ import org.sopt.ui.view.onThrottleClick class ClipEditFragment : BindingFragment({ FragmentClipEditBinding.inflate(it) }) { private val viewModel: ClipEditViewModel by viewModels() private lateinit var clipEditAdapter: ClipEditAdapter - private val itemTouchHelper by lazy { - ItemTouchHelper(ItemTouchCallback(clipEditAdapter)) - } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - clipEditAdapter = ClipEditAdapter( - { itemId, state, position, title -> - when (state) { - "delete" -> { - showDeleteDialog(itemId, title) - } + clipEditAdapter = ClipEditAdapter { itemId, state, position, title -> + when (state) { + "delete" -> { + showDeleteDialog(itemId, title) + } - "edit" -> { - showHomeBottomSheet(itemId, title) - } + "edit" -> { + showHomeBottomSheet(itemId, title) } - }, - deleteClip = { - viewModel.deleteCategory(it) - }, - onLongClick = { - viewModel.last2.flowWithLifecycle(viewLifeCycle).onEach { state -> - when (state) { - is UiState.Success -> { - viewModel.patchCategoryEditPriority(it, state.data + 1) - } - - else -> {} - } - }.launchIn(viewLifeCycleScope) - }, - onLongClick2 = { - viewModel.update2(it.toInt()) - }, - ) + } + } binding.rvClipEdit.adapter = clipEditAdapter - itemTouchHelper.attachToRecyclerView(binding.rvClipEdit) + val callback = ItemTouchCallback( + adapter = clipEditAdapter, + recyclerView = binding.rvClipEdit, + ) { categoryId, newIndex -> + if (categoryId != null) viewModel.updateCategoryEditPriorityState(categoryId, newIndex) + } + ItemTouchHelper(callback).attachToRecyclerView(binding.rvClipEdit) updateEditListView() updateDelete() onClickBackButton() + editCategoryPriority() } private fun updateEditListView() { @@ -117,7 +102,7 @@ class ClipEditFragment : BindingFragment({ FragmentClip } } - fun editCategoryTitle() { + private fun editCategoryTitle() { viewModel.editTitleState.flowWithLifecycle(viewLifeCycle).onEach { state -> when (state) { is UiState.Success -> { @@ -144,4 +129,16 @@ class ClipEditFragment : BindingFragment({ FragmentClip } .show() } + + private fun editCategoryPriority() { + viewModel.categoryEditPriorityState.flowWithLifecycle(viewLifeCycle).onEach { state -> + when (state) { + is UiState.Success -> { + viewModel.patchCategoryEditPriority(state.data.first, state.data.second) + } + + else -> {} + } + }.launchIn(viewLifeCycleScope) + } } diff --git a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewHolder.kt b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewHolder.kt index bfbbbd8d..795ab55a 100644 --- a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewHolder.kt +++ b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewHolder.kt @@ -8,7 +8,6 @@ import org.sopt.model.category.Category class ClipEditViewHolder( private val binding: ItemClipEditClipBinding, private val onClickItemClip: (Long, String, Long, String) -> Unit, - private val onLongClick: (Long) -> Unit, ) : RecyclerView.ViewHolder(binding.root) { fun onBind(clipData: Category) { if (clipData == null) return @@ -29,10 +28,6 @@ class ClipEditViewHolder( onClickItemClip(clipData.categoryId!!.toLong(), "delete", itemId, clipData.categoryTitle ?: "") } } - root.setOnLongClickListener { - onLongClick(clipData.categoryId!!.toLong()) - true - } } } } diff --git a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewModel.kt b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewModel.kt index b1f9c980..89f71a5f 100644 --- a/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewModel.kt +++ b/feature/clip/src/main/java/org/sopt/clip/clipedit/ClipEditViewModel.kt @@ -32,17 +32,17 @@ class ClipEditViewModel @Inject constructor( private val _editTitleState = MutableStateFlow>(UiState.Empty) val editTitleState: StateFlow> = _editTitleState.asStateFlow() - private val _last2 = MutableStateFlow>(UiState.Empty) - val last2: StateFlow> = _last2.asStateFlow() - - fun update2(a: Int) = viewModelScope.launch { - _last2.emit(UiState.Success(a)) - } + private val _categoryEditPriorityState = MutableStateFlow>>(UiState.Empty) + val categoryEditPriorityState: StateFlow>> = _categoryEditPriorityState.asStateFlow() init { getCategoryAll() } + fun updateCategoryEditPriorityState(clipId: Long, newIndex: Int) = viewModelScope.launch { + _categoryEditPriorityState.emit(UiState.Success(Pair(clipId, newIndex))) + } + fun getCategoryAll() = viewModelScope.launch { getCategoryAll.invoke().onSuccess { val allCategoryList = listOf( diff --git a/feature/clip/src/main/java/org/sopt/clip/clipedit/ItemTouchCallback.kt b/feature/clip/src/main/java/org/sopt/clip/clipedit/ItemTouchCallback.kt index 109cf5a0..b8958bac 100644 --- a/feature/clip/src/main/java/org/sopt/clip/clipedit/ItemTouchCallback.kt +++ b/feature/clip/src/main/java/org/sopt/clip/clipedit/ItemTouchCallback.kt @@ -3,20 +3,42 @@ package org.sopt.clip.clipedit import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -class ItemTouchCallback(private val listener: ItemTouchHelperListener) : ItemTouchHelper.Callback() { +class ItemTouchCallback( + private val adapter: ClipEditAdapter, + private val recyclerView: RecyclerView, + private val onMoveItem: (Long?, Int) -> Unit, +) : ItemTouchHelper.Callback() { - override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { - val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN - val swipeFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT - return makeMovementFlags(dragFlags, swipeFlags) + override fun getMovementFlags( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + ): Int { + val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.START or ItemTouchHelper.END + return makeMovementFlags(dragFlags, 0) } - override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { - listener.onItemMove(viewHolder.adapterPosition, target.adapterPosition) - return false + override fun onMove( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + target: RecyclerView.ViewHolder, + ): Boolean { + val fromPosition = viewHolder.bindingAdapterPosition + val toPosition = target.bindingAdapterPosition + adapter.moveItem(fromPosition, toPosition) + return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { - listener.onItemSwipe(viewHolder.layoutPosition) + } + + override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { + super.clearView(recyclerView, viewHolder) + onMoveItem(adapter.getCategoryId(viewHolder.bindingAdapterPosition), viewHolder.bindingAdapterPosition) + viewHolder.itemView.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200).start() + } + + override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) { + super.onSelectedChanged(viewHolder, actionState) + viewHolder?.itemView?.animate()?.scaleX(1.1f)?.scaleY(1.1f)?.setDuration(200)?.start() } } diff --git a/feature/clip/src/main/java/org/sopt/clip/clipedit/ItemTouchHelperListener.kt b/feature/clip/src/main/java/org/sopt/clip/clipedit/ItemTouchHelperListener.kt deleted file mode 100644 index db79afa3..00000000 --- a/feature/clip/src/main/java/org/sopt/clip/clipedit/ItemTouchHelperListener.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.sopt.clip.clipedit - -interface ItemTouchHelperListener { - fun onItemMove(from: Int, to: Int) - fun onItemSwipe(position: Int) -} diff --git a/feature/clip/src/main/res/layout/fragment_clip_edit.xml b/feature/clip/src/main/res/layout/fragment_clip_edit.xml index f9a90821..fedb1aba 100644 --- a/feature/clip/src/main/res/layout/fragment_clip_edit.xml +++ b/feature/clip/src/main/res/layout/fragment_clip_edit.xml @@ -104,4 +104,5 @@ android:layout_width="match_parent" android:layout_height="20dp" app:layout_constraintBottom_toBottomOf="parent"/> +