From acee0a5545e8f5c8191bc97c31a78534d2f3abab Mon Sep 17 00:00:00 2001 From: sowjanyakch Date: Tue, 18 Mar 2025 22:33:02 +0100 Subject: [PATCH] store user groups and circles in room database Signed-off-by: sowjanyakch --- .../13.json | 44 ++++++++++- .../nextcloud/talk/activities/MainActivity.kt | 10 +++ .../com/nextcloud/talk/chat/ChatActivity.kt | 11 --- .../talk/chat/viewmodels/ChatViewModel.kt | 16 ---- .../talk/dagger/modules/DaosModule.kt | 4 + .../talk/dagger/modules/RepositoryModule.kt | 11 +++ .../talk/dagger/modules/UtilsModule.kt | 7 -- .../database/dao/UserCirclesOrGroupsDao.kt | 32 ++++++++ .../data/database/model/UserCirclesEntity.kt | 19 +++++ .../model/UserGroupsCirclesRepository.kt | 78 +++++++++++++++++++ .../data/database/model/UserGroupsEntity.kt | 18 +++++ .../talk/data/source/local/TalkDatabase.kt | 8 +- 12 files changed, 221 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/com/nextcloud/talk/data/database/dao/UserCirclesOrGroupsDao.kt create mode 100644 app/src/main/java/com/nextcloud/talk/data/database/model/UserCirclesEntity.kt create mode 100644 app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsCirclesRepository.kt create mode 100644 app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsEntity.kt diff --git a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json index 2e2345001..f8cb76a68 100644 --- a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json +++ b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 13, - "identityHash": "a521f027909f69f4c7d1855f84a2e67f", + "identityHash": "f58d9b51b48ddc5c6f4dc4c742eb5f3f", "entities": [ { "tableName": "User", @@ -738,12 +738,52 @@ ] } ] + }, + { + "tableName": "user_circles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`displayName` TEXT NOT NULL, PRIMARY KEY(`displayName`))", + "fields": [ + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "displayName" + ] + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "user_groups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`groups` TEXT NOT NULL, PRIMARY KEY(`groups`))", + "fields": [ + { + "fieldPath": "groups", + "columnName": "groups", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "groups" + ] + }, + "indices": [], + "foreignKeys": [] } ], "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a521f027909f69f4c7d1855f84a2e67f')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f58d9b51b48ddc5c6f4dc4c742eb5f3f')" ] } } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt index 0828b475f..7028255f8 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt @@ -21,6 +21,7 @@ import androidx.activity.OnBackPressedCallback import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ProcessLifecycleOwner +import androidx.lifecycle.lifecycleScope import autodagger.AutoInjector import com.google.android.material.snackbar.Snackbar import com.nextcloud.talk.R @@ -30,6 +31,7 @@ import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.chat.ChatActivity import com.nextcloud.talk.conversationlist.ConversationsListActivity +import com.nextcloud.talk.data.database.model.UserGroupsCirclesRepository import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.databinding.ActivityMainBinding import com.nextcloud.talk.invitation.InvitationsActivity @@ -46,6 +48,7 @@ import io.reactivex.SingleObserver import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.launch import javax.inject.Inject @AutoInjector(NextcloudTalkApplication::class) @@ -58,6 +61,9 @@ class MainActivity : BaseActivity(), ActionBarProvider { @Inject lateinit var userManager: UserManager + @Inject + lateinit var userGroupsOrCirclesRepository: UserGroupsCirclesRepository + private val onBackPressedCallback = object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { finish() @@ -146,6 +152,10 @@ class MainActivity : BaseActivity(), ActionBarProvider { } private fun handleActionFromContact(intent: Intent) { + lifecycleScope.launch { + val initialized = userGroupsOrCirclesRepository.initialize() + Log.d("MainActivity", "$initialized") + } if (intent.action == Intent.ACTION_VIEW && intent.data != null) { val cursor = contentResolver.query(intent.data!!, null, null, null, null) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index a722e8086..4feda24ec 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -1212,17 +1212,6 @@ class ChatActivity : } } } - - lifecycleScope.launch { - chatViewModel.userGroups.collect { userGroups -> - messageUtils.setUserGroups(userGroups) - } - } - lifecycleScope.launch { - chatViewModel.userCircles.collect { userCircles -> - messageUtils.setUserCircles(userCircles) - } - } } private fun removeUnreadMessagesMarker() { diff --git a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt index e82130c3d..124d81cdb 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/viewmodels/ChatViewModel.kt @@ -50,9 +50,6 @@ import io.reactivex.schedulers.Schedulers import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.first @@ -236,12 +233,6 @@ class ChatViewModel @Inject constructor( val leaveRoomViewState: LiveData get() = _leaveRoomViewState - private val _userGroups = MutableStateFlow>(emptySet()) - val userGroups: StateFlow> = _userGroups.asStateFlow() - - private val _userCircles = MutableStateFlow>(emptySet()) - val userCircles: StateFlow> = _userCircles.asStateFlow() - object ChatMessageInitialState : ViewState object ChatMessageStartState : ViewState object ChatMessageUpdateState : ViewState @@ -364,13 +355,6 @@ class ChatViewModel @Inject constructor( _getReminderExistState.value = GetReminderStateSet } - fun fetchUserData(user: User) { - viewModelScope.launch { - _userGroups.value = chatNetworkDataSource.getUserGroups(user) - _userCircles.value = chatNetworkDataSource.getUserCircles(user) - } - } - fun deleteReminder(user: User, roomToken: String, messageId: String, chatApiVersion: Int) { chatNetworkDataSource.deleteReminder(user, roomToken, messageId, chatApiVersion) .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/DaosModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/DaosModule.kt index 27ec540a0..3403bcfed 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/DaosModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/DaosModule.kt @@ -10,6 +10,7 @@ package com.nextcloud.talk.dagger.modules import com.nextcloud.talk.data.database.dao.ChatBlocksDao import com.nextcloud.talk.data.database.dao.ChatMessagesDao import com.nextcloud.talk.data.database.dao.ConversationsDao +import com.nextcloud.talk.data.database.dao.UserCirclesOrGroupsDao import com.nextcloud.talk.data.source.local.TalkDatabase import dagger.Module import dagger.Provides @@ -24,4 +25,7 @@ internal object DaosModule { @Provides fun providesChatBlocksDao(database: TalkDatabase): ChatBlocksDao = database.chatBlocksDao() + + @Provides + fun providesUserCirclesOrGroups(database: TalkDatabase): UserCirclesOrGroupsDao = database.userCirclesOrGroupsDao() } diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt index 6eb4d0aa4..e9486ca53 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt @@ -28,6 +28,8 @@ import com.nextcloud.talk.conversationlist.data.network.RetrofitConversationsNet import com.nextcloud.talk.data.database.dao.ChatBlocksDao import com.nextcloud.talk.data.database.dao.ChatMessagesDao import com.nextcloud.talk.data.database.dao.ConversationsDao +import com.nextcloud.talk.data.database.dao.UserCirclesOrGroupsDao +import com.nextcloud.talk.data.database.model.UserGroupsCirclesRepository import com.nextcloud.talk.data.network.NetworkMonitor import com.nextcloud.talk.data.source.local.TalkDatabase import com.nextcloud.talk.data.storage.ArbitraryStoragesRepository @@ -186,4 +188,13 @@ class RepositoryModule { ncApiCoroutines: NcApiCoroutines, currentUserProviderNew: CurrentUserProviderNew ): ConversationCreationRepository = ConversationCreationRepositoryImpl(ncApiCoroutines, currentUserProviderNew) + + @Provides + fun provideUserGroupsCirclesRepository( + userCirclesOrGroupsDao: UserCirclesOrGroupsDao, + ncApiCoroutines: NcApiCoroutines, + userProvider: CurrentUserProviderNew + ): UserGroupsCirclesRepository { + return UserGroupsCirclesRepository(userCirclesOrGroupsDao, ncApiCoroutines, userProvider) + } } diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/UtilsModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/UtilsModule.kt index 05eb3b29f..4bd15fc83 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/UtilsModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/UtilsModule.kt @@ -9,7 +9,6 @@ package com.nextcloud.talk.dagger.modules import android.content.Context import com.nextcloud.talk.utils.DateUtils -import com.nextcloud.talk.utils.message.MessageUtils import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil import com.nextcloud.talk.utils.permissions.PlatformPermissionUtilImpl import dagger.Module @@ -29,10 +28,4 @@ class UtilsModule { fun provideDateUtils(context: Context): DateUtils { return DateUtils(context) } - - @Provides - @Reusable - fun provideMessageUtils(context: Context): MessageUtils { - return MessageUtils(context) - } } diff --git a/app/src/main/java/com/nextcloud/talk/data/database/dao/UserCirclesOrGroupsDao.kt b/app/src/main/java/com/nextcloud/talk/data/database/dao/UserCirclesOrGroupsDao.kt new file mode 100644 index 000000000..4b0143b9c --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/data/database/dao/UserCirclesOrGroupsDao.kt @@ -0,0 +1,32 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.data.database.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.nextcloud.talk.data.database.model.UserCirclesEntity +import com.nextcloud.talk.data.database.model.UserGroupsEntity + +@Dao +interface UserCirclesOrGroupsDao { + + @Query("SELECT groups FROM user_groups") + fun getUserGroups(): List + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertUserGroups(groups:List) + + @Query("SELECT displayName FROM user_circles") + fun getUserCircles(): List + + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertUserCircles(circles: List) + +} diff --git a/app/src/main/java/com/nextcloud/talk/data/database/model/UserCirclesEntity.kt b/app/src/main/java/com/nextcloud/talk/data/database/model/UserCirclesEntity.kt new file mode 100644 index 000000000..da0ef5004 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/data/database/model/UserCirclesEntity.kt @@ -0,0 +1,19 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.data.database.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "user_circles") +data class UserCirclesEntity( + @PrimaryKey + @ColumnInfo(name = "displayName") + var displayName: String, +) diff --git a/app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsCirclesRepository.kt b/app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsCirclesRepository.kt new file mode 100644 index 000000000..80b32a6e1 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsCirclesRepository.kt @@ -0,0 +1,78 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.data.database.model + +import android.util.Log +import com.nextcloud.talk.api.NcApiCoroutines +import com.nextcloud.talk.data.database.dao.UserCirclesOrGroupsDao +import com.nextcloud.talk.utils.ApiUtils +import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import javax.inject.Inject + +class UserGroupsCirclesRepository @Inject constructor( + private val userCirclesOrGroupsDao: UserCirclesOrGroupsDao, + private val ncApiCoroutines: NcApiCoroutines, + private val currentUserProvider: CurrentUserProviderNew +) { + val user = currentUserProvider.currentUser.blockingGet() + suspend fun initialize(): Boolean = withContext(Dispatchers.IO) { + try { + val credentials: String = ApiUtils.getCredentials(user.username, user.token)!! + + coroutineScope { + launch { + val response = ncApiCoroutines.getUserGroups( + credentials, + ApiUtils.getUrlForUserGroups( + user.baseUrl!!, + user.userId!! + ) + ) + val groups = response.ocs?.data?.groups?: emptyList() + + userCirclesOrGroupsDao.insertUserGroups( + groups.map{ + UserGroupsEntity(it) + } + ) + } + + launch { + + val response = ncApiCoroutines.getUserCircles( + credentials, + ApiUtils.getUrlForUserCircles(user.baseUrl!!) + ) + val circles = response.ocs?.data?.map { it.displayName!! }?: emptyList() + userCirclesOrGroupsDao.insertUserCircles( + circles.map{ + UserCirclesEntity(it) + } + ) + } + } + + return@withContext true + } catch (e: Exception) { + Log.e("UserDataRepo", "Error initializing user data", e) + return@withContext false + } + } + + fun getUserGroups(): List { + return userCirclesOrGroupsDao.getUserGroups() + } + + fun getUserCircles(): List { + return userCirclesOrGroupsDao.getUserCircles() + } +} diff --git a/app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsEntity.kt b/app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsEntity.kt new file mode 100644 index 000000000..3e1ffcf07 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/data/database/model/UserGroupsEntity.kt @@ -0,0 +1,18 @@ +/* + * Nextcloud Talk - Android Client + * + * SPDX-FileCopyrightText: 2025 Your Name + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.nextcloud.talk.data.database.model + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "user_groups") +data class UserGroupsEntity( + @PrimaryKey + @ColumnInfo (name="groups") var groups: String, +) diff --git a/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt b/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt index 1108fa394..d064e56c1 100644 --- a/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt +++ b/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt @@ -20,9 +20,12 @@ import com.nextcloud.talk.R import com.nextcloud.talk.data.database.dao.ChatBlocksDao import com.nextcloud.talk.data.database.dao.ChatMessagesDao import com.nextcloud.talk.data.database.dao.ConversationsDao +import com.nextcloud.talk.data.database.dao.UserCirclesOrGroupsDao import com.nextcloud.talk.data.database.model.ChatBlockEntity import com.nextcloud.talk.data.database.model.ChatMessageEntity import com.nextcloud.talk.data.database.model.ConversationEntity +import com.nextcloud.talk.data.database.model.UserCirclesEntity +import com.nextcloud.talk.data.database.model.UserGroupsEntity import com.nextcloud.talk.data.source.local.converters.ArrayListConverter import com.nextcloud.talk.data.source.local.converters.CapabilitiesConverter import com.nextcloud.talk.data.source.local.converters.ExternalSignalingServerConverter @@ -47,7 +50,9 @@ import java.util.Locale ArbitraryStorageEntity::class, ConversationEntity::class, ChatMessageEntity::class, - ChatBlockEntity::class + ChatBlockEntity::class, + UserCirclesEntity:: class, + UserGroupsEntity::class ], version = 16, autoMigrations = [ @@ -72,6 +77,7 @@ abstract class TalkDatabase : RoomDatabase() { abstract fun chatMessagesDao(): ChatMessagesDao abstract fun chatBlocksDao(): ChatBlocksDao abstract fun arbitraryStoragesDao(): ArbitraryStoragesDao + abstract fun userCirclesOrGroupsDao(): UserCirclesOrGroupsDao companion object { const val TAG = "TalkDatabase"