web端优化数据加载
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
# d.ts files Generated by unplugin-auto unplugin-vue-components
|
||||||
|
auto-imports.d.ts
|
||||||
|
components.d.ts
|
||||||
@@ -1,16 +1,12 @@
|
|||||||
import type { AxiosResponse } from 'axios'
|
import type { AxiosResponse } from 'axios'
|
||||||
import type { LeagdoApiResponse } from './api'
|
import type { LeagdoApiResponse } from './api'
|
||||||
import API, {
|
import API, { setWebsocketOnError, setApiEntryPoint } from './api'
|
||||||
setWebsocketOnError,
|
|
||||||
legado_http_entry_point,
|
|
||||||
legado_webSocket_entry_point,
|
|
||||||
setApiEntryPoint,
|
|
||||||
} from './api'
|
|
||||||
import ajax from './axios'
|
import ajax from './axios'
|
||||||
import { validatorHttpUrl } from '@/utils/utils'
|
import { validatorHttpUrl } from '@/utils/utils'
|
||||||
|
|
||||||
const LeagdoApiResponseKeys: string[] = Array.of('isSuccess', 'errorMsg')
|
const LeagdoApiResponseKeys: string[] = Array.of('isSuccess', 'errorMsg')
|
||||||
|
|
||||||
|
const notification = ElMessage
|
||||||
/** Axios.Interceptor: check if resp is LeagaoLeagdoApiResponse*/
|
/** Axios.Interceptor: check if resp is LeagaoLeagdoApiResponse*/
|
||||||
const responseCheckInterceptor = (resp: AxiosResponse) => {
|
const responseCheckInterceptor = (resp: AxiosResponse) => {
|
||||||
let isLeagdoApiResponse = true
|
let isLeagdoApiResponse = true
|
||||||
@@ -26,21 +22,23 @@ const responseCheckInterceptor = (resp: AxiosResponse) => {
|
|||||||
if ((data as LeagdoApiResponse<unknown>).isSuccess === true) {
|
if ((data as LeagdoApiResponse<unknown>).isSuccess === true) {
|
||||||
if (!('data' in data)) {
|
if (!('data' in data)) {
|
||||||
isLeagdoApiResponse = false
|
isLeagdoApiResponse = false
|
||||||
LeagdoApiResponseKeys.length = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
isLeagdoApiResponse = false
|
isLeagdoApiResponse = false
|
||||||
}
|
}
|
||||||
if (isLeagdoApiResponse === false) {
|
if (isLeagdoApiResponse === false) {
|
||||||
ElNotification.warning('后端返回内容格式错误')
|
notification.warning({ message: '后端返回内容格式错误', grouping: true })
|
||||||
throw new Error()
|
throw new Error()
|
||||||
}
|
}
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
const axiosErrorInterceptor = (err: unknown) => {
|
const axiosErrorInterceptor = (err: unknown) => {
|
||||||
ElNotification.error('后端连接失败,请检查阅读WEB服务或者设置其它可用链接')
|
notification.error({
|
||||||
|
message: '后端连接失败,请检查阅读WEB服务或者设置其它可用链接',
|
||||||
|
grouping: true,
|
||||||
|
})
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
// http全局
|
// http全局
|
||||||
@@ -80,8 +78,8 @@ export const parseLeagdoHttpUrlWithDefault = (
|
|||||||
|
|
||||||
console.info('legado_api_config:')
|
console.info('legado_api_config:')
|
||||||
console.table({
|
console.table({
|
||||||
'http API入口': legado_http_entry_point,
|
'http API入口': http_entry_point,
|
||||||
'webSocket API入口': legado_webSocket_entry_point,
|
'webSocket API入口': webSocket_entry_point,
|
||||||
})
|
})
|
||||||
return [http_entry_point, webSocket_entry_point]
|
return [http_entry_point, webSocket_entry_point]
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -9,7 +9,6 @@ declare global {
|
|||||||
const EffectScope: typeof import('vue')['EffectScope']
|
const EffectScope: typeof import('vue')['EffectScope']
|
||||||
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
||||||
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
|
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
|
||||||
const ElNotification: typeof import('element-plus/es')['ElNotification']
|
|
||||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||||
const computed: typeof import('vue')['computed']
|
const computed: typeof import('vue')['computed']
|
||||||
const createApp: typeof import('vue')['createApp']
|
const createApp: typeof import('vue')['createApp']
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ const subJustify = computed(() =>
|
|||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.books-wrapper {
|
.books-wrapper {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const catas = computed(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.selected {
|
.selected {
|
||||||
color: #eb4259;
|
color: #eb4259;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import type { webReadConfig } from '@/web'
|
|||||||
const store = useBookStore()
|
const store = useBookStore()
|
||||||
const readWidth = computed(() => store.config.readWidth)
|
const readWidth = computed(() => store.config.readWidth)
|
||||||
const bookUrl = computed(() => store.readingBook.bookUrl)
|
const bookUrl = computed(() => store.readingBook.bookUrl)
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
chapterIndex: number
|
chapterIndex: number
|
||||||
contents: Array<string>
|
contents: Array<string>
|
||||||
@@ -116,7 +117,7 @@ onUnmounted(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.title {
|
.title {
|
||||||
margin-bottom: 57px;
|
margin-bottom: 57px;
|
||||||
font:
|
font:
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ const gotoChapter = (chapter: BookChapter) => {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.cata-wrapper {
|
.cata-wrapper {
|
||||||
margin: -16px;
|
margin: -16px;
|
||||||
padding: 18px 0 24px 25px;
|
padding: 18px 0 24px 25px;
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ const setInfiniteLoading = (loading: boolean) => {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.iconfont) {
|
:deep(.iconfont) {
|
||||||
font-family: iconfont;
|
font-family: iconfont;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ const isBookSource = computed(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(#debug-text) {
|
:deep(#debug-text) {
|
||||||
height: calc(100vh - 45px - 36px - 5px);
|
height: calc(100vh - 45px - 36px - 5px);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import { Link } from '@element-plus/icons-vue'
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.el-link {
|
.el-link {
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const isSaveError = computed(() => {
|
|||||||
return !map.has(sourceUrl.value)
|
return !map.has(sourceUrl.value)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-checkbox__label) {
|
:deep(.el-checkbox__label) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ watchEffect(async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-input) {
|
:deep(.el-input) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ const outExport = () => {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.tool {
|
.tool {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 4px 0;
|
margin: 4px 0;
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.flex-space-between {
|
.flex-space-between {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
-5
@@ -2,11 +2,6 @@ import type { Source } from '@/source'
|
|||||||
import bookSourceEditConfig from './bookSourceEditConfig'
|
import bookSourceEditConfig from './bookSourceEditConfig'
|
||||||
import rssSourceEditConfig from './rssSourceEditConfig'
|
import rssSourceEditConfig from './rssSourceEditConfig'
|
||||||
|
|
||||||
type PickAnyValueKey<T> = {
|
|
||||||
[K in keyof T]: T[K] extends { [prop: string]: string } ? K : never
|
|
||||||
}
|
|
||||||
type b = keyof PickAnyValueKey<BookSoure>
|
|
||||||
|
|
||||||
type SourceConfigKey =
|
type SourceConfigKey =
|
||||||
| keyof typeof bookSourceEditConfig
|
| keyof typeof bookSourceEditConfig
|
||||||
| keyof typeof rssSourceEditConfig
|
| keyof typeof rssSourceEditConfig
|
||||||
|
|||||||
@@ -19,4 +19,18 @@ const router = createRouter({
|
|||||||
routes: bookRoutes,
|
routes: bookRoutes,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from '@/App.vue'
|
||||||
|
import store, { useBookStore } from '@/store'
|
||||||
|
|
||||||
|
// init pinia instance
|
||||||
|
createApp(App).use(store)
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
// 自动加载阅读配置
|
||||||
|
useBookStore()
|
||||||
|
.loadWebConfig()
|
||||||
|
.then(() => next())
|
||||||
|
.catch(() => next())
|
||||||
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
@@ -11,4 +11,19 @@ const router = createRouter({
|
|||||||
router.afterEach(to => {
|
router.afterEach(to => {
|
||||||
if (to.name == 'shelf') document.title = '书架'
|
if (to.name == 'shelf') document.title = '书架'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from '@/App.vue'
|
||||||
|
import store, { useBookStore } from '@/store'
|
||||||
|
|
||||||
|
// init pinia instance
|
||||||
|
createApp(App).use(store)
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
// 自动加载阅读配置
|
||||||
|
useBookStore()
|
||||||
|
.loadWebConfig()
|
||||||
|
.then(() => next())
|
||||||
|
.catch(() => next())
|
||||||
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
@@ -8,6 +8,23 @@ import type {
|
|||||||
SeachBook,
|
SeachBook,
|
||||||
} from '@/book'
|
} from '@/book'
|
||||||
import type { webReadConfig } from '@/web'
|
import type { webReadConfig } from '@/web'
|
||||||
|
import { ElMessage } from 'element-plus/es'
|
||||||
|
|
||||||
|
const default_config: webReadConfig = {
|
||||||
|
theme: 0,
|
||||||
|
font: 0,
|
||||||
|
fontSize: 18,
|
||||||
|
readWidth: 800,
|
||||||
|
infiniteLoading: false,
|
||||||
|
customFontName: '',
|
||||||
|
jumpDuration: 1000,
|
||||||
|
spacing: {
|
||||||
|
paragraph: 1,
|
||||||
|
line: 0.8,
|
||||||
|
letter: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
let webReadConfigLoadedDate: Date | undefined
|
||||||
|
|
||||||
export const useBookStore = defineStore('book', {
|
export const useBookStore = defineStore('book', {
|
||||||
state: () => {
|
state: () => {
|
||||||
@@ -18,7 +35,7 @@ export const useBookStore = defineStore('book', {
|
|||||||
searchBooks: [] as SeachBook[],
|
searchBooks: [] as SeachBook[],
|
||||||
shelf: [] as Book[],
|
shelf: [] as Book[],
|
||||||
catalog: [] as BookChapter[],
|
catalog: [] as BookChapter[],
|
||||||
readingBook: {} as BaseBook & {
|
readingBook: { chapterPos: 0, chapterIndex: 0 } as BaseBook & {
|
||||||
chapterPos: number
|
chapterPos: number
|
||||||
chapterIndex: number
|
chapterIndex: number
|
||||||
isSeachBook?: boolean
|
isSeachBook?: boolean
|
||||||
@@ -26,20 +43,7 @@ export const useBookStore = defineStore('book', {
|
|||||||
popCataVisible: false,
|
popCataVisible: false,
|
||||||
contentLoading: true,
|
contentLoading: true,
|
||||||
showContent: false,
|
showContent: false,
|
||||||
config: {
|
config: default_config as webReadConfig,
|
||||||
theme: -1,
|
|
||||||
font: 0,
|
|
||||||
fontSize: 18,
|
|
||||||
readWidth: 800,
|
|
||||||
infiniteLoading: false,
|
|
||||||
customFontName: '',
|
|
||||||
jumpDuration: 1000,
|
|
||||||
spacing: {
|
|
||||||
paragraph: 1,
|
|
||||||
line: 0.8,
|
|
||||||
letter: 0,
|
|
||||||
},
|
|
||||||
} as webReadConfig,
|
|
||||||
miniInterface: false,
|
miniInterface: false,
|
||||||
readSettingsVisible: false,
|
readSettingsVisible: false,
|
||||||
}
|
}
|
||||||
@@ -62,7 +66,6 @@ export const useBookStore = defineStore('book', {
|
|||||||
theme: state => {
|
theme: state => {
|
||||||
return state.config.theme
|
return state.config.theme
|
||||||
},
|
},
|
||||||
configInited: state => state.config.theme !== -1,
|
|
||||||
isNight: state => state.config.theme == 6,
|
isNight: state => state.config.theme == 6,
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -75,12 +78,83 @@ export const useBookStore = defineStore('book', {
|
|||||||
setNewConnect(newConnect: boolean) {
|
setNewConnect(newConnect: boolean) {
|
||||||
this.newConnect = newConnect
|
this.newConnect = newConnect
|
||||||
},
|
},
|
||||||
addBooks(books: Book[]) {
|
/** 从后端加载书架书籍,优先返回内存缓存 */
|
||||||
this.shelf = books
|
async loadBookShelf(): Promise<Book[]> {
|
||||||
|
const fetchBookshellf_promise = API.getBookShelf().then(resp => {
|
||||||
|
console.log('API.getBookShelf数据返回')
|
||||||
|
const { isSuccess, data, errorMsg } = resp.data
|
||||||
|
if (isSuccess === true) {
|
||||||
|
if (
|
||||||
|
this.shelf.length !== data.length &&
|
||||||
|
this.shelf.length > 0 &&
|
||||||
|
data.length > 0
|
||||||
|
) {
|
||||||
|
ElMessage.info(`书架数据已更新`)
|
||||||
|
}
|
||||||
|
this.shelf = data.sort((a, b) => {
|
||||||
|
const x = a['durChapterTime'] || 0
|
||||||
|
const y = b['durChapterTime'] || 0
|
||||||
|
return y - x
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (errorMsg.includes('还没有添加小说') && this.shelf.length > 0) {
|
||||||
|
ElMessage.info('当前书架上的书籍已经被删除')
|
||||||
|
return (this.shelf = [])
|
||||||
|
}
|
||||||
|
ElMessage.error(errorMsg ?? '后端返回格式错误!')
|
||||||
|
}
|
||||||
|
console.log('书架数据已更新')
|
||||||
|
return this.shelf
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.shelf.length > 0) {
|
||||||
|
// bookshelf data fetched before:do not await
|
||||||
|
console.log('返回缓存书架数据')
|
||||||
|
return this.shelf
|
||||||
|
} else {
|
||||||
|
console.log('从阅读后端获取书架数据...')
|
||||||
|
return await fetchBookshellf_promise
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clearBooks() {
|
clearBooks() {
|
||||||
this.shelf = []
|
this.shelf = []
|
||||||
},
|
},
|
||||||
|
/** 从后端加载书籍目录,优先返回内存缓存 */
|
||||||
|
async loadWebCatalog(
|
||||||
|
book: typeof this.readingBook,
|
||||||
|
): Promise<BookChapter[]> {
|
||||||
|
const { bookUrl, name, chapterIndex } = book
|
||||||
|
const fetchChapterList_promise = API.getChapterList(
|
||||||
|
book.bookUrl as string,
|
||||||
|
).then(res => {
|
||||||
|
const { isSuccess, data, errorMsg } = res.data
|
||||||
|
if (isSuccess === false) {
|
||||||
|
ElMessage.error(errorMsg)
|
||||||
|
throw new Error()
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
data.length !== this.catalog.length &&
|
||||||
|
data.length > 0 &&
|
||||||
|
this.catalog.length > 0
|
||||||
|
) {
|
||||||
|
ElMessage.info(`书籍${name}: 章节目录已更新`)
|
||||||
|
}
|
||||||
|
this.setCatalog(data)
|
||||||
|
console.log(`书籍${name}: 章节目录已更新`)
|
||||||
|
return this.catalog
|
||||||
|
})
|
||||||
|
if (
|
||||||
|
bookUrl === this.readingBook.bookUrl &&
|
||||||
|
this.catalog.length > 0 &&
|
||||||
|
this.catalog.length - 1 >= chapterIndex
|
||||||
|
) {
|
||||||
|
console.log(`返回书籍《${name}》 缓存的章节目录`)
|
||||||
|
return this.catalog
|
||||||
|
} else {
|
||||||
|
console.log(`从阅读后端获取书籍《${name}》 章节目录数据...`)
|
||||||
|
return await fetchChapterList_promise
|
||||||
|
}
|
||||||
|
},
|
||||||
setCatalog(catalog: BookChapter[]) {
|
setCatalog(catalog: BookChapter[]) {
|
||||||
this.catalog = catalog
|
this.catalog = catalog
|
||||||
},
|
},
|
||||||
@@ -93,8 +167,22 @@ export const useBookStore = defineStore('book', {
|
|||||||
setReadingBook(readingBook: typeof this.readingBook) {
|
setReadingBook(readingBook: typeof this.readingBook) {
|
||||||
this.readingBook = readingBook
|
this.readingBook = readingBook
|
||||||
},
|
},
|
||||||
setConfig(config: webReadConfig) {
|
/** 只从从后端加载一次web阅读配置 */
|
||||||
this.config = Object.assign({}, this.config, config)
|
async loadWebConfig() {
|
||||||
|
if (webReadConfigLoadedDate === undefined) {
|
||||||
|
const _config = await API.getReadConfig()
|
||||||
|
webReadConfigLoadedDate = new Date()
|
||||||
|
console.log(
|
||||||
|
`${this.$id}.loadWebConfig: ${webReadConfigLoadedDate.toLocaleString()}成功加载阅读配置`,
|
||||||
|
)
|
||||||
|
return this.setConfig(_config)
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`${this.$id}.loadWebConfig: 已于${webReadConfigLoadedDate.toLocaleString()}成功加载`,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
setConfig(config?: webReadConfig) {
|
||||||
|
this.config = Object.assign({}, this.config ?? default_config, config)
|
||||||
},
|
},
|
||||||
setReadSettingsVisible(visible: boolean) {
|
setReadSettingsVisible(visible: boolean) {
|
||||||
this.readSettingsVisible = visible
|
this.readSettingsVisible = visible
|
||||||
@@ -118,9 +206,19 @@ export const useBookStore = defineStore('book', {
|
|||||||
clearSearchBooks() {
|
clearSearchBooks() {
|
||||||
this.searchBooks = []
|
this.searchBooks = []
|
||||||
},
|
},
|
||||||
//保存进度到app
|
/** 1.保存进度到app 2.修改内存中的数据*/
|
||||||
async saveBookProgress() {
|
async saveBookProgress() {
|
||||||
if (!this.bookProgress) return Promise.resolve()
|
if (!this.bookProgress) return Promise.resolve()
|
||||||
|
const { bookUrl } = this.readingBook
|
||||||
|
const shelfRaw = toRaw(this.shelf)
|
||||||
|
const findIndex = shelfRaw.findIndex(book => book.bookUrl === bookUrl)
|
||||||
|
if (findIndex > -1) {
|
||||||
|
this.shelf[findIndex] = Object.assign(
|
||||||
|
{},
|
||||||
|
shelfRaw[findIndex],
|
||||||
|
this.bookProgress,
|
||||||
|
)
|
||||||
|
}
|
||||||
return API.saveBookProgress(this.bookProgress)
|
return API.saveBookProgress(this.bookProgress)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
>
|
>
|
||||||
<PopCatalog @getContent="getContent" class="popup" />
|
<PopCatalog @getContent="getContent" class="popup" />
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div class="tool-icon" :class="{ 'no-point': noPoint }">
|
<div class="tool-icon" :class="{ 'no-point': false }">
|
||||||
<div class="iconfont"></div>
|
<div class="iconfont"></div>
|
||||||
<div class="icon-text">目录</div>
|
<div class="icon-text">目录</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -318,7 +318,6 @@ const getContent = (index: number, reloadChapter = true, chapterPos = 0) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
ElMessage({ message: '获取章节内容失败', type: 'error' })
|
|
||||||
const content = ['获取章节内容失败!']
|
const content = ['获取章节内容失败!']
|
||||||
chapterData.value.push({ index, content, title })
|
chapterData.value.push({ index, content, title })
|
||||||
store.setShowContent(true)
|
store.setShowContent(true)
|
||||||
@@ -496,61 +495,25 @@ onMounted(() => {
|
|||||||
chapterPos,
|
chapterPos,
|
||||||
isSeachBook,
|
isSeachBook,
|
||||||
}
|
}
|
||||||
/* const bookStr = localStorage.getItem(bookUrl);
|
|
||||||
if (isNullOrBlank(bookStr)) {
|
|
||||||
return setTimeout(toShelf, 500);
|
|
||||||
}
|
|
||||||
book = JSON.parse(bookStr as string);
|
|
||||||
if (
|
|
||||||
book == null ||
|
|
||||||
chapterIndex != book.chapterIndex ||
|
|
||||||
chapterPos != book.chapterPos
|
|
||||||
) {
|
|
||||||
book = {
|
|
||||||
name: bookName!!,
|
|
||||||
author: bookAuthor!!,
|
|
||||||
bookUrl,
|
|
||||||
chapterIndex,
|
|
||||||
chapterPos,
|
|
||||||
isSeachBook
|
|
||||||
};
|
|
||||||
localStorage.setItem(bookUrl, JSON.stringify(book));
|
|
||||||
} */
|
|
||||||
onResize()
|
onResize()
|
||||||
window.addEventListener('resize', onResize)
|
window.addEventListener('resize', onResize)
|
||||||
loadingWrapper(
|
loadingWrapper(
|
||||||
API.getChapterList(bookUrl as string).then(
|
store.loadWebCatalog(book).then(chapters => {
|
||||||
res => {
|
store.setReadingBook(book)
|
||||||
if (!res.data.isSuccess) {
|
getContent(chapterIndex, true, chapterPos)
|
||||||
ElMessage({ message: res.data.errorMsg, type: 'error' })
|
window.addEventListener('keyup', handleKeyPress)
|
||||||
setTimeout(toShelf, 500)
|
window.addEventListener('keydown', ignoreKeyPress)
|
||||||
return
|
// 兼容Safari < 14
|
||||||
}
|
document.addEventListener('visibilitychange', onVisibilityChange)
|
||||||
const data = res.data.data
|
//监听底部加载
|
||||||
store.setCatalog(data)
|
scrollObserver = new IntersectionObserver(onReachBottom, {
|
||||||
store.setReadingBook(book)
|
rootMargin: '-100% 0% 20% 0%',
|
||||||
|
})
|
||||||
getContent(chapterIndex, true, chapterPos)
|
if (infiniteLoading.value === true) scrollObserver.observe(loading.value)
|
||||||
window.addEventListener('keyup', handleKeyPress)
|
//第二次点击同一本书 页面标题不会变化
|
||||||
window.addEventListener('keydown', ignoreKeyPress)
|
document.title = '...'
|
||||||
// 兼容Safari < 14
|
document.title = (name as string) + ' | ' + chapters[chapterIndex].title
|
||||||
document.addEventListener('visibilitychange', onVisibilityChange)
|
}),
|
||||||
//监听底部加载
|
|
||||||
scrollObserver = new IntersectionObserver(onReachBottom, {
|
|
||||||
rootMargin: '-100% 0% 20% 0%',
|
|
||||||
})
|
|
||||||
if (infiniteLoading.value === true)
|
|
||||||
scrollObserver.observe(loading.value)
|
|
||||||
//第二次点击同一本书 页面标题不会变化
|
|
||||||
document.title = '...'
|
|
||||||
document.title =
|
|
||||||
(name as string) + ' | ' + catalog.value[chapterIndex].title
|
|
||||||
},
|
|
||||||
err => {
|
|
||||||
ElMessage({ message: '获取书籍目录失败', type: 'error' })
|
|
||||||
throw err
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -288,11 +288,7 @@ const toDetail = (
|
|||||||
|
|
||||||
const loadShelf = async () => {
|
const loadShelf = async () => {
|
||||||
try {
|
try {
|
||||||
if (store.configInited === false) {
|
//await store.loadWebConfig() called in router.beforeEach
|
||||||
const config = await API.getReadConfig()
|
|
||||||
applyReadConfig(config)
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
await store.saveBookProgress()
|
await store.saveBookProgress()
|
||||||
//确保各种网络情况下同步请求先完成
|
//确保各种网络情况下同步请求先完成
|
||||||
await fetchBookShelfData()
|
await fetchBookShelfData()
|
||||||
@@ -304,35 +300,11 @@ const loadShelf = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchBookShelfData = () => {
|
const fetchBookShelfData = async () => {
|
||||||
return API.getBookShelf().then(response => {
|
await store.loadBookShelf()
|
||||||
store.setConnectType('success')
|
store.setConnectType('primary')
|
||||||
if (response.data.isSuccess) {
|
store.setConnectStatus('已连接 ' + legado_http_entry_point)
|
||||||
//store.increaseBookNum(response.data.data.length);
|
store.setNewConnect(false)
|
||||||
store.addBooks(
|
|
||||||
response.data.data.sort(function (a, b) {
|
|
||||||
const x = a['durChapterTime'] || 0
|
|
||||||
const y = b['durChapterTime'] || 0
|
|
||||||
return y - x
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
response.data.errorMsg.includes('还没有添加小说') &&
|
|
||||||
shelf.value.length > 0
|
|
||||||
) {
|
|
||||||
ElNotification.warning({
|
|
||||||
title: '提示',
|
|
||||||
message: '当前书架上的书籍已经被删除',
|
|
||||||
position: 'bottom-right',
|
|
||||||
})
|
|
||||||
return store.clearBooks()
|
|
||||||
}
|
|
||||||
ElMessage.error(response.data.errorMsg ?? '后端返回格式错误!')
|
|
||||||
}
|
|
||||||
store.setConnectStatus('已连接 ' + legado_http_entry_point)
|
|
||||||
store.setNewConnect(false)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
//获取最近阅读书籍
|
//获取最近阅读书籍
|
||||||
@@ -348,7 +320,7 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style lang="scss" scoped>
|
||||||
.index-wrapper {
|
.index-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default defineConfig(({ mode }) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
esbuild: {
|
esbuild: {
|
||||||
drop: ["console"],
|
drop: mode === "development" ? undefined : ["console", "debugger"],
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
|
|||||||
Reference in New Issue
Block a user