rewriting translate feature to use MVVM

Signed-off-by: Julius Linus <julius.linus@nextcloud.com>
This commit is contained in:
rapterjet2004 2023-05-22 11:13:46 -05:00
parent 26134343d4
commit 00f86144d8
5 changed files with 88 additions and 73 deletions

View file

@ -47,6 +47,8 @@ import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepositoryImpl
import com.nextcloud.talk.shareditems.repositories.SharedItemsRepository
import com.nextcloud.talk.shareditems.repositories.SharedItemsRepositoryImpl
import com.nextcloud.talk.translate.repositories.TranslateRepository
import com.nextcloud.talk.translate.repositories.TranslateRepositoryImpl
import com.nextcloud.talk.utils.DateUtils
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import dagger.Module
@ -107,4 +109,10 @@ class RepositoryModule {
RequestAssistanceRepository {
return RequestAssistanceRepositoryImpl(ncApi, userProvider)
}
@Provides
fun translateRepository(ncApi: NcApi):
TranslateRepository {
return TranslateRepositoryImpl(ncApi)
}
}

View file

@ -31,6 +31,7 @@ import com.nextcloud.talk.polls.viewmodels.PollVoteViewModel
import com.nextcloud.talk.raisehand.viewmodel.RaiseHandViewModel
import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsViewModel
import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel
import com.nextcloud.talk.translate.viewmodels.TranslateViewModel
import com.nextcloud.talk.viewmodels.CallRecordingViewModel
import dagger.Binds
import dagger.MapKey
@ -101,4 +102,9 @@ abstract class ViewModelModule {
@IntoMap
@ViewModelKey(RaiseHandViewModel::class)
abstract fun raiseHandViewModel(viewModel: RaiseHandViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(TranslateViewModel::class)
abstract fun translateViewModel(viewModel: TranslateViewModel): ViewModel
}

View file

@ -2,8 +2,9 @@ package com.nextcloud.talk.translate.repositories
import com.nextcloud.talk.api.NcApi
import io.reactivex.Observable
import javax.inject.Inject
class TranslateRepositoryImpl(private val ncApi: NcApi) : TranslateRepository {
class TranslateRepositoryImpl @Inject constructor(private val ncApi: NcApi) : TranslateRepository {
override fun translateMessage(
authorization: String,
@ -12,7 +13,7 @@ class TranslateRepositoryImpl(private val ncApi: NcApi) : TranslateRepository {
toLanguage: String,
fromLanguage: String?
): Observable<String> {
return ncApi.translateMessage(authorization, url, text, toLanguage, fromLanguage).map { it?.ocs?.data!!.text}
return ncApi.translateMessage(authorization, url, text, toLanguage, fromLanguage).map { it.ocs?.data!!.text}
}
}

View file

@ -31,7 +31,6 @@ import android.text.method.ScrollingMovementMethod
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@ -56,9 +55,11 @@ class TranslateActivity : BaseActivity() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var viewModel: TranslateViewModel
private lateinit var binding: ActivityTranslateBinding
lateinit var viewModel: TranslateViewModel
lateinit var binding: ActivityTranslateBinding
private var toLanguages : Array<String>? = null
private var fromLanguages : Array<String>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -66,9 +67,23 @@ class TranslateActivity : BaseActivity() {
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
binding = ActivityTranslateBinding.inflate(layoutInflater)
viewModel = ViewModelProvider(this, viewModelFactory)[TranslateViewModel::class.java] // fixme bug here
viewModel = ViewModelProvider(this, viewModelFactory)[TranslateViewModel::class.java]
viewModel.viewState.observe(this) { state ->
when(state) {
is TranslateViewModel.StartState -> {
onStartState()
}
is TranslateViewModel.TranslatedState -> {
onTranslatedState(state.msg)
}
is TranslateViewModel.ErrorState -> {
onErrorState()
}
}
}
setupActionBar()
setContentView(binding.root)
setupSystemColors()
@ -77,25 +92,9 @@ class TranslateActivity : BaseActivity() {
setupSpinners()
setupCopyButton()
val translateViewModelObserver = Observer<TranslateViewModel.TranslateUiState> { state ->
enableSpinners(state.enableSpinners)
binding.progressBar.visibility = if(state.showProgressBar) View.VISIBLE else View.GONE
binding.translatedMessageContainer.visibility =
if(state.showTranslatedMessageContainer) View.VISIBLE else View.GONE
if(state.translatedMessageText != null)
binding.translatedMessageTextview.text = state.translatedMessageText
if(state.errorOccurred)
showDialog()
}
viewModel.viewState.observe(this, translateViewModelObserver)
if (savedInstanceState == null) {
viewModel.translateMessage(Locale.getDefault().language, null)
val text = intent.extras !!.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
viewModel.translateMessage(Locale.getDefault().language, null, text!!)
} else {
binding.translatedMessageTextview.text = savedInstanceState.getString(BundleKeys.SAVED_TRANSLATED_MESSAGE)
}
@ -151,10 +150,8 @@ class TranslateActivity : BaseActivity() {
binding.originalMessageTextview.movementMethod = ScrollingMovementMethod()
binding.translatedMessageTextview.movementMethod = ScrollingMovementMethod()
val bundle = intent.extras
val text = bundle?.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
val text =intent.extras !!.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
binding.originalMessageTextview.text = text
viewModel.viewState.value!!.originalMessageText = text
}
private fun getLanguageOptions() {
@ -173,8 +170,8 @@ class TranslateActivity : BaseActivity() {
fromLanguagesSet.add(current.getString(TO_LABEL))
}
viewModel.viewState.value!!.toLanguages = toLanguagesSet.toTypedArray()
viewModel.viewState.value!!.fromLanguages = fromLanguagesSet.toTypedArray()
toLanguages = toLanguagesSet.toTypedArray()
fromLanguages = fromLanguagesSet.toTypedArray()
}
private fun enableSpinners(value: Boolean) {
@ -205,8 +202,6 @@ class TranslateActivity : BaseActivity() {
)
}
private fun getISOFromLanguage(language: String): String {
if (resources.getString(R.string.translation_device_settings) == language) {
return Locale.getDefault().language
@ -233,42 +228,61 @@ class TranslateActivity : BaseActivity() {
viewThemeUtils.material.colorTextInputLayout(binding.fromLanguageInputLayout)
viewThemeUtils.material.colorTextInputLayout(binding.toLanguageInputLayout)
fillSpinners()
val text = intent.extras !!.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
binding.fromLanguage.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
val fromLabel: String = getISOFromLanguage(parent.getItemAtPosition(position).toString())
val toLabel: String = getISOFromLanguage(binding.toLanguage.text.toString())
viewModel.translateMessage(toLabel, fromLabel)
viewModel.translateMessage(toLabel, fromLabel, text!!)
}
binding.toLanguage.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
val toLabel: String = getISOFromLanguage(parent.getItemAtPosition(position).toString())
val fromLabel: String = getISOFromLanguage(binding.fromLanguage.text.toString())
viewModel.translateMessage(toLabel, fromLabel)
viewModel.translateMessage(toLabel, fromLabel, text!!)
}
}
private fun fillSpinners() {
val fromLanguages = viewModel.viewState.value!!.fromLanguages!!
val toLanguages = viewModel.viewState.value!!.toLanguages!!
binding.fromLanguage.setAdapter(
ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, fromLanguages)
ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, fromLanguages!!)
)
if (fromLanguages.isNotEmpty()) {
binding.fromLanguage.setText(fromLanguages[0])
if (fromLanguages!!.isNotEmpty()) {
binding.fromLanguage.setText(fromLanguages!![0])
}
binding.toLanguage.setAdapter(
ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, toLanguages)
ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, toLanguages!!)
)
if (toLanguages.isNotEmpty()) {
binding.toLanguage.setText(toLanguages[0])
if (toLanguages!!.isNotEmpty()) {
binding.toLanguage.setText(toLanguages!![0])
}
}
private fun setItems() {
binding.fromLanguage.setSimpleItems(viewModel.viewState.value!!.fromLanguages!!)
binding.toLanguage.setSimpleItems(viewModel.viewState.value!!.toLanguages!!)
binding.fromLanguage.setSimpleItems(fromLanguages!!)
binding.toLanguage.setSimpleItems(toLanguages!!)
}
private fun onStartState() {
enableSpinners(false)
binding.translatedMessageContainer.visibility = View.GONE
binding.progressBar.visibility = View.VISIBLE
binding.copyTranslatedMessage.visibility = View.GONE
}
private fun onTranslatedState(msg : String) {
binding.progressBar.visibility = View.GONE
binding.translatedMessageContainer.visibility = View.VISIBLE
binding.translatedMessageTextview.text = msg
binding.copyTranslatedMessage.visibility = View.VISIBLE
enableSpinners(true)
}
private fun onErrorState() {
binding.progressBar.visibility = View.GONE
enableSpinners(true)
showDialog()
}
companion object {

View file

@ -14,33 +14,26 @@ import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject
class TranslateViewModel @Inject constructor(private val repository: TranslateRepository) : ViewModel() {
class TranslateViewModel @Inject constructor(private val repository: TranslateRepository,
private val userManager: UserManager) : ViewModel() {
@Inject
lateinit var userManager: UserManager
sealed interface ViewState
data class TranslateUiState(
var enableSpinners : Boolean = false,
var showProgressBar : Boolean = false,
var showTranslatedMessageContainer : Boolean = false,
var translatedMessageText : String? = null,
var originalMessageText : String? = null,
var errorOccurred : Boolean = false,
var toLanguages : Array<String>? = null,
var fromLanguages : Array<String>? = null
)
object StartState : ViewState
class TranslatedState(val msg: String) : ViewState
object ErrorState : ViewState
private val _viewState = MutableLiveData(TranslateUiState())
val viewState : LiveData<TranslateUiState>
private val _viewState : MutableLiveData<ViewState> = MutableLiveData(StartState)
val viewState : LiveData<ViewState>
get() = _viewState
fun translateMessage(toLanguage: String, fromLanguage: String?) {
fun translateMessage(toLanguage: String, fromLanguage: String?, text: String) {
val currentUser: User = userManager.currentUser.blockingGet()
val authorization: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
val url: String = ApiUtils.getUrlForTranslation(currentUser.baseUrl)
val calculatedFromLanguage = if (fromLanguage == null || fromLanguage == "") { null } else { fromLanguage }
repository.translateMessage(authorization, url,_viewState.value!!.originalMessageText!!,toLanguage,
Log.i(TAG, "translateMessage Called")
repository.translateMessage(authorization, url,text,toLanguage,
calculatedFromLanguage)
.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
@ -49,23 +42,16 @@ class TranslateViewModel @Inject constructor(private val repository: TranslateRe
inner class TranslateObserver() : Observer<String> {
override fun onSubscribe(d: Disposable) {
_viewState.value!!.enableSpinners = false
_viewState.value!!.showTranslatedMessageContainer = false
_viewState.value!!.showProgressBar = true
_viewState.value = StartState
}
override fun onNext(translatedMessage: String) {
_viewState.value!!.showProgressBar = false
_viewState.value!!.showTranslatedMessageContainer = true
_viewState.value!!.translatedMessageText = translatedMessage
_viewState.value!!.enableSpinners = true
_viewState.value = TranslatedState(translatedMessage)
}
override fun onError(e: Throwable) {
_viewState.value!!.showProgressBar = false
_viewState.value!!.errorOccurred = true
_viewState.value!!.enableSpinners = true
Log.w(TAG, "Error while translating message", e)
_viewState.value = ErrorState
Log.e(TAG, "Error while translating message", e)
}
override fun onComplete() {