feat: 添加朗读引擎批量导入选择界面及导出 URL 功能

This commit is contained in:
HapeLee
2026-06-19 00:20:06 +08:00
parent 847f2dc1f4
commit b0c1f9fcec
2 changed files with 30 additions and 1 deletions
@@ -1,12 +1,14 @@
package io.legado.app.ui.association package io.legado.app.ui.association
import android.app.Application import android.app.Application
import android.util.Base64
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.constant.AppPattern
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.HttpTTS import io.legado.app.data.entities.HttpTTS
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
@@ -15,6 +17,7 @@ import io.legado.app.help.http.newCallResponseBody
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.help.http.text import io.legado.app.help.http.text
import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.isDataUrl
import io.legado.app.utils.isJsonArray import io.legado.app.utils.isJsonArray
import io.legado.app.utils.isJsonObject import io.legado.app.utils.isJsonObject
import io.legado.app.utils.isUri import io.legado.app.utils.isUri
@@ -86,6 +89,11 @@ class ImportHttpTtsViewModel(app: Application) : BaseViewModel(app) {
text.isJsonArray() -> HttpTTS.fromJsonArray(text).getOrThrow().let { items -> text.isJsonArray() -> HttpTTS.fromJsonArray(text).getOrThrow().let { items ->
allSources.addAll(items) allSources.addAll(items)
} }
text.isDataUrl() -> {
val data = AppPattern.dataUriRegex.find(text)?.groupValues?.getOrNull(1)
?: throw NoStackTraceException(context.getString(R.string.wrong_format))
importSourceAwait(Base64.decode(data, Base64.DEFAULT).toString(Charsets.UTF_8))
}
text.isAbsUrl() -> { text.isAbsUrl() -> {
importSourceUrl(text) importSourceUrl(text)
} }
@@ -120,4 +128,4 @@ class ImportHttpTtsViewModel(app: Application) : BaseViewModel(app) {
} }
} }
} }
@@ -36,6 +36,7 @@ import io.legado.app.ui.widget.components.AppTextField
import io.legado.app.ui.widget.components.alert.AppAlertDialog import io.legado.app.ui.widget.components.alert.AppAlertDialog
import io.legado.app.ui.widget.components.button.series.SmallTonalButton import io.legado.app.ui.widget.components.button.series.SmallTonalButton
import io.legado.app.ui.widget.components.filePicker.FilePickerSheet import io.legado.app.ui.widget.components.filePicker.FilePickerSheet
import io.legado.app.ui.widget.components.importComponents.BatchImportDialog
import io.legado.app.ui.widget.components.importComponents.SourceInputDialog import io.legado.app.ui.widget.components.importComponents.SourceInputDialog
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenu
import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem import io.legado.app.ui.widget.components.menuItem.RoundDropdownMenuItem
@@ -199,6 +200,19 @@ fun SpeakEngineConfigSheet(
}, },
allowExtensions = arrayOf("json", "txt"), allowExtensions = arrayOf("json", "txt"),
) )
BatchImportDialog(
title = stringResource(R.string.import_tts),
importState = state.httpTtsImportState,
onDismissRequest = { onIntent(ReadBookIntent.CancelHttpTtsImport) },
onToggleItem = { onIntent(ReadBookIntent.ToggleHttpTtsImportSelection(it)) },
onToggleAll = { onIntent(ReadBookIntent.ToggleHttpTtsImportAll(it)) },
onUpdateItem = { index, httpTTS ->
onIntent(ReadBookIntent.UpdateHttpTtsImportItem(index, httpTTS))
},
onConfirm = { onIntent(ReadBookIntent.SaveImportedHttpTts) },
itemTitle = { it.name },
itemSubtitle = { it.url },
)
AppModalBottomSheet( AppModalBottomSheet(
show = show, show = show,
@@ -232,6 +246,13 @@ fun SpeakEngineConfigSheet(
onIntent(ReadBookIntent.ExportAllHttpTts) onIntent(ReadBookIntent.ExportAllHttpTts)
}, },
) )
RoundDropdownMenuItem(
text = stringResource(R.string.copy_url),
onClick = {
expanded = false
onIntent(ReadBookIntent.ExportAllHttpTtsAsUrl)
},
)
RoundDropdownMenuItem( RoundDropdownMenuItem(
text = stringResource(R.string.clear_cache), text = stringResource(R.string.clear_cache),
onClick = { onClick = {