remove unused code (ConversationRepository, ConversationViewModel)

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2025-03-25 11:09:05 +01:00
parent 643385505c
commit d4959d9130
No known key found for this signature in database
GPG Key ID: C793F8B59F43CE7B
6 changed files with 0 additions and 478 deletions

View File

@ -1,307 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversation
import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Intent
import android.content.res.ColorStateList
import android.os.Bundle
import android.os.Parcelable
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.ViewModelProvider
import androidx.work.Data
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkInfo
import androidx.work.WorkManager
import autodagger.AutoInjector
import com.google.android.material.dialog.MaterialAlertDialogBuilder
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.chat.ChatActivity
import com.nextcloud.talk.conversation.viewmodel.ConversationViewModel
import com.nextcloud.talk.databinding.DialogCreateConversationBinding
import com.nextcloud.talk.jobs.AddParticipantsToConversationWorker
import com.nextcloud.talk.models.json.conversations.ConversationEnums
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import com.vanniktech.emoji.EmojiPopup
import org.greenrobot.eventbus.EventBus
import org.parceler.Parcels
import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class)
class CreateConversationDialogFragment : DialogFragment() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject
lateinit var viewThemeUtils: ViewThemeUtils
@Inject
lateinit var eventBus: EventBus
@Inject
lateinit var currentUserProvider: CurrentUserProviderNew
private lateinit var binding: DialogCreateConversationBinding
private lateinit var viewModel: ConversationViewModel
private var emojiPopup: EmojiPopup? = null
private var conversationType: ConversationEnums.ConversationType? = null
private var usersToInvite: ArrayList<String> = ArrayList()
private var groupsToInvite: ArrayList<String> = ArrayList()
private var emailsToInvite: ArrayList<String> = ArrayList()
private var circlesToInvite: ArrayList<String> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
viewModel = ViewModelProvider(this, viewModelFactory)[ConversationViewModel::class.java]
if (arguments?.containsKey(USERS_TO_INVITE) == true) {
usersToInvite = arguments?.getStringArrayList(USERS_TO_INVITE)!!
}
if (arguments?.containsKey(GROUPS_TO_INVITE) == true) {
groupsToInvite = arguments?.getStringArrayList(GROUPS_TO_INVITE)!!
}
if (arguments?.containsKey(EMAILS_TO_INVITE) == true) {
emailsToInvite = arguments?.getStringArrayList(EMAILS_TO_INVITE)!!
}
if (arguments?.containsKey(CIRCLES_TO_INVITE) == true) {
circlesToInvite = arguments?.getStringArrayList(CIRCLES_TO_INVITE)!!
}
if (arguments?.containsKey(KEY_CONVERSATION_TYPE) == true) {
conversationType = Parcels.unwrap(arguments?.getParcelable(KEY_CONVERSATION_TYPE))
}
}
@SuppressLint("InflateParams")
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
binding = DialogCreateConversationBinding.inflate(layoutInflater)
val dialogBuilder = MaterialAlertDialogBuilder(binding.root.context)
.setTitle(resources.getString(R.string.create_conversation))
// listener is null for now to avoid closing after button was clicked.
// listener is set later in onStart
.setPositiveButton(R.string.nc_common_create, null)
.setNegativeButton(R.string.nc_common_dismiss, null)
.setView(binding.root)
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.root.context, dialogBuilder)
return dialogBuilder.create()
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupListeners()
setupStateObserver()
setupEmojiPopup()
}
override fun onStart() {
super.onStart()
val positiveButton = (dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE)
positiveButton.isEnabled = false
positiveButton.setOnClickListener {
viewModel.createConversation(
binding.textEdit.text.toString(),
conversationType
)
}
themeDialog()
}
private fun themeDialog() {
viewThemeUtils.platform.themeDialog(binding.root)
viewThemeUtils.platform.colorTextButtons((dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE))
viewThemeUtils.platform.colorTextButtons((dialog as AlertDialog).getButton(AlertDialog.BUTTON_NEGATIVE))
viewThemeUtils.material.colorTextInputLayout(binding.textInputLayout)
}
private fun setupEmojiPopup() {
emojiPopup = binding.let {
EmojiPopup(
rootView = requireView(),
editText = it.textEdit,
onEmojiPopupShownListener = {
viewThemeUtils.platform.colorImageView(it.smileyButton, ColorRole.PRIMARY)
},
onEmojiPopupDismissListener = {
it.smileyButton.imageTintList = ColorStateList.valueOf(
ResourcesCompat.getColor(
resources,
R.color.medium_emphasis_text,
context?.theme
)
)
},
onEmojiClickListener = {
binding.textEdit.editableText?.append(" ")
}
)
}
}
private fun setupListeners() {
binding.smileyButton.setOnClickListener { emojiPopup?.toggle() }
binding.textEdit.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// unused atm
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
// unused atm
}
override fun afterTextChanged(s: Editable) {
val positiveButton = (dialog as AlertDialog).getButton(AlertDialog.BUTTON_POSITIVE)
if (!TextUtils.isEmpty(s)) {
if (!positiveButton.isEnabled) {
positiveButton.isEnabled = true
}
} else {
if (positiveButton.isEnabled) {
positiveButton.isEnabled = false
}
}
}
})
}
private fun setupStateObserver() {
viewModel.viewState.observe(viewLifecycleOwner) { state ->
when (state) {
is ConversationViewModel.InitialState -> {}
is ConversationViewModel.CreatingState -> {}
is ConversationViewModel.CreatingSuccessState -> addParticipants(state.roomToken)
is ConversationViewModel.CreatingFailedState -> {
Log.e(TAG, "Failed to create conversation")
showError()
}
else -> {}
}
}
}
private fun addParticipants(roomToken: String) {
val data = Data.Builder()
data.putLong(BundleKeys.KEY_INTERNAL_USER_ID, currentUserProvider.currentUser.blockingGet().id!!)
data.putString(BundleKeys.KEY_TOKEN, roomToken)
data.putStringArray(BundleKeys.KEY_SELECTED_USERS, usersToInvite.toTypedArray())
data.putStringArray(BundleKeys.KEY_SELECTED_GROUPS, groupsToInvite.toTypedArray())
data.putStringArray(BundleKeys.KEY_SELECTED_EMAILS, emailsToInvite.toTypedArray())
data.putStringArray(BundleKeys.KEY_SELECTED_CIRCLES, circlesToInvite.toTypedArray())
val addParticipantsToConversationWorker: OneTimeWorkRequest = OneTimeWorkRequest.Builder(
AddParticipantsToConversationWorker::class.java
)
.setInputData(data.build())
.build()
WorkManager.getInstance(requireContext()).enqueue(addParticipantsToConversationWorker)
WorkManager.getInstance(requireContext()).getWorkInfoByIdLiveData(addParticipantsToConversationWorker.id)
.observeForever { workInfo: WorkInfo? ->
if (workInfo != null) {
when (workInfo.state) {
WorkInfo.State.RUNNING -> {
Log.d(TAG, "running AddParticipantsToConversation")
}
WorkInfo.State.SUCCEEDED -> {
Log.d(TAG, "success AddParticipantsToConversation")
initiateConversation(roomToken)
}
WorkInfo.State.FAILED -> {
Log.e(TAG, "failed to AddParticipantsToConversation")
showError()
}
else -> {
}
}
}
}
}
private fun initiateConversation(roomToken: String) {
activity?.let {
val bundle = Bundle()
bundle.putString(BundleKeys.KEY_ROOM_TOKEN, roomToken)
val chatIntent = Intent(it, ChatActivity::class.java)
chatIntent.putExtras(bundle)
chatIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(chatIntent)
}
dismiss()
}
private fun showError() {
dismiss()
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
}
/**
* Fragment creator
*/
companion object {
private val TAG = CreateConversationDialogFragment::class.java.simpleName
private const val USERS_TO_INVITE = "usersToInvite"
private const val GROUPS_TO_INVITE = "groupsToInvite"
private const val EMAILS_TO_INVITE = "emailsToInvite"
private const val CIRCLES_TO_INVITE = "circlesToInvite"
private const val KEY_CONVERSATION_TYPE = "keyConversationType"
@JvmStatic
fun newInstance(
usersToInvite: ArrayList<String>?,
groupsToInvite: ArrayList<String>?,
emailsToInvite: ArrayList<String>?,
circlesToInvite: ArrayList<String>?,
conversationType: Parcelable
): CreateConversationDialogFragment {
val args = Bundle()
args.putStringArrayList(USERS_TO_INVITE, usersToInvite)
args.putStringArrayList(GROUPS_TO_INVITE, groupsToInvite)
args.putStringArrayList(EMAILS_TO_INVITE, emailsToInvite)
args.putStringArrayList(CIRCLES_TO_INVITE, circlesToInvite)
args.putParcelable(KEY_CONVERSATION_TYPE, conversationType)
val fragment = CreateConversationDialogFragment()
fragment.arguments = args
return fragment
}
}
}

View File

@ -1,19 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversation.repository
import com.nextcloud.talk.models.json.conversations.ConversationEnums
import com.nextcloud.talk.models.json.conversations.RoomOverall
import io.reactivex.Observable
interface ConversationRepository {
fun createConversation(
roomName: String,
conversationType: ConversationEnums.ConversationType?
): Observable<RoomOverall>
}

View File

@ -1,62 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversation.repository
import com.nextcloud.talk.api.NcApi
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.utils.ApiUtils
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class ConversationRepositoryImpl(private val ncApi: NcApi, currentUserProvider: CurrentUserProviderNew) :
ConversationRepository {
val currentUser: User = currentUserProvider.currentUser.blockingGet()
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)!!
override fun createConversation(
roomName: String,
conversationType: ConversationEnums.ConversationType?
): Observable<RoomOverall> {
val apiVersion = ApiUtils.getConversationApiVersion(currentUser, intArrayOf(ApiUtils.API_V4, ApiUtils.API_V1))
val retrofitBucket: RetrofitBucket =
if (conversationType == ConversationEnums.ConversationType.ROOM_PUBLIC_CALL) {
ApiUtils.getRetrofitBucketForCreateRoom(
apiVersion,
currentUser.baseUrl!!,
ROOM_TYPE_PUBLIC,
null,
null,
roomName
)
} else {
ApiUtils.getRetrofitBucketForCreateRoom(
apiVersion,
currentUser.baseUrl!!,
ROOM_TYPE_GROUP,
null,
null,
roomName
)
}
return ncApi.createRoom(credentials, retrofitBucket.url, retrofitBucket.queryMap)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry(1)
}
companion object {
private const val ROOM_TYPE_PUBLIC = "3"
private const val ROOM_TYPE_GROUP = "2"
}
}

View File

@ -1,78 +0,0 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2023 Marcel Hibbe <dev@mhibbe.de>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.conversation.viewmodel
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.conversations.ConversationEnums
import com.nextcloud.talk.models.json.conversations.RoomOverall
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 ConversationViewModel @Inject constructor(private val repository: ConversationRepository) : ViewModel() {
sealed class ViewState
object InitialState : ViewState()
object CreatingState : ViewState()
class CreatingSuccessState(val roomToken: String) : ViewState()
object CreatingFailedState : ViewState()
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(
InitialState
)
val viewState: LiveData<ViewState>
get() = _viewState
private var disposable: Disposable? = null
override fun onCleared() {
super.onCleared()
disposable?.dispose()
}
fun createConversation(roomName: String, conversationType: ConversationEnums.ConversationType?) {
_viewState.value = CreatingState
repository.createConversation(
roomName,
conversationType
)
.doOnSubscribe { disposable = it }
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(CreateConversationObserver())
}
inner class CreateConversationObserver : Observer<RoomOverall> {
override fun onSubscribe(d: Disposable) {
// unused atm
}
override fun onNext(roomOverall: RoomOverall) {
val conversation = roomOverall.ocs!!.data
_viewState.value = CreatingSuccessState(conversation?.token!!)
}
override fun onError(e: Throwable) {
// dispose()
}
override fun onComplete() {
// dispose()
}
}
companion object {
private val TAG = ConversationViewModel::class.java.simpleName
}
}

View File

@ -17,8 +17,6 @@ import com.nextcloud.talk.chat.data.network.OfflineFirstChatRepository
import com.nextcloud.talk.chat.data.network.RetrofitChatNetwork import com.nextcloud.talk.chat.data.network.RetrofitChatNetwork
import com.nextcloud.talk.contacts.ContactsRepository import com.nextcloud.talk.contacts.ContactsRepository
import com.nextcloud.talk.contacts.ContactsRepositoryImpl import com.nextcloud.talk.contacts.ContactsRepositoryImpl
import com.nextcloud.talk.conversation.repository.ConversationRepository
import com.nextcloud.talk.conversation.repository.ConversationRepositoryImpl
import com.nextcloud.talk.conversationcreation.ConversationCreationRepository import com.nextcloud.talk.conversationcreation.ConversationCreationRepository
import com.nextcloud.talk.conversationcreation.ConversationCreationRepositoryImpl import com.nextcloud.talk.conversationcreation.ConversationCreationRepositoryImpl
import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepository import com.nextcloud.talk.conversationinfoedit.data.ConversationInfoEditRepository
@ -142,10 +140,6 @@ class RepositoryModule {
return ConversationInfoEditRepositoryImpl(ncApi, ncApiCoroutines, userProvider) return ConversationInfoEditRepositoryImpl(ncApi, ncApiCoroutines, userProvider)
} }
@Provides
fun provideConversationRepository(ncApi: NcApi, userProvider: CurrentUserProviderNew): ConversationRepository =
ConversationRepositoryImpl(ncApi, userProvider)
@Provides @Provides
fun provideInvitationsRepository(ncApi: NcApi): InvitationsRepository = InvitationsRepositoryImpl(ncApi) fun provideInvitationsRepository(ncApi: NcApi): InvitationsRepository = InvitationsRepositoryImpl(ncApi)

View File

@ -12,7 +12,6 @@ import androidx.lifecycle.ViewModelProvider
import com.nextcloud.talk.chat.viewmodels.ChatViewModel import com.nextcloud.talk.chat.viewmodels.ChatViewModel
import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel import com.nextcloud.talk.chat.viewmodels.MessageInputViewModel
import com.nextcloud.talk.contacts.ContactsViewModel import com.nextcloud.talk.contacts.ContactsViewModel
import com.nextcloud.talk.conversation.viewmodel.ConversationViewModel
import com.nextcloud.talk.conversationcreation.ConversationCreationViewModel import com.nextcloud.talk.conversationcreation.ConversationCreationViewModel
import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel
import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel import com.nextcloud.talk.conversationinfoedit.viewmodel.ConversationInfoEditViewModel
@ -135,11 +134,6 @@ abstract class ViewModelModule {
@ViewModelKey(ConversationInfoEditViewModel::class) @ViewModelKey(ConversationInfoEditViewModel::class)
abstract fun conversationInfoEditViewModel(viewModel: ConversationInfoEditViewModel): ViewModel abstract fun conversationInfoEditViewModel(viewModel: ConversationInfoEditViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(ConversationViewModel::class)
abstract fun conversationViewModel(viewModel: ConversationViewModel): ViewModel
@Binds @Binds
@IntoMap @IntoMap
@ViewModelKey(InvitationsViewModel::class) @ViewModelKey(InvitationsViewModel::class)