feat: 添加朗读引擎批量导入选择界面及导出 URL 功能
This commit is contained in:
@@ -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 = {
|
||||||
|
|||||||
Reference in New Issue
Block a user