From 4a6f93a14fbccb4edf1fb574854508084b2d0cb9 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Mon, 25 Mar 2024 13:02:13 +0700 Subject: [PATCH 01/10] edit --- client/components/Reader/versionHistory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/Reader/versionHistory.js b/client/components/Reader/versionHistory.js index 69e756e6..8d22b263 100644 --- a/client/components/Reader/versionHistory.js +++ b/client/components/Reader/versionHistory.js @@ -7,7 +7,7 @@ export const versionHistory = [ ` ` From 1914092520831dae0c79c9df82799c1a7d9d5d3c Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Thu, 25 Jul 2024 16:51:44 +0700 Subject: [PATCH 02/10] npx update-browserslist-db@latest --- package-lock.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf809269..165a27be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "liberama", - "version": "1.1.3", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "liberama", - "version": "1.1.3", + "version": "1.2.0", "hasInstallScript": true, "license": "CC0-1.0", "dependencies": { @@ -3364,9 +3364,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", "dev": true, "funding": [ { @@ -13709,9 +13709,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001566", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz", - "integrity": "sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==", + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", "dev": true }, "chalk": { From 2da1736c992615140fb251d1efc524faa76cbdc9 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Thu, 25 Jul 2024 18:10:13 +0700 Subject: [PATCH 03/10] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=B8=D0=B3=D0=BD=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BD?= =?UTF-8?q?=D0=B5=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=BD=D1=8B=D1=85=20=D1=81?= =?UTF-8?q?=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82=D0=BE?= =?UTF-8?q?=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/server/index.js b/server/index.js index 2bc41cdb..03bef2bb 100644 --- a/server/index.js +++ b/server/index.js @@ -1,4 +1,5 @@ require('tls').DEFAULT_MIN_VERSION = 'TLSv1'; +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; const fs = require('fs-extra'); const express = require('express'); From 613230256a39346a858a3e444f76f191b7d2b2a3 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Fri, 26 Jul 2024 00:49:39 +0700 Subject: [PATCH 04/10] =?UTF-8?q?=D0=9D=D0=B5=D0=B1=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=BE=D0=B9=20=D1=82=D1=8E=D0=BD=D0=B8=D0=BD=D0=B3=20BUC?= =?UTF-8?q?Server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/core/BookUpdateChecker/BUCServer.js | 10 +++++----- server/core/FileDownloader.js | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/server/core/BookUpdateChecker/BUCServer.js b/server/core/BookUpdateChecker/BUCServer.js index d78c15b0..45e228e2 100644 --- a/server/core/BookUpdateChecker/BUCServer.js +++ b/server/core/BookUpdateChecker/BUCServer.js @@ -27,8 +27,8 @@ class BUCServer { this.cleanQueryInterval = 300*dayMs;//интервал очистки устаревших this.oldQueryInterval = 14*dayMs;//интервал устаревания запроса на обновление - this.checkingInterval = 5*hourMs;//интервал проверки обновления одного и того же файла - this.sameHostCheckInterval = 1000;//интервал проверки файла на том же сайте, не менее + this.checkingInterval = 1*dayMs;//интервал проверки обновления одного и того же файла + this.sameHostCheckInterval = 10*1000;//интервал проверки файла на том же сайте, не менее } else { this.maxCheckQueueLength = 10;//максимальная длина checkQueue this.fillCheckQueuePeriod = 10*1000;//период пополнения очереди @@ -262,7 +262,7 @@ class BUCServer { let unchanged = true; let hash = ''; - const headers = await this.down.head(row.id); + const headers = await this.down.head(row.id, {timeout: 10*1000}); const etag = headers['etag'] || ''; const modTime = headers['last-modified'] || ''; @@ -276,7 +276,7 @@ class BUCServer { && (!size || !row.size || (size !== row.size)) ) { - const downdata = await this.down.load(row.id); + const downdata = await this.down.load(row.id, {timeout: 10*1000}); size = downdata.length; hash = await utils.getBufHash(downdata, 'sha256', 'hex'); @@ -327,7 +327,7 @@ class BUCServer { log(LM_ERR, e.stack); } - await utils.sleep(10); + await utils.sleep(100); } } diff --git a/server/core/FileDownloader.js b/server/core/FileDownloader.js index 6fa06111..327c2837 100644 --- a/server/core/FileDownloader.js +++ b/server/core/FileDownloader.js @@ -2,7 +2,7 @@ const https = require('https'); const axios = require('axios'); const utils = require('./utils'); -const userAgent = 'Mozilla/5.0 (X11; HasCodingOs 1.0; Linux x64) AppleWebKit/637.36 (KHTML, like Gecko) Chrome/70.0.3112.101 Safari/637.36 HasBrowser/5.0'; +const userAgent = 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0'; class FileDownloader { constructor(limitDownloadSize = 0) { @@ -16,7 +16,6 @@ class FileDownloader { headers: { 'accept-encoding': 'gzip, compress, deflate', 'user-agent': userAgent, - timeout: 300*1000, }, httpsAgent: new https.Agent({ rejectUnauthorized: false // решение проблемы 'unable to verify the first certificate' для некоторых сайтов с валидным сертификатом @@ -26,6 +25,9 @@ class FileDownloader { if (opts) options = Object.assign({}, opts, options); + if (!options.timeout) + options.timeout = 300*1000;//5 min + try { const res = await axios.get(url, options); @@ -77,8 +79,8 @@ class FileDownloader { const options = { headers: { 'user-agent': userAgent, - timeout: 10*1000, }, + timeout: 10*1000, }; const res = await axios.head(url, options); From d634ebf14c96a40b365b47ce3597ecd52a93877e Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Fri, 26 Jul 2024 15:54:41 +0700 Subject: [PATCH 05/10] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20BUCServer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/config/base.js | 3 +++ server/core/BookUpdateChecker/BUCServer.js | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/server/config/base.js b/server/config/base.js index c1045377..7f9daa00 100644 --- a/server/config/base.js +++ b/server/config/base.js @@ -56,6 +56,9 @@ module.exports = { ip: '0.0.0.0', port: '33443', accessToken: '', + shciForHost: { + 'samlib.ru': 300000 + }, }*/ ], diff --git a/server/core/BookUpdateChecker/BUCServer.js b/server/core/BookUpdateChecker/BUCServer.js index 45e228e2..92216f54 100644 --- a/server/core/BookUpdateChecker/BUCServer.js +++ b/server/core/BookUpdateChecker/BUCServer.js @@ -51,6 +51,7 @@ class BUCServer { this.checkQueue = []; this.hostChecking = {}; + this.shciForHost = this.config.shciForHost || {};//sameHostCheckInterval for host this.main(); //no await @@ -316,7 +317,11 @@ class BUCServer { log(LM_ERR, `error ${row.id} > ${e.stack ? e.stack : e.message}`); } finally { (async() => { - await utils.sleep(this.sameHostCheckInterval); + const sameHostCheckInterval = this.shciForHost[url.hostname] || this.sameHostCheckInterval; + + log(`delay ${sameHostCheckInterval}ms for host '${url.hostname}'`); + await utils.sleep(sameHostCheckInterval); + this.hostChecking[url.hostname] = false; })(); } From afd4d02dad0e0f3636391bdc1a3bf8db649e4705 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Fri, 26 Jul 2024 17:19:45 +0700 Subject: [PATCH 06/10] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20BUCServer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/core/BookUpdateChecker/BUCServer.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/core/BookUpdateChecker/BUCServer.js b/server/core/BookUpdateChecker/BUCServer.js index 92216f54..91525978 100644 --- a/server/core/BookUpdateChecker/BUCServer.js +++ b/server/core/BookUpdateChecker/BUCServer.js @@ -317,11 +317,12 @@ class BUCServer { log(LM_ERR, `error ${row.id} > ${e.stack ? e.stack : e.message}`); } finally { (async() => { - const sameHostCheckInterval = this.shciForHost[url.hostname] || this.sameHostCheckInterval; + let sameHostCheckInterval = this.shciForHost[url.hostname] || this.sameHostCheckInterval; + sameHostCheckInterval = Math.round((Math.random() - 0.5)*(sameHostCheckInterval*0.2) + sameHostCheckInterval); log(`delay ${sameHostCheckInterval}ms for host '${url.hostname}'`); await utils.sleep(sameHostCheckInterval); - + this.hostChecking[url.hostname] = false; })(); } From 0430105061f95cd704e706556e463a7225f1e4a1 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Sun, 28 Jul 2024 17:23:16 +0700 Subject: [PATCH 07/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B9=20=D0=BD=D0=B0=20=D0=BC=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B5,=20=D0=BF=D0=BE=20=D0=BA=D0=BB=D0=B8=D0=BA=D1=83?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=87=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8=20(#50)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Reader/TextPage/DrawHelper.js | 9 ++ .../components/Reader/TextPage/TextPage.vue | 98 +++++++++++++++++-- client/components/Reader/share/BookParser.js | 96 ++++++++++++++++-- 3 files changed, 187 insertions(+), 16 deletions(-) diff --git a/client/components/Reader/TextPage/DrawHelper.js b/client/components/Reader/TextPage/DrawHelper.js index 2bcf2583..f3bf9e77 100644 --- a/client/components/Reader/TextPage/DrawHelper.js +++ b/client/components/Reader/TextPage/DrawHelper.js @@ -39,6 +39,7 @@ export default class DrawHelper { let center = false; let space = 0; let j = 0; + const pad = this.fontSize/2; //формируем строку for (const part of line.parts) { let tOpen = ''; @@ -46,7 +47,12 @@ export default class DrawHelper { tOpen += (part.style.italic ? '' : ''); tOpen += (part.style.sup ? '' : ''); tOpen += (part.style.sub ? '' : ''); + tOpen += (part.style.note ? `` + + `__TEXT` : ''); let tClose = ''; + tClose += (part.style.note ? '' : ''); tClose += (part.style.sub ? '' : ''); tClose += (part.style.sup ? '' : ''); tClose += (part.style.italic ? '' : ''); @@ -64,6 +70,9 @@ export default class DrawHelper { if (text && text.trim() == '') text = `${text}`; + if (part.style.note) + tOpen = tOpen.replace('__TEXT', text); + lineText += `${tOpen}${text}${tClose}`; center = center || part.style.center; diff --git a/client/components/Reader/TextPage/TextPage.vue b/client/components/Reader/TextPage/TextPage.vue index 5568a501..fd393296 100644 --- a/client/components/Reader/TextPage/TextPage.vue +++ b/client/components/Reader/TextPage/TextPage.vue @@ -4,12 +4,12 @@
-
+
-
+
@@ -24,14 +24,9 @@ @wheel.prevent.stop="onMouseWheel" @touchstart.stop="onTouchStart" @touchend.stop="onTouchEnd" @touchmove.stop="onTouchMove" @touchcancel.prevent.stop="onTouchCancel" > -
+ + + + + +
+
+
+ + +
@@ -51,6 +69,7 @@ import {loadCSS} from 'fg-loadcss'; import _ from 'lodash'; import he from 'he'; +import Dialog from '../../share/Dialog.vue'; import './TextPage.css'; import * as utils from '../../../share/utils'; @@ -62,7 +81,19 @@ import {clickMap} from '../share/clickMap'; const minLayoutWidth = 100; +//обработчик кликов по примечаниям, см. DrawHelper +//коряво, но иначе придется сильно усложнять рендеринг страниц (через Vue) +window.onNoteClickLiberama = (noteId, orig) => { + const textPage = window.textPageLiberama; + if (textPage) { + textPage.showNote(noteId, orig); + } +} + const componentOptions = { + components: { + Dialog + }, watch: { bookPos: function() { this.$emit('book-pos-changed', {bookPos: this.bookPos, bookPosSeen: this.bookPosSeen}); @@ -90,6 +121,7 @@ class TextPage { _options = componentOptions; showStatusBar = false; + statusBarClickOpen = false; clickControl = true; background = null; @@ -114,6 +146,10 @@ class TextPage { meta = null; + noteDialogVisible = false; + noteId = ''; + noteHtml = ''; + created() { this.drawHelper = new DrawHelper(); @@ -153,6 +189,8 @@ class TextPage { await utils.sleep(200); this.$nextTick(this.onResize); }); + + window.textPageLiberama = this; } mounted() { @@ -297,6 +335,8 @@ class TextPage { top += this.statusBarHeight*(this.statusBarTop ? 1 : 0); let page1 = this.$refs.scrollBox1.style; let page2 = this.$refs.scrollBox2.style; + + page1.pointerEvents = page2.pointerEvents = (this.clickControl ? 'none' : 'auto'); page1.perspective = page2.perspective = '3072px'; @@ -1209,6 +1249,46 @@ class TextPage { event.clipboardData.setData('text/plain', filtered); } + + showNote(noteId, orig) { + const note = this.parsed.notes[noteId]; + if (note) { + if (orig) {//show dialog + this.noteId = noteId; + const pad = (note.para.length > 1 ? 20 : 0); + this.noteHtml = note.para.map(p => `

${p}

`).join(''); + this.noteDialogVisible = true; + } else {//go to orig + this.goToOrigNote(noteId); + } + } + } + + goToNotes() { + const note = this.parsed.notes[this.noteId]; + if (note && note.noteParaIndex >= 0) { + + const para = this.parsed.parsePara(note.noteParaIndex); + + this.userBookPosChange = true; + this.bookPos = para.lines[0].begin; + + this.noteDialogVisible = false; + } + } + + goToOrigNote(noteId) { + const note = this.parsed.notes[noteId]; + if (note && note.noteParaIndex >= 0) { + + const para = this.parsed.parsePara(note.linkParaIndex); + + this.userBookPosChange = true; + this.bookPos = para.lines[0].begin; + + this.noteDialogVisible = false; + } + } } export default vueComponent(TextPage); @@ -1244,7 +1324,7 @@ export default vueComponent(TextPage); } .events { - z-index: 20; + z-index: 9; background-color: rgba(0,0,0,0); } diff --git a/client/components/Reader/share/BookParser.js b/client/components/Reader/share/BookParser.js index cfceea3e..54f6236d 100644 --- a/client/components/Reader/share/BookParser.js +++ b/client/components/Reader/share/BookParser.js @@ -86,17 +86,23 @@ export default class BookParser { let binaryType = ''; let dimPromises = []; this.coverPageId = ''; + this.images = []; + let imageNum = 0; + + //примечания + this.notes = {}; + let inNote = false; + let noteId = ''; + let inNotesBody = false; //оглавление this.contents = []; - this.images = []; let curTitle = {paraIndex: -1, title: '', subtitles: []}; let curSubtitle = {paraIndex: -1, title: ''}; let inTitle = false; let inSubtitle = false; let sectionLevel = 0; let bodyIndex = 0; - let imageNum = 0; let paraIndex = -1; let paraOffset = 0; @@ -289,7 +295,7 @@ export default class BookParser { if (attrs.href && attrs.href.value) { const href = attrs.href.value; const alt = (attrs.alt && attrs.alt.value ? attrs.alt.value : ''); - const {id, local} = this.imageHrefToId(href); + const {id, local} = this.hrefToId(href); if (local) {//local imageNum++; @@ -322,6 +328,23 @@ export default class BookParser { } } + if (tag == 'a') { + let attrs = sax.getAttrsSync(tail); + if (attrs.href && attrs.href.value && attrs.type && attrs.type.value === 'note') {//note + const href = attrs.href.value; + const {id, local} = this.hrefToId(href); + + if (local) { + inNote = true; + growParagraph(``, 0); + + if (!this.notes[id]) { + this.notes[id] = {id, linkParaIndex: paraIndex}; + } + } + } + } + if (path == '/fictionbook/description/title-info/author') { if (!fb2.author) fb2.author = []; @@ -350,6 +373,11 @@ export default class BookParser { if (path.indexOf('/fictionbook/body') == 0) { if (tag == 'body') { + let attrs = sax.getAttrsSync(tail); + if (attrs.name && attrs.name.value === 'notes') {//notes + inNotesBody = true; + } + if (isFirstBody && fb2.annotation) { const ann = fb2.annotation.split('

').filter(v => v).map(v => utils.removeHtmlTags(v)); ann.forEach(a => { @@ -389,6 +417,23 @@ export default class BookParser { newParagraph(); isFirstSection = false; sectionLevel++; + + if (inNotesBody) { + let attrs = sax.getAttrsSync(tail); + if (attrs.id && attrs.id.value) {//notes + const id = attrs.id.value; + let note = this.notes[id]; + if (!note) { + note = {id}; + this.notes[id] = note; + } + + note.noteParaIndex = paraIndex; + note.para = []; + noteId = id; + } + + } } if (tag == 'emphasis' || tag == 'strong' || tag == 'sup' || tag == 'sub') { @@ -401,6 +446,14 @@ export default class BookParser { if (tag == 'p') { inPara = true; isFirstTitlePara = false; + + if (inNotesBody && noteId) { + if (!inTitle) { + this.notes[noteId].para.push(''); + } else { + growParagraph(``, 0); + } + } } } @@ -440,11 +493,20 @@ export default class BookParser { const onEndNode = (elemName) => {// eslint-disable-line no-unused-vars tag = elemName; + if (tag == 'a' && inNote) { + growParagraph('', 0); + inNote = false; + } + if (tag == 'binary') { binaryId = ''; } if (path.indexOf('/fictionbook/body') == 0) { + if (tag == 'body') { + inNotesBody = false; + } + if (tag == 'title') { isFirstTitlePara = false; bold = false; @@ -462,6 +524,10 @@ export default class BookParser { if (tag == 'p') { inPara = false; + + if (inTitle && inNotesBody && noteId) { + growParagraph('', 0); + } } if (tag == 'subtitle') { @@ -570,6 +636,12 @@ export default class BookParser { growParagraph(`${tOpen}${text}${tClose}`, text.length, text); else growParagraph(' ', 1); + + if (!inTitle && inPara && inNotesBody && noteId) { + const p = this.notes[noteId].para; + if (p.length) + p[p.length - 1] = p[p.length - 1] + text; + } } }; @@ -602,7 +674,7 @@ export default class BookParser { return {fb2}; } - imageHrefToId(id) { + hrefToId(id) { let local = false; if (id[0] == '#') { id = id.substr(1); @@ -635,7 +707,7 @@ export default class BookParser { splitToStyle(s) { let result = [];/*array of { - style: {bold: Boolean, italic: Boolean, sup: Boolean, sub: Boolean, center: Boolean, space: Number}, + style: {bold: Boolean, italic: Boolean, sup: Boolean, sub: Boolean, center: Boolean, space: Number, note: Object}, image: {local: Boolean, inline: Boolean, id: String}, text: String, }*/ @@ -686,7 +758,7 @@ export default class BookParser { case 'image': { let attrs = sax.getAttrsSync(tail); if (attrs.href && attrs.href.value) { - image = this.imageHrefToId(attrs.href.value); + image = this.hrefToId(attrs.href.value); image.inline = false; image.num = (attrs.num && attrs.num.value ? attrs.num.value : 0); } @@ -695,7 +767,7 @@ export default class BookParser { case 'image-inline': { let attrs = sax.getAttrsSync(tail); if (attrs.href && attrs.href.value) { - const img = this.imageHrefToId(attrs.href.value); + const img = this.hrefToId(attrs.href.value); img.inline = true; img.num = (attrs.num && attrs.num.value ? attrs.num.value : 0); result.push({ @@ -706,6 +778,13 @@ export default class BookParser { } break; } + case 'note': { + let attrs = sax.getAttrsSync(tail); + if (attrs.href && attrs.href.value) { + style.note = {id: attrs.href.value, orig: attrs.orig?.value}; + } + break; + } } }; @@ -734,6 +813,9 @@ export default class BookParser { break; case 'image-inline': break; + case 'note': + style.note = false; + break; } }; From c03995367a970f55eee549195dc21aeffe15d5cd Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Sun, 28 Jul 2024 17:45:18 +0700 Subject: [PATCH 08/10] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/Reader/TextPage/TextPage.vue | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/client/components/Reader/TextPage/TextPage.vue b/client/components/Reader/TextPage/TextPage.vue index fd393296..503dac49 100644 --- a/client/components/Reader/TextPage/TextPage.vue +++ b/client/components/Reader/TextPage/TextPage.vue @@ -953,6 +953,22 @@ class TextPage { } } + doPara(paraIndex) { + const para = this.parsed.para[paraIndex]; + + if (para && this.pageLineCount > 0) { + const lines = this.parsed.getLines(para.offset, this.pageLineCount); + + if (lines.length >= this.pageLineCount) { + this.currentAnimation = this.pageChangeAnimation; + this.pageChangeDirectionDown = true; + this.userBookPosChange = true; + this.bookPos = lines[0].begin; + } else + this.doEnd(); + } + } + doToolBarToggle(event) { this.$emit('do-action', {action: 'switchToolbar', event}); } @@ -1267,25 +1283,15 @@ class TextPage { goToNotes() { const note = this.parsed.notes[this.noteId]; if (note && note.noteParaIndex >= 0) { - - const para = this.parsed.parsePara(note.noteParaIndex); - - this.userBookPosChange = true; - this.bookPos = para.lines[0].begin; - + this.doPara(note.noteParaIndex); this.noteDialogVisible = false; } } goToOrigNote(noteId) { const note = this.parsed.notes[noteId]; - if (note && note.noteParaIndex >= 0) { - - const para = this.parsed.parsePara(note.linkParaIndex); - - this.userBookPosChange = true; - this.bookPos = para.lines[0].begin; - + if (note && note.linkParaIndex >= 0) { + this.doPara(note.linkParaIndex); this.noteDialogVisible = false; } } From da0771d5e52ba398ba7d1e71d0ba36b4bc7d84e0 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Sun, 28 Jul 2024 17:47:15 +0700 Subject: [PATCH 09/10] =?UTF-8?q?=D0=9C=D0=B5=D0=BB=D0=BA=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=BC=D0=B5=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/components/Reader/TextPage/TextPage.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/components/Reader/TextPage/TextPage.vue b/client/components/Reader/TextPage/TextPage.vue index 503dac49..8d6ab4f8 100644 --- a/client/components/Reader/TextPage/TextPage.vue +++ b/client/components/Reader/TextPage/TextPage.vue @@ -48,7 +48,7 @@