From 8fa1056af13c5855a3732fa90e0024fba70385bb Mon Sep 17 00:00:00 2001 From: Horis <821938089@qq.com> Date: Fri, 14 Apr 2023 22:14:04 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/book/BookExtensions.kt | 2 +- .../app/help/glide/OkHttpStreamFetcher.kt | 9 ++++ .../io/legado/app/lib/webdav/Authorization.kt | 12 +++--- .../java/io/legado/app/lib/webdav/WebDav.kt | 12 +++++- .../import/remote/ServerConfigViewModel.kt | 6 +-- .../main/java/io/legado/app/web/HttpServer.kt | 6 ++- modules/web/.eslintrc-auto-import.json | 1 - modules/web/jsconfig.json | 8 ++-- modules/web/package.json | 5 ++- modules/web/src/api/axios.js | 2 +- modules/web/src/assets/main.css | 4 -- modules/web/src/auto-imports.d.ts | 1 - modules/web/src/components.d.ts | 2 +- modules/web/src/components/BookItems.vue | 4 +- modules/web/src/components/SourceDebug.vue | 6 ++- modules/web/src/components/SourceItem.vue | 21 ++++++++++ modules/web/src/components/SourceJson.vue | 8 +++- modules/web/src/components/SourceList.vue | 41 ++++++++----------- modules/web/src/components/SourceTabForm.vue | 7 +++- modules/web/src/components/SourceTabTools.vue | 6 ++- modules/web/src/components/ToolBar.vue | 7 +++- modules/web/src/utils/bookSourceEditConfig.js | 10 ++--- modules/web/src/views/SourceEditor.vue | 1 + 23 files changed, 116 insertions(+), 65 deletions(-) create mode 100644 modules/web/src/components/SourceItem.vue diff --git a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt index 1c4710eb1..dbf722bf3 100644 --- a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt +++ b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt @@ -232,7 +232,7 @@ fun Book.isSameNameAuthor(other: Any?): Boolean { fun Book.getExportFileName(suffix: String): String { val jsStr = AppConfig.bookExportFileName if (jsStr.isNullOrBlank()) { - return "${name} 作者:${getRealAuthor()}.$suffix" + return "$name 作者:${getRealAuthor()}.$suffix" } val bindings = SimpleBindings() bindings["name"] = name diff --git a/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt b/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt index cb2b874cc..c0cb80aa0 100644 --- a/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt +++ b/app/src/main/java/io/legado/app/help/glide/OkHttpStreamFetcher.kt @@ -35,7 +35,15 @@ class OkHttpStreamFetcher(private val url: GlideUrl, private val options: Option @Volatile private var call: Call? = null + companion object { + val failUrl = hashSetOf() + } + override fun loadData(priority: Priority, callback: DataFetcher.DataCallback) { + if (failUrl.contains(url.toStringUrl())) { + callback.onLoadFailed(NoStackTraceException("跳过加载失败的图片")) + return + } val loadOnlyWifi = options.get(OkHttpModelLoader.loadOnlyWifiOption) ?: false if (loadOnlyWifi && !appCtx.isWifiConnect) { callback.onLoadFailed(NoStackTraceException("只在wifi加载图片")) @@ -96,6 +104,7 @@ class OkHttpStreamFetcher(private val url: GlideUrl, private val options: Option callback?.onDataReady(stream) } } else { + failUrl.add(url.toStringUrl()) callback?.onLoadFailed(HttpException(response.message, response.code)) } } diff --git a/app/src/main/java/io/legado/app/lib/webdav/Authorization.kt b/app/src/main/java/io/legado/app/lib/webdav/Authorization.kt index 92d2b92a2..b3130b7d1 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/Authorization.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/Authorization.kt @@ -22,13 +22,11 @@ data class Authorization( return "$username:$password" } - constructor(serverID: Long?): this("","") { - serverID ?: throw WebDavException("Unexpected server ID") - appDb.serverDao.get(serverID)?.getWebDavConfig()?.run { - data = Credentials.basic(username, password, charset) - } ?: throw WebDavException("Unexpected WebDav Authorization") - } + constructor(serverID: Long) : this( + appDb.serverDao.get(serverID)?.getWebDavConfig() + ?: throw WebDavException("Unexpected WebDav Authorization") + ) - constructor(webDavConfig: WebDavConfig): this(webDavConfig.username, webDavConfig.password) + constructor(webDavConfig: WebDavConfig) : this(webDavConfig.username, webDavConfig.password) } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt index e173d1d64..e2421f006 100644 --- a/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt +++ b/app/src/main/java/io/legado/app/lib/webdav/WebDav.kt @@ -39,7 +39,7 @@ open class WebDav( companion object { fun fromPath(path: String): WebDav { - val id = AnalyzeUrl(path).serverID + val id = AnalyzeUrl(path).serverID ?: throw WebDavException("没有serverID") val authorization = Authorization(id) return WebDav(path, authorization) } @@ -386,6 +386,16 @@ open class WebDav( private fun checkResult(response: Response) { if (!response.isSuccessful) { val body = response.body?.string() + if (response.code == 401) { + val headers = response.headers("WWW-Authenticate") + val supportBasicAuth = headers.any { + it.startsWith("Basic", ignoreCase = true) + } + if (!supportBasicAuth) { + AppLog.put("服务器不支持BasicAuth认证") + } + } + if (response.message.isNotBlank() || body.isNullOrBlank()) { throw WebDavException("${url}\n${response.code}:${response.message}") } diff --git a/app/src/main/java/io/legado/app/ui/book/import/remote/ServerConfigViewModel.kt b/app/src/main/java/io/legado/app/ui/book/import/remote/ServerConfigViewModel.kt index d23eeadbd..875304232 100644 --- a/app/src/main/java/io/legado/app/ui/book/import/remote/ServerConfigViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/import/remote/ServerConfigViewModel.kt @@ -14,10 +14,10 @@ class ServerConfigViewModel(application: Application): BaseViewModel(application //mServer不为空可能是旋转屏幕界面重新创建,不用更新数据 if (mServer != null) return execute { - if (id != null) { - mServer = appDb.serverDao.get(id) + mServer = if (id != null) { + appDb.serverDao.get(id) } else { - mServer = Server() + Server() } }.onSuccess { onSuccess.invoke() diff --git a/app/src/main/java/io/legado/app/web/HttpServer.kt b/app/src/main/java/io/legado/app/web/HttpServer.kt index 4c84ec696..a65af0e10 100644 --- a/app/src/main/java/io/legado/app/web/HttpServer.kt +++ b/app/src/main/java/io/legado/app/web/HttpServer.kt @@ -98,6 +98,10 @@ class HttpServer(port: Int) : NanoHTTPD(port) { ) } else { try { + val data = returnData.data + if (data is List<*> && data.size > 3000) { + throw OutOfMemoryError() + } newFixedLengthResponse(GSON.toJson(returnData)) } catch (e: OutOfMemoryError) { val path = FileUtils.getPath( @@ -106,7 +110,7 @@ class HttpServer(port: Int) : NanoHTTPD(port) { "bookSources.json" ) val file = FileUtils.createFileIfNotExist(path) - BufferedWriter(FileWriter(file)).use { + BufferedWriter(FileWriter(file), 128 * 1024).use { GSON.toJson(returnData, it) } val fis = FileInputStream(file) diff --git a/modules/web/.eslintrc-auto-import.json b/modules/web/.eslintrc-auto-import.json index 6ed320415..fcb0d053c 100644 --- a/modules/web/.eslintrc-auto-import.json +++ b/modules/web/.eslintrc-auto-import.json @@ -4,7 +4,6 @@ "ComponentPublicInstance": true, "ComputedRef": true, "EffectScope": true, - "ElLoading": true, "ElMessage": true, "InjectionKey": true, "PropType": true, diff --git a/modules/web/jsconfig.json b/modules/web/jsconfig.json index ef3556de4..1666c755d 100644 --- a/modules/web/jsconfig.json +++ b/modules/web/jsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "types": ["element-plus/global", "@element-plus/icons-vue","@vueuse/shared", "vite/client"], + "types": ["@element-plus/icons-vue", "@vueuse/shared", "vite/client"], "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", @@ -10,9 +10,9 @@ "skipLibCheck": true, "noEmit": true, "paths": { - "@/*":["./src/*"], - "@api":["./src/api"], - "@utils/*":["./src/utils/*"] + "@/*": ["./src/*"], + "@api": ["./src/api"], + "@utils/*": ["./src/utils/*"] } }, //"exclude": ["node_modules", "dist"], diff --git a/modules/web/package.json b/modules/web/package.json index d594c4c99..08316ded2 100644 --- a/modules/web/package.json +++ b/modules/web/package.json @@ -21,7 +21,8 @@ "hotkeys-js": "^3.10.2", "pinia": "^2.0.34", "vue": "^3.2.47", - "vue-router": "^4.1.6" + "vue-router": "^4.1.6", + "vue3-virtual-scroll-list": "^0.2.1" }, "devDependencies": { "@vitejs/plugin-vue": "^4.1.0", @@ -36,4 +37,4 @@ "unplugin-vue-components": "^0.24.1", "vite": "^4.2.1" } -} \ No newline at end of file +} diff --git a/modules/web/src/api/axios.js b/modules/web/src/api/axios.js index 0b97ce20c..cb2c50f6b 100644 --- a/modules/web/src/api/axios.js +++ b/modules/web/src/api/axios.js @@ -4,7 +4,7 @@ const SECOND = 1000; const ajax = axios.create({ baseURL: import.meta.env.VITE_API || location.origin, - timeout: 5 * SECOND, + timeout: 120 * SECOND, }); export default ajax; diff --git a/modules/web/src/assets/main.css b/modules/web/src/assets/main.css index 47de07210..26ba33789 100644 --- a/modules/web/src/assets/main.css +++ b/modules/web/src/assets/main.css @@ -1,10 +1,6 @@ @import './kbd.css'; @import './code.css'; -::-webkit-scrollbar { - width: 0; - height: 0; -} body { padding: 0; margin: 0; diff --git a/modules/web/src/auto-imports.d.ts b/modules/web/src/auto-imports.d.ts index 1755533d3..d11a4a101 100644 --- a/modules/web/src/auto-imports.d.ts +++ b/modules/web/src/auto-imports.d.ts @@ -5,7 +5,6 @@ export {} declare global { const EffectScope: typeof import('vue')['EffectScope'] - const ElLoading: typeof import('element-plus/es')['ElLoading'] const ElMessage: typeof import('element-plus/es')['ElMessage'] const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] const computed: typeof import('vue')['computed'] diff --git a/modules/web/src/components.d.ts b/modules/web/src/components.d.ts index 9c863ca59..9a0df73d7 100644 --- a/modules/web/src/components.d.ts +++ b/modules/web/src/components.d.ts @@ -17,7 +17,6 @@ declare module '@vue/runtime-core' { ElDialog: typeof import('element-plus/es')['ElDialog'] ElForm: typeof import('element-plus/es')['ElForm'] ElFormItem: typeof import('element-plus/es')['ElFormItem'] - ElIcon: typeof import('element-plus/es')['ElIcon'] ElInput: typeof import('element-plus/es')['ElInput'] ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] ElLink: typeof import('element-plus/es')['ElLink'] @@ -36,6 +35,7 @@ declare module '@vue/runtime-core' { RouterView: typeof import('vue-router')['RouterView'] SourceDebug: typeof import('./components/SourceDebug.vue')['default'] SourceHelp: typeof import('./components/SourceHelp.vue')['default'] + SourceItem: typeof import('./components/SourceItem.vue')['default'] SourceJson: typeof import('./components/SourceJson.vue')['default'] SourceList: typeof import('./components/SourceList.vue')['default'] SourceTabForm: typeof import('./components/SourceTabForm.vue')['default'] diff --git a/modules/web/src/components/BookItems.vue b/modules/web/src/components/BookItems.vue index 06c1516c0..9b421b5a6 100644 --- a/modules/web/src/components/BookItems.vue +++ b/modules/web/src/components/BookItems.vue @@ -4,7 +4,7 @@
@@ -24,7 +24,7 @@
{{ tag }} diff --git a/modules/web/src/components/SourceDebug.vue b/modules/web/src/components/SourceDebug.vue index 9f5e08ca4..2b78ef2fd 100644 --- a/modules/web/src/components/SourceDebug.vue +++ b/modules/web/src/components/SourceDebug.vue @@ -52,4 +52,8 @@ const isBookSource = computed(() => { }); - + diff --git a/modules/web/src/components/SourceItem.vue b/modules/web/src/components/SourceItem.vue new file mode 100644 index 000000000..bc84a7158 --- /dev/null +++ b/modules/web/src/components/SourceItem.vue @@ -0,0 +1,21 @@ + + + diff --git a/modules/web/src/components/SourceJson.vue b/modules/web/src/components/SourceJson.vue index c2898b660..6bd99a60a 100644 --- a/modules/web/src/components/SourceJson.vue +++ b/modules/web/src/components/SourceJson.vue @@ -1,5 +1,6 @@ - + diff --git a/modules/web/src/components/ToolBar.vue b/modules/web/src/components/ToolBar.vue index a4c86bad5..41099d242 100644 --- a/modules/web/src/components/ToolBar.vue +++ b/modules/web/src/components/ToolBar.vue @@ -72,6 +72,11 @@ import { isInvaildSource } from "../utils/souce"; const store = useSourceStore(); const pull = () => { + const loadingMsg = ElMessage({ + message: '加载中……', + showClose: true, + duration: 0 + }) API.getSources().then(({ data }) => { if (data.isSuccess) { store.changeTabName("editList"); @@ -86,7 +91,7 @@ const pull = () => { type: "error", }); } - }); + }).finally(() => loadingMsg.close()); }; const push = () => { diff --git a/modules/web/src/utils/bookSourceEditConfig.js b/modules/web/src/utils/bookSourceEditConfig.js index f98b6ba70..f1bb37ce8 100644 --- a/modules/web/src/utils/bookSourceEditConfig.js +++ b/modules/web/src/utils/bookSourceEditConfig.js @@ -552,11 +552,11 @@ id: "deleteUrl", id: "enabledExplore", type: "Boolean", }, - { - title: "启用段评", - id: "enabledReview", - type: "Boolean", - }, + // { + // title: "启用段评", + // id: "enabledReview", + // type: "Boolean", + // }, { title: "Cookie", id: "enabledCookieJar", diff --git a/modules/web/src/views/SourceEditor.vue b/modules/web/src/views/SourceEditor.vue index 5eba3f952..f2cd6ac70 100644 --- a/modules/web/src/views/SourceEditor.vue +++ b/modules/web/src/views/SourceEditor.vue @@ -30,6 +30,7 @@ if (/bookSource/i.test(location.href)) { margin-left: 20px; } .right { + flex: 1; width: 360px; margin-right: 20px; }