Добавлена возможность загружать пользовательские обои, пока без синхронизации
@@ -82,6 +82,7 @@ import * as utils from '../../../share/utils';
|
|||||||
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';
|
||||||
|
import wallpaperStorage from '../share/wallpaperStorage';
|
||||||
|
|
||||||
import rstore from '../../../store/modules/reader';
|
import rstore from '../../../store/modules/reader';
|
||||||
import defPalette from './defPalette';
|
import defPalette from './defPalette';
|
||||||
@@ -277,9 +278,15 @@ class SettingsPage extends Vue {
|
|||||||
|
|
||||||
get wallpaperOptions() {
|
get wallpaperOptions() {
|
||||||
let result = [{label: 'Нет', value: ''}];
|
let result = [{label: 'Нет', value: ''}];
|
||||||
for (let i = 1; i < 10; i++) {
|
|
||||||
|
for (const wp of this.userWallpapers) {
|
||||||
|
result.push({label: wp.label, value: wp.cssClass});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 1; i <= 17; i++) {
|
||||||
result.push({label: i, value: `paper${i}`});
|
result.push({label: i, value: `paper${i}`});
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,6 +553,71 @@ class SettingsPage extends Vue {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadWallpaperFileClick() {
|
||||||
|
this.$refs.file.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadWallpaperFile() {
|
||||||
|
const file = this.$refs.file.files[0];
|
||||||
|
if (file.size > 10*1024*1024) {
|
||||||
|
this.$root.stdDialog.alert('Файл обоев не должен превышать в размере 10Mb', 'Ошибка');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.type != 'image/png' && file.type != 'image/jpeg') {
|
||||||
|
this.$root.stdDialog.alert('Файл обоев должен иметь тип PNG или JPEG', 'Ошибка');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.userWallpapers.length >= 100) {
|
||||||
|
this.$root.stdDialog.alert('Превышено максимальное количество пользовательских обоев.', 'Ошибка');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$refs.file.value = '';
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
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() => {
|
||||||
|
await wallpaperStorage.setData(cssClass, e.target.result);
|
||||||
|
|
||||||
|
this.userWallpapers = newUserWallpapers;
|
||||||
|
this.wallpaper = cssClass;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async delWallpaper() {
|
||||||
|
if (this.wallpaper.indexOf('user-paper') == 0) {
|
||||||
|
const newUserWallpapers = [];
|
||||||
|
for (const wp of this.userWallpapers) {
|
||||||
|
if (wp.cssClass != this.wallpaper) {
|
||||||
|
newUserWallpapers.push(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await wallpaperStorage.removeData(this.wallpaper);
|
||||||
|
|
||||||
|
this.userWallpapers = newUserWallpapers;
|
||||||
|
this.wallpaper = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
keyHook(event) {
|
keyHook(event) {
|
||||||
if (!this.$root.stdDialog.active && event.type == 'keydown' && event.key == 'Escape') {
|
if (!this.$root.stdDialog.active && event.type == 'keydown' && event.key == 'Escape') {
|
||||||
this.close();
|
this.close();
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
v-model="bgColorFiltered"
|
v-model="bgColorFiltered"
|
||||||
:rules="['hexColor']"
|
:rules="['hexColor']"
|
||||||
style="max-width: 150px"
|
style="max-width: 150px"
|
||||||
:disable="wallpaper != ''"
|
|
||||||
>
|
>
|
||||||
<template v-slot:prepend>
|
<template v-slot:prepend>
|
||||||
<q-icon name="la la-angle-down la-xs" class="cursor-pointer text-white" :style="colorPanStyle('bg')">
|
<q-icon name="la la-angle-down la-xs" class="cursor-pointer text-white" :style="colorPanStyle('bg')">
|
||||||
@@ -52,7 +51,7 @@
|
|||||||
<div class="q-mt-md"/>
|
<div class="q-mt-md"/>
|
||||||
<div class="item row">
|
<div class="item row">
|
||||||
<div class="label-2">Обои</div>
|
<div class="label-2">Обои</div>
|
||||||
<div class="col row">
|
<div class="col row items-center">
|
||||||
<q-select class="col-left no-mp" v-model="wallpaper" :options="wallpaperOptions"
|
<q-select class="col-left no-mp" v-model="wallpaper" :options="wallpaperOptions"
|
||||||
dropdown-icon="la la-angle-down la-sm"
|
dropdown-icon="la la-angle-down la-sm"
|
||||||
outlined dense emit-value map-options
|
outlined dense emit-value map-options
|
||||||
@@ -74,5 +73,15 @@
|
|||||||
</q-item>
|
</q-item>
|
||||||
</template>
|
</template>
|
||||||
</q-select>
|
</q-select>
|
||||||
|
|
||||||
|
<div class="q-px-xs"/>
|
||||||
|
<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-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-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Удалить выбранные обои</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<input type="file" ref="file" @change="loadWallpaperFile" style='display: none;'/>
|
||||||
|
|||||||
@@ -51,3 +51,43 @@
|
|||||||
.paper9 {
|
.paper9 {
|
||||||
background: url("images/paper9.jpg");
|
background: url("images/paper9.jpg");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.paper10 {
|
||||||
|
background: url("images/paper10.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper11 {
|
||||||
|
background: url("images/paper11.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper12 {
|
||||||
|
background: url("images/paper12.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper13 {
|
||||||
|
background: url("images/paper13.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper14 {
|
||||||
|
background: url("images/paper14.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper15 {
|
||||||
|
background: url("images/paper15.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper16 {
|
||||||
|
background: url("images/paper16.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paper17 {
|
||||||
|
background: url("images/paper17.png") center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,7 +43,10 @@ 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';
|
||||||
@@ -249,6 +252,28 @@ 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;
|
||||||
|
|||||||
BIN
client/components/Reader/TextPage/images/paper10.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
client/components/Reader/TextPage/images/paper11.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
client/components/Reader/TextPage/images/paper12.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
client/components/Reader/TextPage/images/paper13.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
client/components/Reader/TextPage/images/paper14.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
client/components/Reader/TextPage/images/paper15.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
client/components/Reader/TextPage/images/paper16.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
client/components/Reader/TextPage/images/paper17.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
27
client/components/Reader/share/wallpaperStorage.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import localForage from 'localforage';
|
||||||
|
//import _ from 'lodash';
|
||||||
|
|
||||||
|
const wpStore = localForage.createInstance({
|
||||||
|
name: 'wallpaperStorage'
|
||||||
|
});
|
||||||
|
|
||||||
|
class WallpaperStorage {
|
||||||
|
|
||||||
|
async getLength() {
|
||||||
|
return await wpStore.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
async setData(key, data) {
|
||||||
|
await wpStore.setItem(key, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getData(key) {
|
||||||
|
return await wpStore.getItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeData(key) {
|
||||||
|
await wpStore.removeItem(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new WallpaperStorage();
|
||||||
@@ -7,7 +7,7 @@ export const versionHistory = [
|
|||||||
<ul>
|
<ul>
|
||||||
<li>добавлен двухстраничный режим</li>
|
<li>добавлен двухстраничный режим</li>
|
||||||
<li>в настройки добавлены все кириллические веб-шрифты от google</li>
|
<li>в настройки добавлены все кириллические веб-шрифты от google</li>
|
||||||
<li>в настройки добавлены новые фоновые изображения и орнамент для страницы</li>
|
<li>в настройки добавлена возможность загрузки пользовательских обоев (пока что без синхронизации)</li>
|
||||||
<li>немного улучшен парсинг fb2</li>
|
<li>немного улучшен парсинг fb2</li>
|
||||||
</ul>
|
</ul>
|
||||||
`
|
`
|
||||||
|
|||||||
22
client/share/dynamicCss.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
class DynamicCss {
|
||||||
|
constructor() {
|
||||||
|
this.cssNodes = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
replace(name, cssText) {
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.type = 'text/css';
|
||||||
|
style.innerHTML = cssText;
|
||||||
|
|
||||||
|
const parent = document.getElementsByTagName('head')[0];
|
||||||
|
|
||||||
|
if (this.cssNodes[name]) {
|
||||||
|
parent.removeChild(this.cssNodes[name]);
|
||||||
|
delete this.cssNodes[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cssNodes[name] = parent.appendChild(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new DynamicCss();
|
||||||
@@ -175,6 +175,7 @@ const settingDefaults = {
|
|||||||
fontShifts: {},
|
fontShifts: {},
|
||||||
showToolButton: {},
|
showToolButton: {},
|
||||||
userHotKeys: {},
|
userHotKeys: {},
|
||||||
|
userWallpapers: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const font of fonts)
|
for (const font of fonts)
|
||||||
@@ -186,12 +187,13 @@ for (const button of toolButtons)
|
|||||||
for (const hotKey of hotKeys)
|
for (const hotKey of hotKeys)
|
||||||
settingDefaults.userHotKeys[hotKey.name] = hotKey.codes;
|
settingDefaults.userHotKeys[hotKey.name] = hotKey.codes;
|
||||||
|
|
||||||
const excludeDiffHotKeys = [];
|
const diffExclude = [];
|
||||||
for (const hotKey of hotKeys)
|
for (const hotKey of hotKeys)
|
||||||
excludeDiffHotKeys.push(`userHotKeys/${hotKey.name}`);
|
diffExclude.push(`userHotKeys/${hotKey.name}`);
|
||||||
|
diffExclude.push('userWallpapers');
|
||||||
|
|
||||||
function addDefaultsToSettings(settings) {
|
function addDefaultsToSettings(settings) {
|
||||||
const diff = utils.getObjDiff(settings, settingDefaults, {exclude: excludeDiffHotKeys});
|
const diff = utils.getObjDiff(settings, settingDefaults, {exclude: diffExclude});
|
||||||
if (!utils.isEmptyObjDiffDeep(diff, {isApplyChange: false})) {
|
if (!utils.isEmptyObjDiffDeep(diff, {isApplyChange: false})) {
|
||||||
return utils.applyObjDiff(settings, diff, {isApplyChange: false});
|
return utils.applyObjDiff(settings, diff, {isApplyChange: false});
|
||||||
}
|
}
|
||||||
|
|||||||