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

This commit is contained in:
Xwite 2023-05-09 17:18:32 +08:00
parent 271aa770b1
commit 02a215202c
5 changed files with 87 additions and 91 deletions

View File

@ -12,6 +12,10 @@
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
**2023/05/09**
* web: 修复进度同步
**2023/05/08**
* 更新cronet: 113.0.5672.76

View File

@ -1,6 +1,10 @@
<template>
<div class="title">{{ title }}</div>
<div v-for="(para, index) in carray" :key="index">
<div class="title" wordCount="0">{{ title }}</div>
<div
v-for="(para, index) in contents"
:key="index"
:wordCount="calculateWordCount(para)"
>
<img
class="full"
v-if="/^\s*<img[^>]*src[^>]+>$/.test(para)"
@ -8,34 +12,19 @@
@error.once="proxyImage"
loading="lazy"
/>
<p v-else :style="style" v-html="para" />
<p v-else :style="{ fontFamily, fontSize }" v-html="para" />
</div>
</template>
<script setup>
import config from "../plugins/config";
import { getImageFromLegado, isLegadoUrl } from "../plugins/utils";
import { getImageFromLegado, isLegadoUrl } from "@/plugins/utils";
const store = useBookStore();
const props = defineProps({
carray: { type: Array, required: true },
contents: { type: Array, required: true },
title: { type: String, required: true },
spacing: { type: Object, required: true },
});
const fontFamily = computed(() => {
if (store.config.font >= 0) {
return config.fonts[store.config.font];
}
return { fontFamily: store.config.customFontName };
});
const fontSize = computed(() => {
return store.config.fontSize + "px";
});
const style = computed(() => {
let style = fontFamily.value;
style.fontSize = fontSize.value;
return style;
fontFamily: { type: String, required: true },
fontSize: { type: String, required: true },
});
const getImageSrc = (content) => {
@ -48,16 +37,13 @@ const proxyImage = (event) => {
event.target.src = getImageFromLegado(event.target.src);
};
watch(fontSize, () => {
store.setShowContent(false);
nextTick(() => {
store.setShowContent(true);
});
});
const calculateWordCount = (paragraph) => {
const imgPattern = /<img[^>]*src="[^"]*(?:"[^>]+\})?"[^>]*>/g;
//1
const imagePlaceHolder = " ";
return paragraph.trim().replaceAll(imgPattern, imagePlaceHolder).length;
};
const letterSpacing = computed(() => props.spacing.letter); //
const lineSpacing = computed(() => 1 + props.spacing.line); // 1
const paragraphSpacing = computed(() => props.spacing.paragraph); //
</script>
<style lang="scss" scoped>
@ -72,9 +58,9 @@ p {
word-wrap: break-word;
word-break: break-all;
letter-spacing: calc(v-bind("letterSpacing") * 1em);
line-height: v-bind("lineSpacing");
margin: calc(v-bind("paragraphSpacing") * 1em) 0;
letter-spacing: calc(v-bind("props.spacing.letter") * 1em);
line-height: calc(1 + v-bind("props.spacing.line"));
margin: calc(v-bind("props.spacing.paragraph") * 1em) 0;
:deep(img) {
height: 1em;

View File

@ -55,16 +55,11 @@ var settings = {
},
],
fonts: [
{
fontFamily:
"Microsoft YaHei, PingFangSC-Regular, HelveticaNeue-Light, Helvetica Neue Light, sans-serif",
},
{
fontFamily: "PingFangSC-Regular, -apple-system, Simsun",
},
{
fontFamily: "Kaiti",
},
"Microsoft YaHei, PingFangSC-Regular, HelveticaNeue-Light, Helvetica Neue Light, sans-serif",
"PingFangSC-Regular, -apple-system, Simsun",
"Kaiti",
],
};
export default settings;

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, {

View File

@ -197,7 +197,7 @@ onMounted(async () => {
}
}
showLoading.value = true;
//await store.saveBookProcess();
await store.saveBookProcess();
fetchBookShelfData();
});
const fetchBookShelfData = () => {