diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApi.java b/app/src/main/java/com/nextcloud/talk/api/NcApi.java index 2e39a926c..b0f5199fb 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java +++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java @@ -118,26 +118,6 @@ public interface NcApi { @Url String url, @QueryMap Map options); - /* - QueryMap items are as follows: - - "roomName" : "newName" - - Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /room/roomToken - */ - - @FormUrlEncoded - @PUT - Observable renameRoom(@Header("Authorization") String authorization, - @Url String url, - @Field("roomName") String roomName); - - - @FormUrlEncoded - @PUT - Observable setConversationDescription(@Header("Authorization") String authorization, - @Url String url, - @Field("description") String description); - /* QueryMap items are as follows: - "newParticipant" : "user" @@ -413,12 +393,6 @@ public interface NcApi { @Url String url, @Field("level") int level); - @FormUrlEncoded - @PUT - Observable setConversationReadOnly(@Header("Authorization") String authorization, - @Url String url, - @Field("state") int state); - @FormUrlEncoded @POST Observable createRemoteShare(@Nullable @Header("Authorization") String authorization, @@ -492,9 +466,6 @@ public interface NcApi { @Field("objectId") String objectId, @Field("metaData") String metaData); - @DELETE - Observable clearChatHistory(@Header("Authorization") String authorization, @Url String url); - @FormUrlEncoded @POST Observable notificationCalls(@Header("Authorization") String authorization, diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt index cee5671f6..f47978d99 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt +++ b/app/src/main/java/com/nextcloud/talk/api/NcApiCoroutines.kt @@ -133,11 +133,14 @@ interface NcApiCoroutines { @Body body: RequestBody ): GenericOverall + @DELETE + suspend fun clearChatHistory(@Header("Authorization") authorization: String, @Url url: String): GenericOverall + @FormUrlEncoded @PUT - suspend fun setPassword2( + suspend fun setConversationReadOnly( @Header("Authorization") authorization: String, @Url url: String, - @Field("password") password: String + @Field("state") state: Int ): GenericOverall } diff --git a/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt b/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt index 71ce7d09b..8899febd2 100644 --- a/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/conversation/RenameConversationDialogFragment.kt @@ -27,7 +27,7 @@ import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.common.ui.theme.utils.ColorRole import com.nextcloud.talk.R import com.nextcloud.talk.application.NextcloudTalkApplication -import com.nextcloud.talk.conversation.viewmodel.RenameConversationViewModel +import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel import com.nextcloud.talk.conversationlist.ConversationsListActivity import com.nextcloud.talk.databinding.DialogRenameConversationBinding import com.nextcloud.talk.events.ConversationsListFetchDataEvent @@ -49,7 +49,7 @@ class RenameConversationDialogFragment : DialogFragment() { lateinit var eventBus: EventBus private lateinit var binding: DialogRenameConversationBinding - private lateinit var viewModel: RenameConversationViewModel + private lateinit var viewModel: ConversationInfoEditViewModel private var emojiPopup: EmojiPopup? = null @@ -61,7 +61,7 @@ class RenameConversationDialogFragment : DialogFragment() { NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) - viewModel = ViewModelProvider(this, viewModelFactory)[RenameConversationViewModel::class.java] + viewModel = ViewModelProvider(this, viewModelFactory)[ConversationInfoEditViewModel::class.java] roomToken = arguments?.getString(KEY_ROOM_TOKEN)!! initialName = arguments?.getString(INITIAL_NAME)!! } @@ -102,7 +102,7 @@ class RenameConversationDialogFragment : DialogFragment() { val positiveButton = (dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE) positiveButton.isEnabled = false positiveButton.setOnClickListener { - viewModel.renameConversation(roomToken, binding.textEdit.text.toString()) + viewModel.renameRoom(roomToken, binding.textEdit.text.toString()) } themeDialog() @@ -169,17 +169,21 @@ class RenameConversationDialogFragment : DialogFragment() { } private fun setupStateObserver() { - viewModel.viewState.observe(viewLifecycleOwner) { state -> + viewModel.renameRoomUiState.observe(viewLifecycleOwner) { state -> when (state) { - is RenameConversationViewModel.InitialState -> {} - is RenameConversationViewModel.RenamingState -> {} - is RenameConversationViewModel.RenamingSuccessState -> handleSuccess() - is RenameConversationViewModel.RenamingFailedState -> showError() - else -> {} + is ConversationInfoEditViewModel.RenameRoomUiState.None -> { + } + is ConversationInfoEditViewModel.RenameRoomUiState.Success -> { + handleSuccess() + } + is ConversationInfoEditViewModel.RenameRoomUiState.Error -> { + showError() + } } } } + @SuppressLint("StringFormatInvalid") private fun handleSuccess() { eventBus.post(ConversationsListFetchDataEvent()) diff --git a/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepository.kt b/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepository.kt index 70c50aa64..96580c646 100644 --- a/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepository.kt @@ -8,13 +8,10 @@ package com.nextcloud.talk.conversation.repository import com.nextcloud.talk.models.json.conversations.ConversationEnums import com.nextcloud.talk.models.json.conversations.RoomOverall -import com.nextcloud.talk.models.json.generic.GenericOverall import io.reactivex.Observable interface ConversationRepository { - fun renameConversation(roomToken: String, roomNameNew: String): Observable - fun createConversation( roomName: String, conversationType: ConversationEnums.ConversationType? diff --git a/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepositoryImpl.kt index f5dae7059..d7b3467ef 100644 --- a/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/conversation/repository/ConversationRepositoryImpl.kt @@ -11,7 +11,6 @@ import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.RetrofitBucket import com.nextcloud.talk.models.json.conversations.ConversationEnums import com.nextcloud.talk.models.json.conversations.RoomOverall -import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import io.reactivex.Observable @@ -24,23 +23,6 @@ class ConversationRepositoryImpl(private val ncApi: NcApi, currentUserProvider: val currentUser: User = currentUserProvider.currentUser.blockingGet() val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!! - override fun renameConversation(roomToken: String, roomNameNew: String): Observable { - val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) - - return ncApi.renameRoom( - credentials, - ApiUtils.getUrlForRoom( - apiVersion, - currentUser.baseUrl!!, - roomToken - ), - roomNameNew - ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(API_RETRIES) - } - override fun createConversation( roomName: String, conversationType: ConversationEnums.ConversationType? @@ -76,6 +58,5 @@ class ConversationRepositoryImpl(private val ncApi: NcApi, currentUserProvider: companion object { private const val ROOM_TYPE_PUBLIC = "3" private const val ROOM_TYPE_GROUP = "2" - const val API_RETRIES: Long = 3 } } diff --git a/app/src/main/java/com/nextcloud/talk/conversation/viewmodel/RenameConversationViewModel.kt b/app/src/main/java/com/nextcloud/talk/conversation/viewmodel/RenameConversationViewModel.kt deleted file mode 100644 index c998f91f0..000000000 --- a/app/src/main/java/com/nextcloud/talk/conversation/viewmodel/RenameConversationViewModel.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Nextcloud Talk - Android Client - * - * SPDX-FileCopyrightText: 2023 Marcel Hibbe - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package com.nextcloud.talk.conversation.viewmodel - -import android.util.Log -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import com.nextcloud.talk.conversation.repository.ConversationRepository -import com.nextcloud.talk.models.json.generic.GenericOverall -import io.reactivex.Observer -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.Disposable -import io.reactivex.schedulers.Schedulers -import javax.inject.Inject - -class RenameConversationViewModel @Inject constructor(private val repository: ConversationRepository) : ViewModel() { - - sealed class ViewState - object InitialState : ViewState() - object RenamingState : ViewState() - object RenamingSuccessState : ViewState() - object RenamingFailedState : ViewState() - - private val _viewState: MutableLiveData = MutableLiveData( - InitialState - ) - val viewState: LiveData - get() = _viewState - - fun renameConversation(roomToken: String, roomNameNew: String) { - _viewState.value = RenamingState - - repository.renameConversation( - roomToken, - roomNameNew - ) - .subscribeOn(Schedulers.io()) - ?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribe(RenameConversationObserver()) - } - - inner class RenameConversationObserver : Observer { - - lateinit var genericOverall: GenericOverall - - override fun onSubscribe(d: Disposable) = Unit - - override fun onNext(response: GenericOverall) { - genericOverall = response - } - - override fun onError(e: Throwable) { - Log.e(TAG, "Failed to rename conversation", e) - _viewState.value = RenamingFailedState - } - - override fun onComplete() { - _viewState.value = RenamingSuccessState - } - } - - companion object { - private val TAG = RenameConversationViewModel::class.java.simpleName - } -} diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt index 9d40b112d..da36a2d09 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/ConversationInfoActivity.kt @@ -260,12 +260,30 @@ class ConversationInfoActivity : viewModel.getConversationReadOnlyState.observe(this) { state -> when (state) { - is ConversationInfoViewModel.SetConversationReadOnlySuccessState -> { + is ConversationInfoViewModel.SetConversationReadOnlyViewState.Success -> { } - is ConversationInfoViewModel.SetConversationReadOnlyErrorState -> { + is ConversationInfoViewModel.SetConversationReadOnlyViewState.Error -> { Snackbar.make(binding.root, R.string.conversation_read_only_failed, Snackbar.LENGTH_LONG).show() } - else -> { + is ConversationInfoViewModel.SetConversationReadOnlyViewState.None -> { + } + } + } + + viewModel.clearChatHistoryViewState.observe(this) { uiState -> + when (uiState) { + is ConversationInfoViewModel.ClearChatHistoryViewState.None -> { + } + is ConversationInfoViewModel.ClearChatHistoryViewState.Success -> { + Snackbar.make( + binding.root, + context.getString(R.string.nc_clear_history_success), + Snackbar.LENGTH_LONG + ).show() + } + is ConversationInfoViewModel.ClearChatHistoryViewState.Error -> { + Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() + Log.e(TAG, "failed to clear chat history", uiState.exception) } } } @@ -670,7 +688,6 @@ class ConversationInfoActivity : intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) startActivity(intent) } - WorkInfo.State.FAILED -> { val errorType = workInfo.outputData.getString("error_type") if (errorType == LeaveConversationWorker.ERROR_NO_OTHER_MODERATORS_OR_OWNERS_LEFT) { @@ -687,7 +704,6 @@ class ConversationInfoActivity : ).show() } } - else -> { } } @@ -726,35 +742,7 @@ class ConversationInfoActivity : private fun clearHistory() { val apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1)) - - ncApi.clearChatHistory( - credentials, - ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl!!, conversationToken) - ) - ?.subscribeOn(Schedulers.io()) - ?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - // unused atm - } - - override fun onNext(genericOverall: GenericOverall) { - Snackbar.make( - binding.root, - context.getString(R.string.nc_clear_history_success), - Snackbar.LENGTH_LONG - ).show() - } - - override fun onError(e: Throwable) { - Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show() - Log.e(TAG, "failed to clear chat history", e) - } - - override fun onComplete() { - // unused atm - } - }) + viewModel.clearChatHistory(apiVersion, conversationToken) } private fun deleteConversation() { @@ -849,7 +837,7 @@ class ConversationInfoActivity : binding.lockConversationSwitch.isChecked = !isLocked databaseStorageModule!!.saveBoolean("lock_switch", !isLocked) val state = if (isLocked) 0 else 1 - makeConversationReadOnly(conversationUser, conversationToken, state) + makeConversationReadOnly(conversationToken, state) } } else { binding.lockConversation.visibility = GONE @@ -929,8 +917,8 @@ class ConversationInfoActivity : } } - private fun makeConversationReadOnly(conversationUser: User, roomToken: String, state: Int) { - viewModel.setConversationReadOnly(conversationUser, roomToken, state) + private fun makeConversationReadOnly(roomToken: String, state: Int) { + viewModel.setConversationReadOnly(roomToken, state) } private fun initRecordingConsentOption() { diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt b/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt index efad9cfc4..b6b4ef288 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfo/viewmodel/ConversationInfoViewModel.kt @@ -79,13 +79,6 @@ class ConversationInfoViewModel @Inject constructor( val getUnBanActorState: LiveData get() = _getUnBanActorState - object SetConversationReadOnlySuccessState : ViewState - object SetConversationReadOnlyErrorState : ViewState - - private val _getConversationReadOnlyState: MutableLiveData = MutableLiveData() - val getConversationReadOnlyState: LiveData - get() = _getConversationReadOnlyState - object GetRoomStartState : ViewState object GetRoomErrorState : ViewState open class GetRoomSuccessState(val conversationModel: ConversationModel) : ViewState @@ -110,6 +103,16 @@ class ConversationInfoViewModel @Inject constructor( val getCapabilitiesViewState: LiveData get() = _getCapabilitiesViewState + private val _clearChatHistoryViewState: MutableLiveData = + MutableLiveData(ClearChatHistoryViewState.None) + val clearChatHistoryViewState: LiveData + get() = _clearChatHistoryViewState + + private val _getConversationReadOnlyState: MutableLiveData = + MutableLiveData(SetConversationReadOnlyViewState.None) + val getConversationReadOnlyState: LiveData + get() = _getConversationReadOnlyState + fun getRoom(user: User, token: String) { _viewState.value = GetRoomStartState chatNetworkDataSource.getRoom(user, token) @@ -196,28 +199,15 @@ class ConversationInfoViewModel @Inject constructor( }) } - fun setConversationReadOnly(user: User, token: String, state: Int) { - val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) - val url = ApiUtils.getUrlForConversationReadOnly(apiVersion, user.baseUrl!!, token) - conversationsRepository.setConversationReadOnly(user.getCredentials(), url, state) - .subscribeOn(Schedulers.io()) - ?.observeOn(AndroidSchedulers.mainThread()) - ?.subscribe(object : Observer { - override fun onSubscribe(p0: Disposable) { - } - - override fun onError(error: Throwable) { - _getConversationReadOnlyState.value = SetConversationReadOnlyErrorState - } - - override fun onComplete() { - // unused atm - } - - override fun onNext(p0: GenericOverall) { - _getConversationReadOnlyState.value = SetConversationReadOnlySuccessState - } - }) + fun setConversationReadOnly(roomToken: String, state: Int) { + viewModelScope.launch { + try { + conversationsRepository.setConversationReadOnly(roomToken, state) + _getConversationReadOnlyState.value = SetConversationReadOnlyViewState.Success + } catch (exception: Exception) { + _getConversationReadOnlyState.value = SetConversationReadOnlyViewState.Error(exception) + } + } } fun unbanActor(user: User, token: String, banId: Int) { @@ -279,6 +269,17 @@ class ConversationInfoViewModel @Inject constructor( conversationsRepository.unarchiveConversation(user.getCredentials(), url) } + fun clearChatHistory(apiVersion: Int, roomToken: String) { + viewModelScope.launch { + try { + conversationsRepository.clearChatHistory(apiVersion, roomToken) + _clearChatHistoryViewState.value = ClearChatHistoryViewState.Success + } catch (exception: Exception) { + _clearChatHistoryViewState.value = ClearChatHistoryViewState.Error(exception) + } + } + } + inner class GetRoomObserver : Observer { override fun onSubscribe(d: Disposable) { // unused atm @@ -302,6 +303,18 @@ class ConversationInfoViewModel @Inject constructor( private val TAG = ConversationInfoViewModel::class.simpleName } + sealed class ClearChatHistoryViewState { + data object None : ClearChatHistoryViewState() + data object Success : ClearChatHistoryViewState() + data class Error(val exception: Exception) : ClearChatHistoryViewState() + } + + sealed class SetConversationReadOnlyViewState { + data object None : SetConversationReadOnlyViewState() + data object Success : SetConversationReadOnlyViewState() + data class Error(val exception: Exception) : SetConversationReadOnlyViewState() + } + sealed class AllowGuestsUIState { data object None : AllowGuestsUIState() data class Success(val allow: Boolean) : AllowGuestsUIState() diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt index 24dba4f13..43d7cb2b2 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt @@ -36,15 +36,10 @@ import com.nextcloud.talk.extensions.loadUserAvatar import com.nextcloud.talk.models.domain.ConversationModel import com.nextcloud.talk.models.json.capabilities.SpreedCapability import com.nextcloud.talk.models.json.conversations.ConversationEnums -import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.CapabilitiesUtil import com.nextcloud.talk.utils.PickImage import com.nextcloud.talk.utils.bundle.BundleKeys -import io.reactivex.Observer -import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.disposables.Disposable -import io.reactivex.schedulers.Schedulers import java.io.File import javax.inject.Inject @@ -172,6 +167,45 @@ class ConversationInfoEditActivity : BaseActivity() { else -> {} } } + conversationInfoEditViewModel.renameRoomUiState.observe(this) { uiState -> + when (uiState) { + is ConversationInfoEditViewModel.RenameRoomUiState.None -> { + } + is ConversationInfoEditViewModel.RenameRoomUiState.Success -> { + if (CapabilitiesUtil.isConversationDescriptionEndpointAvailable(spreedCapabilities)) { + saveConversationDescription() + } else { + finish() + } + } + is ConversationInfoEditViewModel.RenameRoomUiState.Error -> { + Snackbar.make( + binding.root, + context.getString(R.string.default_error_msg), + Snackbar.LENGTH_LONG + ).show() + Log.e(TAG, "Error while saving conversation name", uiState.exception) + } + } + } + + conversationInfoEditViewModel.setConversationDescriptionUiState.observe(this) { uiState -> + when (uiState) { + is ConversationInfoEditViewModel.SetConversationDescriptionUiState.None -> { + } + is ConversationInfoEditViewModel.SetConversationDescriptionUiState.Success -> { + finish() + } + is ConversationInfoEditViewModel.SetConversationDescriptionUiState.Error -> { + Snackbar.make( + binding.root, + context.getString(R.string.default_error_msg), + Snackbar.LENGTH_LONG + ).show() + Log.e(TAG, "Error while saving conversation description", uiState.exception) + } + } + } } private fun setupAvatarOptions() { @@ -236,87 +270,16 @@ class ConversationInfoEditActivity : BaseActivity() { } private fun saveConversationNameAndDescription() { - val apiVersion = - ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) - - ncApi.renameRoom( - credentials, - ApiUtils.getUrlForRoom( - apiVersion, - conversationUser.baseUrl!!, - conversation!!.token - ), - binding.conversationName.text.toString() + val newRoomName = binding.conversationName.text.toString() + conversationInfoEditViewModel.renameRoom( + conversation!!.token, + newRoomName ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - // unused atm - } - - override fun onNext(genericOverall: GenericOverall) { - if (CapabilitiesUtil.isConversationDescriptionEndpointAvailable(spreedCapabilities)) { - saveConversationDescription() - } else { - finish() - } - } - - override fun onError(e: Throwable) { - Snackbar.make( - binding.root, - context.getString(R.string.default_error_msg), - Snackbar.LENGTH_LONG - ).show() - Log.e(TAG, "Error while saving conversation name", e) - } - - override fun onComplete() { - // unused atm - } - }) } fun saveConversationDescription() { - val apiVersion = - ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) - - ncApi.setConversationDescription( - credentials, - ApiUtils.getUrlForConversationDescription( - apiVersion, - conversationUser.baseUrl!!, - conversation!!.token - ), - binding.conversationDescription.text.toString() - ) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .retry(1) - .subscribe(object : Observer { - override fun onSubscribe(d: Disposable) { - // unused atm - } - - override fun onNext(genericOverall: GenericOverall) { - finish() - } - - override fun onError(e: Throwable) { - Snackbar.make( - binding.root, - context.getString(R.string.default_error_msg), - Snackbar.LENGTH_LONG - ).show() - Log.e(TAG, "Error while saving conversation description", e) - } - - override fun onComplete() { - // unused atm - } - }) + val conversationDescription = binding.conversationDescription.text.toString() + conversationInfoEditViewModel.setConversationDescription(conversation!!.token, conversationDescription) } private fun handleResult(result: ActivityResult, onResult: (result: ActivityResult) -> Unit) { diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepository.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepository.kt index 83628ca7c..7b3571b6f 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepository.kt @@ -8,6 +8,7 @@ package com.nextcloud.talk.conversationinfoedit.data import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.domain.ConversationModel +import com.nextcloud.talk.models.json.generic.GenericOverall import io.reactivex.Observable import java.io.File @@ -16,4 +17,8 @@ interface ConversationInfoEditRepository { fun uploadConversationAvatar(user: User, file: File, roomToken: String): Observable fun deleteConversationAvatar(user: User, roomToken: String): Observable + + suspend fun renameConversation(roomToken: String, roomNameNew: String): GenericOverall + + suspend fun setConversationDescription(roomToken: String, conversationDescription: String?): GenericOverall } diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepositoryImpl.kt index 8ed719a4c..a664419cc 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/data/ConversationInfoEditRepositoryImpl.kt @@ -7,8 +7,10 @@ package com.nextcloud.talk.conversationinfoedit.data import com.nextcloud.talk.api.NcApi +import com.nextcloud.talk.api.NcApiCoroutines import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.domain.ConversationModel +import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.Mimetype import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew @@ -18,7 +20,11 @@ import okhttp3.MultipartBody import okhttp3.RequestBody.Companion.asRequestBody import java.io.File -class ConversationInfoEditRepositoryImpl(private val ncApi: NcApi, currentUserProvider: CurrentUserProviderNew) : +class ConversationInfoEditRepositoryImpl( + private val ncApi: NcApi, + private val ncApiCoroutines: NcApiCoroutines, + currentUserProvider: CurrentUserProviderNew +) : ConversationInfoEditRepository { val currentUser: User = currentUserProvider.currentUser.blockingGet() @@ -53,4 +59,33 @@ class ConversationInfoEditRepositoryImpl(private val ncApi: NcApi, currentUserPr ApiUtils.getUrlForConversationAvatar(1, user.baseUrl!!, roomToken) ).map { ConversationModel.mapToConversationModel(it.ocs?.data!!, user) } } + + override suspend fun renameConversation(roomToken: String, newRoomName: String): GenericOverall { + val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) + + return ncApiCoroutines.renameRoom( + credentials, + ApiUtils.getUrlForRoom( + apiVersion, + currentUser.baseUrl!!, + roomToken + ), + newRoomName + ) + } + + override suspend fun setConversationDescription( + roomToken: String, + conversationDescription: String? + ): GenericOverall { + return ncApiCoroutines.setConversationDescription( + credentials, + ApiUtils.getUrlForConversationDescription( + apiVersion, + currentUser.baseUrl!!, + roomToken + ), + conversationDescription + ) + } } diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/viewmodel/ConversationInfoEditViewModel.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/viewmodel/ConversationInfoEditViewModel.kt index ff8af5955..29d171f05 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/viewmodel/ConversationInfoEditViewModel.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/viewmodel/ConversationInfoEditViewModel.kt @@ -10,6 +10,7 @@ import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.nextcloud.talk.chat.data.network.ChatNetworkDataSource import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepository import com.nextcloud.talk.data.user.model.User @@ -18,6 +19,7 @@ import io.reactivex.Observer import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.launch import java.io.File import javax.inject.Inject @@ -42,6 +44,15 @@ class ConversationInfoEditViewModel @Inject constructor( val viewState: LiveData get() = _viewState + private val _renameRoomUiState = MutableLiveData(RenameRoomUiState.None) + val renameRoomUiState: LiveData + get() = _renameRoomUiState + + private val _setConversationDescriptionUiState = + MutableLiveData(SetConversationDescriptionUiState.None) + val setConversationDescriptionUiState: LiveData + get() = _setConversationDescriptionUiState + fun getRoom(user: User, token: String) { _viewState.value = GetRoomStartState repository.getRoom(user, token) @@ -64,6 +75,32 @@ class ConversationInfoEditViewModel @Inject constructor( ?.subscribe(DeleteConversationAvatarObserver()) } + fun renameRoom(roomToken: String, newRoomName: String) { + viewModelScope.launch { + try { + conversationInfoEditRepository.renameConversation(roomToken, newRoomName) + _renameRoomUiState.value = RenameRoomUiState.Success + } catch (exception: Exception) { + _renameRoomUiState.value = RenameRoomUiState.Error(exception) + } + } + } + + fun setConversationDescription(roomToken: String, conversationDescription: String?) { + viewModelScope.launch { + try { + conversationInfoEditRepository.setConversationDescription( + roomToken, + conversationDescription + ) + + _setConversationDescriptionUiState.value = SetConversationDescriptionUiState.Success + } catch (exception: Exception) { + _setConversationDescriptionUiState.value = SetConversationDescriptionUiState.Error(exception) + } + } + } + inner class GetRoomObserver : Observer { override fun onSubscribe(d: Disposable) { // unused atm @@ -124,4 +161,16 @@ class ConversationInfoEditViewModel @Inject constructor( companion object { private val TAG = ConversationInfoEditViewModel::class.simpleName } + + sealed class RenameRoomUiState { + data object None : RenameRoomUiState() + data object Success : RenameRoomUiState() + data class Error(val exception: Exception) : RenameRoomUiState() + } + + sealed class SetConversationDescriptionUiState { + data object None : SetConversationDescriptionUiState() + data object Success : SetConversationDescriptionUiState() + data class Error(val exception: Exception) : SetConversationDescriptionUiState() + } } 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 1926cbf0e..b33c9ffbb 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 @@ -159,9 +159,10 @@ class RepositoryModule { @Provides fun provideConversationInfoEditRepository( ncApi: NcApi, + ncApiCoroutines: NcApiCoroutines, userProvider: CurrentUserProviderNew ): ConversationInfoEditRepository { - return ConversationInfoEditRepositoryImpl(ncApi, userProvider) + return ConversationInfoEditRepositoryImpl(ncApi, ncApiCoroutines, userProvider) } @Provides diff --git a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt index f1ac935fe..e4c760050 100644 --- a/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt +++ b/app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt @@ -13,7 +13,6 @@ import com.nextcloud.talk.chat.viewmodels.ChatViewModel import com.nextcloud.talk.contacts.ContactsViewModel import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel import com.nextcloud.talk.conversation.viewmodel.ConversationViewModel -import com.nextcloud.talk.conversation.viewmodel.RenameConversationViewModel import com.nextcloud.talk.conversationcreation.ConversationCreationViewModel import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel @@ -138,11 +137,6 @@ abstract class ViewModelModule { @ViewModelKey(ConversationInfoEditViewModel::class) abstract fun conversationInfoEditViewModel(viewModel: ConversationInfoEditViewModel): ViewModel - @Binds - @IntoMap - @ViewModelKey(RenameConversationViewModel::class) - abstract fun renameConversationViewModel(viewModel: RenameConversationViewModel): ViewModel - @Binds @IntoMap @ViewModelKey(ConversationViewModel::class) diff --git a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt index e4114bfaf..75d373dd6 100644 --- a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepository.kt @@ -25,5 +25,7 @@ interface ConversationsRepository { suspend fun setPassword(password: String, token: String): GenericOverall - fun setConversationReadOnly(credentials: String, url: String, state: Int): Observable + suspend fun setConversationReadOnly(roomToken: String, state: Int): GenericOverall + + suspend fun clearChatHistory(apiVersion: Int, roomToken: String): GenericOverall } diff --git a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt index 254f0e4f7..2d7fa0609 100644 --- a/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/repositories/conversations/ConversationsRepositoryImpl.kt @@ -74,8 +74,10 @@ class ConversationsRepositoryImpl( return coroutineApi.unarchiveConversation(credentials, url) } - override fun setConversationReadOnly(credentials: String, url: String, state: Int): Observable { - return api.setConversationReadOnly(credentials, url, state) + override suspend fun setConversationReadOnly(roomToken: String, state: Int): GenericOverall { + val apiVersion = ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1)) + val url = ApiUtils.getUrlForConversationReadOnly(apiVersion, user.baseUrl!!, roomToken) + return coroutineApi.setConversationReadOnly(credentials, url, state) } override suspend fun setPassword(password: String, token: String): GenericOverall { @@ -91,6 +93,13 @@ class ConversationsRepositoryImpl( return result } + override suspend fun clearChatHistory(apiVersion: Int, roomToken: String): GenericOverall { + return coroutineApi.clearChatHistory( + credentials, + ApiUtils.getUrlForChat(apiVersion, user.baseUrl!!, roomToken) + ) + } + private fun apiVersion(): Int { return ApiUtils.getConversationApiVersion(user, intArrayOf(ApiUtils.API_V4)) }