diff --git a/.idea/other.xml b/.idea/other.xml
index 4604c44..94c96f6 100644
--- a/.idea/other.xml
+++ b/.idea/other.xml
@@ -69,6 +69,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -91,6 +113,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -102,6 +135,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -146,6 +190,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -235,6 +290,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/com/starry/myne/epub/EpubParser.kt b/app/src/main/java/com/starry/myne/epub/EpubParser.kt
index 4117e12..633748f 100644
--- a/app/src/main/java/com/starry/myne/epub/EpubParser.kt
+++ b/app/src/main/java/com/starry/myne/epub/EpubParser.kt
@@ -319,7 +319,7 @@ class EpubParser {
val emptyChapters = totalChapters - chapters.size
if (emptyChapters.toDouble() / totalChapters >= emptyChapterThreshold) {
- Log.w(TAG, "More than 60% of chapters have empty bodies. Switching to spine-based parsing.")
+ Log.w(TAG, "25% or more chapters have empty bodies; switching to spine-based parsing")
return parseUsingSpine(document.spine, manifestItems, files)
}
diff --git a/app/src/main/java/com/starry/myne/ui/common/MyneTextSelectionContainer.kt b/app/src/main/java/com/starry/myne/ui/common/MyneTextSelectionContainer.kt
new file mode 100644
index 0000000..3a423cc
--- /dev/null
+++ b/app/src/main/java/com/starry/myne/ui/common/MyneTextSelectionContainer.kt
@@ -0,0 +1,316 @@
+/**
+ * Copyright (c) [2022 - Present] Stɑrry Shivɑm
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.starry.myne.ui.common
+
+import android.content.ClipData
+import android.content.ClipboardManager
+import android.content.Context
+import android.view.ActionMode
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.text.selection.SelectionContainer
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalTextToolbar
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.TextToolbar
+import androidx.compose.ui.platform.TextToolbarStatus
+import com.starry.myne.R
+
+
+private const val MENU_ITEM_COPY = 0
+private const val MENU_ITEM_SHARE = 1
+private const val MENU_ITEM_WEB = 2
+private const val MENU_ITEM_TRANSLATE = 3
+private const val MENU_ITEM_DICTIONARY = 4
+
+/**
+ * Custom Text ActionMode callback. Used in pair with [MyneSelectionToolbar]. Follow [TextToolbar] for more info.
+ */
+private class MyneTextActionModeCallback(
+ private val context: Context,
+ var rect: Rect = Rect.Zero,
+ var onCopyRequested: (() -> Unit)? = null,
+ var onShareRequested: (() -> Unit)? = null,
+ var onWebSearchRequested: (() -> Unit)? = null,
+ var onTranslateRequested: (() -> Unit)? = null,
+ var onDictionaryRequested: (() -> Unit)? = null
+) : ActionMode.Callback {
+ override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+ requireNotNull(menu)
+ requireNotNull(mode)
+
+ onCopyRequested?.let {
+ menu.add(0, MENU_ITEM_COPY, 0, context.getString(R.string.copy))
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
+ }
+
+ onShareRequested?.let {
+ menu.add(0, MENU_ITEM_SHARE, 1, context.getString(R.string.share))
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
+ }
+
+ onWebSearchRequested?.let {
+ menu.add(0, MENU_ITEM_WEB, 2, context.getString(R.string.web_search))
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
+ }
+
+ onTranslateRequested?.let {
+ menu.add(0, MENU_ITEM_TRANSLATE, 3, context.getString(R.string.translate))
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
+ }
+
+ onDictionaryRequested?.let {
+ menu.add(0, MENU_ITEM_DICTIONARY, 4, context.getString(R.string.dictionary))
+ .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
+ }
+
+ return true
+ }
+
+ override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+ return false
+ }
+
+ override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
+ when (item!!.itemId) {
+ MENU_ITEM_COPY -> onCopyRequested?.invoke()
+ MENU_ITEM_SHARE -> onShareRequested?.invoke()
+ MENU_ITEM_WEB -> onWebSearchRequested?.invoke()
+ MENU_ITEM_TRANSLATE -> onTranslateRequested?.invoke()
+ MENU_ITEM_DICTIONARY -> onDictionaryRequested?.invoke()
+ else -> return false
+ }
+ mode?.finish()
+ return true
+ }
+
+ override fun onDestroyActionMode(mode: ActionMode?) {}
+}
+
+/**
+ * Floating [MyneTextActionModeCallback].
+ */
+private class FloatingTextActionModeCallback(
+ val callback: MyneTextActionModeCallback
+) : ActionMode.Callback2() {
+ override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
+ return callback.onActionItemClicked(mode, item)
+ }
+
+ override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+ return callback.onCreateActionMode(mode, menu)
+ }
+
+ override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
+ return callback.onPrepareActionMode(mode, menu)
+ }
+
+ override fun onDestroyActionMode(mode: ActionMode?) {
+ callback.onDestroyActionMode(mode)
+ }
+
+ override fun onGetContentRect(mode: ActionMode?, view: View?, outRect: android.graphics.Rect?) {
+ val rect = callback.rect
+ outRect?.set(
+ rect.left.toInt(),
+ rect.top.toInt(),
+ rect.right.toInt(),
+ rect.bottom.toInt()
+ )
+ }
+}
+
+/**
+ * Custom Selection Toolbar.
+ * Used in pair with [MyneSelectionContainer] to display custom toolbar.
+ */
+@Suppress("DEPRECATION")
+private class MyneSelectionToolbar(
+ private val view: View,
+ context: Context,
+ private val onCopyRequest: (() -> Unit)?,
+ private val onShareRequest: ((String) -> Unit)?,
+ private val onWebSearchRequest: ((String) -> Unit)?,
+ private val onTranslateRequest: ((String) -> Unit)?,
+ private val onDictionaryRequest: ((String) -> Unit)?
+) : TextToolbar {
+ private var actionMode: ActionMode? = null
+ private val callback = MyneTextActionModeCallback(context = context)
+
+ val clipboardManager =
+ context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
+
+ override var status: TextToolbarStatus by mutableStateOf(TextToolbarStatus.Hidden)
+
+ override fun showMenu(
+ rect: Rect,
+ onCopyRequested: (() -> Unit)?,
+ onPasteRequested: (() -> Unit)?,
+ onCutRequested: (() -> Unit)?,
+ onSelectAllRequested: (() -> Unit)?
+ ) {
+ callback.rect = rect
+ callback.onCopyRequested = {
+ onCopyRequested?.invoke()
+ onCopyRequest?.invoke()
+ }
+ callback.onShareRequested = {
+ val previousClipboard = clipboardManager.primaryClip
+ onCopyRequested?.invoke()
+ val currentClipboard = clipboardManager.text
+
+ onShareRequest?.invoke(currentClipboard.toString())
+
+ if (previousClipboard != null) {
+ clipboardManager.setPrimaryClip(
+ previousClipboard
+ )
+ } else {
+ clipboardManager.setPrimaryClip(ClipData.newPlainText(null, " "))
+ }
+ }
+ callback.onWebSearchRequested = {
+ val previousClipboard = clipboardManager.primaryClip
+ onCopyRequested?.invoke()
+ val currentClipboard = clipboardManager.text
+
+ onWebSearchRequest?.invoke(currentClipboard.toString())
+
+ if (previousClipboard != null) {
+ clipboardManager.setPrimaryClip(
+ previousClipboard
+ )
+ } else {
+ clipboardManager.setPrimaryClip(ClipData.newPlainText(null, " "))
+ }
+ }
+ callback.onTranslateRequested = {
+ val previousClipboard = clipboardManager.primaryClip
+ onCopyRequested?.invoke()
+ val currentClipboard = clipboardManager.text
+
+ onTranslateRequest?.invoke(currentClipboard.toString())
+
+ if (previousClipboard != null) {
+ clipboardManager.setPrimaryClip(
+ previousClipboard
+ )
+ } else {
+ clipboardManager.setPrimaryClip(ClipData.newPlainText(null, " "))
+ }
+ }
+ callback.onDictionaryRequested = {
+ val previousClipboard = clipboardManager.primaryClip
+ onCopyRequested?.invoke()
+ val currentClipboard = clipboardManager.text
+
+ onDictionaryRequest?.invoke(currentClipboard.toString())
+
+ if (previousClipboard != null) {
+ clipboardManager.setPrimaryClip(
+ previousClipboard
+ )
+ } else {
+ clipboardManager.setPrimaryClip(ClipData.newPlainText(null, " "))
+ }
+ }
+
+ if (actionMode == null) {
+ status = TextToolbarStatus.Shown
+ actionMode = view.startActionMode(
+ FloatingTextActionModeCallback(callback),
+ ActionMode.TYPE_FLOATING
+ )
+ } else {
+ actionMode?.invalidate()
+ }
+ }
+
+ override fun hide() {
+ status = TextToolbarStatus.Hidden
+ actionMode?.finish()
+ actionMode = null
+ }
+}
+
+/**
+ * Custom selection container.
+ *
+ * @param onCopyRequested Callback for when the copy option is clicked.
+ * @param onTranslateRequested Callback for when the translate option is clicked.
+ * @param onDictionaryRequested Callback for when the dictionary option is clicked.
+ * @param content Selection container content.
+ */
+@Composable
+fun MyneSelectionContainer(
+ onCopyRequested: (() -> Unit),
+ onShareRequested: ((String) -> Unit),
+ onWebSearchRequested: ((String) -> Unit),
+ onTranslateRequested: ((String) -> Unit),
+ onDictionaryRequested: ((String) -> Unit),
+ content: @Composable (toolbarHidden: Boolean) -> Unit
+) {
+ val view = LocalView.current
+ val context = LocalContext.current
+
+ val myneSelectionToolbar = remember {
+ MyneSelectionToolbar(
+ view = view,
+ context = context,
+
+ onCopyRequest = {
+ onCopyRequested()
+ },
+ onShareRequest = {
+ onShareRequested(it)
+ },
+ onWebSearchRequest = {
+ onWebSearchRequested(it)
+ },
+ onTranslateRequest = {
+ onTranslateRequested(it)
+ },
+ onDictionaryRequest = {
+ onDictionaryRequested(it)
+ }
+ )
+ }
+ val isToolbarHidden = remember(myneSelectionToolbar.status) {
+ derivedStateOf {
+ myneSelectionToolbar.status == TextToolbarStatus.Hidden
+ }
+ }
+
+ CompositionLocalProvider(
+ LocalTextToolbar provides myneSelectionToolbar
+ ) {
+ SelectionContainer(Modifier.fillMaxSize()) {
+ content(isToolbarHidden.value)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/starry/myne/ui/screens/reader/composables/ReaderContent.kt b/app/src/main/java/com/starry/myne/ui/screens/reader/composables/ReaderContent.kt
index 0f2a136..63e1cc6 100644
--- a/app/src/main/java/com/starry/myne/ui/screens/reader/composables/ReaderContent.kt
+++ b/app/src/main/java/com/starry/myne/ui/screens/reader/composables/ReaderContent.kt
@@ -16,6 +16,11 @@
package com.starry.myne.ui.screens.reader.composables
+import android.app.SearchManager
+import android.content.ActivityNotFoundException
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.gestures.awaitEachGesture
@@ -29,7 +34,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
-import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -47,8 +51,11 @@ import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import coil.request.ImageRequest
+import com.starry.myne.R
import com.starry.myne.epub.BookTextMapper
import com.starry.myne.epub.models.EpubChapter
+import com.starry.myne.helpers.toToast
+import com.starry.myne.ui.common.MyneSelectionContainer
import com.starry.myne.ui.screens.reader.viewmodels.ReaderScreenState
import com.starry.myne.ui.screens.reader.viewmodels.ReaderViewModel
import com.starry.myne.ui.theme.pacificoFont
@@ -85,8 +92,10 @@ private fun ChapterLazyItemItem(
state: ReaderScreenState,
onClick: () -> Unit
) {
+ val context = LocalContext.current
val epubBook = state.epubBook
val paragraphs = remember { chunkText(chapter.body) }
+
val targetFontSize = (state.fontSize / 10) * 1.8f
val fontSize by animateFloatAsState(
targetValue = targetFontSize,
@@ -94,12 +103,80 @@ private fun ChapterLazyItemItem(
label = "fontSize"
)
val titleFontSize by animateFloatAsState(
- targetValue = targetFontSize * 1.5f,
+ targetValue = targetFontSize * 1.4f,
animationSpec = tween(durationMillis = 300),
label = "titleFontSize"
)
- SelectionContainer {
+ MyneSelectionContainer(
+ onCopyRequested = {
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
+ context.getString(R.string.copied).toToast(context)
+ }
+ },
+ onShareRequested = {
+ val intent = Intent().apply {
+ action = Intent.ACTION_SEND
+ putExtra(Intent.EXTRA_TEXT, it)
+ type = "text/plain"
+ }
+ try {
+ context.startActivity(Intent.createChooser(intent, null))
+ } catch (e: ActivityNotFoundException) {
+ context.getString(R.string.no_app_to_handle_content).toToast(context)
+ }
+ },
+ onWebSearchRequested = {
+ val intent = Intent().apply {
+ action = Intent.ACTION_WEB_SEARCH
+ putExtra(SearchManager.QUERY, it)
+ }
+ try {
+ context.startActivity(intent)
+ } catch (e: ActivityNotFoundException) {
+ context.getString(R.string.no_app_to_handle_content).toToast(context)
+ }
+ },
+ onTranslateRequested = {
+ val intent = Intent(
+ Intent.ACTION_VIEW,
+ Uri.parse("https://translate.google.com/?sl=auto&tl=en&text=$it")
+ )
+ try {
+ context.startActivity(intent)
+ } catch (e: ActivityNotFoundException) {
+ context.getString(R.string.no_app_to_handle_content).toToast(context)
+ }
+ },
+ onDictionaryRequested = {
+ val dictionaryIntent = Intent()
+ val browserIntent = Intent()
+
+ dictionaryIntent.type = "text/plain"
+ dictionaryIntent.action = Intent.ACTION_PROCESS_TEXT
+ dictionaryIntent.putExtra(Intent.EXTRA_PROCESS_TEXT, it.trim())
+ dictionaryIntent.putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true)
+
+ browserIntent.action = Intent.ACTION_VIEW
+ val text = it.trim().replace(" ", "+")
+ browserIntent.data = Uri.parse("https://www.onelook.com/?w=$text")
+
+ var dictionaryFailure = false
+ try {
+ context.startActivity(Intent.createChooser(dictionaryIntent, null))
+ } catch (e: ActivityNotFoundException) {
+ dictionaryFailure = true
+ }
+
+ if (dictionaryFailure) {
+ try {
+ context.startActivity(Intent.createChooser(browserIntent, null))
+ } catch (e: ActivityNotFoundException) {
+ context.getString(R.string.no_app_to_handle_content).toToast(context)
+ }
+ }
+ }
+ ) {
Column(
modifier = Modifier
.fillMaxWidth()
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 3dd6aab..0f7292a 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -11,6 +11,7 @@
أُووبس! فشل الاتصال بالخادم.
حاول ثانية
حدث خطأ ما
+ لا يمكن العثور على تطبيق لفتح هذا المحتوى.
الرئيسية
@@ -84,6 +85,14 @@
تغيير نمط الخط
الفصول
+
+ نسخ
+ تم النسخ!
+ بحث ويب
+ مشاركة
+ ترجمة
+ معنى
+
الاعدادات
محمل الكتب الالكترونية
@@ -149,7 +158,6 @@
دعم التطوير
تعتقد أنني أستحق الكوكيز؟ انقر هنا!
-
التراخيص
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 2d5e8e9..22d4cba 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -10,6 +10,7 @@
Oops! Failed to connect with the server.
Try Again
Jejda! Něco se pokazilo.
+ Nelze najít aplikaci pro otevření tohoto obsahu.
Domů
@@ -83,6 +84,14 @@
Change FontStyle
Kapitoly
+
+ Kopírovat
+ Zkopírováno!
+ Webový vyhledávač
+ Sdílet
+ Přeložit
+ Význam
+
Nastavení
Stahování e-knih
@@ -148,7 +157,6 @@
Podpora vývoje
Myslíte si, že si zasloužím sušenky? Klikněte sem!
-
Licence
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index be889f2..513fd86 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -11,6 +11,7 @@
Hoppla! Konnte keine Verbindung zum Server aufbauen.
Erneut versuchen
Hoppla! Etwas ist schiefgelaufen.
+ Keine App gefunden, um diesen Inhalt zu öffnen.
Start
@@ -84,6 +85,14 @@
Schriftart ändern
Kapitel
+
+ Kopieren
+ Kopiert!
+ Websuche
+ Teilen
+ Übersetzen
+ Bedeutung
+
Einstellungen
E-Book-Downloader
@@ -150,7 +159,6 @@
Entwicklung unterstützen
Denken Sie, ich verdiene Kekse? Klicken Sie hier!
-
Lizenzen
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 002ab45..4b0d4f4 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -11,6 +11,7 @@
Oops! Failed to connect with the server.
Try Again
¡Ups! Algo ha ido mal.
+ No se puede encontrar ninguna aplicación para abrir este contenido.
Inicio
@@ -84,6 +85,14 @@
Change FontStyle
Capítulos
+
+ Copiar
+ ¡Copiado!
+ Búsqueda web
+ Compartir
+ Traducir
+ Significado
+
Ajustes
Descargador de Ebooks
@@ -149,7 +158,6 @@
Entwicklung unterstützen
Denken Sie, ich verdiene Kekse? Klicken Sie hier!
-
Licencias
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 9d37dcf..26255b2 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -10,6 +10,7 @@
उफ़! सर्वर से कनेक्ट करने में विफल रहा।
फिर से कोशिश करें
उफ़! कुछ गड़बड़ हो गई।
+ इस सामग्री को खोलने के लिए कोई ऐप नहीं मिला।
होम
@@ -83,6 +84,14 @@
फ़ॉन्ट शैली बदलें
अध्याय
+
+ प्रतिलिपि करें
+ प्रतिलिपि बनाई गई!
+ वेब खोज
+ साझा करें
+ अनुवाद करें
+ अर्थ
+
सेटिंग्स
ई-बुक डाउनलोडर
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 73d6519..9221d67 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -11,6 +11,7 @@
Ops! Connessione al server fallita.
Riprova
Ops! Qualcosa è andato storto.
+ Nessuna app trovata per aprire questo contenuto.
Home
@@ -84,6 +85,14 @@
Cambia Font
Capitoli
+
+ Copia
+ Copiato!
+ Ricerca web
+ Condividi
+ Traduci
+ Significato
+
Impostazioni
Ebook Downloader
@@ -149,7 +158,6 @@
Supporta lo Sviluppo
Pensi che meriti dei biscotti? Clicca qui!
-
Licenze
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index ae6587a..870afcf 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -11,6 +11,7 @@
Ops! Falha ao conectar com o servidor.
Tente Novamente
Ops! Algo deu errado.
+ Não foi possível encontrar nenhum aplicativo para abrir este conteúdo.
Home
@@ -84,6 +85,14 @@
Mudar estilo da fonte
Capítulos
+
+ Copiar
+ Copiado!
+ Pesquisa na web
+ Compartilhar
+ Traduzir
+ Significado
+
Configurações
Downloader Ebook
@@ -149,7 +158,6 @@
Supporta lo Sviluppo
Pensi che meriti dei biscotti? Clicca qui!
-
Licenças
\ No newline at end of file
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index e39c756..2d2e304 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -11,6 +11,7 @@
Ups! Nu a reușit să se conecteze cu serverul.
Încearcă din nou
Ups! Ceva a mers rău.
+ Nu s-a găsit nicio aplicație pentru a deschide acest conținut.
Acasă
@@ -84,6 +85,14 @@
Schimbați FontStyle
Capitole
+
+ Copiază
+ Copiat!
+ Căutare pe web
+ Partajează
+ Tradu
+ Semnificație
+
Setări
Descărcător de Ebook
@@ -150,7 +159,6 @@
Susține Dezvoltarea
Crezi că merit biscuiți? Dă clic aici!
-
Licențe
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 95c24e0..9d0ffe3 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -11,6 +11,7 @@
Упс! Не удалось подключиться к серверу.
Попытайтесь снова
Ой! Что-то пошло не так.
+ Не удалось найти приложение для открытия этого содержимого.
Главная
@@ -84,6 +85,14 @@
Стиль шрифта
Главы
+
+ Копировать
+ Скопировано!
+ Веб-поиск
+ Поделиться
+ Перевести
+ Значение
+
Настройки
Установщик электронных книг
@@ -149,7 +158,6 @@
Поддержать Разработку
На кофе с печеньками:)
-
Лицензии
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 5e854e2..cdc5522 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -11,6 +11,7 @@
Hata! Sunucuya bağlanılamadı.
Tekrar Dene
Hata! Bir şeyler ters gitti.
+ Bu içeriği açmak için uygulama bulunamadı.
Anasayfa
@@ -84,6 +85,14 @@
Yazı Tipini Değiştir
Bölümler
+
+ Kopyala
+ Kopyalandı!
+ Web Araması
+ Paylaş
+ Çevir
+ Anlam
+
Ayarlar
E-kitap İndirici
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 4b3ad40..18c5ee8 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -12,6 +12,7 @@
噢!服务器没连上
重试
啊!出错了
+ 找不到可以打开此内容的应用程序。
主页
@@ -85,6 +86,14 @@
改变字体风格
章节
+
+ 复制
+ 已复制!
+ 网页搜索
+ 分享
+ 翻译
+ 意义
+
设置
电子书下载器
@@ -150,7 +159,6 @@
支持开发
认为我应该得到饼干吗?点击这里!
-
许可证
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6e94aa6..eab6fd9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -11,6 +11,7 @@
Oops! Failed to connect with the server.
Try Again
Oops! Something went wrong.
+ Can\'t find any app to open this content.
Home
@@ -84,6 +85,14 @@
Change FontStyle
Chapters
+
+ Copy
+ Copied!
+ Web Search
+ Share
+ Translate
+ Meaning
+
Settings
Ebook Downloader