fix(web): 修复进度同步和返回书架同步

This commit is contained in:
Xwite
2023-05-09 17:19:46 +08:00
parent 271aa770b1
commit 02a215202c
5 changed files with 87 additions and 91 deletions
+57 -46
View File
@@ -81,11 +81,18 @@
<div class="chapter" ref="content" :style="chapterTheme">
<div class="content">
<div class="top-bar" ref="top"></div>
<div v-for="data in chapterData" :key="data.index" ref="chapter">
<div
v-for="data in chapterData"
:key="data.index"
:chapterIndex="data.index"
ref="chapter"
>
<chapter-content
:carray="data.content"
:contents="data.content"
:title="data.title"
:spacing="store.config.spacing"
:fontSize="fontSize"
:fontFamily="fontFamily"
v-if="showContent"
/>
</div>
@@ -124,10 +131,9 @@ try {
} catch {
localStorage.removeItem("config");
}
const loading = ref();
const noPoint = ref(true);
const showToolBar = ref(false);
const chapterData = ref([]);
const scrollObserve = ref(null);
@@ -139,11 +145,32 @@ const {
readSettingsVisible,
miniInterface,
showContent,
config,
readingBook,
} = storeToRefs(store);
const { chapterPos, index: chapterIndex } = toRefs(store.readingBook);
const chapterPos = computed({
get: () => readingBook.value.chapterPos,
set: (value) => (readingBook.value.chapterPos = value),
});
const chapterIndex = computed({
get: () => readingBook.value.index,
set: (value) => (readingBook.value.index = value),
});
const { theme, infiniteLoading } = toRefs(store.config);
const theme = computed(() => config.value.theme);
const infiniteLoading = computed(() => config.value.infiniteLoading);
// 字体
const fontFamily = computed(() => {
if (store.config.font >= 0) {
return settings.fonts[store.config.font];
}
return store.config.customFontName;
});
const fontSize = computed(() => {
return store.config.fontSize + "px";
});
// 主题部分
const bodyColor = computed(() => settings.themes[theme.value].body);
@@ -193,10 +220,7 @@ const rightBarTheme = computed(() => {
display: miniInterface.value && !showToolBar.value ? "none" : "block",
};
});
const isNight = ref(false);
watchEffect(() => {
isNight.value = theme.value == 6;
});
const isNight = computed(() => theme.value == 6);
watchEffect(() => {
if (chapterData.value.length > 0) {
@@ -239,6 +263,7 @@ const getContent = (index, reloadChapter = true, chapterPos = 0) => {
let data = res.data.data;
let content = data.split(/\n+/);
updateChapterData({ index, content, title }, reloadChapter);
toChapterPos(chapterPos);
} else {
ElMessage({ message: res.data.errorMsg, type: "error" });
let content = [res.data.errorMsg];
@@ -263,39 +288,32 @@ const getContent = (index, reloadChapter = true, chapterPos = 0) => {
);
};
const chapter = ref();
const toChapterPos = (chapterPos) => {
if (!chapterPos) return;
const toChapterPos = (pos) => {
nextTick(() => {
//计算chapterPos对应的段落行数
let wordCount = 0;
let index = chapterData.value[0].content.findIndex((paragraph) => {
wordCount += paragraph.length;
return wordCount >= chapterPos.value;
});
if (index == -1) index = chapterData.value[0].content.length - 1;
if (index == 0) return; //第一行不跳转
//跳转
jump(chapter.value[0].children[1].children[index], {
duration: 0,
callback: () => (chapterPos.value = 0),
});
for (let element of chapter.value[0].children) {
wordCount += parseInt(element.getAttribute("wordCount"));
if (wordCount >= pos) {
jump(element, {
duration: 0,
});
break;
}
}
});
};
//计算当前章节阅读的字数
const computeChapterPos = () => {
//dom没渲染时 返回0
if (!chapter.value[0]) return;
if (chapter.value.length == 0) return;
//计算当前阅读进度对应的element
let index = chapterData.value.findIndex(
(chapter) => chapter.index == chapterIndex.value
let chapterElement = chapter.value.find(
(element) => element.getAttribute("chapterIndex") == chapterIndex.value
);
if (index == -1) return;
let element = chapter.value[index].children[1].children;
if (!chapterElement) return;
//计算已读字数
let mChapterPos = 0;
for (let paragraph of element) {
let text = paragraph.innerText;
mChapterPos += text.length;
for (let paragraph of chapterElement.children) {
mChapterPos += parseInt(paragraph.getAttribute("wordCount"));
if (paragraph.getBoundingClientRect().top >= 0) {
chapterPos.value = mChapterPos;
break;
@@ -431,9 +449,7 @@ const handleIScrollObserve = (entries) => {
const handleIReadingObserve = (entries) => {
nextTick(() => {
for (let { isIntersecting, target, boundingClientRect } of entries) {
let titleElement = target.querySelector(".title");
if (!titleElement) return;
let chapterTitleIndex = parseInt(titleElement.getAttribute("index"));
let chapterTitleIndex = parseInt(target.getAttribute("chapterIndex"));
if (isIntersecting) {
chapterIndex.value = chapterTitleIndex;
} else {
@@ -454,17 +470,13 @@ const addReadingObserve = () => {
chapterElements.forEach((el) => readingObserve.value.observe(el));
});
};
/*
onBeforeRouteLeave((to, from, next) => {
if (
store.searchBooks.every((book) => book.bookUrl != store.readingBook.bookUrl)
) {
next();
} else {
alert(111);
next(false);
}
computeChapterPos();
saveReadingBookProgressToBrowser(chapterIndex.value);
next();
});
/*
window.addEventListener("beforeunload", (e) => {
e.preventDefault();
e.returnValue = "";
@@ -508,7 +520,6 @@ onMounted(() => {
store.setReadingBook(book);
getContent(chapterIndex, true, chapterPos);
window.addEventListener("keyup", handleKeyPress);
//监听底部加载
scrollObserve.value = new IntersectionObserver(handleIScrollObserve, {