Compare commits

..

20 Commits
0.2.1 ... 0.3.0

Author SHA1 Message Date
Book Pauk
8ddd2d6290 Merge branch 'release/0.3.0' 2019-02-17 20:16:11 +07:00
Book Pauk
f6c8666f06 Версия 0.3.0 2019-02-17 20:15:50 +07:00
Book Pauk
1bf173fcae Поправка бага 2019-02-17 20:10:25 +07:00
Book Pauk
696866f065 Merge branch 'feature/draw-page' into develop 2019-02-17 20:08:06 +07:00
Book Pauk
c82283c7f0 Поправка дефолтов 2019-02-17 20:04:28 +07:00
Book Pauk
0e62f25557 Переделки отображения needle при поиске 2019-02-17 20:02:18 +07:00
Book Pauk
e2c51f44bf Изменение drawPage - теперь не позиционирует каждое слово отдельно,
вместо этого используются возможности CSS
2019-02-17 19:35:32 +07:00
Book Pauk
d4768392a6 Мелкая поправка 2019-02-17 19:32:30 +07:00
Book Pauk
580744819d Поправил настройки по-умолчанию 2019-02-17 19:31:50 +07:00
Book Pauk
959794de10 Merge tag '0.2.2' into develop
0.2.2
2019-02-17 14:59:34 +07:00
Book Pauk
3a32c09feb Merge branch 'release/0.2.2' 2019-02-17 14:59:14 +07:00
Book Pauk
09bfce4590 Версия 0.2.2 2019-02-17 14:58:37 +07:00
Book Pauk
092697a4b2 Поправил бажок 2019-02-17 14:55:01 +07:00
Book Pauk
a36de9424e Улучшил распарсивание текста 2019-02-17 14:46:52 +07:00
Book Pauk
db4bc2afb2 Улучшена эвристика определения текста 2019-02-17 14:27:49 +07:00
Book Pauk
73bfc07082 Увеличил количество хранимых недавних до 1000 2019-02-17 13:57:12 +07:00
Book Pauk
b3cf88aac3 Поправил бажок 2019-02-17 13:33:49 +07:00
Book Pauk
69bcc61a01 Включаем yandex-метрику только на production 2019-02-17 13:30:08 +07:00
Book Pauk
bdc124052c Merge tag '0.2.1' into develop
0.2.1
2019-02-16 03:38:38 +07:00
Book Pauk
2b1bb6a299 Merge tag '0.2.0' into develop
0.2.0
2019-02-16 03:20:51 +07:00
10 changed files with 126 additions and 132 deletions

View File

@@ -6,7 +6,7 @@ const api = axios.create({
class Misc { class Misc {
async loadConfig() { async loadConfig() {
const response = await api.post('/config', {params: ['name', 'version', 'mode', 'maxUploadFileSize']}); const response = await api.post('/config', {params: ['name', 'version', 'mode', 'maxUploadFileSize', 'branch']});
return response.data; return response.data;
} }
} }

View File

@@ -210,7 +210,7 @@ class App extends Vue {
} }
//yandex-метрика для omnireader //yandex-метрика для omnireader
if (this.mode == 'omnireader' && !this.yaMetricsDone) { if (this.config.branch == 'production' && this.mode == 'omnireader' && !this.yaMetricsDone) {
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");// eslint-disable-line no-unexpected-multiline (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");// eslint-disable-line no-unexpected-multiline

View File

@@ -126,8 +126,10 @@ class HistoryPage extends Vue {
updateTableData() { updateTableData() {
let result = []; let result = [];
for (let bookKey in bookManager.recent) { const sorted = bookManager.getSortedRecent();
const book = bookManager.recent[bookKey]; const len = (sorted.length < 100 ? sorted.length : 100);
for (let i = 0; i < len; i++) {
const book = sorted[i];
let d = new Date(); let d = new Date();
d.setTime(book.touchTime); d.setTime(book.touchTime);
const t = formatDate(d).split(' '); const t = formatDate(d).split(' ');

View File

@@ -23,17 +23,17 @@ export default class DrawHelper {
if (!this.lastBook || this.pageLineCount < 1 || !this.book || !lines || !this.parsed.textLength) if (!this.lastBook || this.pageLineCount < 1 || !this.book || !lines || !this.parsed.textLength)
return ''; return '';
const spaceWidth = this.measureText(' ', {}); const font = this.fontByStyle({});
const justify = (this.textAlignJustify ? 'text-align: justify; text-align-last: justify;' : '');
let out = `<div class="layout" style="width: ${this.realWidth}px; height: ${this.realHeight}px;` + let out = `<div class="layout" style="width: ${this.w}px; height: ${this.h}px;` +
` color: ${this.textColor}">`; ` position: absolute; top: ${this.fontSize*this.textShift}px; color: ${this.textColor}; font: ${font}; ${justify}` +
` line-height: ${this.lineHeight}px;">`;
let len = lines.length; let len = lines.length;
const lineCount = this.pageLineCount + (isScrolling ? 1 : 0); const lineCount = this.pageLineCount + (isScrolling ? 1 : 0);
len = (len > lineCount ? lineCount : len); len = (len > lineCount ? lineCount : len);
let y = this.fontSize*this.textShift;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const line = lines[i]; const line = lines[i];
/* line: /* line:
@@ -47,77 +47,57 @@ export default class DrawHelper {
text: String, text: String,
} }
}*/ }*/
let sel = new Set();
if (i == 0 && this.searching) {
let pureText = '';
for (const part of line.parts) {
pureText += part.text;
}
let indent = line.first ? this.p : 0; pureText = pureText.toLowerCase();
let j = 0;
while (1) {// eslint-disable-line no-constant-condition
j = pureText.indexOf(this.needle, j);
if (j >= 0) {
for (let k = 0; k < this.needle.length; k++) {
sel.add(j + k);
}
} else
break;
j++;
}
}
let lineText = ''; let lineText = '';
let center = false; let center = false;
let centerStyle = {}; let j = 0;
for (const part of line.parts) { for (const part of line.parts) {
lineText += part.text; let tOpen = (part.style.bold ? '<b>' : '');
tOpen += (part.style.italic ? '<i>' : '');
let tClose = (part.style.italic ? '</i>' : '');
tClose += (part.style.bold ? '</b>' : '');
let text = '';
if (i == 0 && this.searching) {
for (let k = 0; k < part.text.length; k++) {
text += (sel.has(j) ? `<ins>${part.text[k]}</ins>` : part.text[k]);
j++;
}
} else
text = part.text;
lineText += `${tOpen}${text}${tClose}`;
center = center || part.style.center; center = center || part.style.center;
if (part.style.center)
centerStyle = part.style;
} }
let filled = false; const centerStyle = (center ? `text-align: center; text-align-last: center; width: ${this.w}px` : '')
// если выравнивание по ширине включено if (line.first)
if (this.textAlignJustify && !line.last && !center) { lineText = `<span style="display: inline-block; margin-left: ${this.p}px"></span>${lineText}`;
const words = lineText.split(' '); if (line.last || center)
lineText = `<span style="display: inline-block; ${centerStyle}">${lineText}</span>`;
if (words.length > 1) { out += (i > 0 ? '<br>' : '') + lineText;
const spaceCount = words.length - 1;
const space = (this.w - line.width + spaceWidth*spaceCount)/spaceCount;
let x = indent;
for (const part of line.parts) {
const font = this.fontByStyle(part.style);
let partWords = part.text.split(' ');
for (let j = 0; j < partWords.length; j++) {
let f = font;
let style = part.style;
let word = partWords[j];
if (i == 0 && this.searching && word.toLowerCase().indexOf(this.needle) >= 0) {
style = Object.assign({}, part.style, {bold: true});
f = this.fontByStyle(style);
}
out += this.fillText(word, x, y, f);
x += this.measureText(word, style) + (j < partWords.length - 1 ? space : 0);
}
}
filled = true;
}
}
// просто выводим текст
if (!filled) {
let x = indent;
x = (center ? (this.w - this.measureText(lineText, centerStyle))/2 : x);
for (const part of line.parts) {
let font = this.fontByStyle(part.style);
if (i == 0 && this.searching) {//для поиска, разбивка по словам
let partWords = part.text.split(' ');
for (let j = 0; j < partWords.length; j++) {
let f = font;
let style = part.style;
let word = partWords[j];
if (word.toLowerCase().indexOf(this.needle) >= 0) {
style = Object.assign({}, part.style, {bold: true});
f = this.fontByStyle(style);
}
out += this.fillText(word, x, y, f);
x += this.measureText(word, style) + (j < partWords.length - 1 ? spaceWidth : 0);
}
} else {
out += this.fillText(part.text, x, y, font);
x += this.measureText(part.text, part.style);
}
}
}
y += this.lineHeight;
} }
out += '</div>'; out += '</div>';

View File

@@ -1,6 +1,6 @@
<template> <template>
<div ref="main" class="main"> <div ref="main" class="main">
<div class="layout back"> <div class="layout back" @wheel.prevent.stop="onMouseWheel">
<div v-html="background"></div> <div v-html="background"></div>
<!-- img --> <!-- img -->
</div> </div>
@@ -436,15 +436,7 @@ class TextPage extends Vue {
} }
startSearch(needle) { startSearch(needle) {
this.drawHelper.needle = ''; this.drawHelper.needle = needle;
const words = needle.split(' ');
for (const word of words) {
if (word != '') {
this.drawHelper.needle = word;
break;
}
}
this.drawHelper.searching = true; this.drawHelper.searching = true;
this.draw(); this.draw();
} }
@@ -569,7 +561,7 @@ class TextPage extends Vue {
} }
if (this.book && this.bookPos > 0 && this.bookPos >= this.parsed.textLength) { if (this.book && this.bookPos > 0 && this.bookPos >= this.parsed.textLength) {
this.doEnd(); this.doEnd(true);
return; return;
} }
@@ -591,7 +583,7 @@ class TextPage extends Vue {
this.debouncedDrawStatusBar(); this.debouncedDrawStatusBar();
if (this.book && this.linesDown && this.linesDown.length < this.pageLineCount) { if (this.book && this.linesDown && this.linesDown.length < this.pageLineCount) {
this.doEnd(); this.doEnd(true);
return; return;
} }
} }
@@ -822,7 +814,7 @@ class TextPage extends Vue {
this.bookPos = 0; this.bookPos = 0;
} }
doEnd() { doEnd(noAni) {
if (this.parsed.para.length && this.pageLineCount > 0) { if (this.parsed.para.length && this.pageLineCount > 0) {
let i = this.parsed.para.length - 1; let i = this.parsed.para.length - 1;
let lastPos = this.parsed.para[i].offset + this.parsed.para[i].length - 1; let lastPos = this.parsed.para[i].offset + this.parsed.para[i].length - 1;
@@ -830,7 +822,8 @@ class TextPage extends Vue {
if (lines) { if (lines) {
i = this.pageLineCount - 1; i = this.pageLineCount - 1;
i = (i > lines.length - 1 ? lines.length - 1 : i); i = (i > lines.length - 1 ? lines.length - 1 : i);
this.currentAnimation = this.pageChangeAnimation; if (!noAni)
this.currentAnimation = this.pageChangeAnimation;
this.pageChangeDirectionDown = true; this.pageChangeDirectionDown = true;
this.bookPos = lines[i].begin; this.bookPos = lines[i].begin;
} }

View File

@@ -22,7 +22,8 @@ class BookManager {
this.settings = settings; this.settings = settings;
this.books = {}; this.books = {};
this.recent = {}; this.recent = {};
this.recentChanged = true; this.recentChanged1 = true;
this.recentChanged2 = true;
let len = await bmMetaStore.length(); let len = await bmMetaStore.length();
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
@@ -170,7 +171,8 @@ class BookManager {
await bmRecentStore.setItem(result.key, result); await bmRecentStore.setItem(result.key, result);
await this.cleanRecentBooks(); await this.cleanRecentBooks();
this.recentChanged = true; this.recentChanged1 = true;
this.recentChanged2 = true;
return result; return result;
} }
@@ -186,14 +188,15 @@ class BookManager {
await bmRecentStore.removeItem(value.key); await bmRecentStore.removeItem(value.key);
delete this.recent[value.key]; delete this.recent[value.key];
this.recentChanged = true; this.recentChanged1 = true;
this.recentChanged2 = true;
} }
async cleanRecentBooks() { async cleanRecentBooks() {
if (!this.recent) if (!this.recent)
await this.init(); await this.init();
if (Object.keys(this.recent).length > 100) { if (Object.keys(this.recent).length > 1000) {
let min = Date.now(); let min = Date.now();
let found = null; let found = null;
for (let key in this.recent) { for (let key in this.recent) {
@@ -212,7 +215,7 @@ class BookManager {
} }
mostRecentBook() { mostRecentBook() {
if (!this.recentChanged && this.mostRecentCached) { if (!this.recentChanged1 && this.mostRecentCached) {
return this.mostRecentCached; return this.mostRecentCached;
} }
@@ -226,10 +229,25 @@ class BookManager {
} }
} }
this.mostRecentCached = result; this.mostRecentCached = result;
this.recentChanged = false; this.recentChanged1 = false;
return result; return result;
} }
getSortedRecent() {
if (!this.recentChanged2 && this.sortedRecentCached) {
return this.sortedRecentCached;
}
let result = Object.values(this.recent);
result.sort((a, b) => b.touchTime - a.touchTime);
this.sortedRecentCached = result;
this.recentChanged2 = false;
return result;
}
} }
export default new BookManager(); export default new BookManager();

View File

@@ -6,7 +6,7 @@ const fonts = [
{name: 'Arimo', fontVertShift: 0}, {name: 'Arimo', fontVertShift: 0},
{name: 'Avrile', fontVertShift: -10}, {name: 'Avrile', fontVertShift: -10},
{name: 'OpenSans', fontVertShift: -5}, {name: 'OpenSans', fontVertShift: -5},
{name: 'Roboto', fontVertShift: 10}, {name: 'Roboto', fontVertShift: 0},
{name: 'Rubik', fontVertShift: 0}, {name: 'Rubik', fontVertShift: 0},
]; ];

View File

@@ -1,6 +1,6 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.2.1", "version": "0.3.0",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },

View File

@@ -43,7 +43,7 @@ class BookConverter {
else { else {
//может это чистый текст? //может это чистый текст?
if (textUtils.checkIfText(data)) { if (textUtils.checkIfText(data)) {
await fs.writeFile(outputFile, this.convertHtml(data)); await fs.writeFile(outputFile, this.convertHtml(data, true));
return; return;
} }
@@ -167,7 +167,7 @@ class BookConverter {
titleInfo['book-title'] = title; titleInfo['book-title'] = title;
//подозрение на чистый текст, надо разбить на параграфы //подозрение на чистый текст, надо разбить на параграфы
if ((isText || pars.length < buf.length/2000) && spaceCounter.length) { if (isText || pars.length < buf.length/2000) {
let total = 0; let total = 0;
for (let i = 0; i < spaceCounter.length; i++) { for (let i = 0; i < spaceCounter.length; i++) {
total += (spaceCounter[i] ? spaceCounter[i] : 0); total += (spaceCounter[i] ? spaceCounter[i] : 0);
@@ -176,41 +176,37 @@ class BookConverter {
let i = spaceCounter.length - 1; let i = spaceCounter.length - 1;
while (i > 0 && (!spaceCounter[i] || spaceCounter[i] < total)) i--; while (i > 0 && (!spaceCounter[i] || spaceCounter[i] < total)) i--;
const parIndent = i; const parIndent = (i > 0 ? i : 0);
if (parIndent > 0) {//нашли отступ параграфа
let newPars = []; let newPars = [];
const newPar = () => { const newPar = () => {
newPars.push({_n: 'p', _t: ''}); newPars.push({_n: 'p', _t: ''});
}; };
const growPar = (text) => { const growPar = (text) => {
const l = newPars.length; const l = newPars.length;
if (l) { if (l) {
newPars[l - 1]._t += text; newPars[l - 1]._t += text;
}
} }
for (const par of pars) {
newPar();
const lines = par._t.split('\n');
for (const line of lines) {
const sp = line.split(' ');
let l = 0;
while (l < sp.length && sp[l].trim() == '') {
l++;
}
if (l >= parIndent)
newPar();
growPar(line.trim() + ' ');
}
}
body.section._a[0] = newPars;
} else {
body.section._a[0] = pars;
} }
for (const par of pars) {
newPar();
const lines = par._t.split('\n');
for (const line of lines) {
const sp = line.split(' ');
let l = 0;
while (l < sp.length && sp[l].trim() == '') {
l++;
}
if (l >= parIndent)
newPar();
growPar(line.trim() + ' ');
}
}
body.section._a[0] = newPars;
} else { } else {
body.section._a[0] = pars; body.section._a[0] = pars;
} }
@@ -288,11 +284,9 @@ class BookConverter {
openTag('p'); openTag('p');
break; break;
case 'i': case 'i':
openTag('emphasis');
italic = true; italic = true;
break; break;
case 'b': case 'b':
openTag('strong');
bold = true; bold = true;
break; break;
case 'div': case 'div':
@@ -338,11 +332,9 @@ class BookConverter {
closeTag('p'); closeTag('p');
break; break;
case 'i': case 'i':
closeTag('emphasis');
italic = false; italic = false;
break; break;
case 'b': case 'b':
closeTag('strong');
bold = false; bold = false;
break; break;
case 'div': case 'div':

View File

@@ -70,13 +70,22 @@ function getEncoding(buf) {
function checkIfText(buf) { function checkIfText(buf) {
let spaceCount = 0; let spaceCount = 0;
let crCount = 0;
let lfCount = 0;
for (let i = 0; i < buf.length; i++) { for (let i = 0; i < buf.length; i++) {
if (buf[i] == 32) if (buf[i] == 32)
spaceCount++; spaceCount++;
if (buf[i] == 13)
crCount++;
if (buf[i] == 10)
lfCount++;
} }
const freq = spaceCount/(buf.length + 1);
return (freq > 0.1); const spaceFreq = spaceCount/(buf.length + 1);
const crFreq = crCount/(buf.length + 1);
const lfFreq = lfCount/(buf.length + 1);
return (spaceFreq > 0.1 || crFreq > 0.03 || lfFreq > 0.03);
} }
module.exports = { module.exports = {