From 36b4bf1440204c4871fae7987baa5a9aa78f99de Mon Sep 17 00:00:00 2001
From: Taras Smakula <tarassmakula@gmail.com>
Date: Wed, 27 Sep 2023 16:36:47 +0300
Subject: [PATCH] Add relations validation

---
 .../circles/feature/home/HomeViewModel.kt     |  2 +-
 .../workspace/ConfigureWorkspaceViewModel.kt  |  4 +-
 .../ConfigureWorkspaceDataSource.kt           | 39 ++++++++++++-------
 3 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/app/src/main/java/org/futo/circles/feature/home/HomeViewModel.kt b/app/src/main/java/org/futo/circles/feature/home/HomeViewModel.kt
index 5684ef386..0348c5338 100644
--- a/app/src/main/java/org/futo/circles/feature/home/HomeViewModel.kt
+++ b/app/src/main/java/org/futo/circles/feature/home/HomeViewModel.kt
@@ -47,7 +47,7 @@ class HomeViewModel @Inject constructor(
         val tasks = workspaceTasksProvider.getMandatoryTasks()
         tasks.forEach { item ->
             when (val validationResponse =
-                createResult { workspaceDataSource.validate(item.room) }) {
+                createResult { workspaceDataSource.validateAndFixIfExist(item.room) }) {
                 is Response.Error -> {
                     validateWorkspaceResultLiveData.postValue(Response.Error(""))
                     return@launchBg
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/workspace/ConfigureWorkspaceViewModel.kt b/auth/src/main/java/org/futo/circles/auth/feature/workspace/ConfigureWorkspaceViewModel.kt
index a4378e768..4687258c3 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/workspace/ConfigureWorkspaceViewModel.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/workspace/ConfigureWorkspaceViewModel.kt
@@ -43,7 +43,7 @@ class ConfigureWorkspaceViewModel @Inject constructor(
         tasks.forEachIndexed { i, item ->
             updateTaskStatus(i, TaskStatus.RUNNING)
             when (val validationResponse =
-                createResult { workspaceDataSource.validate(item.room) }) {
+                createResult { workspaceDataSource.validateAndFixIfExist(item.room) }) {
                 is Response.Error -> {
                     hasError = true
                     updateTaskStatus(i, TaskStatus.FAILED)
@@ -71,7 +71,7 @@ class ConfigureWorkspaceViewModel @Inject constructor(
             if (item.status == TaskStatus.SUCCESS) return@forEachIndexed
 
             updateTaskStatus(i, TaskStatus.RUNNING)
-            when (val result = createResult { workspaceDataSource.perform(item.room) }) {
+            when (val result = createResult { workspaceDataSource.performCreate(item.room) }) {
                 is Response.Error -> {
                     updateTaskStatus(i, TaskStatus.FAILED)
                     workspaceResultLiveData.postValue(result)
diff --git a/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt b/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt
index 3447021b1..7a1abc03d 100644
--- a/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt
+++ b/auth/src/main/java/org/futo/circles/auth/feature/workspace/data_source/ConfigureWorkspaceDataSource.kt
@@ -4,19 +4,21 @@ import kotlinx.coroutines.delay
 import org.futo.circles.core.model.CirclesRoom
 import org.futo.circles.core.provider.MatrixSessionProvider
 import org.futo.circles.core.room.CreateRoomDataSource
+import org.futo.circles.core.room.RoomRelationsBuilder
 import org.futo.circles.core.utils.getJoinedRoomById
 import org.futo.circles.core.workspace.SpacesTreeAccountDataSource
+import org.matrix.android.sdk.api.session.room.Room
 import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.model.RoomType
 import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
 import javax.inject.Inject
 
 class ConfigureWorkspaceDataSource @Inject constructor(
     private val createRoomDataSource: CreateRoomDataSource,
-    private val spacesTreeAccountDataSource: SpacesTreeAccountDataSource
+    private val spacesTreeAccountDataSource: SpacesTreeAccountDataSource,
+    private val roomRelationsBuilder: RoomRelationsBuilder
 ) {
 
-    suspend fun perform(room: CirclesRoom) {
+    suspend fun performCreate(room: CirclesRoom) {
         val roomId = createRoomDataSource.createRoom(room)
         room.accountDataKey?.let { key ->
             spacesTreeAccountDataSource.updateSpacesConfigAccountData(key, roomId)
@@ -24,21 +26,30 @@ class ConfigureWorkspaceDataSource @Inject constructor(
         delay(CREATE_ROOM_DELAY)
     }
 
-    suspend fun validate(room: CirclesRoom): Boolean {
+    suspend fun validateAndFixIfExist(room: CirclesRoom): Boolean {
         val accountDataKey = room.accountDataKey ?: return false
-        if (spacesTreeAccountDataSource.getRoomIdByKey(accountDataKey) == null) {
-            addRecordToAccountDataIfRoomExist(room)
-        }
-        return getJoinedRoomById(
-            spacesTreeAccountDataSource.getRoomIdByKey(accountDataKey) ?: ""
-        ) != null
+        var roomId = spacesTreeAccountDataSource.getRoomIdByKey(accountDataKey)
+        if (roomId == null) roomId = addIdToAccountDataIfRoomExistWithTag(room)
+        val joinedRoom = roomId?.let { getJoinedRoomById(roomId) } ?: return false
+        validateOrSetupRelations(room.parentAccountDataKey, joinedRoom)
+        return true
+    }
+
+    private suspend fun validateOrSetupRelations(parentAccountDataKey: String?, joinedRoom: Room) {
+        val parentKey = parentAccountDataKey ?: return
+        val parentRoomId = spacesTreeAccountDataSource.getRoomIdByKey(parentKey) ?: return
+        val hasRelations = joinedRoom.asSpace()
+            ?.spaceSummary()?.spaceParents?.mapNotNull { it.roomSummary?.roomId }
+            ?.contains(parentRoomId) == true
+        if (!hasRelations) roomRelationsBuilder.setRelations(joinedRoom.roomId, parentRoomId)
     }
 
-    private suspend fun addRecordToAccountDataIfRoomExist(room: CirclesRoom) {
-        val tag = room.getTag() ?: return
-        val key = room.accountDataKey ?: return
-        val roomId = getJoinedRoomIdByTag(tag) ?: return
+    private suspend fun addIdToAccountDataIfRoomExistWithTag(room: CirclesRoom): String? {
+        val tag = room.getTag() ?: return null
+        val key = room.accountDataKey ?: return null
+        val roomId = getJoinedRoomIdByTag(tag) ?: return null
         spacesTreeAccountDataSource.updateSpacesConfigAccountData(key, roomId)
+        return roomId
     }
 
     private fun getJoinedRoomIdByTag(tag: String): String? {
-- 
GitLab