Compare commits

...

26 Commits

Author SHA1 Message Date
Book Pauk
ea2f178730 Merge branch 'release/0.11.4-2' 2022-04-14 19:54:14 +07:00
Book Pauk
4b5c8d9efe Добавил подсказку 2022-04-14 19:53:47 +07:00
Book Pauk
28ebf13c3a Merge tag '0.11.4-1' into develop
0.11.4-1
2022-04-14 19:19:21 +07:00
Book Pauk
5d52e63dd9 Merge branch 'release/0.11.4-1' 2022-04-14 19:19:14 +07:00
Book Pauk
1a0e024050 Поправил баг 2022-04-14 19:18:49 +07:00
Book Pauk
e627a0d970 Merge tag '0.11.4' into develop
0.11.4
2022-04-14 19:05:36 +07:00
Book Pauk
48668d94ad Merge branch 'release/0.11.4' 2022-04-14 19:05:31 +07:00
Book Pauk
e08c431dd9 Версия 0.11.4 2022-04-14 19:05:07 +07:00
Book Pauk
5ee58ad6f0 Поправка багов 2022-04-14 19:00:04 +07:00
Book Pauk
ac0a4f0586 Добавлена кнопка 'Управление кликом' 2022-04-14 18:50:11 +07:00
Book Pauk
b6f4c153e5 Добавлена кнопка 'Загрузить из буфера обмена' 2022-04-14 18:34:41 +07:00
Book Pauk
4fdaf5f555 Добавлена кнопка 'Загрузить файл с диска' 2022-04-14 17:48:51 +07:00
Book Pauk
b4ee9d6c00 Скрыта опция "Помочь проекту".
Добавлена кнопка "Вызвать справку".
2022-04-14 17:27:29 +07:00
Book Pauk
7c73c74730 Добавлена подсказка при невалидном URL книги 2022-04-14 17:13:38 +07:00
Book Pauk
c20aa089fa npm 2022-03-29 17:45:57 +07:00
Book Pauk
b0e15c22ea Merge tag '0.11.3' into develop
0.11.3
2022-03-29 17:41:03 +07:00
Book Pauk
d58a2c065a Merge branch 'release/0.11.3' 2022-03-29 17:40:57 +07:00
Book Pauk
53135e7ee8 Поправка даты 2022-03-29 17:40:29 +07:00
Book Pauk
5c48ca9e6c Рефакторинг versionHistory, небольшие поправки 2022-03-29 17:37:24 +07:00
Book Pauk
c4a280f3d8 Скрыл устаревший чекбокс 2022-03-29 16:52:03 +07:00
Book Pauk
ba2943c722 Поправлен баг 2022-03-29 16:49:04 +07:00
Book Pauk
26f6ffc83a Убрал PayPal из списка 2022-03-29 16:25:26 +07:00
Book Pauk
bcf075a72c Доработки WebSocketConnection 2022-03-29 16:23:34 +07:00
Book Pauk
02d458d192 Миграция "jembadb" => "^2.3.0" 2022-03-29 15:49:48 +07:00
Book Pauk
a349d8af68 Обновил пакет JembaDb 2022-02-08 20:55:31 +07:00
Book Pauk
0dbaf32aac Merge tag '0.11.2' into develop
0.11.2
2022-01-11 23:25:23 +07:00
20 changed files with 413 additions and 141 deletions

View File

@@ -31,6 +31,7 @@
"vue/max-attributes-per-line": "off", "vue/max-attributes-per-line": "off",
"vue/html-self-closing": "off", "vue/html-self-closing": "off",
"vue/no-v-html": "off", "vue/no-v-html": "off",
"vue/no-v-model-argument": "off",
"strict": 0, "strict": 0,
"indent": [0, 4, { "indent": [0, 4, {

View File

@@ -5,11 +5,12 @@ const { VueLoaderPlugin } = require('vue-loader');
const clientDir = path.resolve(__dirname, '../client'); const clientDir = path.resolve(__dirname, '../client');
module.exports = { module.exports = {
/*resolve: { resolve: {
alias: { alias: {
vue: '@vue/compat' ws: false,
//vue: '@vue/compat'
} }
},*/ },
entry: [`${clientDir}/main.js`], entry: [`${clientDir}/main.js`],
output: { output: {
publicPath: '/app/', publicPath: '/app/',

View File

@@ -219,7 +219,7 @@ class Reader {
const state = response.state; const state = response.state;
if (!state) if (!state)
throw new Error('Неверный ответ api'); throw new Error('Неверный ответ api');
if (response.state == 'error') { if (state == 'error') {
throw new Error(response.error); throw new Error(response.error);
} }

View File

@@ -55,16 +55,16 @@
<div class="col fit tree"> <div class="col fit tree">
<div v-show="nodes.length" class="checkbox-tick-all"> <div v-show="nodes.length" class="checkbox-tick-all">
<q-checkbox v-model="tickAll" size="36px" label="Выбрать все" @input="makeTickAll" /> <q-checkbox v-model="tickAll" size="36px" label="Выбрать все" @update:model-value="makeTickAll" />
</div> </div>
<q-tree <q-tree
v-model:selected="selected"
v-model:ticked="ticked"
v-model:expanded="expanded"
class="q-my-xs" class="q-my-xs"
:nodes="nodes" :nodes="nodes"
node-key="key" node-key="key"
tick-strategy="leaf" tick-strategy="leaf"
v-model:selected="selected"
v-model:ticked="ticked"
v-model:expanded="expanded"
selected-color="black" selected-color="black"
:filter="search" :filter="search"
no-nodes-label="Закладок пока нет" no-nodes-label="Закладок пока нет"
@@ -97,7 +97,7 @@ const componentOptions = {
Window, Window,
}, },
watch: { watch: {
ticked: function() { ticked() {
this.checkAllTicked(); this.checkAllTicked();
}, },
} }

View File

@@ -19,7 +19,7 @@
</div> </div>
</div> </div>
<div class="address"> <!--div class="address">
<img class="logo" src="./assets/paypal.png"> <img class="logo" src="./assets/paypal.png">
<div class="para"> <div class="para">
{{ paypalAddress }} {{ paypalAddress }}
@@ -29,7 +29,7 @@
</q-tooltip> </q-tooltip>
</q-icon> </q-icon>
</div> </div>
</div> </div-->
<div class="address"> <div class="address">
<img class="logo" src="./assets/bitcoin.png"> <img class="logo" src="./assets/bitcoin.png">

View File

@@ -29,14 +29,14 @@ import CommonHelpPage from './CommonHelpPage/CommonHelpPage.vue';
import HotkeysHelpPage from './HotkeysHelpPage/HotkeysHelpPage.vue'; import HotkeysHelpPage from './HotkeysHelpPage/HotkeysHelpPage.vue';
import MouseHelpPage from './MouseHelpPage/MouseHelpPage.vue'; import MouseHelpPage from './MouseHelpPage/MouseHelpPage.vue';
import VersionHistoryPage from './VersionHistoryPage/VersionHistoryPage.vue'; import VersionHistoryPage from './VersionHistoryPage/VersionHistoryPage.vue';
import DonateHelpPage from './DonateHelpPage/DonateHelpPage.vue'; //import DonateHelpPage from './DonateHelpPage/DonateHelpPage.vue';
const pages = { const pages = {
'CommonHelpPage': CommonHelpPage, 'CommonHelpPage': CommonHelpPage,
'HotkeysHelpPage': HotkeysHelpPage, 'HotkeysHelpPage': HotkeysHelpPage,
'MouseHelpPage': MouseHelpPage, 'MouseHelpPage': MouseHelpPage,
'VersionHistoryPage': VersionHistoryPage, 'VersionHistoryPage': VersionHistoryPage,
'DonateHelpPage': DonateHelpPage, //'DonateHelpPage': DonateHelpPage,
}; };
const tabs = [ const tabs = [
@@ -44,7 +44,7 @@ const tabs = [
['MouseHelpPage', 'Мышь/тачскрин'], ['MouseHelpPage', 'Мышь/тачскрин'],
['HotkeysHelpPage', 'Клавиатура'], ['HotkeysHelpPage', 'Клавиатура'],
['VersionHistoryPage', 'История версий'], ['VersionHistoryPage', 'История версий'],
['DonateHelpPage', 'Помочь проекту'], //['DonateHelpPage', 'Помочь проекту'],
]; ];
const componentOptions = { const componentOptions = {
@@ -73,7 +73,7 @@ class HelpPage {
} }
activateDonateHelpPage() { activateDonateHelpPage() {
this.selectedTab = 'DonateHelpPage'; //this.selectedTab = 'DonateHelpPage';
} }
activateVersionHistoryHelpPage() { activateVersionHistoryHelpPage() {

View File

@@ -33,14 +33,15 @@ class VersionHistoryPage {
mounted() { mounted() {
let vh = []; let vh = [];
for (const version of versionHistory) { for (const v of versionHistory) {
vh.push(version.header); vh.push(`${v.version} (${v.releaseDate})`);
} }
this.versionHeader = vh; this.versionHeader = vh;
let vc = []; let vc = [];
for (const version of versionHistory) { for (const v of versionHistory) {
vc.push({key: version.header, content: 'Версия ' + version.header + version.content}); let header = `${v.version} (${v.releaseDate})`;
vc.push({key: header, content: 'Версия ' + header + v.content});
} }
this.versionContent = vc; this.versionContent = vc;
} }

View File

@@ -22,11 +22,13 @@
<div class="q-my-sm"></div> <div class="q-my-sm"></div>
<q-btn no-caps dense class="q-px-sm" color="primary" size="13px" @click="loadFileClick"> <q-btn no-caps dense class="q-px-sm" color="primary" size="13px" @click="loadFileClick">
<q-icon class="q-mr-xs" name="la la-caret-square-up" size="24px" />
Загрузить файл с диска Загрузить файл с диска
</q-btn> </q-btn>
<div class="q-my-sm"></div> <div class="q-my-sm"></div>
<q-btn no-caps dense class="q-px-sm" color="primary" size="13px" @click="loadBufferClick"> <q-btn no-caps dense class="q-px-sm" color="primary" size="13px" @click="loadBufferClick">
<q-icon class="q-mr-xs" name="la la-comment" size="24px" />
Из буфера обмена Из буфера обмена
</q-btn> </q-btn>
@@ -45,14 +47,27 @@
</div> </div>
<div class="col column justify-end items-center no-wrap overflow-hidden"> <div class="col column justify-end items-center no-wrap overflow-hidden">
<span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="findBook">Найти книгу</span>
<span class="bottom-span clickable" @click="openHelp">Справка</span> <span class="bottom-span clickable" @click="openHelp">Справка</span>
<span class="bottom-span clickable" @click="openDonate">Помочь проекту</span> <!--span class="bottom-span clickable" @click="openDonate">Помочь проекту</span-->
<span v-if="version == clientVersion" class="bottom-span">v{{ version }}</span> <span v-if="version == clientVersion" class="bottom-span">v{{ version }}</span>
<span v-else class="bottom-span">Версия сервера {{ version }}, версия клиента {{ clientVersion }}, необходимо обновить страницу</span> <span v-else class="bottom-span">Версия сервера {{ version }}, версия клиента {{ clientVersion }}, необходимо обновить страницу</span>
</div> </div>
<PasteTextPage v-if="pasteTextActive" ref="pasteTextPage" @paste-text-toggle="pasteTextToggle" @load-buffer="loadBuffer"></PasteTextPage> <PasteTextPage v-if="pasteTextActive" ref="pasteTextPage" @paste-text-toggle="pasteTextToggle" @load-buffer="loadBuffer"></PasteTextPage>
<Dialog ref="dialog1" v-model="findBookVisible">
<template #header>
Подсказка ;-)
</template>
<div style="word-break: normal">
Если вы хотите найти определенную книгу, добро пожаловать в
раздел "Сетевая библиотека" (кнопка <q-icon name="la la-sitemap" size="32px" />) на сайте читалки
<a href="https://liberama.top" target="_blank">liberama.top</a>
</div>
</Dialog>
</div> </div>
</template> </template>
@@ -62,12 +77,15 @@ import vueComponent from '../../vueComponent.js';
import GithubCorner from './GithubCorner/GithubCorner.vue'; import GithubCorner from './GithubCorner/GithubCorner.vue';
import Dialog from '../../share/Dialog.vue';
import PasteTextPage from './PasteTextPage/PasteTextPage.vue'; import PasteTextPage from './PasteTextPage/PasteTextPage.vue';
import {versionHistory} from '../versionHistory'; import {versionHistory} from '../versionHistory';
import * as utils from '../../../share/utils';
const componentOptions = { const componentOptions = {
components: { components: {
GithubCorner, GithubCorner,
Dialog,
PasteTextPage, PasteTextPage,
}, },
}; };
@@ -77,6 +95,7 @@ class LoaderPage {
bookUrl = null; bookUrl = null;
loadPercent = 0; loadPercent = 0;
pasteTextActive = false; pasteTextActive = false;
findBookVisible = false;
created() { created() {
this.commit = this.$store.commit; this.commit = this.$store.commit;
@@ -114,9 +133,7 @@ class LoaderPage {
} }
get clientVersion() { get clientVersion() {
let v = versionHistory[0].header; return versionHistory[0].version;
v = v.split(' ')[0];
return v;
} }
submitUrl() { submitUrl() {
@@ -138,7 +155,7 @@ class LoaderPage {
} }
loadBufferClick() { loadBufferClick() {
this.pasteTextToggle(); this.showPasteText();
} }
loadBuffer(opts) { loadBuffer(opts) {
@@ -148,6 +165,10 @@ class LoaderPage {
} }
} }
showPasteText() {
this.pasteTextActive = true;
}
pasteTextToggle() { pasteTextToggle() {
this.pasteTextActive = !this.pasteTextActive; this.pasteTextActive = !this.pasteTextActive;
} }
@@ -160,6 +181,10 @@ class LoaderPage {
this.$emit('do-action', {action: 'donate'}); this.$emit('do-action', {action: 'donate'});
} }
findBook() {
this.findBookVisible = true;
}
openComments() { openComments() {
window.open('http://samlib.ru/comment/b/bookpauk/bookpauk_reader', '_blank'); window.open('http://samlib.ru/comment/b/bookpauk/bookpauk_reader', '_blank');
} }
@@ -168,26 +193,24 @@ class LoaderPage {
window.open('http://old.omnireader.ru', '_blank'); window.open('http://old.omnireader.ru', '_blank');
} }
onInputKeydown(event) { async onInputKeydown(event) {
if (event.key == 'Enter') { if (event.key == 'Enter') {
await utils.sleep(100);
this.submitUrl(); this.submitUrl();
} }
} }
keyHook(event) { keyHook(event) {
if (this.$refs.dialog1.active)
return true;
if (this.pasteTextActive) { if (this.pasteTextActive) {
return this.$refs.pasteTextPage.keyHook(event); return this.$refs.pasteTextPage.keyHook(event);
} }
const input = this.$refs.input.getNativeElement(); const input = this.$refs.input.getNativeElement();
if (event.type == 'keydown' && document.activeElement !== input) { if (event.type == 'keydown' && (document.activeElement === input || event.code == 'Enter') && event.code != 'Escape')
const action = this.$root.readerActionByKeyEvent(event); return true;
switch (action) {
case 'help':
this.openHelp(event);
return true;
}
}
return false; return false;
} }

View File

@@ -9,6 +9,24 @@
{{ rstore.readerActions['loader'] }} {{ rstore.readerActions['loader'] }}
</q-tooltip> </q-tooltip>
</button> </button>
<button v-show="showToolButton['loadFile']" ref="loadFile" v-ripple class="tool-button" :class="buttonActiveClass('loadFile')" @click="buttonClick('loadFile')">
<q-icon name="la la-caret-square-up" size="32px" />
<q-tooltip :delay="1500" anchor="bottom right" content-style="font-size: 80%">
{{ rstore.readerActions['loadFile'] }}
</q-tooltip>
</button>
<button v-show="showToolButton['loadBuffer']" ref="loadBuffer" v-ripple class="tool-button" :class="buttonActiveClass('loadBuffer')" @click="buttonClick('loadBuffer')">
<q-icon name="la la-comment" size="32px" />
<q-tooltip :delay="1500" anchor="bottom right" content-style="font-size: 80%">
{{ rstore.readerActions['loadBuffer'] }}
</q-tooltip>
</button>
<button v-show="showToolButton['help']" ref="help" v-ripple class="tool-button" :class="buttonActiveClass('help')" @click="buttonClick('help')">
<q-icon name="la la-question" size="32px" />
<q-tooltip :delay="1500" anchor="bottom right" content-style="font-size: 80%">
{{ rstore.readerActions['help'] }}
</q-tooltip>
</button>
</div> </div>
<div> <div>
@@ -89,6 +107,12 @@
</div> </div>
<div> <div>
<button v-show="showToolButton['clickControl']" ref="clickControl" v-ripple class="tool-button" :class="buttonActiveClass('clickControl')" @click="buttonClick('clickControl')">
<q-icon name="la la-mouse" size="32px" />
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
{{ rstore.readerActions['clickControl'] }}
</q-tooltip>
</button>
<button v-show="showToolButton['offlineMode']" ref="offlineMode" v-ripple class="tool-button" :class="buttonActiveClass('offlineMode')" @click="buttonClick('offlineMode')"> <button v-show="showToolButton['offlineMode']" ref="offlineMode" v-ripple class="tool-button" :class="buttonActiveClass('offlineMode')" @click="buttonClick('offlineMode')">
<q-icon name="la la-unlink" size="32px" /> <q-icon name="la la-unlink" size="32px" />
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%"> <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
@@ -136,7 +160,7 @@
<ContentsPage v-show="contentsActive" ref="contentsPage" :book-pos="bookPos" :is-visible="contentsActive" @do-action="doAction" @book-pos-changed="bookPosChanged"></ContentsPage> <ContentsPage v-show="contentsActive" ref="contentsPage" :book-pos="bookPos" :is-visible="contentsActive" @do-action="doAction" @book-pos-changed="bookPosChanged"></ContentsPage>
<ServerStorage v-show="hidden" ref="serverStorage"></ServerStorage> <ServerStorage v-show="hidden" ref="serverStorage"></ServerStorage>
<ReaderDialogs ref="dialogs" @donate-toggle="donateToggle" @version-history-toggle="versionHistoryToggle"></ReaderDialogs> <ReaderDialogs ref="dialogs" @donate-toggle="donateToggle" @version-history-toggle="versionHistoryToggle" @load-buffer-toggle="loadBufferToggle"></ReaderDialogs>
</div> </div>
</div> </div>
</template> </template>
@@ -245,6 +269,8 @@ class Reader {
rstore = {}; rstore = {};
loaderActive = false; loaderActive = false;
loadFileActive = false;
loadBufferActive = false;
fullScreenActive = false; fullScreenActive = false;
setPositionActive = false; setPositionActive = false;
searchActive = false; searchActive = false;
@@ -254,6 +280,7 @@ class Reader {
contentsActive = false; contentsActive = false;
libsActive = false; libsActive = false;
recentBooksActive = false; recentBooksActive = false;
clickControlActive = false;
offlineModeActive = false; offlineModeActive = false;
settingsActive = false; settingsActive = false;
@@ -372,6 +399,7 @@ class Reader {
this.copyFullText = settings.copyFullText; this.copyFullText = settings.copyFullText;
this.showClickMapPage = settings.showClickMapPage; this.showClickMapPage = settings.showClickMapPage;
this.clickControl = settings.clickControl; this.clickControl = settings.clickControl;
this.clickControlActive = this.clickControl;
this.blinkCachedLoad = settings.blinkCachedLoad; this.blinkCachedLoad = settings.blinkCachedLoad;
this.showToolButton = settings.showToolButton; this.showToolButton = settings.showToolButton;
this.enableSitesFilter = settings.enableSitesFilter; this.enableSitesFilter = settings.enableSitesFilter;
@@ -393,6 +421,23 @@ class Reader {
this.loadWallpapers();//no await this.loadWallpapers();//no await
} }
showHelpOnErrorIfNeeded(errorMessage) {
//небольшая эвристика
let i = errorMessage.indexOf('http://');
if (i < 0)
i = errorMessage.indexOf('https://');
errorMessage = errorMessage.substring(i + 7);
const perCount = errorMessage.split('%').length - 1;
if (perCount > errorMessage.length/3.2) {
this.$refs.dialogs.showUrlHelp();
return true;
}
return false;
}
//wallpaper css //wallpaper css
async loadWallpapers() { async loadWallpapers() {
const wallpaperDataLength = await wallpaperStorage.getLength(); const wallpaperDataLength = await wallpaperStorage.getLength();
@@ -525,9 +570,7 @@ class Reader {
} }
get clientVersion() { get clientVersion() {
let v = versionHistory[0].header; return versionHistory[0].version;
v = v.split(' ')[0];
return v;
} }
get routeParamUrl() { get routeParamUrl() {
@@ -659,6 +702,28 @@ class Reader {
} }
} }
loadFileToggle() {
if (!this.loaderActive)
this.loaderToggle();
this.$nextTick(() => {
const page = this.$refs.page;
if (this.activePage == 'LoaderPage' && page.loadFileClick) {
page.loadFileClick();
}
});
}
loadBufferToggle() {
if (!this.loaderActive)
this.loaderToggle();
this.$nextTick(() => {
const page = this.$refs.page;
if (this.activePage == 'LoaderPage' && page.showPasteText) {
page.showPasteText();
}
});
}
setPositionToggle() { setPositionToggle() {
this.setPositionActive = !this.setPositionActive; this.setPositionActive = !this.setPositionActive;
const page = this.$refs.page; const page = this.$refs.page;
@@ -786,6 +851,12 @@ class Reader {
} }
} }
clickControlToggle() {
const newSettings = _.cloneDeep(this.settings);
newSettings.clickControl = !this.clickControl;
this.commit('reader/setSettings', newSettings);
}
offlineModeToggle() { offlineModeToggle() {
this.offlineModeActive = !this.offlineModeActive; this.offlineModeActive = !this.offlineModeActive;
this.$refs.serverStorage.offlineModeActive = this.offlineModeActive; this.$refs.serverStorage.offlineModeActive = this.offlineModeActive;
@@ -874,6 +945,9 @@ class Reader {
switch (action) { switch (action) {
case 'loader': case 'loader':
case 'loadFile':
case 'loadBuffer':
case 'help':
case 'fullScreen': case 'fullScreen':
case 'setPosition': case 'setPosition':
case 'search': case 'search':
@@ -883,6 +957,7 @@ class Reader {
case 'contents': case 'contents':
case 'libs': case 'libs':
case 'recentBooks': case 'recentBooks':
case 'clickControl':
case 'offlineMode': case 'offlineMode':
case 'settings': case 'settings':
if (this.progressActive) { if (this.progressActive) {
@@ -1119,7 +1194,9 @@ class Reader {
} catch (e) { } catch (e) {
progress.hide(); this.progressActive = false; progress.hide(); this.progressActive = false;
this.loaderActive = true; this.loaderActive = true;
this.$root.stdDialog.alert(e.message, 'Ошибка', {color: 'negative'}); if (!this.showHelpOnErrorIfNeeded(e.message)) {
this.$root.stdDialog.alert(e.message, 'Ошибка', {color: 'negative'});
}
} finally { } finally {
this.checkNewVersionAvailable(); this.checkNewVersionAvailable();
} }
@@ -1185,6 +1262,12 @@ class Reader {
case 'loader': case 'loader':
this.loaderToggle(); this.loaderToggle();
break; break;
case 'loadFile':
this.loadFileToggle();
break;
case 'loadBuffer':
this.loadBufferToggle();
break;
case 'help': case 'help':
this.helpToggle(); this.helpToggle();
break; break;
@@ -1227,6 +1310,9 @@ class Reader {
case 'recentBooks': case 'recentBooks':
this.recentBooksToggle(); this.recentBooksToggle();
break; break;
case 'clickControl':
this.clickControlToggle();
break;
case 'offlineMode': case 'offlineMode':
this.offlineModeToggle(); this.offlineModeToggle();
break; break;
@@ -1329,13 +1415,14 @@ class Reader {
if (!result && event.type == 'keydown') { if (!result && event.type == 'keydown') {
const action = this.$root.readerActionByKeyEvent(event); const action = this.$root.readerActionByKeyEvent(event);
if (action == 'loader') { /*if (action == 'loader') {
result = this.doAction({action, event}); result = this.doAction({action, event});
} }
if (!result && this.activePage == 'TextPage') { if (!result && this.activePage == 'TextPage') {
result = this.doAction({action, event}); result = this.doAction({action, event});
} }*/
result = this.doAction({action, event});
} }
} }
return result; return result;

View File

@@ -5,12 +5,17 @@
Что нового: Что нового:
</template> </template>
<div style="line-height: 20px" v-html="whatsNewContent"></div> <div style="line-height: 20px; min-width: 300px">
<div v-html="whatsNewContent"></div>
</div>
<span class="clickable" @click="openVersionHistory">Посмотреть историю версий</span> <span class="clickable" style="font-size: 13px" @click="openVersionHistory">Посмотреть историю версий</span>
<span slot="footer">
<q-btn class="q-px-md" dense no-caps @click="whatsNewDisable">Больше не показывать</q-btn> <template #footer>
</span> <q-btn class="q-px-md" dense no-caps @click="whatsNewDisable">
Больше не показывать
</q-btn>
</template>
</Dialog> </Dialog>
<Dialog ref="dialog2" v-model="donationVisible"> <Dialog ref="dialog2" v-model="donationVisible">
@@ -49,17 +54,40 @@
<br><br> <br><br>
<div class="row justify-center"> <div class="row justify-center">
<q-btn class="q-px-sm" color="primary" dense no-caps rounded @click="openDonate"> <!--q-btn class="q-px-sm" color="primary" dense no-caps rounded @click="openDonate">
Помочь проекту Помочь проекту
</q-btn> </q-btn-->
</div> </div>
</div> </div>
<span slot="footer"> <template #footer>
<span class="clickable row justify-end" style="font-size: 60%; color: grey" @click="donationDialogDisable">Больше не показывать</span> <span class="clickable row justify-end" style="font-size: 60%; color: grey" @click="donationDialogDisable">Больше не показывать</span>
<br> <br>
<q-btn class="q-px-sm" dense no-caps @click="donationDialogRemind">Напомнить позже</q-btn> <q-btn class="q-px-sm" dense no-caps @click="donationDialogRemind">
</span> Напомнить позже
</q-btn>
</template>
</Dialog>
<Dialog ref="dialog3" v-model="urlHelpVisible">
<template #header>
Обнаружена невалидная ссылка в поле "URL книги".
<br>
</template>
<div style="word-break: normal">
Если вы хотите найти определенную книгу и открыть в читалке, добро пожаловать в
раздел "Сетевая библиотека" (кнопка <q-icon name="la la-sitemap" size="32px" />) на сайте
<a href="https://liberama.top" target="_blank">liberama.top</a>
<br><br>
Если же вы пытаетесь вставить текст в читалку из буфера обмена, пожалуйста воспользуйтесь кнопкой
<q-btn no-caps dense class="q-px-sm" color="primary" size="13px" @click="loadBufferClick">
<q-icon class="q-mr-xs" name="la la-comment" size="24px" />
Из буфера обмена
</q-btn>
на странице загрузки.
</div>
</Dialog> </Dialog>
</div> </div>
</template> </template>
@@ -88,6 +116,7 @@ class ReaderDialogs {
whatsNewVisible = false; whatsNewVisible = false;
whatsNewContent = ''; whatsNewContent = '';
donationVisible = false; donationVisible = false;
urlHelpVisible = false;
created() { created() {
this.commit = this.$store.commit; this.commit = this.$store.commit;
@@ -112,9 +141,9 @@ class ReaderDialogs {
const whatsNew = versionHistory[0]; const whatsNew = versionHistory[0];
if (this.showWhatsNewDialog && if (this.showWhatsNewDialog &&
whatsNew.showUntil >= utils.formatDate(new Date(), 'coDate') && whatsNew.showUntil >= utils.formatDate(new Date(), 'coDate') &&
whatsNew.header != this.whatsNewContentHash) { this.whatsNewHeader != this.whatsNewContentHash) {
await utils.sleep(2000); await utils.sleep(2000);
this.whatsNewContent = 'Версия ' + whatsNew.header + whatsNew.content; this.whatsNewContent = 'Версия ' + this.whatsNewHeader + whatsNew.content;
this.whatsNewVisible = true; this.whatsNewVisible = true;
} }
} }
@@ -128,6 +157,15 @@ class ReaderDialogs {
} }
} }
async showUrlHelp() {
this.urlHelpVisible = true;
}
loadBufferClick() {
this.$emit('load-buffer-toggle');
this.urlHelpVisible = false;
}
donationDialogDisable() { donationDialogDisable() {
this.donationVisible = false; this.donationVisible = false;
if (this.showDonationDialog2020) { if (this.showDonationDialog2020) {
@@ -160,8 +198,11 @@ class ReaderDialogs {
whatsNewDisable() { whatsNewDisable() {
this.whatsNewVisible = false; this.whatsNewVisible = false;
const whatsNew = versionHistory[0]; this.commit('reader/setWhatsNewContentHash', this.whatsNewHeader);
this.commit('reader/setWhatsNewContentHash', whatsNew.header); }
get whatsNewHeader() {
return `${versionHistory[0].version} (${versionHistory[0].releaseDate})`;
} }
get mode() { get mode() {
@@ -181,7 +222,7 @@ class ReaderDialogs {
} }
keyHook() { keyHook() {
if (this.$refs.dialog1.active || this.$refs.dialog2.active) if (this.$refs.dialog1.active || this.$refs.dialog2.active || this.$refs.dialog3.active)
return true; return true;
return false; return false;
} }

View File

@@ -52,7 +52,7 @@
</q-checkbox> </q-checkbox>
</div> </div>
<div class="item row"> <!--div class="item row">
<div class="label-6">Уведомление</div> <div class="label-6">Уведомление</div>
<q-checkbox size="xs" v-model="showDonationDialog2020"> <q-checkbox size="xs" v-model="showDonationDialog2020">
Показывать "Оплатим хостинг вместе" Показывать "Оплатим хостинг вместе"
@@ -60,7 +60,7 @@
Показывать уведомление "Оплатим хостинг вместе" Показывать уведомление "Оплатим хостинг вместе"
</q-tooltip> </q-tooltip>
</q-checkbox> </q-checkbox>
</div> </div-->
<!----------------------------------------------> <!---------------------------------------------->
<div class="part-header">Другое</div> <div class="part-header">Другое</div>

View File

@@ -1,73 +1,113 @@
export const versionHistory = [ export const versionHistory = [
{ {
version: '0.11.4',
releaseDate: '2022-04-14',
showUntil: '2022-04-13',
content:
`
<ul>
<li>небольшие дополнения интерфейса</li>
<li>исправления багов</li>
</ul>
`
},
{
version: '0.11.3',
releaseDate: '2022-03-29',
showUntil: '2022-03-28',
content:
`
<ul>
<li>исправления багов</li>
</ul>
`
},
{
version: '0.11.2',
releaseDate: '2022-01-11',
showUntil: '2022-01-10', showUntil: '2022-01-10',
header: '0.11.2 (2022-01-11)',
content: content:
` `
<ul> <ul>
<li>переход на JembaDb вместо SQLite</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.11.1',
releaseDate: '2021-12-03',
showUntil: '2021-12-02', showUntil: '2021-12-02',
header: '0.11.1 (2021-12-03)',
content: content:
` `
<ul> <ul>
<li>переход на JembaDb вместо SQLite</li> <li>переход на JembaDb вместо SQLite</li>
</ul> </ul>
` `
}, },
{ {
version: '0.11.0',
releaseDate: '2021-11-18',
showUntil: '2021-11-17', showUntil: '2021-11-17',
header: '0.11.0 (2021-11-18)',
content: content:
` `
<ul> <ul>
<li>переход на Vue 3</li> <li>переход на Vue 3</li>
</ul> </ul>
` `
}, },
{ {
version: '0.10.3',
releaseDate: '2021-10-24',
showUntil: '2021-10-23', showUntil: '2021-10-23',
header: '0.10.3 (2021-10-24)',
content: content:
` `
<ul> <ul>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.10.2',
releaseDate: '2021-10-19',
showUntil: '2021-10-18', showUntil: '2021-10-18',
header: '0.10.2 (2021-10-19)',
content: content:
` `
<ul> <ul>
<li>актуализация версий пакетов и стека используемых технологий</li> <li>актуализация версий пакетов и стека используемых технологий</li>
</ul> </ul>
` `
}, },
{ {
version: '0.10.1',
releaseDate: '2021-10-10',
showUntil: '2021-10-09', showUntil: '2021-10-09',
header: '0.10.1 (2021-10-10)',
content: content:
` `
<ul> <ul>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.10.0',
releaseDate: '2021-02-09',
showUntil: '2021-02-16', showUntil: '2021-02-16',
header: '0.10.0 (2021-02-09)',
content: content:
` `
<ul> <ul>
@@ -76,12 +116,14 @@ export const versionHistory = [
<li>в настройки добавлена возможность загрузки пользовательских обоев (пока без синхронизации)</li> <li>в настройки добавлена возможность загрузки пользовательских обоев (пока без синхронизации)</li>
<li>немного улучшен парсинг fb2</li> <li>немного улучшен парсинг fb2</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.12',
releaseDate: '2020-12-18',
showUntil: '2020-12-17', showUntil: '2020-12-17',
header: '0.9.12 (2020-12-18)',
content: content:
` `
<ul> <ul>
@@ -90,23 +132,27 @@ export const versionHistory = [
<li>добавлена кнопка для быстрого доступа к настройкам конвертирования</li> <li>добавлена кнопка для быстрого доступа к настройкам конвертирования</li>
<li>улучшения работы конвертеров</li> <li>улучшения работы конвертеров</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.11',
releaseDate: '2020-12-09',
showUntil: '2020-12-08', showUntil: '2020-12-08',
header: '0.9.11 (2020-12-09)',
content: content:
` `
<ul> <ul>
<li>оптимизации, улучшения работы конвертеров</li> <li>оптимизации, улучшения работы конвертеров</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.10',
releaseDate: '2020-12-03',
showUntil: '2020-12-10', showUntil: '2020-12-10',
header: '0.9.10 (2020-12-03)',
content: content:
` `
<ul> <ul>
@@ -114,69 +160,81 @@ export const versionHistory = [
<li>добавлена поддержка Rar-архивов</li> <li>добавлена поддержка Rar-архивов</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.9',
releaseDate: '2020-11-21',
showUntil: '2020-11-20', showUntil: '2020-11-20',
header: '0.9.9 (2020-11-21)',
content: content:
` `
<ul> <ul>
<li>оптимизации, исправления багов</li> <li>оптимизации, исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.8',
releaseDate: '2020-11-13',
showUntil: '2020-11-12', showUntil: '2020-11-12',
header: '0.9.8 (2020-11-13)',
content: content:
` `
<ul> <ul>
<li>добавлено окно "Оглавление/закладки"</li> <li>добавлено окно "Оглавление/закладки"</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.7',
releaseDate: '2020-11-12',
showUntil: '2020-11-11', showUntil: '2020-11-11',
header: '0.9.7 (2020-11-12)',
content: content:
` `
<ul> <ul>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.6',
releaseDate: '2020-11-06',
showUntil: '2020-11-05', showUntil: '2020-11-05',
header: '0.9.6 (2020-11-06)',
content: content:
` `
<ul> <ul>
<li>завершена работа над новым окном "Библиотека"</li> <li>завершена работа над новым окном "Библиотека"</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.5',
releaseDate: '2020-11-01',
showUntil: '2020-10-31', showUntil: '2020-10-31',
header: '0.9.5 (2020-11-01)',
content: content:
` `
<ul> <ul>
<li>на панель инструментов добавлена новая кнопка "Обновить с разбиением на параграфы"</li> <li>на панель инструментов добавлена новая кнопка "Обновить с разбиением на параграфы"</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.4',
releaseDate: '2020-10-29',
showUntil: '2020-10-28', showUntil: '2020-10-28',
header: '0.9.4 (2020-10-29)',
content: content:
` `
<ul> <ul>
@@ -184,23 +242,27 @@ export const versionHistory = [
<li>для liberama.top добавлено новое окно: "Библиотека"</li> <li>для liberama.top добавлено новое окно: "Библиотека"</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.3',
releaseDate: '2020-05-21',
showUntil: '2020-05-20', showUntil: '2020-05-20',
header: '0.9.3 (2020-05-21)',
content: content:
` `
<ul> <ul>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.2',
releaseDate: '2020-03-15',
showUntil: '2020-04-25', showUntil: '2020-04-25',
header: '0.9.2 (2020-03-15)',
content: content:
` `
<ul> <ul>
@@ -208,119 +270,139 @@ export const versionHistory = [
<li>переход на Service Worker вместо AppCache для автономного режима работы</li> <li>переход на Service Worker вместо AppCache для автономного режима работы</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.1',
releaseDate: '2020-03-03',
showUntil: '2020-03-02', showUntil: '2020-03-02',
header: '0.9.1 (2020-03-03)',
content: content:
` `
<ul> <ul>
<li>улучшение работы серверной части</li> <li>улучшение работы серверной части</li>
<li>незначительные изменения интерфейса</li> <li>незначительные изменения интерфейса</li>
</ul> </ul>
` `
}, },
{ {
version: '0.9.0',
releaseDate: '2020-02-26',
showUntil: '2020-02-25', showUntil: '2020-02-25',
header: '0.9.0 (2020-02-26)',
content: content:
` `
<ul> <ul>
<li>переход на UI-фреймфорк Quasar</li> <li>переход на UI-фреймфорк Quasar</li>
<li>незначительные изменения интерфейса</li> <li>незначительные изменения интерфейса</li>
</ul> </ul>
` `
}, },
{ {
version: '0.8.4',
releaseDate: '2020-02-06',
showUntil: '2020-02-05', showUntil: '2020-02-05',
header: '0.8.4 (2020-02-06)',
content: content:
` `
<ul> <ul>
<li>добавлен paypal-адрес для пожертвований</li> <li>добавлен paypal-адрес для пожертвований</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.8.3',
releaseDate: '2020-01-28',
showUntil: '2020-01-27', showUntil: '2020-01-27',
header: '0.8.3 (2020-01-28)',
content: content:
` `
<ul> <ul>
<li>добавлено всплывающее окно с акцией "Оплатим хостинг вместе"</li> <li>добавлено всплывающее окно с акцией "Оплатим хостинг вместе"</li>
<li>внутренние оптимизации</li> <li>внутренние оптимизации</li>
</ul> </ul>
` `
}, },
{ {
version: '0.8.2',
releaseDate: '2020-01-20',
showUntil: '2020-01-19', showUntil: '2020-01-19',
header: '0.8.2 (2020-01-20)',
content: content:
` `
<ul> <ul>
<li>внутренние оптимизации</li> <li>внутренние оптимизации</li>
</ul> </ul>
` `
}, },
{ {
version: '0.8.1',
releaseDate: '2020-01-07',
showUntil: '2020-01-06', showUntil: '2020-01-06',
header: '0.8.1 (2020-01-07)',
content: content:
` `
<ul> <ul>
<li>добавлена частичная поддержка формата FB3</li> <li>добавлена частичная поддержка формата FB3</li>
<li>исправлен баг "Request path contains unescaped characters"</li> <li>исправлен баг "Request path contains unescaped characters"</li>
</ul> </ul>
` `
}, },
{ {
version: '0.8.0',
releaseDate: '2020-01-02',
showUntil: '2020-01-05', showUntil: '2020-01-05',
header: '0.8.0 (2020-01-02)',
content: content:
` `
<ul> <ul>
<li>окончательный переход на https</li> <li>окончательный переход на https</li>
<li>код проекта теперь Open Source: <a href="https://github.com/bookpauk/liberama" target="_blank">https://github.com/bookpauk/liberama</a></li> <li>код проекта теперь Open Source: <a href="https://github.com/bookpauk/liberama" target="_blank">https://github.com/bookpauk/liberama</a></li>
</ul> </ul>
` `
}, },
{ {
version: '0.7.9',
releaseDate: '2019-11-27',
showUntil: '2019-11-26', showUntil: '2019-11-26',
header: '0.7.9 (2019-11-27)',
content: content:
` `
<ul> <ul>
<li>добавлен неубираемый баннер для http-версии о переходе на httpS</li> <li>добавлен неубираемый баннер для http-версии о переходе на httpS</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.7.8',
releaseDate: '2019-11-25',
showUntil: '2019-11-24', showUntil: '2019-11-24',
header: '0.7.8 (2019-11-25)',
content: content:
` `
<ul> <ul>
<li>улучшение html-фильтров для сайтов</li> <li>улучшение html-фильтров для сайтов</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.7.7',
releaseDate: '2019-11-06',
showUntil: '2019-11-10', showUntil: '2019-11-10',
header: '0.7.7 (2019-11-06)',
content: content:
` `
<ul> <ul>
@@ -332,34 +414,40 @@ export const versionHistory = [
<li style="list-style-type: square">от центра влево: уменьшить скорость скроллинга</li> <li style="list-style-type: square">от центра влево: уменьшить скорость скроллинга</li>
</ul> </ul>
</ul> </ul>
` `
}, },
{ {
version: '0.7.6',
releaseDate: '2019-10-30',
showUntil: '2019-10-29', showUntil: '2019-10-29',
header: '0.7.6 (2019-10-30)',
content: content:
` `
<ul> <ul>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.7.5',
releaseDate: '2019-10-22',
showUntil: '2019-10-21', showUntil: '2019-10-21',
header: '0.7.5 (2019-10-22)',
content: content:
` `
<ul> <ul>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.7.3',
releaseDate: '2019-10-18',
showUntil: '2019-10-17', showUntil: '2019-10-17',
header: '0.7.3 (2019-10-18)',
content: content:
` `
<ul> <ul>
@@ -368,12 +456,14 @@ export const versionHistory = [
<li>добавлен параметр "Включить html-фильтр для сайтов" в раздел "Вид"->"Текст" в настройках</li> <li>добавлен параметр "Включить html-фильтр для сайтов" в раздел "Вид"->"Текст" в настройках</li>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.7.1',
releaseDate: '2019-09-20',
showUntil: '2019-09-19', showUntil: '2019-09-19',
header: '0.7.1 (2019-09-20)',
content: content:
` `
<ul> <ul>
@@ -381,12 +471,14 @@ export const versionHistory = [
<li>на панель управления добавлена кнопка "Автономный режим"</li> <li>на панель управления добавлена кнопка "Автономный режим"</li>
<li>актуализирована справка</li> <li>актуализирована справка</li>
</ul> </ul>
` `
}, },
{ {
version: '0.7.0',
releaseDate: '2019-09-07',
showUntil: '2019-10-01', showUntil: '2019-10-01',
header: '0.7.0 (2019-09-07)',
content: content:
` `
<ul> <ul>
@@ -397,23 +489,27 @@ export const versionHistory = [
<li>немного улучшен внешний вид и управление на смартфонах</li> <li>немного улучшен внешний вид и управление на смартфонах</li>
<li>добавлен параметр "Компактность" в раздел "Вид"->"Текст" в настройках</li> <li>добавлен параметр "Компактность" в раздел "Вид"->"Текст" в настройках</li>
</ul> </ul>
` `
}, },
{ {
version: '0.6.10',
releaseDate: '2019-07-21',
showUntil: '2019-07-20', showUntil: '2019-07-20',
header: '0.6.10 (2019-07-21)',
content: content:
` `
<ul> <ul>
<li>исправления багов</li> <li>исправления багов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.6.9',
releaseDate: '2019-06-23',
showUntil: '2019-06-22', showUntil: '2019-06-22',
header: '0.6.9 (2019-06-23)',
content: content:
` `
<ul> <ul>
@@ -424,12 +520,14 @@ export const versionHistory = [
<li>улучшены прогрессбары</li> <li>улучшены прогрессбары</li>
<li>исправления недочетов, небольшие оптимизации</li> <li>исправления недочетов, небольшие оптимизации</li>
</ul> </ul>
` `
}, },
{ {
version: '0.6.7',
releaseDate: '2019-05-30',
showUntil: '2019-06-05', showUntil: '2019-06-05',
header: '0.6.7 (2019-05-30)',
content: content:
` `
<ul> <ul>
@@ -442,36 +540,42 @@ export const versionHistory = [
<li>добавлен GET-параметр вида "/reader?__pp=50.5&url=..." для указания позиции в книге в процентах</li> <li>добавлен GET-параметр вида "/reader?__pp=50.5&url=..." для указания позиции в книге в процентах</li>
<li>исправления багов и недочетов</li> <li>исправления багов и недочетов</li>
</ul> </ul>
` `
}, },
{ {
version: '0.6.6',
releaseDate: '2019-03-29',
showUntil: '2019-03-29', showUntil: '2019-03-29',
header: '0.6.6 (2019-03-29)',
content: content:
` `
<ul> <ul>
<li>в справку добавлено описание настройки браузеров для автономной работы читалки (без доступа к интернету)</li> <li>в справку добавлено описание настройки браузеров для автономной работы читалки (без доступа к интернету)</li>
<li>оптимизации процесса синхронизации, внутренние переделки</li> <li>оптимизации процесса синхронизации, внутренние переделки</li>
</ul> </ul>
` `
}, },
{ {
version: '0.6.4',
releaseDate: '2019-03-24',
showUntil: '2019-03-24', showUntil: '2019-03-24',
header: '0.6.4 (2019-03-24)',
content: content:
` `
<ul> <ul>
<li>исправления багов, оптимизации</li> <li>исправления багов, оптимизации</li>
<li>добавлена возможность синхронизации данных между устройствами</li> <li>добавлена возможность синхронизации данных между устройствами</li>
</ul> </ul>
` `
}, },
{ {
version: '0.5.4',
releaseDate: '2019-03-04',
showUntil: '2019-03-04', showUntil: '2019-03-04',
header: '0.5.4 (2019-03-04)',
content: content:
` `
<ul> <ul>
@@ -480,12 +584,14 @@ export const versionHistory = [
<li>(0.4.2) фильтр для СИ больше не вырезает изображения</li> <li>(0.4.2) фильтр для СИ больше не вырезает изображения</li>
<li>(0.4.0) добавлено отображение картинок в fb2</li> <li>(0.4.0) добавлено отображение картинок в fb2</li>
</ul> </ul>
` `
}, },
{ {
version: '0.3.0',
releaseDate: '2019-02-17',
showUntil: '2019-02-17', showUntil: '2019-02-17',
header: '0.3.0 (2019-02-17)',
content: content:
` `
<ul> <ul>
@@ -493,12 +599,14 @@ export const versionHistory = [
<li>улучшено распознавание текста</li> <li>улучшено распознавание текста</li>
<li>изменена верстка страницы - убрано позиционирование каждого слова</li> <li>изменена верстка страницы - убрано позиционирование каждого слова</li>
</ul> </ul>
` `
}, },
{ {
version: '0.1.7',
releaseDate: '2019-02-14',
showUntil: '2019-02-14', showUntil: '2019-02-14',
header: '0.1.7 (2019-02-14)',
content: content:
` `
<ul> <ul>
@@ -508,17 +616,20 @@ export const versionHistory = [
<li>добавлена возможность сброса настроек</li> <li>добавлена возможность сброса настроек</li>
<li>убран автоматический редирект на последнюю загруженную книгу, если не задан url в маршруте</li> <li>убран автоматический редирект на последнюю загруженную книгу, если не задан url в маршруте</li>
</ul> </ul>
` `
}, },
{ {
version: '0.1.0',
releaseDate: '2019-02-12',
showUntil: '2019-02-12', showUntil: '2019-02-12',
header: '0.1.0 (2019-02-12)',
content: content:
` `
<ul> <ul>
<li>первый деплой проекта, длительность разработки - 2 месяца</li> <li>первый деплой проекта, длительность разработки - 2 месяца</li>
</ul> </ul>
` `
}, },

View File

@@ -2,8 +2,10 @@ import * as utils from '../../share/utils';
import googleFonts from './fonts/fonts.json'; import googleFonts from './fonts/fonts.json';
const readerActions = { const readerActions = {
'help': 'Вызвать cправку',
'loader': 'На страницу загрузки', 'loader': 'На страницу загрузки',
'loadFile': 'Загрузить файл с диска',
'loadBuffer': 'Загрузить из буфера обмена',
'help': 'Вызвать cправку',
'settings': 'Настроить', 'settings': 'Настроить',
'undoAction': 'Действие назад', 'undoAction': 'Действие назад',
'redoAction': 'Действие вперед', 'redoAction': 'Действие вперед',
@@ -15,6 +17,7 @@ const readerActions = {
'copyText': 'Скопировать текст со страницы', 'copyText': 'Скопировать текст со страницы',
'convOptions': 'Настроить конвертирование', 'convOptions': 'Настроить конвертирование',
'refresh': 'Принудительно обновить книгу', 'refresh': 'Принудительно обновить книгу',
'clickControl': 'Управление кликом',
'offlineMode': 'Автономный режим (без интернета)', 'offlineMode': 'Автономный режим (без интернета)',
'contents': 'Оглавление/закладки', 'contents': 'Оглавление/закладки',
'libs': 'Сетевая библиотека', 'libs': 'Сетевая библиотека',
@@ -35,6 +38,9 @@ const readerActions = {
//readerActions[name] //readerActions[name]
const toolButtons = [ const toolButtons = [
{name: 'loadFile', show: true},
{name: 'loadBuffer', show: true},
{name: 'help', show: true},
{name: 'undoAction', show: true}, {name: 'undoAction', show: true},
{name: 'redoAction', show: true}, {name: 'redoAction', show: true},
{name: 'fullScreen', show: true}, {name: 'fullScreen', show: true},
@@ -47,13 +53,16 @@ const toolButtons = [
{name: 'contents', show: true}, {name: 'contents', show: true},
{name: 'libs', show: true}, {name: 'libs', show: true},
{name: 'recentBooks', show: true}, {name: 'recentBooks', show: true},
{name: 'clickControl', show: false},
{name: 'offlineMode', show: false}, {name: 'offlineMode', show: false},
]; ];
//readerActions[name] //readerActions[name]
const hotKeys = [ const hotKeys = [
{name: 'help', codes: ['F1', 'H']},
{name: 'loader', codes: ['Escape']}, {name: 'loader', codes: ['Escape']},
{name: 'loadFile', codes: ['F3']},
{name: 'loadBuffer', codes: ['F4']},
{name: 'help', codes: ['F1', 'H']},
{name: 'settings', codes: ['S']}, {name: 'settings', codes: ['S']},
{name: 'undoAction', codes: ['Ctrl+BracketLeft']}, {name: 'undoAction', codes: ['Ctrl+BracketLeft']},
{name: 'redoAction', codes: ['Ctrl+BracketRight']}, {name: 'redoAction', codes: ['Ctrl+BracketRight']},
@@ -67,6 +76,7 @@ const hotKeys = [
{name: 'contents', codes: ['C']}, {name: 'contents', codes: ['C']},
{name: 'libs', codes: ['L']}, {name: 'libs', codes: ['L']},
{name: 'recentBooks', codes: ['X']}, {name: 'recentBooks', codes: ['X']},
{name: 'clickControl', codes: ['Ctrl+B']},
{name: 'offlineMode', codes: ['O']}, {name: 'offlineMode', codes: ['O']},
{name: 'switchToolbar', codes: ['Tab', 'Q']}, {name: 'switchToolbar', codes: ['Tab', 'Q']},

18
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.11.1", "version": "0.11.4",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "Liberama", "name": "Liberama",
"version": "0.11.1", "version": "0.11.4",
"hasInstallScript": true, "hasInstallScript": true,
"license": "CC0-1.0", "license": "CC0-1.0",
"dependencies": { "dependencies": {
@@ -22,7 +22,7 @@
"got": "^11.8.2", "got": "^11.8.2",
"he": "^1.2.0", "he": "^1.2.0",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"jembadb": "^1.3.0", "jembadb": "^2.3.0",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"minimist": "^1.2.5", "minimist": "^1.2.5",
@@ -6379,9 +6379,9 @@
} }
}, },
"node_modules/jembadb": { "node_modules/jembadb": {
"version": "1.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/jembadb/-/jembadb-1.3.0.tgz", "resolved": "https://registry.npmjs.org/jembadb/-/jembadb-2.3.0.tgz",
"integrity": "sha512-zMJ1GyXmqvniWToaZTzc3JPHK+SfvcynFHYsZAx8bJWlgVdQd6cqYpIEXJFP+3OZqxPTzMYG5OBGclxTsoOqtg==", "integrity": "sha512-Jrvbe+4a3ULZvYmM6VnIK6mGFegPELbAppSYTTvPUeMmndNVOAVr1RDHKEiV8ccLanv1xWnJYiCo1mdnepR/Cg==",
"engines": { "engines": {
"node": ">=14.4.0" "node": ">=14.4.0"
} }
@@ -16229,9 +16229,9 @@
} }
}, },
"jembadb": { "jembadb": {
"version": "1.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/jembadb/-/jembadb-1.3.0.tgz", "resolved": "https://registry.npmjs.org/jembadb/-/jembadb-2.3.0.tgz",
"integrity": "sha512-zMJ1GyXmqvniWToaZTzc3JPHK+SfvcynFHYsZAx8bJWlgVdQd6cqYpIEXJFP+3OZqxPTzMYG5OBGclxTsoOqtg==" "integrity": "sha512-Jrvbe+4a3ULZvYmM6VnIK6mGFegPELbAppSYTTvPUeMmndNVOAVr1RDHKEiV8ccLanv1xWnJYiCo1mdnepR/Cg=="
}, },
"jest-worker": { "jest-worker": {
"version": "27.3.1", "version": "27.3.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.11.2", "version": "0.11.4",
"author": "Book Pauk <bookpauk@gmail.com>", "author": "Book Pauk <bookpauk@gmail.com>",
"license": "CC0-1.0", "license": "CC0-1.0",
"repository": "bookpauk/liberama", "repository": "bookpauk/liberama",
@@ -60,7 +60,7 @@
"got": "^11.8.2", "got": "^11.8.2",
"he": "^1.2.0", "he": "^1.2.0",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"jembadb": "^1.3.0", "jembadb": "^2.3.0",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"minimist": "^1.2.5", "minimist": "^1.2.5",

View File

@@ -55,8 +55,7 @@ class WebSocketController {
ws.lastActivity = Date.now(); ws.lastActivity = Date.now();
//pong for WebSocketConnection //pong for WebSocketConnection
if (req._rpo === 1) this.send({_rok: 1}, req, ws);
this.send({_rok: 1}, req, ws);
switch (req.action) { switch (req.action) {
case 'test': case 'test':

View File

@@ -1,27 +1,26 @@
let instance = null; let instance = null;
const defaultTimeout = 15*1000;//15 sec const defaultTimeout = 15*1000;//15 sec
const exitSignals = ['SIGINT', 'SIGTERM', 'SIGBREAK', 'SIGHUP', 'uncaughtException', 'SIGUSR2']; const exitSignals = ['SIGINT', 'SIGTERM', 'SIGBREAK', 'SIGHUP', 'uncaughtException'];
//singleton //singleton
class AsyncExit { class AsyncExit {
constructor() { constructor(signals = exitSignals, codeOnSignal = 2) {
if (!instance) { if (!instance) {
this.onSignalCallbacks = new Map(); this.onSignalCallbacks = new Map();
this.callbacks = new Map(); this.callbacks = new Map();
this.afterCallbacks = new Map(); this.afterCallbacks = new Map();
this.exitTimeout = defaultTimeout; this.exitTimeout = defaultTimeout;
this.inited = false;
this._init(signals, codeOnSignal);
instance = this; instance = this;
} }
return instance; return instance;
} }
init(signals = exitSignals, codeOnSignal = 2) { _init(signals, codeOnSignal) {
if (this.inited)
throw new Error('AsyncExit: initialized already');
const runSingalCallbacks = async(signal) => { const runSingalCallbacks = async(signal) => {
for (const signalCallback of this.onSignalCallbacks.keys()) { for (const signalCallback of this.onSignalCallbacks.keys()) {
try { try {
@@ -38,8 +37,6 @@ class AsyncExit {
this.exit(codeOnSignal); this.exit(codeOnSignal);
}); });
} }
this.inited = true;
} }
onSignal(signalCallback) { onSignal(signalCallback) {

View File

@@ -9,8 +9,7 @@ const cleanPeriod = 5*1000;//5 секунд
class WebSocketConnection { class WebSocketConnection {
//messageLifeTime в секундах (проверка каждый cleanPeriod интервал) //messageLifeTime в секундах (проверка каждый cleanPeriod интервал)
constructor(url, openTimeoutSecs = 10, messageLifeTimeSecs = 30) { constructor(url, openTimeoutSecs = 10, messageLifeTimeSecs = 30) {
//const ws = 'ws';//for nodejs this.WebSocket = (isBrowser ? WebSocket : require('ws'));
this.WebSocket = (isBrowser ? WebSocket : null/*for nodejs require(ws)*/);
this.url = url; this.url = url;
this.ws = null; this.ws = null;
this.listeners = []; this.listeners = [];
@@ -166,7 +165,7 @@ class WebSocketConnection {
this.requestId = (this.requestId < 1000000 ? this.requestId + 1 : 1); this.requestId = (this.requestId < 1000000 ? this.requestId + 1 : 1);
const requestId = this.requestId;//реентерабельность!!! const requestId = this.requestId;//реентерабельность!!!
this.ws.send(JSON.stringify(Object.assign({requestId, _rpo: 1}, req)));//_rpo: 1 - ждем в ответ _rok: 1 this.ws.send(JSON.stringify(Object.assign({requestId}, req)));
let resp = {}; let resp = {};
try { try {

View File

@@ -14,6 +14,7 @@ class JembaConnManager {
constructor() { constructor() {
if (!instance) { if (!instance) {
this.inited = false; this.inited = false;
this._db = {};
instance = this; instance = this;
} }
@@ -28,6 +29,8 @@ class JembaConnManager {
this.config = config; this.config = config;
this._db = {}; this._db = {};
ayncExit.add(this.close.bind(this));
for (const dbConfig of this.config.jembaDb) { for (const dbConfig of this.config.jembaDb) {
const dbPath = `${this.config.dataDir}/db/${dbConfig.dbName}`; const dbPath = `${this.config.dataDir}/db/${dbConfig.dbName}`;
@@ -44,17 +47,23 @@ class JembaConnManager {
} else { } else {
dbConn = new JembaDb(); dbConn = new JembaDb();
} }
this._db[dbConfig.dbName] = dbConn;
log(`Open "${dbConfig.dbName}" begin`); log(`Open "${dbConfig.dbName}" begin`);
await dbConn.openDb({ await dbConn.lock({
dbPath, dbPath,
create: true, create: true,
cacheSize: dbConfig.cacheSize, softLock: true,
compressed: dbConfig.compressed,
forceFileClosing: dbConfig.forceFileClosing tableDefaults: {
cacheSize: dbConfig.cacheSize,
compressed: dbConfig.compressed,
forceFileClosing: dbConfig.forceFileClosing,
typeCompatMode: true,
},
}); });
if (dbConfig.openAll) { if (dbConfig.openAll || forceAutoRepair || dbConfig.autoRepair) {
try { try {
await dbConn.openAll(); await dbConn.openAll();
} catch(e) { } catch(e) {
@@ -83,21 +92,15 @@ class JembaConnManager {
if (applied.length) if (applied.length)
log(`${applied.length} migrations applied to "${dbConfig.dbName}"`); log(`${applied.length} migrations applied to "${dbConfig.dbName}"`);
} }
this._db[dbConfig.dbName] = dbConn;
} }
ayncExit.add(this.close.bind(this));
this.inited = true; this.inited = true;
} }
async close() { async close() {
if (!this.inited)
return;
for (const dbConfig of this.config.jembaDb) { for (const dbConfig of this.config.jembaDb) {
await this._db[dbConfig.dbName].closeDb(); if (this._db[dbConfig.dbName])
await this._db[dbConfig.dbName].unlock();
} }
this._db = {}; this._db = {};

View File

@@ -8,7 +8,6 @@ const http = require('http');
const WebSocket = require ('ws'); const WebSocket = require ('ws');
const ayncExit = new (require('./core/AsyncExit'))(); const ayncExit = new (require('./core/AsyncExit'))();
ayncExit.init();
let log = null; let log = null;