diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 46aa445f1..05d94e9f2 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -8,13 +8,16 @@ * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则出现问题。先关闭替换净化并刷新,再观察是否正常。如果正常说明净化规则存在误杀,如果关闭后仍然出现相关问题,请点击源链接查看原文与正文是否相同,如果不同,再进行反馈。 * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源! -**2021/07/21** -* 非关键规则添加try防止报错中断解析 -* 添加获取封面的api -* 获取正文api使用替换规则 -* 添加一个ronet版本,网络访问使用Chromium内核 -* web书架增加【最近一次更新书籍信息的时间】 -* 采用Flow替换LiveData,优化资源使用 +**2021/07/22** +1. 非关键规则添加try防止报错中断解析 +2. 添加获取封面的api +3. 获取正文api使用替换规则 +4. 添加一个ronet版本,网络访问使用Chromium内核 +5. web书架增加【最近一次更新书籍信息的时间】 +6. 采用Flow替换LiveData,优化资源使用 +7. 统一网络一键导入路径legado://import/{path}?src={url} +* path: bookSource,rssSource,replaceRule,textTocRule,httpTTS,theme,readConfig +* 添加了txt小说规则,在线朗读引擎,主题,排版 的一键导入支持,老url依然可用 **2021/07/16** 1. js扩展函数添加删除本地文件方法 diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 60580566f..edf8ae55b 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -346,7 +346,6 @@ interface JsExtensions { } val bos = ByteArrayOutputStream() val zis = ZipInputStream(ByteArrayInputStream(bytes)) - var entry: ZipEntry? = zis.nextEntry while (entry != null) { if (entry.name.equals(path)) { diff --git a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt index b024838f3..d76027909 100644 --- a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt +++ b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt @@ -10,6 +10,8 @@ import io.legado.app.constant.PreferKey import io.legado.app.help.coroutine.Coroutine import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.utils.* +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.withContext import splitties.init.appCtx import java.io.File @@ -355,6 +357,63 @@ object ReadBookConfig { return exportConfig } + suspend fun import(byteArray: ByteArray): Config { + return withContext(IO) { + val configZipPath = FileUtils.getPath(appCtx.externalCache, configFileName) + FileUtils.deleteFile(configZipPath) + val zipFile = FileUtils.createFileIfNotExist(configZipPath) + zipFile.writeBytes(byteArray) + val configDirPath = FileUtils.getPath(appCtx.externalCache, "readConfig") + FileUtils.deleteFile(configDirPath) + @Suppress("BlockingMethodInNonBlockingContext") + ZipUtils.unzipFile(zipFile, FileUtils.createFolderIfNotExist(configDirPath)) + val configDir = FileUtils.createFolderIfNotExist(configDirPath) + val configFile = FileUtils.getFile(configDir, "readConfig.json") + val config: Config = GSON.fromJsonObject(configFile.readText())!! + if (config.textFont.isNotEmpty()) { + val fontName = FileUtils.getName(config.textFont) + val fontPath = + FileUtils.getPath(appCtx.externalFiles, "font", fontName) + if (!FileUtils.exist(fontPath)) { + FileUtils.getFile(configDir, fontName).copyTo(File(fontPath)) + } + config.textFont = fontPath + } + if (config.bgType == 2) { + val bgName = FileUtils.getName(config.bgStr) + val bgPath = FileUtils.getPath(appCtx.externalFiles, "bg", bgName) + if (!FileUtils.exist(bgPath)) { + val bgFile = FileUtils.getFile(configDir, bgName) + if (bgFile.exists()) { + bgFile.copyTo(File(bgPath)) + } + } + } + if (config.bgTypeNight == 2) { + val bgName = FileUtils.getName(config.bgStrNight) + val bgPath = FileUtils.getPath(appCtx.externalFiles, "bg", bgName) + if (!FileUtils.exist(bgPath)) { + val bgFile = FileUtils.getFile(configDir, bgName) + if (bgFile.exists()) { + bgFile.copyTo(File(bgPath)) + } + } + } + if (config.bgTypeEInk == 2) { + val bgName = FileUtils.getName(config.bgStrEInk) + @Suppress("BlockingMethodInNonBlockingContext") val bgPath = + FileUtils.getPath(appCtx.externalFiles, "bg", bgName) + if (!FileUtils.exist(bgPath)) { + val bgFile = FileUtils.getFile(configDir, bgName) + if (bgFile.exists()) { + bgFile.copyTo(File(bgPath)) + } + } + } + return@withContext config + } + } + @Keep class Config( var name: String = "", diff --git a/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt b/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt index 389b5b7ab..6973a844b 100644 --- a/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/OnLineImportActivity.kt @@ -33,6 +33,7 @@ class OnLineImportActivity : "textTocRule" -> viewModel.importTextTocRule(url, this::finallyDialog) "httpTTS" -> viewModel.importHttpTTS(url, this::finallyDialog) "theme" -> viewModel.importTheme(url, this::finallyDialog) + "readConfig" -> viewModel.importReadConfig(url, this::finallyDialog) else -> { } } diff --git a/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt b/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt index 7488a895b..2526d32b9 100644 --- a/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt @@ -6,6 +6,7 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.appDb import io.legado.app.data.entities.HttpTTS import io.legado.app.data.entities.TxtTocRule +import io.legado.app.help.ReadBookConfig import io.legado.app.help.ThemeConfig import io.legado.app.help.http.newCall import io.legado.app.help.http.okHttpClient @@ -85,4 +86,26 @@ class OnLineImportViewModel(app: App) : BaseViewModel(app) { } } + fun importReadConfig(url: String, finally: (title: String, msg: String) -> Unit) { + execute { + @Suppress("BlockingMethodInNonBlockingContext") + val bytes = okHttpClient.newCall { + url(url) + }.bytes() + val config = ReadBookConfig.import(bytes) + ReadBookConfig.configList.forEachIndexed { index, c -> + if (c.name == config.name) { + ReadBookConfig.configList[index] = config + return@execute config.name + } + ReadBookConfig.configList.add(config) + return@execute config.name + } + }.onSuccess { + finally.invoke(context.getString(R.string.success), "导入排版成功") + }.onError { + finally.invoke(context.getString(R.string.error), it.localizedMessage ?: "未知错误") + } + } + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index 3837b6c22..5175f6610 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -308,6 +308,7 @@ class BgTextConfigDialog : BaseDialogFragment() { private fun importNetConfig(url: String) { execute { + @Suppress("BlockingMethodInNonBlockingContext") okHttpClient.newCall { url(url) }.bytes().let { @@ -318,9 +319,9 @@ class BgTextConfigDialog : BaseDialogFragment() { } } - @Suppress("BlockingMethodInNonBlockingContext") private fun importConfig(uri: Uri) { execute { + @Suppress("BlockingMethodInNonBlockingContext") importConfig(uri.readBytes(requireContext())!!) }.onError { it.printStackTrace() @@ -328,61 +329,13 @@ class BgTextConfigDialog : BaseDialogFragment() { } } - @Suppress("BlockingMethodInNonBlockingContext") + @Suppress("BlockingMethodInNonBlockingContext", "BlockingMethodInNonBlockingContext") private fun importConfig(byteArray: ByteArray) { execute { - val configZipPath = FileUtils.getPath(requireContext().externalCache, configFileName) - FileUtils.deleteFile(configZipPath) - val zipFile = FileUtils.createFileIfNotExist(configZipPath) - zipFile.writeBytes(byteArray) - val configDirPath = FileUtils.getPath(requireContext().externalCache, "readConfig") - FileUtils.deleteFile(configDirPath) - ZipUtils.unzipFile(zipFile, FileUtils.createFolderIfNotExist(configDirPath)) - val configDir = FileUtils.createFolderIfNotExist(configDirPath) - val configFile = FileUtils.getFile(configDir, "readConfig.json") - val config: ReadBookConfig.Config = GSON.fromJsonObject(configFile.readText())!! - if (config.textFont.isNotEmpty()) { - val fontName = FileUtils.getName(config.textFont) - val fontPath = - FileUtils.getPath(requireContext().externalFiles, "font", fontName) - if (!FileUtils.exist(fontPath)) { - FileUtils.getFile(configDir, fontName).copyTo(File(fontPath)) - } - config.textFont = fontPath - } - if (config.bgType == 2) { - val bgName = FileUtils.getName(config.bgStr) - val bgPath = FileUtils.getPath(requireContext().externalFiles, "bg", bgName) - if (!FileUtils.exist(bgPath)) { - val bgFile = FileUtils.getFile(configDir, bgName) - if (bgFile.exists()) { - bgFile.copyTo(File(bgPath)) - } - } - } - if (config.bgTypeNight == 2) { - val bgName = FileUtils.getName(config.bgStrNight) - val bgPath = FileUtils.getPath(requireContext().externalFiles, "bg", bgName) - if (!FileUtils.exist(bgPath)) { - val bgFile = FileUtils.getFile(configDir, bgName) - if (bgFile.exists()) { - bgFile.copyTo(File(bgPath)) - } - } - } - if (config.bgTypeEInk == 2) { - val bgName = FileUtils.getName(config.bgStrEInk) - val bgPath = FileUtils.getPath(requireContext().externalFiles, "bg", bgName) - if (!FileUtils.exist(bgPath)) { - val bgFile = FileUtils.getFile(configDir, bgName) - if (bgFile.exists()) { - bgFile.copyTo(File(bgPath)) - } - } - } - ReadBookConfig.durConfig = config - postEvent(EventBus.UP_CONFIG, true) + ReadBookConfig.import(byteArray) }.onSuccess { + ReadBookConfig.durConfig = it + postEvent(EventBus.UP_CONFIG, true) toastOnUi("导入成功") }.onError { it.printStackTrace()