From ee692683fbe2545668b546eef7846eebe43a56a3 Mon Sep 17 00:00:00 2001 From: jaehan4707 Date: Wed, 13 Dec 2023 11:38:34 +0900 Subject: [PATCH 01/13] =?UTF-8?q?feat(#286):=20RecycleBinClickListener=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mindsync/ui/recyclebin/RecycleBinClickListener.kt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt new file mode 100644 index 00000000..5ccda2a2 --- /dev/null +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt @@ -0,0 +1,7 @@ +package boostcamp.and07.mindsync.ui.recyclebin + +import boostcamp.and07.mindsync.data.model.Board + +interface RecycleBinClickListener { + fun onCheckBoxClick(board: Board) +} \ No newline at end of file From d143d9438c266ce9e93721cb0fb468465bb64b9f Mon Sep 17 00:00:00 2001 From: jaehan4707 Date: Wed, 13 Dec 2023 11:39:02 +0900 Subject: [PATCH 02/13] =?UTF-8?q?feat(#286):=20RecycleBinAdapter,BindingAd?= =?UTF-8?q?apter=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/recyclebin/RecycleBinAdapter.kt | 71 +++++++++++++++++++ .../ui/recyclebin/RecycleBinBindingAdpater.kt | 13 ++++ 2 files changed, 84 insertions(+) create mode 100644 AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt create mode 100644 AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt new file mode 100644 index 00000000..7f114213 --- /dev/null +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt @@ -0,0 +1,71 @@ +package boostcamp.and07.mindsync.ui.RecycleBin + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import boostcamp.and07.mindsync.data.model.Board +import boostcamp.and07.mindsync.databinding.ItemRecycleBoardBinding +import boostcamp.and07.mindsync.ui.recyclebin.RecycleBinClickListener + +class RecycleBinAdapter : + ListAdapter(DIFF_CALLBACK) { + private var clickListener: RecycleBinClickListener? = null + + fun setRecycleBinClickListener(listener: RecycleBinClickListener) { + this.clickListener = listener + } + + class RecycleBinViewHolder( + private val binding: ItemRecycleBoardBinding, + private val clickListener: RecycleBinClickListener?, + ) : + RecyclerView.ViewHolder(binding.root) { + fun bind(item: Board) { + with(binding) { + board = item + cbBoard.isChecked = item.isChecked + cbBoard.setOnClickListener { + item.isChecked = !item.isChecked + clickListener?.onCheckBoxClick(item) + } + } + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int, + ): RecycleBinViewHolder { + val binding = + ItemRecycleBoardBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return RecycleBinViewHolder(binding, clickListener) + } + + override fun onBindViewHolder( + holder: RecycleBinViewHolder, + position: Int, + ) { + holder.bind(getItem(position)) + } + + companion object { + val DIFF_CALLBACK = + object : DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: Board, + newItem: Board, + ): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame( + oldItem: Board, + newItem: Board, + ): Boolean { + return oldItem == newItem + } + } + } +} diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt new file mode 100644 index 00000000..75248632 --- /dev/null +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt @@ -0,0 +1,13 @@ +package boostcamp.and07.mindsync.ui.recyclebin + +import androidx.databinding.BindingAdapter +import androidx.recyclerview.widget.RecyclerView +import boostcamp.and07.mindsync.data.model.Board +import boostcamp.and07.mindsync.ui.RecycleBin.RecycleBinAdapter + +@BindingAdapter("app:restoreBoards") +fun RecyclerView.bindRestoreBoards(boards:List){ + if(this.adapter!=null){ + (this.adapter as RecycleBinAdapter).submitList(boards.toMutableList()) + } +} \ No newline at end of file From cf889e3fe8e13f97d3859b20f5dfbcf1c95a27b4 Mon Sep 17 00:00:00 2001 From: jaehan4707 Date: Wed, 13 Dec 2023 11:39:53 +0900 Subject: [PATCH 03/13] =?UTF-8?q?feat(#286):=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=EC=96=B4=EB=8E=81=ED=84=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BoardListAdapter -> RecycleBinAdapter --- .../ui/recyclebin/RecycleBinFragment.kt | 22 +++++-------------- .../main/res/layout/fragment_recycle_bin.xml | 2 +- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt index 7b8bc3bc..88343f7a 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt @@ -1,21 +1,18 @@ package boostcamp.and07.mindsync.ui.recyclebin import androidx.fragment.app.viewModels -import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import boostcamp.and07.mindsync.R import boostcamp.and07.mindsync.data.model.Board import boostcamp.and07.mindsync.databinding.FragmentRecycleBinBinding +import boostcamp.and07.mindsync.ui.RecycleBin.RecycleBinAdapter import boostcamp.and07.mindsync.ui.base.BaseFragment -import boostcamp.and07.mindsync.ui.boardlist.BoardClickListener -import boostcamp.and07.mindsync.ui.boardlist.BoardListAdapter -import boostcamp.and07.mindsync.ui.boardlist.BoardListFragmentDirections import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class RecycleBinFragment : BaseFragment(R.layout.fragment_recycle_bin) { private val recycleBinViewModel: RecycleBinViewModel by viewModels() - private val boardListAdapter = BoardListAdapter() + private val recycleBinAdapter = RecycleBinAdapter() private val args: RecycleBinFragmentArgs by navArgs() override fun initView() { @@ -26,18 +23,9 @@ class RecycleBinFragment : BaseFragment(R.layout.frag private fun setBinding() { binding.vm = recycleBinViewModel - binding.rvRecyclebinBoard.adapter = boardListAdapter - boardListAdapter.setBoardClickListener( - object : BoardClickListener { - override fun onClick(board: Board) { - findNavController().navigate( - BoardListFragmentDirections.actionBoardListFragmentToMindMapFragment( - boardId = board.id, - boardName = board.name, - ), - ) - } - + binding.rvRecyclebinBoard.adapter = recycleBinAdapter + recycleBinAdapter.setRecycleBinClickListener( + object :RecycleBinClickListener { override fun onCheckBoxClick(board: Board) { recycleBinViewModel.selectBoard(board) } diff --git a/AOS/app/src/main/res/layout/fragment_recycle_bin.xml b/AOS/app/src/main/res/layout/fragment_recycle_bin.xml index 57e2d285..83a66204 100644 --- a/AOS/app/src/main/res/layout/fragment_recycle_bin.xml +++ b/AOS/app/src/main/res/layout/fragment_recycle_bin.xml @@ -43,7 +43,7 @@ android:layout_gravity="center|top" android:layout_marginTop="15dp" android:background="@android:color/transparent" - app:boards="@{vm.uiState.boards}" + app:restoreBoards="@{vm.uiState.boards}" app:flexBoxLayoutManager="@{FlexDirection.ROW}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@id/gl_recyclebin_end" From a5110eed5a6df59262ad4de67d0c3d1a2fab5db0 Mon Sep 17 00:00:00 2001 From: jaehan4707 Date: Wed, 13 Dec 2023 11:40:36 +0900 Subject: [PATCH 04/13] =?UTF-8?q?feat(#286):=20=EC=95=B1=20=ED=83=80?= =?UTF-8?q?=EC=9D=B4=ED=8B=80=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/boostcamp/and07/mindsync/ui/main/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainActivity.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainActivity.kt index 90d22b30..e3855a5e 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainActivity.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainActivity.kt @@ -41,6 +41,7 @@ class MainActivity : super.onStart() mainViewModel.fetchProfile() mainViewModel.getSpaces() + setTitle() } override fun init() { @@ -52,7 +53,6 @@ class MainActivity : setSideBarNavigation() setBinding() observeEvent() - setTitle() } override fun getViewModel(): BaseActivityViewModel { From cf33e442af50562979420ea8b63b8e9fa32cc2b4 Mon Sep 17 00:00:00 2001 From: "seona.Yang" <75965560+yang1318@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:45:01 +0900 Subject: [PATCH 05/13] =?UTF-8?q?fix(#286):=20=EC=84=A0=ED=83=9D=EB=90=9C?= =?UTF-8?q?=20=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=9C=A0=EC=A7=80=20?= =?UTF-8?q?=EC=95=88=EB=90=98=EB=8A=94=20=ED=98=84=EC=83=81=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../and07/mindsync/ui/main/MainViewModel.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt index 6421c794..6786d90c 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt @@ -49,10 +49,20 @@ class MainViewModel fun getSpaces() { viewModelScope.launch(coroutineExceptionHandler) { - profileSpaceRepository.getSpaces().collectLatest { spaces -> + profileSpaceRepository.getSpaces().collectLatest { responseSpaces -> + val spaceMap: Map = + _uiState.value.spaces.associateBy { space -> space.id } + val newSpaces = mutableListOf() + responseSpaces.forEach { space -> + if (spaceMap.containsKey(space.id)) { + newSpaces.add(space.copy(isSelected = spaceMap[space.id]!!.isSelected)) + } else { + newSpaces.add(space) + } + } _uiState.update { uiState -> uiState.copy( - spaces = spaces, + spaces = newSpaces, ) } } From a5d8226d3f2b4996ff0f71d1abfd1a8e603d9588 Mon Sep 17 00:00:00 2001 From: "seona.Yang" <75965560+yang1318@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:45:39 +0900 Subject: [PATCH 06/13] =?UTF-8?q?style:=20ktlint=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt | 3 +-- .../mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt | 7 +++---- .../mindsync/ui/recyclebin/RecycleBinClickListener.kt | 2 +- .../and07/mindsync/ui/recyclebin/RecycleBinFragment.kt | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt index 7f114213..df201a30 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinAdapter.kt @@ -1,4 +1,4 @@ -package boostcamp.and07.mindsync.ui.RecycleBin +package boostcamp.and07.mindsync.ui.recyclebin import android.view.LayoutInflater import android.view.ViewGroup @@ -7,7 +7,6 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import boostcamp.and07.mindsync.data.model.Board import boostcamp.and07.mindsync.databinding.ItemRecycleBoardBinding -import boostcamp.and07.mindsync.ui.recyclebin.RecycleBinClickListener class RecycleBinAdapter : ListAdapter(DIFF_CALLBACK) { diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt index 75248632..075dbd43 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinBindingAdpater.kt @@ -3,11 +3,10 @@ package boostcamp.and07.mindsync.ui.recyclebin import androidx.databinding.BindingAdapter import androidx.recyclerview.widget.RecyclerView import boostcamp.and07.mindsync.data.model.Board -import boostcamp.and07.mindsync.ui.RecycleBin.RecycleBinAdapter @BindingAdapter("app:restoreBoards") -fun RecyclerView.bindRestoreBoards(boards:List){ - if(this.adapter!=null){ +fun RecyclerView.bindRestoreBoards(boards: List) { + if (this.adapter != null) { (this.adapter as RecycleBinAdapter).submitList(boards.toMutableList()) } -} \ No newline at end of file +} diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt index 5ccda2a2..1ff46e9e 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinClickListener.kt @@ -4,4 +4,4 @@ import boostcamp.and07.mindsync.data.model.Board interface RecycleBinClickListener { fun onCheckBoxClick(board: Board) -} \ No newline at end of file +} diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt index 88343f7a..db350f2f 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/recyclebin/RecycleBinFragment.kt @@ -5,7 +5,6 @@ import androidx.navigation.fragment.navArgs import boostcamp.and07.mindsync.R import boostcamp.and07.mindsync.data.model.Board import boostcamp.and07.mindsync.databinding.FragmentRecycleBinBinding -import boostcamp.and07.mindsync.ui.RecycleBin.RecycleBinAdapter import boostcamp.and07.mindsync.ui.base.BaseFragment import dagger.hilt.android.AndroidEntryPoint @@ -25,7 +24,7 @@ class RecycleBinFragment : BaseFragment(R.layout.frag binding.vm = recycleBinViewModel binding.rvRecyclebinBoard.adapter = recycleBinAdapter recycleBinAdapter.setRecycleBinClickListener( - object :RecycleBinClickListener { + object : RecycleBinClickListener { override fun onCheckBoxClick(board: Board) { recycleBinViewModel.selectBoard(board) } From 928c5cd48de717df5d266df0c20024598536e574 Mon Sep 17 00:00:00 2001 From: "seona.Yang" <75965560+yang1318@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:54:36 +0900 Subject: [PATCH 07/13] =?UTF-8?q?refactor(#286):=20spaceMap=EC=9D=84=20?= =?UTF-8?q?=EC=9D=B4=EC=9A=A9=ED=95=9C=20=EC=BD=94=EB=93=9C=EB=A5=BC=20now?= =?UTF-8?q?Space=EB=A5=BC=20=ED=99=9C=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boostcamp/and07/mindsync/ui/main/MainViewModel.kt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt index 6786d90c..3990c56e 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt @@ -50,14 +50,11 @@ class MainViewModel fun getSpaces() { viewModelScope.launch(coroutineExceptionHandler) { profileSpaceRepository.getSpaces().collectLatest { responseSpaces -> - val spaceMap: Map = - _uiState.value.spaces.associateBy { space -> space.id } - val newSpaces = mutableListOf() - responseSpaces.forEach { space -> - if (spaceMap.containsKey(space.id)) { - newSpaces.add(space.copy(isSelected = spaceMap[space.id]!!.isSelected)) + val newSpaces = responseSpaces.map { space -> + if (space.id == _uiState.value.nowSpace?.id) { + space.copy(isSelected = true) } else { - newSpaces.add(space) + space } } _uiState.update { uiState -> From 40e435c0a605bb051b167fb3d769c3336a4d367d Mon Sep 17 00:00:00 2001 From: "seona.Yang" <75965560+yang1318@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:55:43 +0900 Subject: [PATCH 08/13] =?UTF-8?q?style:=20ktlint=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../and07/mindsync/ui/main/MainViewModel.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt index 3990c56e..93611de8 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/main/MainViewModel.kt @@ -50,13 +50,14 @@ class MainViewModel fun getSpaces() { viewModelScope.launch(coroutineExceptionHandler) { profileSpaceRepository.getSpaces().collectLatest { responseSpaces -> - val newSpaces = responseSpaces.map { space -> - if (space.id == _uiState.value.nowSpace?.id) { - space.copy(isSelected = true) - } else { - space + val newSpaces = + responseSpaces.map { space -> + if (space.id == _uiState.value.nowSpace?.id) { + space.copy(isSelected = true) + } else { + space + } } - } _uiState.update { uiState -> uiState.copy( spaces = newSpaces, From 37f527c945cc91671e7f1f8a644669071ca23c3f Mon Sep 17 00:00:00 2001 From: dltkd1395 Date: Wed, 13 Dec 2023 12:10:10 +0900 Subject: [PATCH 09/13] =?UTF-8?q?feat(#286):=20Serializable=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/boostcamp/and07/mindsync/data/model/Node.kt | 4 +++- .../main/java/boostcamp/and07/mindsync/data/model/NodePath.kt | 2 ++ .../java/boostcamp/and07/mindsync/ui/util/DensityUtils.kt | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/Node.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/Node.kt index ee50390c..3076c7d1 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/Node.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/Node.kt @@ -1,14 +1,16 @@ package boostcamp.and07.mindsync.data.model import boostcamp.and07.mindsync.ui.util.Dp +import kotlinx.serialization.Serializable +@Serializable sealed class Node( open val id: String, open val parentId: String?, open val path: NodePath, open val description: String, open val children: List, -) +) : java.io.Serializable data class CircleNode( override val id: String, diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/NodePath.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/NodePath.kt index d37f3323..e6199f7e 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/NodePath.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/data/model/NodePath.kt @@ -1,7 +1,9 @@ package boostcamp.and07.mindsync.data.model import boostcamp.and07.mindsync.ui.util.Dp +import kotlinx.serialization.Serializable +@Serializable sealed class NodePath(open val centerX: Dp, open val centerY: Dp) data class RectanglePath( diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/DensityUtils.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/DensityUtils.kt index 217b8641..adda668c 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/DensityUtils.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/util/DensityUtils.kt @@ -2,7 +2,9 @@ package boostcamp.and07.mindsync.ui.util import android.content.Context import android.util.TypedValue +import kotlinx.serialization.Serializable +@Serializable data class Dp(val dpVal: Float) { operator fun plus(dpValue: Dp): Dp { return Dp(dpVal + dpValue.dpVal) From b5cbaafc5a0d60f8aeae33a2ce287ef75e322cb9 Mon Sep 17 00:00:00 2001 From: dltkd1395 Date: Wed, 13 Dec 2023 12:11:01 +0900 Subject: [PATCH 10/13] =?UTF-8?q?feat(#286):=20operation,=20node=20argumen?= =?UTF-8?q?t=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AOS/app/src/main/res/navigation/nav_graph.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/AOS/app/src/main/res/navigation/nav_graph.xml b/AOS/app/src/main/res/navigation/nav_graph.xml index 37a95504..5959ee83 100644 --- a/AOS/app/src/main/res/navigation/nav_graph.xml +++ b/AOS/app/src/main/res/navigation/nav_graph.xml @@ -18,6 +18,9 @@ + + android:label="EditDescriptionDialog" > + + + Date: Wed, 13 Dec 2023 12:12:59 +0900 Subject: [PATCH 11/13] =?UTF-8?q?refactor(#286):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boostcamp/and07/mindsync/ui/mindmap/MindMapViewModel.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModel.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModel.kt index cf1cc522..7ec4c61b 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModel.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModel.kt @@ -19,7 +19,6 @@ import boostcamp.and07.mindsync.data.network.SocketEventType import boostcamp.and07.mindsync.data.network.SocketState import boostcamp.and07.mindsync.data.network.response.mindmap.SerializedCrdtTree import boostcamp.and07.mindsync.data.network.response.mindmap.SerializedOperation -import boostcamp.and07.mindsync.data.repository.mindmap.MindMapRepository import boostcamp.and07.mindsync.ui.util.Dp import boostcamp.and07.mindsync.ui.util.ExceptionMessage import dagger.hilt.android.lifecycle.HiltViewModel @@ -32,9 +31,7 @@ import javax.inject.Inject @HiltViewModel class MindMapViewModel @Inject - constructor( - private val mindMapRepository: MindMapRepository, - ) : ViewModel() { + constructor() : ViewModel() { private var boardId: String = "" val crdtTree = CrdtTree(id = IdGenerator.makeRandomNodeId(), tree = Tree()) private var _selectedNode = MutableStateFlow(null) From 721da99a0d21c364b509efcfd2a4b2ede5597f87 Mon Sep 17 00:00:00 2001 From: dltkd1395 Date: Wed, 13 Dec 2023 12:13:20 +0900 Subject: [PATCH 12/13] =?UTF-8?q?feat(#286):=20MindMapViewModelFactory=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/mindmap/MindMapViewModelFactory.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModelFactory.kt diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModelFactory.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModelFactory.kt new file mode 100644 index 00000000..ceed6148 --- /dev/null +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapViewModelFactory.kt @@ -0,0 +1,15 @@ +package boostcamp.and07.mindsync.ui.mindmap + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider + +class MindMapViewModelFactory : + ViewModelProvider.Factory { + override fun create(modelClass: Class): T { + if (modelClass.isAssignableFrom(MindMapViewModel::class.java)) { + @Suppress("UNCHECKED_CAST") + return MindMapViewModel() as T + } + throw IllegalArgumentException("Unknown ViewModel class") + } +} From 8ff7cceef96b6c2efd049dbe8d97416346773aca Mon Sep 17 00:00:00 2001 From: dltkd1395 Date: Wed, 13 Dec 2023 12:15:51 +0900 Subject: [PATCH 13/13] =?UTF-8?q?fix(#286):=20=ED=9A=8C=EC=A0=84=20?= =?UTF-8?q?=EC=8B=9C=20=EB=8B=A4=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=98=20=EC=9E=91=EC=84=B1=20=EB=B2=84=ED=8A=BC=EC=9D=84=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=ED=96=88=EC=9D=84=20=EB=95=8C=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/dialog/EditDescriptionDialog.kt | 59 +++++++++++++++---- .../mindsync/ui/mindmap/MindMapFragment.kt | 58 +++++++++--------- 2 files changed, 74 insertions(+), 43 deletions(-) diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/EditDescriptionDialog.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/EditDescriptionDialog.kt index 7240a5f9..4eee8e1b 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/EditDescriptionDialog.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/dialog/EditDescriptionDialog.kt @@ -10,17 +10,22 @@ import android.view.View import android.view.ViewGroup import android.view.WindowManager import androidx.fragment.app.DialogFragment +import androidx.navigation.fragment.navArgs +import androidx.navigation.navGraphViewModels import boostcamp.and07.mindsync.R +import boostcamp.and07.mindsync.data.NodeGenerator +import boostcamp.and07.mindsync.data.crdt.OperationType +import boostcamp.and07.mindsync.data.model.CircleNode +import boostcamp.and07.mindsync.data.model.RectangleNode import boostcamp.and07.mindsync.databinding.DialogEditDescriptionBinding +import boostcamp.and07.mindsync.ui.mindmap.MindMapViewModel class EditDescriptionDialog : DialogFragment() { private var _binding: DialogEditDescriptionBinding? = null private val binding get() = _binding!! private lateinit var editDialogInterface: EditDialogInterface - - fun setListener(listener: EditDialogInterface) { - editDialogInterface = listener - } + private val mindMapViewModel: MindMapViewModel by navGraphViewModels(R.id.nav_graph) + private val args: EditDescriptionDialogArgs by navArgs() override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) @@ -36,16 +41,46 @@ class EditDescriptionDialog : DialogFragment() { savedInstanceState: Bundle?, ): View { _binding = DialogEditDescriptionBinding.inflate(inflater, container, false) - binding.run { - btnCancel.setOnClickListener { - dismiss() - } - btnSubmit.setOnClickListener { - editDialogInterface.onSubmitClick(binding.etNodeDescription.text.toString()) - dismiss() + return binding.root + } + + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { + super.onViewCreated(view, savedInstanceState) + setupCancelBtn() + setupSubmitBtn() + } + + private fun setupSubmitBtn() { + binding.btnSubmit.setOnClickListener { + val node = args.node + val description = binding.etNodeDescription.text.toString() + when (args.operation) { + OperationType.ADD -> { + mindMapViewModel.addNode(node, NodeGenerator.makeNode(description, node.id)) + } + + OperationType.UPDATE -> { + val newNode = + when (node) { + is CircleNode -> node.copy(description = description) + is RectangleNode -> node.copy(description = description) + } + mindMapViewModel.updateNode(newNode) + } + + else -> {} } + dismiss() + } + } + + private fun setupCancelBtn() { + binding.btnCancel.setOnClickListener { + dismiss() } - return binding.root } override fun onStart() { diff --git a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapFragment.kt b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapFragment.kt index b77a0470..e50df17f 100644 --- a/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapFragment.kt +++ b/AOS/app/src/main/java/boostcamp/and07/mindsync/ui/mindmap/MindMapFragment.kt @@ -1,22 +1,19 @@ package boostcamp.and07.mindsync.ui.mindmap import android.util.Log -import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle +import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs +import androidx.navigation.navGraphViewModels import boostcamp.and07.mindsync.R -import boostcamp.and07.mindsync.data.NodeGenerator -import boostcamp.and07.mindsync.data.model.CircleNode +import boostcamp.and07.mindsync.data.crdt.OperationType import boostcamp.and07.mindsync.data.model.Node -import boostcamp.and07.mindsync.data.model.RectangleNode import boostcamp.and07.mindsync.data.model.Tree import boostcamp.and07.mindsync.data.network.SocketState import boostcamp.and07.mindsync.databinding.FragmentMindMapBinding import boostcamp.and07.mindsync.ui.base.BaseFragment -import boostcamp.and07.mindsync.ui.dialog.EditDescriptionDialog -import boostcamp.and07.mindsync.ui.dialog.EditDialogInterface import boostcamp.and07.mindsync.ui.util.Dp import boostcamp.and07.mindsync.ui.util.Px import boostcamp.and07.mindsync.ui.util.ThrottleDuration @@ -36,7 +33,9 @@ class MindMapFragment : NodeClickListener, TreeUpdateListener, NodeMoveListener { - private val mindMapViewModel: MindMapViewModel by viewModels() + private val mindMapViewModel: MindMapViewModel by navGraphViewModels(R.id.nav_graph) { + MindMapViewModelFactory() + } private lateinit var mindMapContainer: MindMapContainer private val args: MindMapFragmentArgs by navArgs() @@ -111,42 +110,39 @@ class MindMapFragment : } private fun showDialog( - selectNode: Node, - action: (Node, String) -> Unit, + operationType: OperationType, + selectedNode: Node, ) { - val dialog = EditDescriptionDialog() - dialog.setListener( - object : EditDialogInterface { - override fun onSubmitClick(description: String) { - action.invoke(selectNode, description) - } - }, + findNavController().navigate( + MindMapFragmentDirections.actionMindMapFragmentToEditDescriptionDialog( + operationType, + selectedNode, + ), ) - dialog.show(requireActivity().supportFragmentManager, "EditDescriptionDialog") } private fun setClickEventThrottle() { with(binding) { - imgbtnMindMapAdd.setClickEvent(lifecycleScope, ThrottleDuration.SHORT_DURATION.duration) { + imgbtnMindMapAdd.setClickEvent( + lifecycleScope, + ThrottleDuration.SHORT_DURATION.duration, + ) { mindMapViewModel.selectedNode.value?.let { selectNode -> - showDialog(selectNode) { parent, description -> - mindMapViewModel.addNode(parent, NodeGenerator.makeNode(description, parent.id)) - } + showDialog(OperationType.ADD, selectNode) } } - imgbtnMindMapEdit.setClickEvent(lifecycleScope, ThrottleDuration.SHORT_DURATION.duration) { + imgbtnMindMapEdit.setClickEvent( + lifecycleScope, + ThrottleDuration.SHORT_DURATION.duration, + ) { mindMapViewModel.selectedNode.value?.let { selectNode -> - showDialog(selectNode) { node, description -> - val newNode = - when (node) { - is CircleNode -> node.copy(description = description) - is RectangleNode -> node.copy(description = description) - } - mindMapViewModel.updateNode(newNode) - } + showDialog(OperationType.UPDATE, selectNode) } } - imgbtnMindMapRemove.setClickEvent(lifecycleScope, ThrottleDuration.SHORT_DURATION.duration) { + imgbtnMindMapRemove.setClickEvent( + lifecycleScope, + ThrottleDuration.SHORT_DURATION.duration, + ) { mindMapViewModel.selectedNode.value?.let { selectNode -> mindMapViewModel.removeNode(selectNode) }