From 16e57a1936b4ec859cc9dc788cc24f32f4d825ab Mon Sep 17 00:00:00 2001 From: dltkd1395 Date: Thu, 14 Dec 2023 03:53:51 +0900 Subject: [PATCH] =?UTF-8?q?fix(#304):=20=EB=92=A4=EB=A1=9C=20=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EC=8B=9C=20OnBackPressedCallback=EC=9D=84=20?= =?UTF-8?q?=ED=99=9C=EC=9A=A9=ED=95=9C=20CrdtTree=20=ED=81=B4=EB=A6=AC?= =?UTF-8?q?=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yang1318 Co-authored-by: jaehan4707 --- .../mindsync/ui/mindmap/MindMapFragment.kt | 23 ++ .../mindsync/ui/mindmap/MindMapViewModel.kt | 297 +++++++++--------- 2 files changed, 174 insertions(+), 146 deletions(-) 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 e50df17f..f5cd1962 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,6 +1,10 @@ package boostcamp.and07.mindsync.ui.mindmap +import android.content.Context +import android.content.res.Configuration +import android.os.Bundle import android.util.Log +import androidx.activity.OnBackPressedCallback import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle @@ -38,6 +42,18 @@ class MindMapFragment : } private lateinit var mindMapContainer: MindMapContainer private val args: MindMapFragmentArgs by navArgs() + private var isBack = false + + override fun onAttach(context: Context) { + super.onAttach(context) + val callback = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + isBack = true + findNavController().popBackStack() + } + } + requireActivity().onBackPressedDispatcher.addCallback(this, callback) + } override fun initView() { setupRootNode() @@ -165,4 +181,11 @@ class MindMapFragment : ) { mindMapViewModel.moveNode(tree, target, parent) } + + override fun onDestroyView() { + super.onDestroyView() + if (isBack) { + mindMapViewModel.clearTree() + } + } } 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 d7927b7e..8beefc75 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 @@ -30,133 +30,149 @@ import javax.inject.Inject @HiltViewModel class MindMapViewModel - @Inject - constructor() : ViewModel() { - private var boardId: String = "" - val crdtTree = CrdtTree(id = IdGenerator.makeRandomNodeId(), tree = Tree()) - private var _selectedNode = MutableStateFlow(null) - val selectedNode: StateFlow = _selectedNode - private val _operation = MutableStateFlow(null) - val operation: StateFlow = _operation - private val mindMapSocketManager = MindMapSocketManager() - private val _socketState = MutableStateFlow(SocketState.DISCONNECT) - val socketState: StateFlow = _socketState - private val _socketEvent = MutableStateFlow(null) - val socketEvent: StateFlow = _socketEvent - private val _operationType = MutableStateFlow("") - val operationType: StateFlow = _operationType - - init { - setSocketState() - setSocketEvent() - } +@Inject +constructor() : ViewModel() { + private var boardId: String = "" + var crdtTree = CrdtTree(id = IdGenerator.makeRandomNodeId(), tree = Tree()) + private var _selectedNode = MutableStateFlow(null) + val selectedNode: StateFlow = _selectedNode + private val _operation = MutableStateFlow(null) + val operation: StateFlow = _operation + private val mindMapSocketManager = MindMapSocketManager() + private val _socketState = MutableStateFlow(SocketState.DISCONNECT) + val socketState: StateFlow = _socketState + private val _socketEvent = MutableStateFlow(null) + val socketEvent: StateFlow = _socketEvent + private val _operationType = MutableStateFlow("") + val operationType: StateFlow = _operationType + + init { + setSocketState() + setSocketEvent() + } - fun setBoard( - boardId: String, - boardName: String, - ) { - if (this.boardId != boardId) { - this.boardId = boardId - joinBoard(boardId, boardName) - updateNode(crdtTree.tree.getRootNode().copy(description = boardName)) - } + fun setBoard( + boardId: String, + boardName: String, + ) { + if (this.boardId != boardId) { + this.boardId = boardId + joinBoard(boardId, boardName) + updateNode(crdtTree.tree.getRootNode().copy(description = boardName)) } + } - private fun setSocketState() { - viewModelScope.launch { - mindMapSocketManager.listenState().collectLatest { state -> - _socketState.value = state - } + private fun setSocketState() { + viewModelScope.launch { + mindMapSocketManager.listenState().collectLatest { state -> + _socketState.value = state } } + } + + private fun setSocketEvent() { + viewModelScope.launch { + mindMapSocketManager.listenEvent().collectLatest { event -> + _socketEvent.value = event + when (event.eventType) { + SocketEventType.OPERATION_FROM_SERVER -> { + when (val operation = event.operation) { + is SerializedOperation -> { + applyOperation(operation) + } - private fun setSocketEvent() { - viewModelScope.launch { - mindMapSocketManager.listenEvent().collectLatest { event -> - _socketEvent.value = event - when (event.eventType) { - SocketEventType.OPERATION_FROM_SERVER -> { - when (val operation = event.operation) { - is SerializedOperation -> { - applyOperation(operation) - } - - is SerializedCrdtTree -> { - applyOperation(operation) - } + is SerializedCrdtTree -> { + applyOperation(operation) } } } } } } + } - fun joinBoard( - boardId: String, - boardName: String, - ) { - mindMapSocketManager.joinBoard(boardId, boardName) - } + fun joinBoard( + boardId: String, + boardName: String, + ) { + mindMapSocketManager.joinBoard(boardId, boardName) + } - fun addNode( - parent: Node, - addNode: RectangleNode, - ) { - val addOperation = - crdtTree.generateOperationAdd(addNode.id, parent.id, addNode.description) - crdtTree.applyOperation(addOperation) - _operation.value = addOperation - requestUpdateMindMap(operation = addOperation) - } + fun addNode( + parent: Node, + addNode: RectangleNode, + ) { + val addOperation = + crdtTree.generateOperationAdd(addNode.id, parent.id, addNode.description) + crdtTree.applyOperation(addOperation) + _operation.value = addOperation + requestUpdateMindMap(operation = addOperation) + } - fun removeNode(target: Node) { - _selectedNode.value = null - val removeOperation = crdtTree.generateOperationDelete(target.id) - crdtTree.applyOperation(removeOperation) - _operation.value = removeOperation - requestUpdateMindMap(operation = removeOperation) - } + fun removeNode(target: Node) { + _selectedNode.value = null + val removeOperation = crdtTree.generateOperationDelete(target.id) + crdtTree.applyOperation(removeOperation) + _operation.value = removeOperation + requestUpdateMindMap(operation = removeOperation) + } - fun moveNode( - tree: Tree, - target: Node, - parent: Node, - ) { - this.crdtTree.tree = tree - val moveOperation = crdtTree.generateOperationMove(target.id, parent.id) - crdtTree.applyOperation(moveOperation) - _operation.value = moveOperation - requestUpdateMindMap(operation = moveOperation) - } + fun moveNode( + tree: Tree, + target: Node, + parent: Node, + ) { + this.crdtTree.tree = tree + val moveOperation = crdtTree.generateOperationMove(target.id, parent.id) + crdtTree.applyOperation(moveOperation) + _operation.value = moveOperation + requestUpdateMindMap(operation = moveOperation) + } - fun setSelectedNode(selectNode: Node?) { - _selectedNode.value = selectNode - } + fun setSelectedNode(selectNode: Node?) { + _selectedNode.value = selectNode + } + + fun requestUpdateMindMap(operation: Operation) { + val serializedOperation = + when (operation) { + is OperationAdd -> crdtTree.serializeOperationAdd(operation) - fun requestUpdateMindMap(operation: Operation) { - val serializedOperation = - when (operation) { - is OperationAdd -> crdtTree.serializeOperationAdd(operation) + is OperationDelete -> crdtTree.serializeOperationDelete(operation) - is OperationDelete -> crdtTree.serializeOperationDelete(operation) + is OperationMove -> crdtTree.serializeOperationMove(operation) - is OperationMove -> crdtTree.serializeOperationMove(operation) + is OperationUpdate -> crdtTree.serializeOperationUpdate(operation) + } + mindMapSocketManager.updateMindMap( + serializedOperation = serializedOperation, + boardId = boardId, + ) + } - is OperationUpdate -> crdtTree.serializeOperationUpdate(operation) + fun applyOperation(operation: SerializedOperation) { + val operation = + when (operation.operationType) { + OperationType.ADD.command -> crdtTree.deserializeOperationAdd(operation) + OperationType.DELETE.command -> crdtTree.deserializeOperationDelete(operation) + OperationType.UPDATE.command -> crdtTree.deserializeOperationUpdate(operation) + OperationType.MOVE.command -> crdtTree.deserializeOperationMove(operation) + else -> { + throw IllegalArgumentException(ExceptionMessage.ERROR_MESSAGE_NOT_DEFINED_OPERATION.message) } - mindMapSocketManager.updateMindMap( - serializedOperation = serializedOperation, - boardId = boardId, - ) - } + } + crdtTree.applyOperation(operation) + _operation.value = operation + } - fun applyOperation(operation: SerializedOperation) { + fun applyOperation(operation: SerializedCrdtTree) { + operation.operationLogs?.forEach { operationLog -> val operation = - when (operation.operationType) { - OperationType.ADD.command -> crdtTree.deserializeOperationAdd(operation) - OperationType.DELETE.command -> crdtTree.deserializeOperationDelete(operation) - OperationType.UPDATE.command -> crdtTree.deserializeOperationUpdate(operation) - OperationType.MOVE.command -> crdtTree.deserializeOperationMove(operation) + when (operationLog.operation.operationType) { + OperationType.ADD.command -> crdtTree.deserializeOperationAdd(operationLog.operation) + OperationType.DELETE.command -> crdtTree.deserializeOperationDelete(operationLog.operation) + OperationType.UPDATE.command -> crdtTree.deserializeOperationUpdate(operationLog.operation) + OperationType.MOVE.command -> crdtTree.deserializeOperationMove(operationLog.operation) else -> { throw IllegalArgumentException(ExceptionMessage.ERROR_MESSAGE_NOT_DEFINED_OPERATION.message) } @@ -164,52 +180,41 @@ class MindMapViewModel crdtTree.applyOperation(operation) _operation.value = operation } + } - fun applyOperation(operation: SerializedCrdtTree) { - operation.operationLogs?.forEach { operationLog -> - val operation = - when (operationLog.operation.operationType) { - OperationType.ADD.command -> crdtTree.deserializeOperationAdd(operationLog.operation) - OperationType.DELETE.command -> crdtTree.deserializeOperationDelete(operationLog.operation) - OperationType.UPDATE.command -> crdtTree.deserializeOperationUpdate(operationLog.operation) - OperationType.MOVE.command -> crdtTree.deserializeOperationMove(operationLog.operation) - else -> { - throw IllegalArgumentException(ExceptionMessage.ERROR_MESSAGE_NOT_DEFINED_OPERATION.message) - } - } - crdtTree.applyOperation(operation) - _operation.value = operation - } - } - - fun updateNode(updateNode: Node) { - val updateOperation = - crdtTree.generateOperationUpdate(updateNode.id, updateNode.description) - crdtTree.applyOperation(updateOperation) - _operation.value = updateOperation - requestUpdateMindMap(updateOperation) - } + fun updateNode(updateNode: Node) { + val updateOperation = + crdtTree.generateOperationUpdate(updateNode.id, updateNode.description) + crdtTree.applyOperation(updateOperation) + _operation.value = updateOperation + requestUpdateMindMap(updateOperation) + } - fun update(newTree: Tree) { - crdtTree.tree = newTree - } + fun update(newTree: Tree) { + crdtTree.tree = newTree + } - fun changeRootXY( - windowWidth: Dp, - windowHeight: Dp, - ) { - crdtTree.tree.setRootNode( - crdtTree.tree.getRootNode().copy( - path = - crdtTree.tree.getRootNode().path.copy( - centerX = windowWidth, - centerY = windowHeight, - ), + fun changeRootXY( + windowWidth: Dp, + windowHeight: Dp, + ) { + crdtTree.tree.setRootNode( + crdtTree.tree.getRootNode().copy( + path = + crdtTree.tree.getRootNode().path.copy( + centerX = windowWidth, + centerY = windowHeight, ), - ) - } + ), + ) + } - fun updateOperationType(operationType: String) { - _operationType.value = operationType - } + fun updateOperationType(operationType: String) { + _operationType.value = operationType + } + + fun clearTree() { + crdtTree = CrdtTree(id = "", tree = Tree()) + _selectedNode.value = null } +}