ConversationCreationViewModel.kt 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Nextcloud Talk - Android Client
  3. *
  4. * SPDX-FileCopyrightText: 2024 Sowjanya Kota <sowjanya.kch@gmail.com>
  5. * SPDX-License-Identifier: GPL-3.0-or-later
  6. */
  7. package com.nextcloud.talk.conversationcreation
  8. import android.net.Uri
  9. import android.util.Log
  10. import androidx.compose.runtime.mutableStateOf
  11. import androidx.core.net.toFile
  12. import androidx.lifecycle.ViewModel
  13. import androidx.lifecycle.viewModelScope
  14. import com.nextcloud.talk.data.user.model.User
  15. import com.nextcloud.talk.models.json.autocomplete.AutocompleteUser
  16. import com.nextcloud.talk.models.json.conversations.Conversation
  17. import com.nextcloud.talk.models.json.generic.GenericMeta
  18. import com.nextcloud.talk.repositories.conversations.ConversationsRepositoryImpl.Companion.STATUS_CODE_OK
  19. import com.nextcloud.talk.users.UserManager
  20. import kotlinx.coroutines.flow.MutableStateFlow
  21. import kotlinx.coroutines.flow.StateFlow
  22. import kotlinx.coroutines.launch
  23. import javax.inject.Inject
  24. class ConversationCreationViewModel @Inject constructor(
  25. private val repository: ConversationCreationRepository,
  26. private val userManager: UserManager
  27. ) : ViewModel() {
  28. private val _selectedParticipants = MutableStateFlow<List<AutocompleteUser>>(emptyList())
  29. val selectedParticipants: StateFlow<List<AutocompleteUser>> = _selectedParticipants
  30. private val roomViewState = MutableStateFlow<RoomUIState>(RoomUIState.None)
  31. private val _currentUser = userManager.currentUser.blockingGet()
  32. val currentUser: User = _currentUser
  33. fun updateSelectedParticipants(participants: List<AutocompleteUser>) {
  34. _selectedParticipants.value = participants
  35. }
  36. private val _roomName = MutableStateFlow("")
  37. val roomName: StateFlow<String> = _roomName
  38. private val _password = MutableStateFlow("")
  39. val password: StateFlow<String> = _password
  40. private val _conversationDescription = MutableStateFlow("")
  41. val conversationDescription: StateFlow<String> = _conversationDescription
  42. var isGuestsAllowed = mutableStateOf(false)
  43. var isConversationAvailableForRegisteredUsers = mutableStateOf(false)
  44. var openForGuestAppUsers = mutableStateOf(false)
  45. private val addParticipantsViewState = MutableStateFlow<AddParticipantsUiState>(AddParticipantsUiState.None)
  46. private val allowGuestsResult = MutableStateFlow<AllowGuestsUiState>(AllowGuestsUiState.None)
  47. fun updateRoomName(roomName: String) {
  48. _roomName.value = roomName
  49. }
  50. fun updatePassword(password: String) {
  51. _password.value = password
  52. }
  53. fun updateConversationDescription(conversationDescription: String) {
  54. _conversationDescription.value = conversationDescription
  55. }
  56. fun createRoomAndAddParticipants(
  57. roomType: String,
  58. conversationName: String,
  59. participants: Set<AutocompleteUser>,
  60. selectedImageUri: Uri?,
  61. onRoomCreated: (String) -> Unit
  62. ) {
  63. val scope = when {
  64. isConversationAvailableForRegisteredUsers.value && !openForGuestAppUsers.value -> 1
  65. isConversationAvailableForRegisteredUsers.value && openForGuestAppUsers.value -> 2
  66. else -> 0
  67. }
  68. viewModelScope.launch {
  69. roomViewState.value = RoomUIState.None
  70. try {
  71. val roomResult = repository.createRoom(roomType, conversationName)
  72. val conversation = roomResult.ocs?.data
  73. if (conversation != null) {
  74. val token = conversation.token
  75. if (token != null) {
  76. try {
  77. repository.setConversationDescription(
  78. token,
  79. _conversationDescription.value
  80. )
  81. val allowGuestResultOverall = repository.allowGuests(token, isGuestsAllowed.value)
  82. val statusCode: GenericMeta? = allowGuestResultOverall.ocs?.meta
  83. val result = (statusCode?.statusCode == STATUS_CODE_OK)
  84. if (result) {
  85. allowGuestsResult.value = AllowGuestsUiState.Success(result)
  86. for (participant in participants) {
  87. if (participant.id != null) {
  88. val participantOverall = repository.addParticipants(
  89. token,
  90. participant.id!!,
  91. participant.source!!
  92. ).ocs?.data
  93. addParticipantsViewState.value =
  94. AddParticipantsUiState.Success(participantOverall)
  95. }
  96. }
  97. }
  98. if (_password.value.isNotEmpty()) {
  99. repository.setPassword(token, _password.value)
  100. }
  101. repository.openConversation(token, scope)
  102. if(selectedImageUri!= null){
  103. repository.uploadConversationAvatar(selectedImageUri.toFile(), token)
  104. }
  105. onRoomCreated(token)
  106. } catch (exception: Exception) {
  107. allowGuestsResult.value = AllowGuestsUiState.Error(exception.message ?: "")
  108. }
  109. }
  110. roomViewState.value = RoomUIState.Success(conversation)
  111. } else {
  112. roomViewState.value = RoomUIState.Error("Conversation is null")
  113. }
  114. } catch (e: Exception) {
  115. roomViewState.value = RoomUIState.Error(e.message ?: "Unknown error")
  116. Log.e("ConversationCreationViewModel", "Error - ${e.message}")
  117. }
  118. }
  119. }
  120. fun getImageUri(avatarId: String, requestBigSize: Boolean): String {
  121. return repository.getImageUri(avatarId, requestBigSize)
  122. }
  123. fun createRoom(roomType: String, conversationName: String?) {
  124. viewModelScope.launch {
  125. try {
  126. val room = repository.createRoom(
  127. roomType,
  128. conversationName
  129. )
  130. val conversation: Conversation? = room.ocs?.data
  131. roomViewState.value = RoomUIState.Success(conversation)
  132. } catch (exception: Exception) {
  133. roomViewState.value = RoomUIState.Error(exception.message ?: "")
  134. }
  135. }
  136. }
  137. }
  138. sealed class AllowGuestsUiState {
  139. data object None : AllowGuestsUiState()
  140. data class Success(val result: Boolean) : AllowGuestsUiState()
  141. data class Error(val message: String) : AllowGuestsUiState()
  142. }
  143. sealed class RoomUIState {
  144. data object None : RoomUIState()
  145. data class Success(val conversation: Conversation?) : RoomUIState()
  146. data class Error(val message: String) : RoomUIState()
  147. }
  148. sealed class AddParticipantsUiState {
  149. data object None : AddParticipantsUiState()
  150. data class Success(val participants: List<Conversation>?) : AddParticipantsUiState()
  151. data class Error(val message: String) : AddParticipantsUiState()
  152. }