Browse Source

Добавлена возможность загружать пользовательские обои, пока без синхронизации

Book Pauk 4 years ago
parent
commit
ed901fc181

+ 73 - 1
client/components/Reader/SettingsPage/SettingsPage.vue

@@ -82,6 +82,7 @@ import * as utils from '../../../share/utils';
 import Window from '../../share/Window.vue';
 import NumInput from '../../share/NumInput.vue';
 import UserHotKeys from './UserHotKeys/UserHotKeys.vue';
+import wallpaperStorage from '../share/wallpaperStorage';
 
 import rstore from '../../../store/modules/reader';
 import defPalette from './defPalette';
@@ -277,9 +278,15 @@ class SettingsPage extends Vue {
 
     get wallpaperOptions() {
         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}`});
         }
+
         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) {
         if (!this.$root.stdDialog.active && event.type == 'keydown' && event.key == 'Escape') {
             this.close();

+ 11 - 2
client/components/Reader/SettingsPage/include/ViewTab/Color.inc

@@ -34,7 +34,6 @@
             v-model="bgColorFiltered"
             :rules="['hexColor']"
             style="max-width: 150px"
-            :disable="wallpaper != ''"
         >
             <template v-slot:prepend>
                 <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="item row">
     <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"
             dropdown-icon="la la-angle-down la-sm"
             outlined dense emit-value map-options
@@ -74,5 +73,15 @@
                 </q-item>
             </template>
         </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>
+
+<input type="file" ref="file" @change="loadWallpaperFile" style='display: none;'/>

+ 40 - 0
client/components/Reader/TextPage/TextPage.css

@@ -51,3 +51,43 @@
 .paper9 {
     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%;
+}

+ 25 - 0
client/components/Reader/TextPage/TextPage.vue

@@ -43,7 +43,10 @@ import _ from 'lodash';
 import './TextPage.css';
 
 import * as utils from '../../../share/utils';
+import dynamicCss from '../../../share/dynamicCss';
+
 import bookManager from '../share/bookManager';
+import wallpaperStorage from '../share/wallpaperStorage';
 import DrawHelper from './DrawHelper';
 import rstore from '../../../store/modules/reader';
 import {clickMap} from '../share/clickMap';
@@ -249,6 +252,28 @@ class TextPage extends Vue {
         //statusBar
         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
         if (this.parsed) {
             let wideLine = wideLetter;

BIN
client/components/Reader/TextPage/images/paper10.png


BIN
client/components/Reader/TextPage/images/paper11.png


BIN
client/components/Reader/TextPage/images/paper12.png


BIN
client/components/Reader/TextPage/images/paper13.png


BIN
client/components/Reader/TextPage/images/paper14.png


BIN
client/components/Reader/TextPage/images/paper15.png


BIN
client/components/Reader/TextPage/images/paper16.png


BIN
client/components/Reader/TextPage/images/paper17.png


+ 27 - 0
client/components/Reader/share/wallpaperStorage.js

@@ -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();

+ 1 - 1
client/components/Reader/versionHistory.js

@@ -7,7 +7,7 @@ export const versionHistory = [
 <ul>
     <li>добавлен двухстраничный режим</li>
     <li>в настройки добавлены все кириллические веб-шрифты от google</li>
-    <li>в настройки добавлены новые фоновые изображения и орнамент для страницы</li>
+    <li>в настройки добавлена возможность загрузки пользовательских обоев (пока что без синхронизации)</li>
     <li>немного улучшен парсинг fb2</li>
 </ul>
 `

+ 22 - 0
client/share/dynamicCss.js

@@ -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();

+ 5 - 3
client/store/modules/reader.js

@@ -175,6 +175,7 @@ const settingDefaults = {
     fontShifts: {},
     showToolButton: {},
     userHotKeys: {},
+    userWallpapers: [],
 };
 
 for (const font of fonts)
@@ -186,12 +187,13 @@ for (const button of toolButtons)
 for (const hotKey of hotKeys)
     settingDefaults.userHotKeys[hotKey.name] = hotKey.codes;
 
-const excludeDiffHotKeys = [];
+const diffExclude = [];
 for (const hotKey of hotKeys)
-    excludeDiffHotKeys.push(`userHotKeys/${hotKey.name}`);
+    diffExclude.push(`userHotKeys/${hotKey.name}`);
+diffExclude.push('userWallpapers');
 
 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})) {
         return utils.applyObjDiff(settings, diff, {isApplyChange: false});
     }