diff --git a/app/src/main/java/info/plateaukao/einkbro/activity/BrowserActivity.kt b/app/src/main/java/info/plateaukao/einkbro/activity/BrowserActivity.kt
index 8e594c33..d4ec5029 100755
--- a/app/src/main/java/info/plateaukao/einkbro/activity/BrowserActivity.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/activity/BrowserActivity.kt
@@ -657,8 +657,8 @@ open class BrowserActivity : FragmentActivity(), BrowserController {
override fun translate(translationMode: TranslationMode) {
when (translationMode) {
TranslationMode.TRANSLATE_BY_PARAGRAPH -> translateByParagraph(TRANSLATE_API.GOOGLE)
-
TranslationMode.PAPAGO_TRANSLATE_BY_PARAGRAPH -> translateByParagraph(TRANSLATE_API.PAPAGO)
+ TranslationMode.DEEPL_BY_PARAGRAPH -> translateByParagraph(TRANSLATE_API.DEEPL)
TranslationMode.PAPAGO_TRANSLATE_BY_SCREEN -> translateWebView()
TranslationMode.GOOGLE_IN_PLACE -> ebWebView.addGoogleTranslation()
@@ -674,8 +674,10 @@ open class BrowserActivity : FragmentActivity(), BrowserController {
LanguageSettingDialogFragment(translateApi, translationViewModel) {
if (translateApi == TRANSLATE_API.GOOGLE) {
translateByParagraph(TRANSLATE_API.GOOGLE)
- } else {
+ } else if (translateApi == TRANSLATE_API.PAPAGO) {
translateByParagraph(TRANSLATE_API.PAPAGO)
+ } else if (translateApi == TRANSLATE_API.DEEPL) {
+ translateByParagraph(TRANSLATE_API.DEEPL)
}
}
.show(supportFragmentManager, "LanguageSettingDialog")
@@ -1232,10 +1234,6 @@ open class BrowserActivity : FragmentActivity(), BrowserController {
webView: EBWebView = ebWebView,
) {
translateByParagraphInPlace(translateApi, webView)
-// if (config.enableInplaceParagraphTranslate) {
-// } else {
-// translateByParagraphInReaderMode(translateApi)
-// }
}
private fun translateByParagraphInPlace(
diff --git a/app/src/main/java/info/plateaukao/einkbro/browser/JsWebInterface.kt b/app/src/main/java/info/plateaukao/einkbro/browser/JsWebInterface.kt
index d1b915b0..04ff04a7 100644
--- a/app/src/main/java/info/plateaukao/einkbro/browser/JsWebInterface.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/browser/JsWebInterface.kt
@@ -9,6 +9,7 @@ import info.plateaukao.einkbro.viewmodel.TRANSLATE_API
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent
@@ -23,6 +24,9 @@ class JsWebInterface(private val webView: EBWebView) :
// to control the translation request threshold
private val semaphoreForTranslate = Semaphore(4)
+ // deepL has a limit of 5 requests per second
+ private val semaphoreForDeepL = Semaphore(1)
+
@JavascriptInterface
fun getAnchorPosition(left: Float, top: Float, right: Float, bottom: Float) {
Log.d("touch", "rect: $left, $top, $right, $bottom")
@@ -35,19 +39,32 @@ class JsWebInterface(private val webView: EBWebView) :
val translateApi = webView.translateApi
GlobalScope.launch(Dispatchers.IO) {
- semaphoreForTranslate.acquire()
+ if (translateApi == TRANSLATE_API.DEEPL) {
+ semaphoreForDeepL.acquire()
+ } else {
+ semaphoreForTranslate.acquire()
+ }
+
Log.d("JsWebInterface", "getTranslation: $originalText")
val translatedString = if (translateApi == TRANSLATE_API.PAPAGO) {
- translateRepository.ppTranslate(
+ translateRepository.pTranslate(
originalText,
configManager.translationLanguage.value,
).orEmpty()
- } else {
+ } else if (translateApi == TRANSLATE_API.GOOGLE) {
translateRepository.gTranslateWithApi(
originalText,
configManager.translationLanguage.value
- )
- }.orEmpty()
+ ).orEmpty()
+ } else if (translateApi == TRANSLATE_API.DEEPL) {
+ translateRepository.deepLTranslate(
+ originalText,
+ configManager.translationLanguage
+ ).orEmpty()
+ } else {
+ ""
+ }
+
withContext(Dispatchers.Main) {
if (webView.isAttachedToWindow && translatedString.isNotEmpty()) {
webView.evaluateJavascript(
@@ -56,7 +73,12 @@ class JsWebInterface(private val webView: EBWebView) :
)
}
}
- semaphoreForTranslate.release()
+ if (translateApi == TRANSLATE_API.DEEPL) {
+ delay(300)
+ semaphoreForDeepL.release()
+ } else {
+ semaphoreForTranslate.release()
+ }
}
}
}
diff --git a/app/src/main/java/info/plateaukao/einkbro/preference/ConfigManager.kt b/app/src/main/java/info/plateaukao/einkbro/preference/ConfigManager.kt
index 9b0627c3..60ce667a 100644
--- a/app/src/main/java/info/plateaukao/einkbro/preference/ConfigManager.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/preference/ConfigManager.kt
@@ -230,7 +230,6 @@ class ConfigManager(
K_GPT_USER_PROMPT_WEB_PAGE,
"Summarize in 300 words:"
)
- var papagoApiSecret by StringPreference(sp, K_PAPAGO_API_SECRET, "")
var imageApiKey by StringPreference(sp, K_IMAGE_API_KEY, "")
var gptModel by StringPreference(sp, K_GPT_MODEL, "gpt-3.5-turbo")
var alternativeModel by StringPreference(sp, K_ALTERNATIVE_MODEL, gptModel)
@@ -1082,7 +1081,8 @@ enum class TranslationMode(val labelResId: Int) {
GOOGLE_IN_PLACE(R.string.google_in_place),
TRANSLATE_BY_PARAGRAPH(R.string.translate_by_paragraph),
PAPAGO_TRANSLATE_BY_PARAGRAPH(R.string.papago_translate_by_paragraph),
- PAPAGO_TRANSLATE_BY_SCREEN(R.string.papago_translate_by_screen)
+ PAPAGO_TRANSLATE_BY_SCREEN(R.string.papago_translate_by_screen),
+ DEEPL_BY_PARAGRAPH(R.string.deepl_translate_by_paragraph),
}
enum class FontType(val resId: Int) {
diff --git a/app/src/main/java/info/plateaukao/einkbro/service/TranslateRepository.kt b/app/src/main/java/info/plateaukao/einkbro/service/TranslateRepository.kt
index 288848dc..65442275 100644
--- a/app/src/main/java/info/plateaukao/einkbro/service/TranslateRepository.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/service/TranslateRepository.kt
@@ -4,6 +4,7 @@ import android.graphics.Bitmap
import android.util.Base64
import android.util.Log
import info.plateaukao.einkbro.preference.ConfigManager
+import info.plateaukao.einkbro.util.TranslationLanguage
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
import okhttp3.FormBody
@@ -37,34 +38,6 @@ class TranslateRepository : KoinComponent {
private val client = OkHttpClient()
private val config: ConfigManager by inject()
- suspend fun gTranslateWithWeb(
- text: String,
- targetLanguage: String = "en",
- sourceLanguage: String = "auto",
- ): String? {
- return withContext(IO) {
- val url = HttpUrl.Builder()
- .scheme("https")
- .host("translate.google.com")
- .addPathSegment("m")
- .addQueryParameter("tl", targetLanguage)
- .addQueryParameter("sl", sourceLanguage)
- .addQueryParameter("q", text)
- .build()
-
- val request = Request.Builder().url(url).build()
-
- client.newCall(request).execute().use { response ->
- val body = response.body?.string() ?: return@use null
-
- Jsoup.parse(body)
- .body()
- .getElementsByClass("result-container")
- .first()?.text()
- }
- }
- }
-
private fun getICount(translateText: String): Int {
return translateText.split("i").size - 1
}
@@ -98,9 +71,16 @@ class TranslateRepository : KoinComponent {
suspend fun deepLTranslate(
text: String,
- targetLanguage: String = "zh",
- sourceLanguage: String = "auto",
+ targetLanguage: TranslationLanguage,
): String? {
+ val target = when (targetLanguage) {
+ TranslationLanguage.ZH_TW,
+ TranslationLanguage.ZH_CN,
+ -> "zh"
+
+ else -> config.translationLanguage.value
+ }
+
val headers = Headers.Builder()
.add("content-type", "application/json")
.build()
@@ -113,8 +93,8 @@ class TranslateRepository : KoinComponent {
put("params", JSONObject().apply {
put("splitting", "newlines")
put("lang", JSONObject().apply {
- put("source_lang_user_selected", sourceLanguage.uppercase(Locale.getDefault()))
- put("target_lang", targetLanguage.uppercase(Locale.getDefault()))
+ put("source_lang_user_selected", "AUTO")
+ put("target_lang", target.uppercase(Locale.getDefault()))
})
put("texts", JSONArray().apply {
put(JSONObject().apply {
@@ -195,42 +175,6 @@ class TranslateRepository : KoinComponent {
}
}
- suspend fun pTranslate(
- text: String,
- targetLanguage: String = "en",
- sourceLanguage: String = "auto",
- ): String? {
- return withContext(IO) {
- val request = Request.Builder()
- .url("https://openapi.naver.com/v1/papago/n2mt")
- .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
- .addHeader("X-Naver-Client-Id", "wCrZZHNa1x_wi8tkGERB")
- .addHeader("X-Naver-Client-Secret", config.papagoApiSecret)
- .post(
- FormBody.Builder()
- .add("source", sourceLanguage)
- .add("target", targetLanguage)
- .add("text", text)
- .build()
- )
- .build()
-
- try {
- client.newCall(request).execute().use { response ->
- if (!response.isSuccessful) return@use null
-
- val body = JSONObject(response.body?.string() ?: return@use null)
- body.getJSONObject("message")
- .getJSONObject("result")
- .getString("translatedText")
- }
- } catch (e: Exception) {
- Log.e("TranslateRepository", "pTranslate: $e")
- null
- }
- }
- }
-
private fun getAuthKey(): String? {
val url = "https://papago.naver.com"
val response = client.newCall(Request.Builder().url(url).build()).execute()
@@ -255,7 +199,7 @@ class TranslateRepository : KoinComponent {
}
private var authKey: String? = null
- suspend fun ppTranslate(
+ suspend fun pTranslate(
text: String,
targetLanguage: String = "en",
sourceLanguage: String = "auto",
@@ -313,52 +257,6 @@ class TranslateRepository : KoinComponent {
}
}
- suspend fun pDetectLanguage(text: String): String? {
- if (authKey == null) {
- authKey = getAuthKey()
- }
- val key = authKey?.toByteArray(Charsets.UTF_8) ?: return ""
-
- val guid = UUID.randomUUID()
- val timestamp = System.currentTimeMillis()
- val code = "$guid\n$DETECT_LANGUAGE_URL\n$timestamp".toByteArray(Charsets.UTF_8)
- val hmac = Mac.getInstance("HmacMD5")
- val secretKeySpec = SecretKeySpec(key, "HmacMD5")
- hmac.init(secretKeySpec)
- val token = Base64.encodeToString(hmac.doFinal(code), Base64.DEFAULT)
-
- return withContext(IO) {
- val request = Request.Builder()
- .url(DETECT_LANGUAGE_URL)
- .addHeader("device-type", "pc")
- .addHeader("x-apigw-partnerid", "papago")
- .addHeader("Origin", "https://papago.naver.com")
- .addHeader("Referer", "https://papago.naver.com")
- .addHeader("Authorization", "PPG $guid:$token".replace("\n", ""))
- .addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
- .addHeader("Timestamp", timestamp.toString())
- .post(
- FormBody.Builder()
- .add("query", text)
- .build()
- )
- .build()
-
- try {
- client.newCall(request).execute().use { response ->
- if (!response.isSuccessful) return@use null
-
- val body = JSONObject(response.body?.string() ?: return@use null)
- body.getString("langCode")
- }
- } catch (e: Exception) {
- Log.d("TranslateRepository", "pDetectLanguage: $e")
- null
- }
- }
- }
-
-
private val sid: String by lazy { "${P_IMAGE_API_VERSION}${UUID.randomUUID()}" }
private fun signUrl(url: String): Signature {
diff --git a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ContextMenuDialogFragment.kt b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ContextMenuDialogFragment.kt
index 0b508eeb..c65a1804 100644
--- a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ContextMenuDialogFragment.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ContextMenuDialogFragment.kt
@@ -151,7 +151,8 @@ private fun ContextMenuItems(
ContextMenuItem(R.string.text_select, showIcons, Icons.AutoMirrored.Outlined.Segment) {
onClicked(SelectText)
}
- if (shouldShowTranslateImage && (url.endsWith(".jpg") || url.endsWith(".png"))) {
+ val lowerCaseUrl = url.lowercase()
+ if (shouldShowTranslateImage && (lowerCaseUrl.contains("jpg") || lowerCaseUrl.contains("png"))) {
ContextMenuItem(R.string.translate, showIcons, iconResId = R.drawable.ic_papago) {
onClicked(TranslateImage)
}
diff --git a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ToolbarConfigDialogFragment.kt b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ToolbarConfigDialogFragment.kt
index 22e3d02b..3716668b 100644
--- a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ToolbarConfigDialogFragment.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/ToolbarConfigDialogFragment.kt
@@ -98,7 +98,7 @@ class ToolbarConfigDialogFragment : ComposeDialogFragment() {
.filter { it.isAddable }
.filterNot { config.toolbarActions.contains(it) }
// hide papago action if papago api key is not set
- .filterNot { config.papagoApiSecret.isBlank() && it == ToolbarAction.PapagoByParagraph }
+ .filterNot { config.imageApiKey.isBlank() && it == ToolbarAction.PapagoByParagraph }
.map { ToolbarActionItemInfo(it, false) }
}
diff --git a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslateDialogFragment.kt b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslateDialogFragment.kt
index 35a5b96d..28052ae1 100644
--- a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslateDialogFragment.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslateDialogFragment.kt
@@ -77,7 +77,7 @@ class TranslateDialogFragment(
MyTheme {
TranslateResponse(
translationViewModel,
- showExtraIcons = config.papagoApiSecret.isNotBlank(),
+ showExtraIcons = config.imageApiKey.isNotBlank(),
this::changeTranslationLanguage,
this::getTranslationWebView,
closeAction ?: { dismiss() }
@@ -163,9 +163,9 @@ private fun TranslateResponse(
if (ViewUnit.isTablet(LocalContext.current)) {
GptRow(viewModel)
}
- DeepLButton(iconSize, iconPadding, translateDeepL, onTargetLanguageClick)
GoogleButton(iconSize, iconPadding, translateGoogle, onTargetLanguageClick)
if (showExtraIcons) {
+ DeepLButton(iconSize, iconPadding, translateDeepL, onTargetLanguageClick)
PapagoButton(iconSize, iconPadding, translatePapago, onTargetLanguageClick)
NaverButton(iconSize, iconPadding, translateNaver)
}
diff --git a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslationConfigDlgFragment.kt b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslationConfigDlgFragment.kt
index a88c029d..bc09f628 100644
--- a/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslationConfigDlgFragment.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/view/dialog/compose/TranslationConfigDlgFragment.kt
@@ -92,15 +92,16 @@ fun TranslationConfigScreen(
expanded = actionExpanded,
onDismissRequest = { actionExpanded = false }
) {
- TranslationMode.entries.forEach { type ->
- val text = context.getString(type.labelResId)
- DropdownMenuItem(onClick = {
- translationModeChanged(type)
- actionExpanded = false
- }) {
- Text(text = text)
+ TranslationMode.entries.toMutableList().apply { remove(TranslationMode.DEEPL_BY_PARAGRAPH) }
+ .forEach { type ->
+ val text = context.getString(type.labelResId)
+ DropdownMenuItem(onClick = {
+ translationModeChanged(type)
+ actionExpanded = false
+ }) {
+ Text(text = text)
+ }
}
- }
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/info/plateaukao/einkbro/view/handlers/ToolbarActionHandler.kt b/app/src/main/java/info/plateaukao/einkbro/view/handlers/ToolbarActionHandler.kt
index 9240da04..0a900c94 100644
--- a/app/src/main/java/info/plateaukao/einkbro/view/handlers/ToolbarActionHandler.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/view/handlers/ToolbarActionHandler.kt
@@ -24,14 +24,6 @@ class ToolbarActionHandler(
ToolbarAction.BoldFont -> browserController.showFontBoldnessDialog()
ToolbarAction.Bookmark -> browserController.saveBookmark()
ToolbarAction.Font -> browserController.toggleReaderMode()
- ToolbarAction.InputUrl -> {
- // toggle papago translate
- if (config.papagoApiSecret.isBlank()) {
- config.papagoApiSecret = "123"
- } else {
- config.papagoApiSecret = ""
- }
- }
ToolbarAction.NewTab -> IntentUnit.launchNewBrowser(activity, config.favoriteUrl)
ToolbarAction.PageDown -> browserController.jumpToBottom()
ToolbarAction.PageInfo -> browserController.summarizeContent()
diff --git a/app/src/main/java/info/plateaukao/einkbro/view/viewControllers/TwoPaneController.kt b/app/src/main/java/info/plateaukao/einkbro/view/viewControllers/TwoPaneController.kt
index b2e28792..36fc1fa3 100644
--- a/app/src/main/java/info/plateaukao/einkbro/view/viewControllers/TwoPaneController.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/view/viewControllers/TwoPaneController.kt
@@ -182,8 +182,11 @@ class TwoPaneController(
EBToast.showShort(activity, "No more supported")
TranslationMode.GOOGLE_IN_PLACE -> webView.addGoogleTranslation()
+
TranslationMode.TRANSLATE_BY_PARAGRAPH -> translateByParagraph(TRANSLATE_API.GOOGLE, webView)
TranslationMode.PAPAGO_TRANSLATE_BY_PARAGRAPH -> translateByParagraph(TRANSLATE_API.PAPAGO, webView)
+ TranslationMode.DEEPL_BY_PARAGRAPH -> translateByParagraph(TRANSLATE_API.DEEPL, webView)
+
TranslationMode.PAPAGO_TRANSLATE_BY_SCREEN -> translateByScreen()
}
}
@@ -251,7 +254,7 @@ class TwoPaneController(
remove(TranslationMode.ONYX)
remove(TranslationMode.PAPAGO)
remove(TranslationMode.GOOGLE)
- if (config.papagoApiSecret.isBlank()) {
+ if (config.imageApiKey.isBlank()) {
remove(TranslationMode.PAPAGO_TRANSLATE_BY_PARAGRAPH)
remove(TranslationMode.PAPAGO_TRANSLATE_BY_SCREEN)
}
@@ -331,7 +334,7 @@ class TwoPaneController(
private fun toggleTranslationWindow(
- isEnabled: Boolean, onTranslationClosed: () -> Unit = {}
+ isEnabled: Boolean, onTranslationClosed: () -> Unit = {},
) {
if (!isEnabled) {
webView.loadUrl(BrowserUnit.URL_ABOUT_BLANK)
diff --git a/app/src/main/java/info/plateaukao/einkbro/viewmodel/ActionModeMenuViewModel.kt b/app/src/main/java/info/plateaukao/einkbro/viewmodel/ActionModeMenuViewModel.kt
index febec893..49315324 100644
--- a/app/src/main/java/info/plateaukao/einkbro/viewmodel/ActionModeMenuViewModel.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/viewmodel/ActionModeMenuViewModel.kt
@@ -104,7 +104,7 @@ class ActionModeMenuViewModel : ViewModel(), KoinComponent {
val menuInfos = resolveInfos.map { it.toMenuInfo(packageManager) }.toMutableList()
- if (configManager.papagoApiSecret.isNotEmpty()) {
+ if (configManager.imageApiKey.isNotEmpty()) {
menuInfos.add(
0,
MenuInfo(
@@ -131,14 +131,16 @@ class ActionModeMenuViewModel : ViewModel(), KoinComponent {
action = { _actionModeMenuState.value = ActionModeMenuState.GoogleTranslate }
)
)
- menuInfos.add(
- 0,
- MenuInfo(
- context.getString(R.string.deepl_translate),
- drawable = ContextCompat.getDrawable(context, R.drawable.ic_translate),
- action = { _actionModeMenuState.value = ActionModeMenuState.DeeplTranslate }
+ if (configManager.imageApiKey.isNotBlank()) {
+ menuInfos.add(
+ 0,
+ MenuInfo(
+ context.getString(R.string.deepl_translate),
+ drawable = ContextCompat.getDrawable(context, R.drawable.ic_translate),
+ action = { _actionModeMenuState.value = ActionModeMenuState.DeeplTranslate }
+ )
)
- )
+ }
if (configManager.gptActionList.isNotEmpty()) {
configManager.gptActionList.mapIndexed { index, actionInfo ->
diff --git a/app/src/main/java/info/plateaukao/einkbro/viewmodel/TranslationViewModel.kt b/app/src/main/java/info/plateaukao/einkbro/viewmodel/TranslationViewModel.kt
index adc10212..e1316450 100644
--- a/app/src/main/java/info/plateaukao/einkbro/viewmodel/TranslationViewModel.kt
+++ b/app/src/main/java/info/plateaukao/einkbro/viewmodel/TranslationViewModel.kt
@@ -199,19 +199,9 @@ class TranslationViewModel : ViewModel(), KoinComponent {
private fun callDeepLTranslate() {
val message = _inputMessage.value
viewModelScope.launch(Dispatchers.IO) {
- val targetLanguage = when (config.translationLanguage) {
- TranslationLanguage.ZH_TW,
- TranslationLanguage.ZH_CN,
- -> "zh"
-
- else -> config.translationLanguage.value
- }
_responseMessage.value =
AnnotatedString(
- translateRepository.deepLTranslate(
- message,
- targetLanguage = targetLanguage,
- )
+ translateRepository.deepLTranslate(message, targetLanguage = config.translationLanguage)
?: "Something went wrong."
)
}
@@ -222,10 +212,7 @@ class TranslationViewModel : ViewModel(), KoinComponent {
viewModelScope.launch(Dispatchers.IO) {
_responseMessage.value =
AnnotatedString(
- translateRepository.ppTranslate(
- message,
- targetLanguage = config.translationLanguage.value,
- )
+ translateRepository.pTranslate(message, targetLanguage = config.translationLanguage.value)
?: "Something went wrong."
)
}
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index b377386d..560fdf9b 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -590,4 +590,5 @@
Choose the style you like for paragraph translation
Gray
Bold
+ Deepl by Paragraph
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index cca4aef0..293ebe3e 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -572,4 +572,5 @@
Choose the style you like for paragraph translation
Gray
Bold
+ Deepl by Paragraph
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index d282bc41..8263cc01 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -504,4 +504,5 @@
選擇想要的文字區塊外觀
灰色字體
粗體字
+ Deepl by Paragraph
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a4029a13..db2156f6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -593,4 +593,5 @@
Choose the style you like for paragraph translation
Gray
Bold
+ Deepl by Paragraph