Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6e534b9db | ||
|
|
032ab6a85d | ||
|
|
21716163cb | ||
|
|
ca924148a5 | ||
|
|
37aa9b84ae | ||
|
|
c7bd7d4d7d | ||
|
|
d81a50e696 | ||
|
|
dda9943dbe |
@@ -131,6 +131,9 @@ import ContentsPage from './ContentsPage/ContentsPage.vue';
|
|||||||
import ReaderDialogs from './ReaderDialogs/ReaderDialogs.vue';
|
import ReaderDialogs from './ReaderDialogs/ReaderDialogs.vue';
|
||||||
|
|
||||||
import bookManager from './share/bookManager';
|
import bookManager from './share/bookManager';
|
||||||
|
import wallpaperStorage from './share/wallpaperStorage';
|
||||||
|
import dynamicCss from '../../share/dynamicCss';
|
||||||
|
|
||||||
import rstore from '../../store/modules/reader';
|
import rstore from '../../store/modules/reader';
|
||||||
import readerApi from '../../api/reader';
|
import readerApi from '../../api/reader';
|
||||||
import miscApi from '../../api/misc';
|
import miscApi from '../../api/misc';
|
||||||
@@ -274,6 +277,7 @@ class Reader extends Vue {
|
|||||||
this.updateHeaderMinWidth();
|
this.updateHeaderMinWidth();
|
||||||
|
|
||||||
(async() => {
|
(async() => {
|
||||||
|
await wallpaperStorage.init();
|
||||||
await bookManager.init(this.settings);
|
await bookManager.init(this.settings);
|
||||||
bookManager.addEventListener(this.bookManagerEvent);
|
bookManager.addEventListener(this.bookManagerEvent);
|
||||||
|
|
||||||
@@ -327,6 +331,7 @@ class Reader extends Vue {
|
|||||||
this.pdfAsText = settings.pdfAsText;
|
this.pdfAsText = settings.pdfAsText;
|
||||||
this.pdfQuality = settings.pdfQuality;
|
this.pdfQuality = settings.pdfQuality;
|
||||||
this.dualPageMode = settings.dualPageMode;
|
this.dualPageMode = settings.dualPageMode;
|
||||||
|
this.userWallpapers = settings.userWallpapers;
|
||||||
|
|
||||||
this.readerActionByKeyCode = utils.userHotKeysObjectSwap(settings.userHotKeys);
|
this.readerActionByKeyCode = utils.userHotKeysObjectSwap(settings.userHotKeys);
|
||||||
this.$root.readerActionByKeyEvent = (event) => {
|
this.$root.readerActionByKeyEvent = (event) => {
|
||||||
@@ -334,6 +339,30 @@ class Reader extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updateHeaderMinWidth();
|
this.updateHeaderMinWidth();
|
||||||
|
|
||||||
|
this.loadWallpapers();//no await
|
||||||
|
}
|
||||||
|
|
||||||
|
//wallpaper css
|
||||||
|
async loadWallpapers() {
|
||||||
|
const wallpaperDataLength = await wallpaperStorage.getLength();
|
||||||
|
if (wallpaperDataLength !== this.wallpaperDataLength) {//оптимизация
|
||||||
|
this.wallpaperDataLength = wallpaperDataLength;
|
||||||
|
|
||||||
|
let newCss = '';
|
||||||
|
for (const wp of this.userWallpapers) {
|
||||||
|
const data = await wallpaperStorage.getData(wp.cssClass);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
//здесь будем восстанавливать данные с сервера
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
newCss += `.${wp.cssClass} {background: url(${data}) center; background-size: 100% 100%;}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamicCss.replace('wallpapers', newCss);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkNewVersionAvailable() {
|
async checkNewVersionAvailable() {
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ import Component from 'vue-class-component';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import * as utils from '../../../share/utils';
|
import * as utils from '../../../share/utils';
|
||||||
|
import * as cryptoUtils from '../../../share/cryptoUtils';
|
||||||
import Window from '../../share/Window.vue';
|
import Window from '../../share/Window.vue';
|
||||||
import NumInput from '../../share/NumInput.vue';
|
import NumInput from '../../share/NumInput.vue';
|
||||||
import UserHotKeys from './UserHotKeys/UserHotKeys.vue';
|
import UserHotKeys from './UserHotKeys/UserHotKeys.vue';
|
||||||
@@ -279,8 +280,12 @@ class SettingsPage extends Vue {
|
|||||||
get wallpaperOptions() {
|
get wallpaperOptions() {
|
||||||
let result = [{label: 'Нет', value: ''}];
|
let result = [{label: 'Нет', value: ''}];
|
||||||
|
|
||||||
for (const wp of this.userWallpapers) {
|
const userWallpapers = _.cloneDeep(this.userWallpapers);
|
||||||
result.push({label: wp.label, value: wp.cssClass});
|
userWallpapers.sort((a, b) => a.label.localeCompare(b.label));
|
||||||
|
|
||||||
|
for (const wp of userWallpapers) {
|
||||||
|
if (wallpaperStorage.keyExists(wp.cssClass))
|
||||||
|
result.push({label: wp.label, value: wp.cssClass});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 1; i <= 17; i++) {
|
for (let i = 1; i <= 17; i++) {
|
||||||
@@ -579,19 +584,19 @@ class SettingsPage extends Vue {
|
|||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
const newUserWallpapers = _.cloneDeep(this.userWallpapers);
|
|
||||||
let n = 0;
|
|
||||||
for (const wp of newUserWallpapers) {
|
|
||||||
const newN = parseInt(wp.label.replace(/\D/g, ''), 10);
|
|
||||||
if (newN > n)
|
|
||||||
n = newN;
|
|
||||||
}
|
|
||||||
n++;
|
|
||||||
|
|
||||||
const cssClass = `user-paper${n}`;
|
|
||||||
newUserWallpapers.push({label: `#${n}`, cssClass});
|
|
||||||
(async() => {
|
(async() => {
|
||||||
await wallpaperStorage.setData(cssClass, e.target.result);
|
const data = e.target.result;
|
||||||
|
const key = utils.toHex(cryptoUtils.sha256(data));
|
||||||
|
const label = `#${key.substring(0, 4)}`;
|
||||||
|
const cssClass = `user-paper${key}`;
|
||||||
|
|
||||||
|
const newUserWallpapers = _.cloneDeep(this.userWallpapers);
|
||||||
|
const index = _.findIndex(newUserWallpapers, (item) => (item.cssClass == cssClass));
|
||||||
|
|
||||||
|
if (index < 0)
|
||||||
|
newUserWallpapers.push({label, cssClass});
|
||||||
|
if (!wallpaperStorage.keyExists(cssClass))
|
||||||
|
await wallpaperStorage.setData(cssClass, data);
|
||||||
|
|
||||||
this.userWallpapers = newUserWallpapers;
|
this.userWallpapers = newUserWallpapers;
|
||||||
this.wallpaper = cssClass;
|
this.wallpaper = cssClass;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
>
|
>
|
||||||
<template v-slot:selected-item="scope">
|
<template v-slot:selected-item="scope">
|
||||||
<div >{{ scope.opt.label }}</div>
|
<div >{{ scope.opt.label }}</div>
|
||||||
<div v-show="scope.opt.value" class="q-ml-sm" :class="scope.opt.value" style="width: 50px; height: 30px;"></div>
|
<div v-show="scope.opt.value" class="q-ml-sm" :class="scope.opt.value" style="width: 40px; height: 28px;"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-slot:option="scope">
|
<template v-slot:option="scope">
|
||||||
@@ -66,10 +66,10 @@
|
|||||||
v-bind="scope.itemProps"
|
v-bind="scope.itemProps"
|
||||||
v-on="scope.itemEvents"
|
v-on="scope.itemEvents"
|
||||||
>
|
>
|
||||||
<q-item-section>
|
<q-item-section style="min-width: 50px;">
|
||||||
<q-item-label v-html="scope.opt.label" />
|
<q-item-label v-html="scope.opt.label" />
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section v-show="scope.opt.value" :class="scope.opt.value" style="min-width: 70px; min-height: 50px"/>
|
<q-item-section v-show="scope.opt.value" :class="scope.opt.value" style="min-width: 70px; min-height: 50px;"/>
|
||||||
</q-item>
|
</q-item>
|
||||||
</template>
|
</template>
|
||||||
</q-select>
|
</q-select>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
<q-btn class="q-ml-sm" round dense color="blue" icon="la la-plus" @click.stop="loadWallpaperFileClick">
|
<q-btn class="q-ml-sm" round dense color="blue" icon="la la-plus" @click.stop="loadWallpaperFileClick">
|
||||||
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Добавить файл обоев</q-tooltip>
|
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Добавить файл обоев</q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-btn class="q-ml-sm" round dense color="blue" icon="la la-minus" @click.stop="delWallpaper" :disable="wallpaper.indexOf('user-paper') != 0">
|
<q-btn v-show="wallpaper.indexOf('user-paper') === 0" class="q-ml-sm" round dense color="blue" icon="la la-minus" @click.stop="delWallpaper">
|
||||||
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Удалить выбранные обои</q-tooltip>
|
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Удалить выбранные обои</q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import {sleep} from '../../../share/utils';
|
|||||||
|
|
||||||
export default class DrawHelper {
|
export default class DrawHelper {
|
||||||
fontBySize(size) {
|
fontBySize(size) {
|
||||||
return `${size}px ${this.fontName}`;
|
return `${size}px '${this.fontName}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
fontByStyle(style) {
|
fontByStyle(style) {
|
||||||
return `${style.italic ? 'italic' : this.fontStyle} ${style.bold ? 'bold' : this.fontWeight} ${this.fontSize}px ${this.fontName}`;
|
return `${style.italic ? 'italic' : this.fontStyle} ${style.bold ? 'bold' : this.fontWeight} ${this.fontSize}px '${this.fontName}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
measureText(text, style) {// eslint-disable-line no-unused-vars
|
measureText(text, style) {// eslint-disable-line no-unused-vars
|
||||||
|
|||||||
@@ -43,10 +43,8 @@ import _ from 'lodash';
|
|||||||
import './TextPage.css';
|
import './TextPage.css';
|
||||||
|
|
||||||
import * as utils from '../../../share/utils';
|
import * as utils from '../../../share/utils';
|
||||||
import dynamicCss from '../../../share/dynamicCss';
|
|
||||||
|
|
||||||
import bookManager from '../share/bookManager';
|
import bookManager from '../share/bookManager';
|
||||||
import wallpaperStorage from '../share/wallpaperStorage';
|
|
||||||
import DrawHelper from './DrawHelper';
|
import DrawHelper from './DrawHelper';
|
||||||
import rstore from '../../../store/modules/reader';
|
import rstore from '../../../store/modules/reader';
|
||||||
import {clickMap} from '../share/clickMap';
|
import {clickMap} from '../share/clickMap';
|
||||||
@@ -162,7 +160,7 @@ class TextPage extends Vue {
|
|||||||
const wideLetter = 'Щ';
|
const wideLetter = 'Щ';
|
||||||
|
|
||||||
//preloaded fonts
|
//preloaded fonts
|
||||||
this.fontList = [`12px ${this.fontName}`];
|
this.fontList = [`12px '${this.fontName}'`];
|
||||||
|
|
||||||
//widths
|
//widths
|
||||||
this.realWidth = this.$refs.main.clientWidth;
|
this.realWidth = this.$refs.main.clientWidth;
|
||||||
@@ -252,28 +250,6 @@ class TextPage extends Vue {
|
|||||||
//statusBar
|
//statusBar
|
||||||
this.statusBarClickable = this.drawHelper.statusBarClickable(this.statusBarTop, this.statusBarHeight);
|
this.statusBarClickable = this.drawHelper.statusBarClickable(this.statusBarTop, this.statusBarHeight);
|
||||||
|
|
||||||
//wallpaper css, асинхронно
|
|
||||||
(async() => {
|
|
||||||
const wallpaperDataLength = await wallpaperStorage.getLength();
|
|
||||||
if (wallpaperDataLength !== this.wallpaperDataLength) {//оптимизация
|
|
||||||
this.wallpaperDataLength = wallpaperDataLength;
|
|
||||||
|
|
||||||
let newCss = '';
|
|
||||||
for (const wp of this.userWallpapers) {
|
|
||||||
const data = await wallpaperStorage.getData(wp.cssClass);
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
//здесь будем восстанавливать данные с сервера
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
newCss += `.${wp.cssClass} {background: url(${data}) center; background-size: 100% 100%;}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dynamicCss.replace('wallpapers', newCss);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
//parsed
|
//parsed
|
||||||
if (this.parsed) {
|
if (this.parsed) {
|
||||||
let wideLine = wideLetter;
|
let wideLine = wideLetter;
|
||||||
@@ -524,7 +500,7 @@ class TextPage extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get font() {
|
get font() {
|
||||||
return `${this.fontStyle} ${this.fontWeight} ${this.fontSize}px ${this.fontName}`;
|
return `${this.fontStyle} ${this.fontWeight} ${this.fontSize}px '${this.fontName}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
onPage1TransitionEnd() {
|
onPage1TransitionEnd() {
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ const wpStore = localForage.createInstance({
|
|||||||
});
|
});
|
||||||
|
|
||||||
class WallpaperStorage {
|
class WallpaperStorage {
|
||||||
|
constructor() {
|
||||||
|
this.cachedKeys = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
this.cachedKeys = await wpStore.keys();
|
||||||
|
}
|
||||||
|
|
||||||
async getLength() {
|
async getLength() {
|
||||||
return await wpStore.length();
|
return await wpStore.length();
|
||||||
@@ -13,6 +20,7 @@ class WallpaperStorage {
|
|||||||
|
|
||||||
async setData(key, data) {
|
async setData(key, data) {
|
||||||
await wpStore.setItem(key, data);
|
await wpStore.setItem(key, data);
|
||||||
|
this.cachedKeys = await wpStore.keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getData(key) {
|
async getData(key) {
|
||||||
@@ -21,6 +29,11 @@ class WallpaperStorage {
|
|||||||
|
|
||||||
async removeData(key) {
|
async removeData(key) {
|
||||||
await wpStore.removeItem(key);
|
await wpStore.removeItem(key);
|
||||||
|
this.cachedKeys = await wpStore.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
keyExists(key) {//не асинхронная
|
||||||
|
return this.cachedKeys.includes(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ export function sleep(ms) {
|
|||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toHex(buf) {
|
||||||
|
return Buffer.from(buf).toString('hex');
|
||||||
|
}
|
||||||
|
|
||||||
export function stringToHex(str) {
|
export function stringToHex(str) {
|
||||||
return Buffer.from(str).toString('hex');
|
return Buffer.from(str).toString('hex');
|
||||||
}
|
}
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Liberama",
|
"name": "Liberama",
|
||||||
"version": "0.9.11",
|
"version": "0.10.1",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Liberama",
|
"name": "Liberama",
|
||||||
"version": "0.10.0",
|
"version": "0.10.1",
|
||||||
"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",
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ const SqliteConnectionPool = require('./SqliteConnectionPool');
|
|||||||
const log = new (require('../core/AppLogger'))().log;//singleton
|
const log = new (require('../core/AppLogger'))().log;//singleton
|
||||||
|
|
||||||
const migrations = {
|
const migrations = {
|
||||||
|
'app': require('./migrations/app'),
|
||||||
|
'readerStorage': require('./migrations/readerStorage'),
|
||||||
};
|
};
|
||||||
|
|
||||||
let instance = null;
|
let instance = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user