From 7e0087a7db9de5401a51544e47668dbd7a9c8c40 Mon Sep 17 00:00:00 2001 From: UnknownMp Date: Tue, 27 May 2025 23:57:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B8=A6=E7=AB=A0=E8=8A=82?= =?UTF-8?q?=E4=BD=9C=E5=93=81=20=E7=BD=91=E7=AB=99=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=8C=E5=96=84=20=F0=9F=A5=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [UX] 增加对格式错误的链接检测 在搜索或者切换章节时地址栏和标题会跟着变动 [UI] 不再使用 mdui-collapse 作为作品信息容器 SSR 时作品文段渲染增加到 20 行 [Fix] SSR 时 Category 与 Fandom 标识错误 [Base] Summary 不再使用 v-for [NewBug] 在搜索不到东西时会显示搜索完成, 推断是状态转移不完全 --- src/stores/workRead.js | 26 +++++++++-- src/views/SimpleSearch.vue | 10 +++-- src/views/Work.vue | 90 +++++++++++++++++++++++++------------- 3 files changed, 89 insertions(+), 37 deletions(-) diff --git a/src/stores/workRead.js b/src/stores/workRead.js index 1aa2e03..d1e1d26 100644 --- a/src/stores/workRead.js +++ b/src/stores/workRead.js @@ -21,10 +21,13 @@ export const useWorkReadState = defineStore('workRead', () => { const category = ref([]) const fandom = ref([]) const lang = ref(null) + const chapters = ref([]) + const chapterIndex = ref(null) function setData(data) { + cid.value = data.chapterId id.value = data.workId title.value = data.title - summary.value = [escapeAndFormatText(data.summary)] + summary.value = data.summary ? escapeAndFormatText(data.summary) : null pseud.value = data.pseud text.value = data.text publishedTime.value = data.stats.publishedTime @@ -34,11 +37,26 @@ export const useWorkReadState = defineStore('workRead', () => { category.value = data.category fandom.value = data.fandom lang.value = data.lang + chapters.value = data.chapters || [] + chapterIndex.value = data.chapterIndex ?? null } async function loadWork(target, targetc) { - if (target == id.value && targetc == cid.value || state.value == 'loading') return + const itarget = parseInt(target) + if (isNaN(itarget)) { + console.log('a') + state.value = 'errformat' + return + } + const itargetc = parseInt(targetc) + if ( + itarget === id.value && + (itargetc === cid.value || (isNaN(itargetc) && cid.value === null)) && + state.value !== 'loading' + ) return + id.value = itarget + cid.value = isNaN(itargetc) ? null : itargetc state.value = 'loading' - const result = await api.getWork(target, targetc) + const result = await api.getWork(id.value, cid.value) if (result.status == 200) { setData(result.data) state.value = 'ready' @@ -61,6 +79,8 @@ export const useWorkReadState = defineStore('workRead', () => { category, fandom, lang, + chapters, + chapterIndex, setData, loadWork } diff --git a/src/views/SimpleSearch.vue b/src/views/SimpleSearch.vue index 99e12ca..584e755 100644 --- a/src/views/SimpleSearch.vue +++ b/src/views/SimpleSearch.vue @@ -1,6 +1,6 @@ diff --git a/src/views/Work.vue b/src/views/Work.vue index b2ecb66..053f580 100644 --- a/src/views/Work.vue +++ b/src/views/Work.vue @@ -19,8 +19,6 @@ import 'mdui/components/button.js' import 'mdui/components/dropdown.js' import 'mdui/components/menu.js' import 'mdui/components/menu-item.js' -import 'mdui/components/collapse.js' -import 'mdui/components/collapse-item.js' import 'mdui/components/card.js' import '@mdui/icons/bookmark.js' @@ -41,6 +39,7 @@ let lastCloseTimer = null let isObserver = null let paragraphs = [] let currentParagraph = null +const chapterDialog = ref(null) const categoryName = { mm: "男/男", @@ -48,21 +47,25 @@ const categoryName = { fm: '女/男' } - onServerPrefetch(async () => { await workReadState.loadWork(route.params.id, route.params.cid) }) onMounted(async () => { + watch(() => workReadState.state, (value) => { if (value == 'ready') routeState.customTitle = workReadState.title }) if (workReadState.state != 'ssrnotfound') await workReadState.loadWork(route.params.id, route.params.cid) if (workReadState.state == 'ready') { routeState.customTitle = workReadState.title + if (parseInt(route.params.cid) != workReadState.cid) { + router.replace(`/work/${workReadState.id}/${workReadState.cid}`) + return; + } const paraCount = workReadState.text.length - 1 isObserver = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { currentParagraph = entry.target - readIndex = entry.target.dataset.index; + readIndex = entry.target.dataset.index readPercent.value = parseInt(readIndex / paraCount * 100) if (lastPercent == 0) { lastPercent = readPercent.value @@ -89,8 +92,13 @@ onMounted(async () => { }) onBeforeUnmount(() => { - isObserver.disconnect(); + if(isObserver) isObserver.disconnect(); }) + +async function switchWorkWithIndex(target) { + workReadState.loadWork(workReadState.id,workReadState.chapters[target].chapterId); + router.replace(`/work/${workReadState.id}/${workReadState.cid}`) +} 返回 +