mirror of
https://github.com/gedoor/legado.git
synced 2024-07-19 01:17:25 +08:00
优化
This commit is contained in:
parent
3e0938a2c9
commit
8fa1056af1
@ -232,7 +232,7 @@ fun Book.isSameNameAuthor(other: Any?): Boolean {
|
|||||||
fun Book.getExportFileName(suffix: String): String {
|
fun Book.getExportFileName(suffix: String): String {
|
||||||
val jsStr = AppConfig.bookExportFileName
|
val jsStr = AppConfig.bookExportFileName
|
||||||
if (jsStr.isNullOrBlank()) {
|
if (jsStr.isNullOrBlank()) {
|
||||||
return "${name} 作者:${getRealAuthor()}.$suffix"
|
return "$name 作者:${getRealAuthor()}.$suffix"
|
||||||
}
|
}
|
||||||
val bindings = SimpleBindings()
|
val bindings = SimpleBindings()
|
||||||
bindings["name"] = name
|
bindings["name"] = name
|
||||||
|
@ -35,7 +35,15 @@ class OkHttpStreamFetcher(private val url: GlideUrl, private val options: Option
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var call: Call? = null
|
private var call: Call? = null
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val failUrl = hashSetOf<String>()
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||||
|
if (failUrl.contains(url.toStringUrl())) {
|
||||||
|
callback.onLoadFailed(NoStackTraceException("跳过加载失败的图片"))
|
||||||
|
return
|
||||||
|
}
|
||||||
val loadOnlyWifi = options.get(OkHttpModelLoader.loadOnlyWifiOption) ?: false
|
val loadOnlyWifi = options.get(OkHttpModelLoader.loadOnlyWifiOption) ?: false
|
||||||
if (loadOnlyWifi && !appCtx.isWifiConnect) {
|
if (loadOnlyWifi && !appCtx.isWifiConnect) {
|
||||||
callback.onLoadFailed(NoStackTraceException("只在wifi加载图片"))
|
callback.onLoadFailed(NoStackTraceException("只在wifi加载图片"))
|
||||||
@ -96,6 +104,7 @@ class OkHttpStreamFetcher(private val url: GlideUrl, private val options: Option
|
|||||||
callback?.onDataReady(stream)
|
callback?.onDataReady(stream)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
failUrl.add(url.toStringUrl())
|
||||||
callback?.onLoadFailed(HttpException(response.message, response.code))
|
callback?.onLoadFailed(HttpException(response.message, response.code))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,11 @@ data class Authorization(
|
|||||||
return "$username:$password"
|
return "$username:$password"
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(serverID: Long?): this("","") {
|
constructor(serverID: Long) : this(
|
||||||
serverID ?: throw WebDavException("Unexpected server ID")
|
appDb.serverDao.get(serverID)?.getWebDavConfig()
|
||||||
appDb.serverDao.get(serverID)?.getWebDavConfig()?.run {
|
?: throw WebDavException("Unexpected WebDav Authorization")
|
||||||
data = Credentials.basic(username, password, charset)
|
)
|
||||||
} ?: throw WebDavException("Unexpected WebDav Authorization")
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(webDavConfig: WebDavConfig): this(webDavConfig.username, webDavConfig.password)
|
constructor(webDavConfig: WebDavConfig) : this(webDavConfig.username, webDavConfig.password)
|
||||||
|
|
||||||
}
|
}
|
@ -39,7 +39,7 @@ open class WebDav(
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun fromPath(path: String): WebDav {
|
fun fromPath(path: String): WebDav {
|
||||||
val id = AnalyzeUrl(path).serverID
|
val id = AnalyzeUrl(path).serverID ?: throw WebDavException("没有serverID")
|
||||||
val authorization = Authorization(id)
|
val authorization = Authorization(id)
|
||||||
return WebDav(path, authorization)
|
return WebDav(path, authorization)
|
||||||
}
|
}
|
||||||
@ -386,6 +386,16 @@ open class WebDav(
|
|||||||
private fun checkResult(response: Response) {
|
private fun checkResult(response: Response) {
|
||||||
if (!response.isSuccessful) {
|
if (!response.isSuccessful) {
|
||||||
val body = response.body?.string()
|
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()) {
|
if (response.message.isNotBlank() || body.isNullOrBlank()) {
|
||||||
throw WebDavException("${url}\n${response.code}:${response.message}")
|
throw WebDavException("${url}\n${response.code}:${response.message}")
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@ class ServerConfigViewModel(application: Application): BaseViewModel(application
|
|||||||
//mServer不为空可能是旋转屏幕界面重新创建,不用更新数据
|
//mServer不为空可能是旋转屏幕界面重新创建,不用更新数据
|
||||||
if (mServer != null) return
|
if (mServer != null) return
|
||||||
execute {
|
execute {
|
||||||
if (id != null) {
|
mServer = if (id != null) {
|
||||||
mServer = appDb.serverDao.get(id)
|
appDb.serverDao.get(id)
|
||||||
} else {
|
} else {
|
||||||
mServer = Server()
|
Server()
|
||||||
}
|
}
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
onSuccess.invoke()
|
onSuccess.invoke()
|
||||||
|
@ -98,6 +98,10 @@ class HttpServer(port: Int) : NanoHTTPD(port) {
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
val data = returnData.data
|
||||||
|
if (data is List<*> && data.size > 3000) {
|
||||||
|
throw OutOfMemoryError()
|
||||||
|
}
|
||||||
newFixedLengthResponse(GSON.toJson(returnData))
|
newFixedLengthResponse(GSON.toJson(returnData))
|
||||||
} catch (e: OutOfMemoryError) {
|
} catch (e: OutOfMemoryError) {
|
||||||
val path = FileUtils.getPath(
|
val path = FileUtils.getPath(
|
||||||
@ -106,7 +110,7 @@ class HttpServer(port: Int) : NanoHTTPD(port) {
|
|||||||
"bookSources.json"
|
"bookSources.json"
|
||||||
)
|
)
|
||||||
val file = FileUtils.createFileIfNotExist(path)
|
val file = FileUtils.createFileIfNotExist(path)
|
||||||
BufferedWriter(FileWriter(file)).use {
|
BufferedWriter(FileWriter(file), 128 * 1024).use {
|
||||||
GSON.toJson(returnData, it)
|
GSON.toJson(returnData, it)
|
||||||
}
|
}
|
||||||
val fis = FileInputStream(file)
|
val fis = FileInputStream(file)
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
"ComponentPublicInstance": true,
|
"ComponentPublicInstance": true,
|
||||||
"ComputedRef": true,
|
"ComputedRef": true,
|
||||||
"EffectScope": true,
|
"EffectScope": true,
|
||||||
"ElLoading": true,
|
|
||||||
"ElMessage": true,
|
"ElMessage": true,
|
||||||
"InjectionKey": true,
|
"InjectionKey": true,
|
||||||
"PropType": true,
|
"PropType": true,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"types": ["element-plus/global", "@element-plus/icons-vue","@vueuse/shared", "vite/client"],
|
"types": ["@element-plus/icons-vue", "@vueuse/shared", "vite/client"],
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
@ -10,9 +10,9 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*":["./src/*"],
|
"@/*": ["./src/*"],
|
||||||
"@api":["./src/api"],
|
"@api": ["./src/api"],
|
||||||
"@utils/*":["./src/utils/*"]
|
"@utils/*": ["./src/utils/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//"exclude": ["node_modules", "dist"],
|
//"exclude": ["node_modules", "dist"],
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
"hotkeys-js": "^3.10.2",
|
"hotkeys-js": "^3.10.2",
|
||||||
"pinia": "^2.0.34",
|
"pinia": "^2.0.34",
|
||||||
"vue": "^3.2.47",
|
"vue": "^3.2.47",
|
||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6",
|
||||||
|
"vue3-virtual-scroll-list": "^0.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^4.1.0",
|
"@vitejs/plugin-vue": "^4.1.0",
|
||||||
|
@ -4,7 +4,7 @@ const SECOND = 1000;
|
|||||||
|
|
||||||
const ajax = axios.create({
|
const ajax = axios.create({
|
||||||
baseURL: import.meta.env.VITE_API || location.origin,
|
baseURL: import.meta.env.VITE_API || location.origin,
|
||||||
timeout: 5 * SECOND,
|
timeout: 120 * SECOND,
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ajax;
|
export default ajax;
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
@import './kbd.css';
|
@import './kbd.css';
|
||||||
@import './code.css';
|
@import './code.css';
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
body {
|
body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
1
modules/web/src/auto-imports.d.ts
vendored
1
modules/web/src/auto-imports.d.ts
vendored
@ -5,7 +5,6 @@
|
|||||||
export {}
|
export {}
|
||||||
declare global {
|
declare global {
|
||||||
const EffectScope: typeof import('vue')['EffectScope']
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
const ElLoading: typeof import('element-plus/es')['ElLoading']
|
|
||||||
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
||||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||||
const computed: typeof import('vue')['computed']
|
const computed: typeof import('vue')['computed']
|
||||||
|
2
modules/web/src/components.d.ts
vendored
2
modules/web/src/components.d.ts
vendored
@ -17,7 +17,6 @@ declare module '@vue/runtime-core' {
|
|||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
ElForm: typeof import('element-plus/es')['ElForm']
|
ElForm: typeof import('element-plus/es')['ElForm']
|
||||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
ElLink: typeof import('element-plus/es')['ElLink']
|
ElLink: typeof import('element-plus/es')['ElLink']
|
||||||
@ -36,6 +35,7 @@ declare module '@vue/runtime-core' {
|
|||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
SourceDebug: typeof import('./components/SourceDebug.vue')['default']
|
SourceDebug: typeof import('./components/SourceDebug.vue')['default']
|
||||||
SourceHelp: typeof import('./components/SourceHelp.vue')['default']
|
SourceHelp: typeof import('./components/SourceHelp.vue')['default']
|
||||||
|
SourceItem: typeof import('./components/SourceItem.vue')['default']
|
||||||
SourceJson: typeof import('./components/SourceJson.vue')['default']
|
SourceJson: typeof import('./components/SourceJson.vue')['default']
|
||||||
SourceList: typeof import('./components/SourceList.vue')['default']
|
SourceList: typeof import('./components/SourceList.vue')['default']
|
||||||
SourceTabForm: typeof import('./components/SourceTabForm.vue')['default']
|
SourceTabForm: typeof import('./components/SourceTabForm.vue')['default']
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div
|
<div
|
||||||
class="book"
|
class="book"
|
||||||
v-for="book in props.books"
|
v-for="book in props.books"
|
||||||
:key="book.noteUrl"
|
:key="book.bookUrl"
|
||||||
@click="handleClick(book)"
|
@click="handleClick(book)"
|
||||||
>
|
>
|
||||||
<div class="cover-img">
|
<div class="cover-img">
|
||||||
@ -24,7 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tags" v-show="props.isSearch">
|
<div class="tags" v-show="props.isSearch">
|
||||||
<el-tag
|
<el-tag
|
||||||
v-for="tag in book.kind.split(',').slice(0, 2)"
|
v-for="tag in book.kind?.split(',').slice(0, 2)"
|
||||||
:key="tag"
|
:key="tag"
|
||||||
>
|
>
|
||||||
{{ tag }}
|
{{ tag }}
|
||||||
|
@ -52,4 +52,8 @@ const isBookSource = computed(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
:deep(#debug-text) {
|
||||||
|
height: calc(100vh - 45px - 36px - 5px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
21
modules/web/src/components/SourceItem.vue
Normal file
21
modules/web/src/components/SourceItem.vue
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<el-checkbox
|
||||||
|
size="large"
|
||||||
|
border
|
||||||
|
:label="source"
|
||||||
|
:class="{ error: errorPushSources.includes(source) }"
|
||||||
|
@change="handleSourceClick(source)"
|
||||||
|
:key="source.bookSourceUrl"
|
||||||
|
>
|
||||||
|
{{ source.bookSourceName || source.sourceName }}
|
||||||
|
</el-checkbox>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const { source } = defineProps(['source'])
|
||||||
|
const store = useSourceStore()
|
||||||
|
const { errorPushSources } = storeToRefs(store)
|
||||||
|
const handleSourceClick = source => {
|
||||||
|
store.changeCurrentSource(source)
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-input
|
<el-input
|
||||||
|
id="source-json"
|
||||||
v-model="sourceString"
|
v-model="sourceString"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
placeholder="这里输出序列化的JSON数据,可直接导入'阅读'APP"
|
placeholder="这里输出序列化的JSON数据,可直接导入'阅读'APP"
|
||||||
@ -33,8 +34,11 @@ watchEffect(async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style scoped>
|
||||||
.el-input {
|
:deep(.el-input) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
:deep(#source-json) {
|
||||||
|
height: calc(100vh - 50px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<div class="tool">
|
<div class="tool">
|
||||||
<el-button @click="importSourceFile" :icon="Folder"> 打开 </el-button>
|
<el-button @click="importSourceFile" :icon="Folder"> 打开 </el-button>
|
||||||
<el-button
|
<el-button
|
||||||
:disabled="sourceSelect.length === 0"
|
:disabled="sourcesFiltered.length === 0"
|
||||||
@click="outExport"
|
@click="outExport"
|
||||||
:icon="Download"
|
:icon="Download"
|
||||||
>
|
>
|
||||||
@ -29,35 +29,28 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<el-checkbox-group id="source-list" v-model="sourceSelect">
|
<el-checkbox-group id="source-list" v-model="sourceSelect">
|
||||||
<el-checkbox
|
<virtual-list
|
||||||
v-for="source in sourcesFiltered"
|
style="height: 100%; overflow-y: auto; overflow-x: hidden;"
|
||||||
size="large"
|
:data-key="'bookSourceUrl'"
|
||||||
border
|
:data-sources="sourcesFiltered"
|
||||||
:label="source"
|
:data-component="SourceItem"
|
||||||
:class="{ error: errorPushSources.includes(source) }"
|
:estimate-size="45"
|
||||||
@click="handleSourceClick(source)"
|
/>
|
||||||
:key="source.bookSourceName"
|
|
||||||
>
|
|
||||||
{{ source.bookSourceName || source.sourceName }}
|
|
||||||
</el-checkbox>
|
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Folder, Delete, Download, Search } from "@element-plus/icons-vue";
|
import { Folder, Delete, Download, Search } from "@element-plus/icons-vue";
|
||||||
import { isSourceContains } from "../utils/souce";
|
import { isSourceContains } from "../utils/souce";
|
||||||
|
import VirtualList from 'vue3-virtual-scroll-list';
|
||||||
|
import SourceItem from "./SourceItem.vue";
|
||||||
const store = useSourceStore();
|
const store = useSourceStore();
|
||||||
const sourceSelect = ref([]);
|
const sourceSelect = ref([]);
|
||||||
const searchKey = ref("");
|
const searchKey = ref("");
|
||||||
const { sources, errorPushSources } = storeToRefs(store);
|
const { sources } = storeToRefs(store);
|
||||||
|
|
||||||
const isBookSource = computed(() => {
|
const isBookSource = computed(() => {
|
||||||
return /bookSource/.test(window.location.href);
|
return /bookSource/.test(window.location.href);
|
||||||
});
|
});
|
||||||
const handleSourceClick = (source) => {
|
|
||||||
store.changeCurrentSource(source);
|
|
||||||
};
|
|
||||||
const deleteSelectSources = () => {
|
const deleteSelectSources = () => {
|
||||||
store.deleteSources(sourceSelect.value);
|
store.deleteSources(sourceSelect.value);
|
||||||
sourceSelect.value = [];
|
sourceSelect.value = [];
|
||||||
@ -104,7 +97,7 @@ const importSourceFile = () => {
|
|||||||
};
|
};
|
||||||
const outExport = () => {
|
const outExport = () => {
|
||||||
const exportFile = document.createElement("a");
|
const exportFile = document.createElement("a");
|
||||||
let sources = store.sources,
|
let sources = sourceSelect.value.length === 0 ? sourcesFiltered.value : sourceSelect.value,
|
||||||
sourceType = isBookSource.value ? "BookSource" : "RssSource";
|
sourceType = isBookSource.value ? "BookSource" : "RssSource";
|
||||||
|
|
||||||
exportFile.download = `${sourceType}_${Date()
|
exportFile.download = `${sourceType}_${Date()
|
||||||
@ -122,15 +115,13 @@ const outExport = () => {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.tool {
|
.tool {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 4px 0;
|
margin: 4px 0;
|
||||||
justify-content: space-between;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#source-list {
|
#source-list {
|
||||||
padding-top: 6px;
|
margin-top: 6px;
|
||||||
height: calc(100vh - 112px - 20px);
|
height: calc(100vh - 112px - 7px);
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
:deep(.el-checkbox) {
|
:deep(.el-checkbox) {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
|
@ -69,7 +69,12 @@ const { currentSource } = storeToRefs(store);
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-tab-pane) {
|
:deep(.el-tab-pane) {
|
||||||
height: calc(100vh - 40px);
|
height: calc(100vh - 55px);
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-right: 5px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
:deep(.el-tabs__header) {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -29,4 +29,8 @@ const tabData = ref([
|
|||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
:deep(.el-tabs__header) {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -72,6 +72,11 @@ import { isInvaildSource } from "../utils/souce";
|
|||||||
|
|
||||||
const store = useSourceStore();
|
const store = useSourceStore();
|
||||||
const pull = () => {
|
const pull = () => {
|
||||||
|
const loadingMsg = ElMessage({
|
||||||
|
message: '加载中……',
|
||||||
|
showClose: true,
|
||||||
|
duration: 0
|
||||||
|
})
|
||||||
API.getSources().then(({ data }) => {
|
API.getSources().then(({ data }) => {
|
||||||
if (data.isSuccess) {
|
if (data.isSuccess) {
|
||||||
store.changeTabName("editList");
|
store.changeTabName("editList");
|
||||||
@ -86,7 +91,7 @@ const pull = () => {
|
|||||||
type: "error",
|
type: "error",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
}).finally(() => loadingMsg.close());
|
||||||
};
|
};
|
||||||
|
|
||||||
const push = () => {
|
const push = () => {
|
||||||
|
@ -552,11 +552,11 @@ id: "deleteUrl",
|
|||||||
id: "enabledExplore",
|
id: "enabledExplore",
|
||||||
type: "Boolean",
|
type: "Boolean",
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: "启用段评",
|
// title: "启用段评",
|
||||||
id: "enabledReview",
|
// id: "enabledReview",
|
||||||
type: "Boolean",
|
// type: "Boolean",
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: "Cookie",
|
title: "Cookie",
|
||||||
id: "enabledCookieJar",
|
id: "enabledCookieJar",
|
||||||
|
@ -30,6 +30,7 @@ if (/bookSource/i.test(location.href)) {
|
|||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
.right {
|
.right {
|
||||||
|
flex: 1;
|
||||||
width: 360px;
|
width: 360px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user