Merge pull request #3038 from nextcloud/translate-message-mvvm-impl

rewriting translate feature to use MVVM
This commit is contained in:
Marcel Hibbe 2023-05-23 19:09:34 +02:00 committed by GitHub
commit fd5fec937f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 212 additions and 100 deletions

View File

@ -190,7 +190,7 @@
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity <activity
android:name=".translate.TranslateActivity" android:name=".translate.ui.TranslateActivity"
android:theme="@style/AppTheme" /> android:theme="@style/AppTheme" />
<activity <activity

View File

@ -44,7 +44,7 @@ import com.nextcloud.talk.models.json.search.ContactsByNumberOverall;
import com.nextcloud.talk.models.json.signaling.SignalingOverall; import com.nextcloud.talk.models.json.signaling.SignalingOverall;
import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall; import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall;
import com.nextcloud.talk.models.json.status.StatusOverall; import com.nextcloud.talk.models.json.status.StatusOverall;
import com.nextcloud.talk.models.json.translations.TranslationsOverall; import com.nextcloud.talk.translate.repositories.model.TranslationsOverall;
import com.nextcloud.talk.models.json.unifiedsearch.UnifiedSearchOverall; import com.nextcloud.talk.models.json.unifiedsearch.UnifiedSearchOverall;
import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall;
import com.nextcloud.talk.models.json.userprofile.UserProfileOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileOverall;

View File

@ -155,8 +155,8 @@ import com.nextcloud.talk.remotefilebrowser.activities.RemoteFileBrowserActivity
import com.nextcloud.talk.repositories.reactions.ReactionsRepository import com.nextcloud.talk.repositories.reactions.ReactionsRepository
import com.nextcloud.talk.shareditems.activities.SharedItemsActivity import com.nextcloud.talk.shareditems.activities.SharedItemsActivity
import com.nextcloud.talk.signaling.SignalingMessageReceiver import com.nextcloud.talk.signaling.SignalingMessageReceiver
import com.nextcloud.talk.translate.ui.TranslateActivity
import com.nextcloud.talk.signaling.SignalingMessageSender import com.nextcloud.talk.signaling.SignalingMessageSender
import com.nextcloud.talk.translate.TranslateActivity
import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet
import com.nextcloud.talk.ui.dialog.AttachmentDialog import com.nextcloud.talk.ui.dialog.AttachmentDialog
import com.nextcloud.talk.ui.dialog.MessageActionsDialog import com.nextcloud.talk.ui.dialog.MessageActionsDialog

View File

@ -47,6 +47,8 @@ import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepositoryImpl import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepositoryImpl
import com.nextcloud.talk.shareditems.repositories.SharedItemsRepository import com.nextcloud.talk.shareditems.repositories.SharedItemsRepository
import com.nextcloud.talk.shareditems.repositories.SharedItemsRepositoryImpl 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.DateUtils
import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
import dagger.Module import dagger.Module
@ -107,4 +109,10 @@ class RepositoryModule {
RequestAssistanceRepository { RequestAssistanceRepository {
return RequestAssistanceRepositoryImpl(ncApi, userProvider) 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.raisehand.viewmodel.RaiseHandViewModel
import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsViewModel import com.nextcloud.talk.remotefilebrowser.viewmodels.RemoteFileBrowserItemsViewModel
import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel import com.nextcloud.talk.shareditems.viewmodels.SharedItemsViewModel
import com.nextcloud.talk.translate.viewmodels.TranslateViewModel
import com.nextcloud.talk.viewmodels.CallRecordingViewModel import com.nextcloud.talk.viewmodels.CallRecordingViewModel
import dagger.Binds import dagger.Binds
import dagger.MapKey import dagger.MapKey
@ -101,4 +102,9 @@ abstract class ViewModelModule {
@IntoMap @IntoMap
@ViewModelKey(RaiseHandViewModel::class) @ViewModelKey(RaiseHandViewModel::class)
abstract fun raiseHandViewModel(viewModel: RaiseHandViewModel): ViewModel abstract fun raiseHandViewModel(viewModel: RaiseHandViewModel): ViewModel
@Binds
@IntoMap
@ViewModelKey(TranslateViewModel::class)
abstract fun translateViewModel(viewModel: TranslateViewModel): ViewModel
} }

View File

@ -0,0 +1,14 @@
package com.nextcloud.talk.translate.repositories
import io.reactivex.Observable
interface TranslateRepository {
fun translateMessage(
authorization: String,
url: String,
text: String,
toLanguage: String,
fromLanguage: String?
): Observable<String>
}

View File

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

View File

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.models.json.translations package com.nextcloud.talk.translate.repositories.model
import android.os.Parcelable import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonField

View File

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.models.json.translations package com.nextcloud.talk.translate.repositories.model
import android.os.Parcelable import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonField

View File

@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.models.json.translations package com.nextcloud.talk.translate.repositories.model
import android.os.Parcelable import android.os.Parcelable
import com.bluelinelabs.logansquare.annotation.JsonField import com.bluelinelabs.logansquare.annotation.JsonField

View File

@ -19,68 +19,82 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.nextcloud.talk.translate package com.nextcloud.talk.translate.ui
import android.app.AlertDialog
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.text.method.ScrollingMovementMethod import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import androidx.appcompat.app.AlertDialog import androidx.lifecycle.ViewModelProvider
import autodagger.AutoInjector import autodagger.AutoInjector
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.activities.BaseActivity import com.nextcloud.talk.activities.BaseActivity
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ActivityTranslateBinding import com.nextcloud.talk.databinding.ActivityTranslateBinding
import com.nextcloud.talk.models.json.translations.TranslationsOverall import com.nextcloud.talk.translate.viewmodels.TranslateViewModel
import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.json.JSONArray import org.json.JSONArray
import java.util.Locale import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class TranslateActivity : BaseActivity() { class TranslateActivity : BaseActivity() {
private lateinit var binding: ActivityTranslateBinding
@Inject
lateinit var ncApi: NcApi
@Inject @Inject
lateinit var userManager: UserManager lateinit var userManager: UserManager
private var fromLanguages = arrayOf<String>() @Inject
private var toLanguages = arrayOf<String>() lateinit var viewModelFactory: ViewModelProvider.Factory
private var text: String? = null
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?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this) NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
binding = ActivityTranslateBinding.inflate(layoutInflater) binding = ActivityTranslateBinding.inflate(layoutInflater)
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() setupActionBar()
setContentView(binding.root) setContentView(binding.root)
setupSystemColors() setupSystemColors()
setupTextViews() setupTextViews()
getLanguageOptions()
setupSpinners() setupSpinners()
setupCopyButton() setupCopyButton()
getLanguageOptions()
if (savedInstanceState == null) { if (savedInstanceState == null) {
translate(null, Locale.getDefault().language) val text = intent.extras!!.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
viewModel.translateMessage(Locale.getDefault().language, null, text!!)
} else { } else {
binding.translatedMessageTextview.text = savedInstanceState.getString(BundleKeys.SAVED_TRANSLATED_MESSAGE) binding.translatedMessageTextview.text = savedInstanceState.getString(BundleKeys.SAVED_TRANSLATED_MESSAGE)
} }
@ -90,7 +104,6 @@ class TranslateActivity : BaseActivity() {
super.onResume() super.onResume()
setItems() setItems()
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {
outState.run { outState.run {
putString(BundleKeys.SAVED_TRANSLATED_MESSAGE, binding.translatedMessageTextview.text.toString()) putString(BundleKeys.SAVED_TRANSLATED_MESSAGE, binding.translatedMessageTextview.text.toString())
@ -137,14 +150,12 @@ class TranslateActivity : BaseActivity() {
binding.originalMessageTextview.movementMethod = ScrollingMovementMethod() binding.originalMessageTextview.movementMethod = ScrollingMovementMethod()
binding.translatedMessageTextview.movementMethod = ScrollingMovementMethod() binding.translatedMessageTextview.movementMethod = ScrollingMovementMethod()
val text = intent.extras!!.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
val bundle = intent.extras binding.originalMessageTextview.text = text
binding.originalMessageTextview.text = bundle?.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
text = bundle?.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
} }
private fun getLanguageOptions() { private fun getLanguageOptions() {
val currentUser: User = userManager.currentUser.blockingGet() val currentUser = userManager.currentUser.blockingGet()
val json = JSONArray(CapabilitiesUtilNew.getLanguages(currentUser).toString()) val json = JSONArray(CapabilitiesUtilNew.getLanguages(currentUser).toString())
val fromLanguagesSet = mutableSetOf(resources.getString(R.string.translation_detect_language)) val fromLanguagesSet = mutableSetOf(resources.getString(R.string.translation_detect_language))
@ -159,9 +170,8 @@ class TranslateActivity : BaseActivity() {
fromLanguagesSet.add(current.getString(TO_LABEL)) fromLanguagesSet.add(current.getString(TO_LABEL))
} }
fromLanguages = fromLanguagesSet.toTypedArray()
toLanguages = toLanguagesSet.toTypedArray() toLanguages = toLanguagesSet.toTypedArray()
fillSpinners() fromLanguages = fromLanguagesSet.toTypedArray()
} }
private fun enableSpinners(value: Boolean) { private fun enableSpinners(value: Boolean) {
@ -169,35 +179,7 @@ class TranslateActivity : BaseActivity() {
binding.toLanguageInputLayout.isEnabled = value binding.toLanguageInputLayout.isEnabled = value
} }
private fun translate(fromLanguage: String?, toLanguage: String) { private fun showDialog() {
val currentUser: User = userManager.currentUser.blockingGet()
val credentials: String = ApiUtils.getCredentials(currentUser.username, currentUser.token)
val translateURL = ApiUtils.getUrlForTranslation(currentUser.baseUrl)
val calculatedFromLanguage = if (fromLanguage == null || fromLanguage == "") {
null
} else {
fromLanguage
}
ncApi.translateMessage(credentials, translateURL, text, toLanguage, calculatedFromLanguage)
?.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(object : Observer<TranslationsOverall> {
override fun onSubscribe(d: Disposable) {
enableSpinners(false)
binding.translatedMessageContainer.visibility = View.GONE
binding.progressBar.visibility = View.VISIBLE
}
override fun onNext(translationOverall: TranslationsOverall) {
binding.progressBar.visibility = View.GONE
binding.translatedMessageContainer.visibility = View.VISIBLE
binding.translatedMessageTextview.text = translationOverall.ocs?.data?.text
}
override fun onError(e: Throwable) {
Log.w(TAG, "Error while translating message", e)
binding.progressBar.visibility = View.GONE
val dialogBuilder = MaterialAlertDialogBuilder(this@TranslateActivity) val dialogBuilder = MaterialAlertDialogBuilder(this@TranslateActivity)
.setIcon( .setIcon(
viewThemeUtils.dialog.colorMaterialAlertDialogIcon( viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
@ -220,14 +202,6 @@ class TranslateActivity : BaseActivity() {
) )
} }
override fun onComplete() {
// nothing?
}
})
enableSpinners(true)
}
private fun getISOFromLanguage(language: String): String { private fun getISOFromLanguage(language: String): String {
if (resources.getString(R.string.translation_device_settings) == language) { if (resources.getString(R.string.translation_device_settings) == language) {
return Locale.getDefault().language return Locale.getDefault().language
@ -237,7 +211,7 @@ class TranslateActivity : BaseActivity() {
} }
private fun getISOFromServer(language: String): String { private fun getISOFromServer(language: String): String {
val currentUser: User = userManager.currentUser.blockingGet() val currentUser = userManager.currentUser.blockingGet()
val json = JSONArray(CapabilitiesUtilNew.getLanguages(currentUser).toString()) val json = JSONArray(CapabilitiesUtilNew.getLanguages(currentUser).toString())
for (i in 0 until json.length()) { for (i in 0 until json.length()) {
@ -254,43 +228,64 @@ class TranslateActivity : BaseActivity() {
viewThemeUtils.material.colorTextInputLayout(binding.fromLanguageInputLayout) viewThemeUtils.material.colorTextInputLayout(binding.fromLanguageInputLayout)
viewThemeUtils.material.colorTextInputLayout(binding.toLanguageInputLayout) viewThemeUtils.material.colorTextInputLayout(binding.toLanguageInputLayout)
fillSpinners() fillSpinners()
val text = intent.extras!!.getString(BundleKeys.KEY_TRANSLATE_MESSAGE)
binding.fromLanguage.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ -> binding.fromLanguage.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
val fromLabel: String = getISOFromLanguage(parent.getItemAtPosition(position).toString()) val fromLabel: String = getISOFromLanguage(parent.getItemAtPosition(position).toString())
val toLabel: String = getISOFromLanguage(binding.toLanguage.text.toString()) val toLabel: String = getISOFromLanguage(binding.toLanguage.text.toString())
translate(fromLabel, toLabel) viewModel.translateMessage(toLabel, fromLabel, text!!)
} }
binding.toLanguage.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ -> binding.toLanguage.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
val toLabel: String = getISOFromLanguage(parent.getItemAtPosition(position).toString()) val toLabel: String = getISOFromLanguage(parent.getItemAtPosition(position).toString())
val fromLabel: String = getISOFromLanguage(binding.fromLanguage.text.toString()) val fromLabel: String = getISOFromLanguage(binding.fromLanguage.text.toString())
translate(fromLabel, toLabel) viewModel.translateMessage(toLabel, fromLabel, text!!)
} }
} }
private fun fillSpinners() { private fun fillSpinners() {
binding.fromLanguage.setAdapter( 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()) { if (fromLanguages!!.isNotEmpty()) {
binding.fromLanguage.setText(fromLanguages[0]) binding.fromLanguage.setText(fromLanguages!![0])
} }
binding.toLanguage.setAdapter( 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()) { if (toLanguages!!.isNotEmpty()) {
binding.toLanguage.setText(toLanguages[0]) binding.toLanguage.setText(toLanguages!![0])
} }
} }
private fun setItems() { private fun setItems() {
binding.fromLanguage.setSimpleItems(fromLanguages) binding.fromLanguage.setSimpleItems(fromLanguages!!)
binding.toLanguage.setSimpleItems(toLanguages) 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 { companion object {
private val TAG = TranslateActivity::class.simpleName
private const val FROM_ID = "from" private const val FROM_ID = "from"
private const val FROM_LABEL = "fromLabel" private const val FROM_LABEL = "fromLabel"
private const val TO_LABEL = "toLabel" private const val TO_LABEL = "toLabel"

View File

@ -0,0 +1,71 @@
package com.nextcloud.talk.translate.viewmodels
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.translate.repositories.TranslateRepository
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
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 TranslateViewModel @Inject constructor(
private val repository: TranslateRepository,
private val userManager: UserManager
) : ViewModel() {
sealed interface ViewState
object StartState : ViewState
class TranslatedState(val msg: String) : ViewState
object ErrorState : ViewState
private val _viewState: MutableLiveData<ViewState> = MutableLiveData(StartState)
val viewState: LiveData<ViewState>
get() = _viewState
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 }
Log.i(TAG, "translateMessage Called")
repository.translateMessage(
authorization,
url,
text,
toLanguage,
calculatedFromLanguage
)
.subscribeOn(Schedulers.io())
?.observeOn(AndroidSchedulers.mainThread())
?.subscribe(TranslateObserver())
}
inner class TranslateObserver : Observer<String> {
override fun onSubscribe(d: Disposable) {
_viewState.value = StartState
}
override fun onNext(translatedMessage: String) {
_viewState.value = TranslatedState(translatedMessage)
}
override fun onError(e: Throwable) {
_viewState.value = ErrorState
Log.e(TAG, "Error while translating message", e)
}
override fun onComplete() {
// nothing?
}
}
companion object {
private val TAG = TranslateViewModel::class.simpleName
}
}