diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9ce563ec..05ab0ba8e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -189,6 +189,10 @@ android:name=".location.GeocodingActivity" android:theme="@style/AppTheme" /> + + 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 6204f5218..2b41e9caa 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java +++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java @@ -44,6 +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.settings.SignalingSettingsOverall; import com.nextcloud.talk.models.json.status.StatusOverall; +import com.nextcloud.talk.models.json.translations.TranslationsOverall; import com.nextcloud.talk.models.json.unifiedsearch.UnifiedSearchOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileOverall; @@ -654,4 +655,18 @@ public interface NcApi { @DELETE Observable sendCommonDeleteRequest(@Header("Authorization") String authorization, @Url String url); + + @POST + Observable translateMessage(@Header("Authorization") String authorization, + @Url String url, + @Field("text") String text, + @Field("fromLanguage") String fromLanguage, + @Field("toLanguage") String toLanguage); + +// @GET +// Observable getLanguageOptions(@Header("Authorization") String authorization, +// @Url String url, +// @Field("languageDetection") String fromLanguage, +// @Field("languages") Object languages[]); + // TODO finish ^ function declaration } diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 292911191..4827ac978 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -150,6 +150,7 @@ import com.nextcloud.talk.remotefilebrowser.activities.RemoteFileBrowserActivity import com.nextcloud.talk.repositories.reactions.ReactionsRepository import com.nextcloud.talk.shareditems.activities.SharedItemsActivity import com.nextcloud.talk.signaling.SignalingMessageReceiver +import com.nextcloud.talk.translate.TranslateActivity import com.nextcloud.talk.ui.bottom.sheet.ProfileBottomSheet import com.nextcloud.talk.ui.dialog.AttachmentDialog import com.nextcloud.talk.ui.dialog.MessageActionsDialog @@ -3231,6 +3232,16 @@ class ChatActivity : clipboardManager.setPrimaryClip(clipData) } + fun translateMessage(message: IMessage?) { + val bundle = Bundle() + bundle.putString(BundleKeys.KEY_TRANSLATE_MESSAGE, message?.text) + + val intent = Intent(this, TranslateActivity::class.java) + intent.putExtras(bundle) + startActivity(intent) + + } + private fun hasVisibleItems(message: ChatMessage): Boolean { return !message.isDeleted || // copy message message.replyable || // reply to diff --git a/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslateData.kt b/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslateData.kt new file mode 100644 index 000000000..761562e22 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslateData.kt @@ -0,0 +1,19 @@ +package com.nextcloud.talk.models.json.translations + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class TranslateData( + + @JsonField(name = ["text"]) + var text: String?, + @JsonField(name = ["from"]) + var fromLanguage: String? +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : this(null, null ) +} \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslateOCS.kt b/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslateOCS.kt new file mode 100644 index 000000000..608eeeb94 --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslateOCS.kt @@ -0,0 +1,19 @@ +package com.nextcloud.talk.models.json.translations + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import com.nextcloud.talk.models.json.generic.GenericMeta +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +data class TranslateOCS( // TODO finish this model + @JsonField(name = ["meta"]) + var meta: GenericMeta?, + @JsonField(name = ["data"]) + var data: TranslateData? +) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : this(null, TranslateData()) +} \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslationsOverall.kt b/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslationsOverall.kt new file mode 100644 index 000000000..8fbc9b80d --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/models/json/translations/TranslationsOverall.kt @@ -0,0 +1,16 @@ +package com.nextcloud.talk.models.json.translations + +import android.os.Parcelable +import com.bluelinelabs.logansquare.annotation.JsonField +import com.bluelinelabs.logansquare.annotation.JsonObject +import kotlinx.parcelize.Parcelize + +@Parcelize +@JsonObject +class TranslationsOverall( + @JsonField(name = ["ocs"]) + var ocs: TranslateOCS? + ) : Parcelable { + // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' + constructor() : this(null) + } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/translate/TranslateActivity.kt b/app/src/main/java/com/nextcloud/talk/translate/TranslateActivity.kt new file mode 100644 index 000000000..baf5f6fdb --- /dev/null +++ b/app/src/main/java/com/nextcloud/talk/translate/TranslateActivity.kt @@ -0,0 +1,136 @@ +package com.nextcloud.talk.translate +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.text.method.ScrollingMovementMethod +import android.view.View +import autodagger.AutoInjector +import com.nextcloud.talk.R +import com.nextcloud.talk.activities.BaseActivity +import com.nextcloud.talk.api.NcApi +import com.nextcloud.talk.application.NextcloudTalkApplication +import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.databinding.ActivityTranslateBinding +import com.nextcloud.talk.users.UserManager +import com.nextcloud.talk.utils.bundle.BundleKeys +import javax.inject.Inject + + + +// TODO include license at top of the file + + +@AutoInjector(NextcloudTalkApplication::class) +class TranslateActivity : BaseActivity() +{ + private lateinit var binding: ActivityTranslateBinding + + @Inject + lateinit var ncApi: NcApi + + @Inject + lateinit var userManager: UserManager + + lateinit var currentUser: User + + val url : String? = currentUser.baseUrl + "/translation" + + var text : String? = null + + var fromLanguage : String = "en" + + val toLanguage : String = "de" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityTranslateBinding.inflate(layoutInflater) + + + setupTextViews() + setupActionBar() + setupSpinners() + setContentView(binding.root) + // translate() + } + + private fun setupActionBar() { + setSupportActionBar(binding.translationToolbar) + binding.translationToolbar.setNavigationOnClickListener { + onBackPressed() + } + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + supportActionBar?.setIcon(ColorDrawable(resources!!.getColor(R.color.transparent))) + supportActionBar?.title = "Translation" + viewThemeUtils.material.themeToolbar(binding.translationToolbar) + } + + private fun setupTextViews() { + val original = binding.originalMessageTextview + val translation = binding.translatedMessageTextview + + original.movementMethod = ScrollingMovementMethod() + translation.movementMethod = ScrollingMovementMethod() + + val bundle = intent.extras + binding.originalMessageTextview.text = bundle?.getString(BundleKeys.KEY_TRANSLATE_MESSAGE) + text = binding.originalMessageTextview.text as String? + } + + + private fun getLanguageOptions() { + // TODO implement this function to retrieve an array of strings from the server for each language option + // this uses another call to their /languages endpoint which requires another separate function in ncAPI and + // seprarate models for the JSON :| + } + + // TODO get this function working + // private fun translate() { + // val credentials = ApiUtils.getCredentials(currentUser.username, currentUser.token) + // + // val translateURL = url + "/translate" + // + // + // + // ncApi.translateMessage(credentials, translateURL, text, fromLanguage, toLanguage) + // ?.subscribeOn(Schedulers.io()) + // ?.observeOn(AndroidSchedulers.mainThread()) + // ?.subscribe(object : Observer { + // override fun onSubscribe(d: Disposable) { + // // TODO set progress bar to show + // binding.translatedMessageTextview.visibility = View.GONE + // binding.progressBar.visibility = View.VISIBLE + // } + // + // override fun onNext(translationOverall: TranslationsOverall) { + // // TODO hide progress bar + // binding.progressBar.visibility = View.GONE + // binding.translatedMessageTextview.visibility = View.VISIBLE + // binding.translatedMessageTextview.text = translationOverall.ocs?.data?.text + // } + // + // override fun onError(e: Throwable) { + // Log.e("TranslateActivity", "Error") + // } + // + // override fun onComplete() { + // // not needed? + // } + // }) + // + // } + + private fun setupSpinners() { + // TODO set spinner options to use array from getLanguageOptions() + + // TODO set onClickListener to call server using translate() + binding.toLanguageSpinner.setOnClickListener(View.OnClickListener { + // translate() + }) + + binding.fromLanguageSpinner.setOnClickListener(View.OnClickListener { + // translate() + }) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt index 9b93117fc..dbf59af04 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/MessageActionsDialog.kt @@ -88,6 +88,7 @@ class MessageActionsDialog( viewThemeUtils.platform.themeDialog(dialogMessageActionsBinding.root) initEmojiBar(hasChatPermission) initMenuItemCopy(!message.isDeleted) + initMenuItemTranslate(!message.isDeleted) initMenuReplyToMessage(message.replyable && hasChatPermission) initMenuReplyPrivately( message.replyable && @@ -296,6 +297,17 @@ class MessageActionsDialog( dialogMessageActionsBinding.menuCopyMessage.visibility = getVisibility(visible) } + private fun initMenuItemTranslate(visible: Boolean) { + if (visible) { + dialogMessageActionsBinding.menuTranslateMessage.setOnClickListener { + chatActivity.translateMessage(message) + dismiss() + } + } + + dialogMessageActionsBinding.menuCopyMessage.visibility = getVisibility(visible) + } + private fun getVisibility(visible: Boolean): Int { return if (visible) { View.VISIBLE diff --git a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt index dc6a893d3..88f8acb4a 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/bundle/BundleKeys.kt @@ -29,6 +29,7 @@ object BundleKeys { const val KEY_SELECTED_EMAILS = "KEY_SELECTED_EMAILS" const val KEY_USERNAME = "KEY_USERNAME" const val KEY_TOKEN = "KEY_TOKEN" + const val KEY_TRANSLATE_MESSAGE = "KEY_TRANSLATE_MESSAGE" const val KEY_BASE_URL = "KEY_BASE_URL" const val KEY_IS_ACCOUNT_IMPORT = "KEY_IS_ACCOUNT_IMPORT" const val KEY_ORIGINAL_PROTOCOL = "KEY_ORIGINAL_PROTOCOL" diff --git a/app/src/main/res/drawable/ic_baseline_translate_24.xml b/app/src/main/res/drawable/ic_baseline_translate_24.xml new file mode 100644 index 000000000..1a73c2d64 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_translate_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_translate.xml b/app/src/main/res/layout/activity_translate.xml new file mode 100644 index 000000000..806d24178 --- /dev/null +++ b/app/src/main/res/layout/activity_translate.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_message_actions.xml b/app/src/main/res/layout/dialog_message_actions.xml index ebd2987f0..ebbf99827 100644 --- a/app/src/main/res/layout/dialog_message_actions.xml +++ b/app/src/main/res/layout/dialog_message_actions.xml @@ -287,6 +287,39 @@ + + + + + + + + You are not allowed to activate audio! You are not allowed to activate video! Scroll to bottom + Translate + Translation