浏览代码

Глобальный рефакторинг SettingsPage (в процессе)

Book Pauk 2 年之前
父节点
当前提交
e8d1817566

+ 20 - 68
client/components/Reader/SettingsPage/SettingsPage.vue

@@ -9,7 +9,8 @@
                 <q-tabs
                     ref="tabs"
                     v-model="selectedTab"
-                    class="bg-grey-3 text-black"
+                    class="bg-grey-3 text-grey-9"
+                    style="max-width: 130px"
                     
                     left-icon="la la-caret-up"
                     right-icon="la la-caret-down"
@@ -21,15 +22,12 @@
                     stretch
                     inline-label
                 >
-                    <q-tab class="tab" name="profiles" icon="la la-users" label="Профили" />
-                    <q-tab class="tab" name="view" icon="la la-eye" label="Вид" />
-                    <q-tab class="tab" name="toolbar" icon="la la-grip-horizontal" label="Панель" />
-                    <q-tab class="tab" name="keys" icon="la la-gamepad" label="Управление" />
-                    <q-tab class="tab" name="pagemove" icon="la la-school" label="Листание" />
-                    <q-tab class="tab" name="convert" icon="la la-magic" label="Конвертир." />
-                    <q-tab class="tab" name="update" icon="la la-retweet" label="Обновление" />
-                    <q-tab class="tab" name="others" icon="la la-list-ul" label="Прочее" />
-                    <q-tab class="tab" name="reset" icon="la la-broom" label="Сброс" />
+                    <q-tab v-for="item in tabs" :key="item.name" class="tab row items-center" :name="item.name">
+                        <q-icon :name="item.icon" :color="selectedTab == item.name ? 'yellow' : 'teal-7'" size="24px" />
+                        <div class="q-ml-xs" style="font-size: 90%">
+                            {{ item.label }}
+                        </div>
+                    </q-tab>
                 </q-tabs>
             </div>
 
@@ -108,30 +106,6 @@ const componentOptions = {
             },
             deep: true,
         },
-        fontBold: function(newValue) {
-            this.fontWeight = (newValue ? 'bold' : '');
-        },
-        fontItalic: function(newValue) {
-            this.fontStyle = (newValue ? 'italic' : '');
-        },
-        vertShift: function(newValue) {
-            const font = (this.webFontName ? this.webFontName : this.fontName);
-            if (this.fontShifts[font] != newValue || this.fontVertShift != newValue) {
-                this.fontShifts = Object.assign({}, this.fontShifts, {[font]: newValue});
-                this.fontVertShift = newValue;
-            }
-        },
-        fontName: function(newValue) {
-            const font = (this.webFontName ? this.webFontName : newValue);
-            this.vertShift = this.fontShifts[font] || 0;
-        },
-        webFontName: function(newValue) {
-            const font = (newValue ? newValue : this.fontName);
-            this.vertShift = this.fontShifts[font] || 0;
-        },
-        textColor: function(newValue) {
-            this.textColorFiltered = newValue;
-        },
         statusBarColor(newValue) {
             this.statusBarColorFiltered = newValue;
         },
@@ -146,21 +120,27 @@ class SettingsPage {
 
     form = {};
 
+    tabs = [
+        { name: 'profiles', icon: 'la la-users', label: 'Профили' },
+        { name: 'view', icon: 'la la-eye', label: 'Вид'},
+        { name: 'toolbar', icon: 'la la-grip-horizontal', label: 'Панель'},
+        { name: 'keys', icon: 'la la-gamepad', label: 'Управление'},
+        { name: 'pagemove', icon: 'la la-school', label: 'Листание'},
+        { name: 'convert', icon: 'la la-magic', label: 'Конвертир.'},
+        { name: 'update', icon: 'la la-retweet', label: 'Обновление'},
+        { name: 'others', icon: 'la la-list-ul', label: 'Прочее'},
+        { name: 'reset', icon: 'la la-broom', label: 'Сброс'},
+    ];
     selectedTab = 'profiles';
 
     isSetsChanged = false;
 
-    fontBold = false;
-    fontItalic = false;
-    vertShift = 0;
     statusBarColorFiltered = '';
-    webFonts = [];
-    fonts = [];    
 
     created() {
         this.commit = this.$store.commit;
 
-        this.debouncedCommitSettings = _.debounce(() => {
+        this.debouncedCommitSettings = _.debounce(() => {            
             this.commit('reader/setSettings', _.cloneDeep(this.form));
         }, 50);
 
@@ -181,14 +161,6 @@ class SettingsPage {
             this.form = reactive(_.cloneDeep(this.settings));
             const form = this.form;
 
-            this.fontBold = (form.fontWeight == 'bold');
-            this.fontItalic = (form.fontStyle == 'italic');
-
-            this.fonts = rstore.fonts;
-            this.webFonts = rstore.webFonts;
-            const font = (form.webFontName ? form.webFontName : form.fontName);
-            this.vertShift = form.fontShifts[font] || 0;
-            this.dualDivColorFiltered = form.dualDivColor;
             this.statusBarColorFiltered = form.statusBarColor;
         } finally {
             await this.$nextTick();
@@ -200,30 +172,10 @@ class SettingsPage {
         return this.$store.state.reader.settings;
     }
 
-    get fontsOptions() {
-        let result = [];
-        this.fonts.forEach(font => {
-            result.push({label: (font.label ? font.label : font.name), value: font.name});
-        });
-        return result;
-    }
-
-    get webFontsOptions() {
-        let result = [{label: 'Нет', value: ''}];
-        this.webFonts.forEach(font => {
-            result.push({label: font.name, value: font.name});
-        });
-        return result;
-    }
-
     needReload() {
         this.$root.notify.warning('Необходимо обновить страницу (F5), чтобы изменения возымели эффект');
     }
 
-    needTextReload() {
-        this.$root.notify.warning('Необходимо обновить книгу в обход кэша, чтобы изменения возымели эффект');
-    }
-
     close() {
         this.$emit('do-action', {action: 'settings'});
     }

+ 0 - 121
client/components/Reader/SettingsPage/ViewTab/Color.inc

@@ -1,121 +0,0 @@
-                            <!---------------------------------------------->
-                            <div class="hidden part-header">
-                                Цвет
-                            </div>
-
-                            <div class="item row">
-                                <div class="label-2">
-                                    Текст
-                                </div>
-                                <div class="col row">
-                                    <q-input
-                                        v-model="textColorFiltered"
-                                        class="col-left no-mp"
-                                        outlined dense
-                                        
-                                        :rules="['hexColor']"
-                                        style="max-width: 150px"
-                                    >
-                                        <template #prepend>
-                                            <q-icon name="la la-angle-down la-xs" class="cursor-pointer text-white" :style="colorPanStyle('text')">
-                                                <q-popup-proxy anchor="bottom middle" self="top middle">
-                                                    <div>
-                                                        <q-color
-                                                            v-model="textColor"
-                                                            no-header default-view="palette" :palette="predefineTextColors"
-                                                        />
-                                                    </div>
-                                                </q-popup-proxy>
-                                            </q-icon>
-                                        </template>
-                                    </q-input>
-                                </div>
-                            </div>
-
-                            <div class="q-mt-md" />
-                            <div class="item row">
-                                <div class="label-2">
-                                    Фон
-                                </div>
-                                <div class="col row">
-                                    <q-input 
-                                        v-model="bgColorFiltered"
-                                        class="col-left no-mp"
-                                        outlined dense
-                                        
-                                        :rules="['hexColor']"
-                                        style="max-width: 150px"
-                                    >
-                                        <template #prepend>
-                                            <q-icon name="la la-angle-down la-xs" class="cursor-pointer text-white" :style="colorPanStyle('bg')">
-                                                <q-popup-proxy anchor="bottom middle" self="top middle">
-                                                    <div>
-                                                        <q-color v-model="backgroundColor" no-header default-view="palette" :palette="predefineBackgroundColors" />
-                                                    </div>
-                                                </q-popup-proxy>
-                                            </q-icon>
-                                        </template>
-                                    </q-input>
-                                </div>
-                            </div>
-
-                            <div class="q-mt-md" />
-                            <div class="item row">
-                                <div class="label-2">
-                                    Обои
-                                </div>
-                                <div class="col row items-center">
-                                    <q-select 
-                                        v-model="wallpaper"
-                                        class="col-left no-mp"
-                                        :options="wallpaperOptions"
-                                        dropdown-icon="la la-angle-down la-sm"
-                                        outlined dense emit-value map-options
-                                    >
-                                        <template #selected-item="scope">
-                                            <div>
-                                                {{ scope.opt.label }}
-                                            </div>
-                                            <div v-show="scope.opt.value" class="q-ml-sm" :class="scope.opt.value" style="width: 40px; height: 28px;"></div>
-                                        </template>
-
-                                        <template #option="scope">
-                                            <q-item
-                                                v-bind="scope.itemProps"
-                                            >
-                                                <q-item-section style="min-width: 50px;">
-                                                    <q-item-label v-html="scope.opt.label" />
-                                                </q-item-section>
-                                                <q-item-section v-show="scope.opt.value" :class="scope.opt.value" style="min-width: 70px; min-height: 50px;" />
-                                            </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 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-btn>
-                                    <q-btn v-show="wallpaper.indexOf('user-paper') === 0" class="q-ml-sm" round dense color="blue" icon="la la-file-download" @click.stop="downloadWallpaper">
-                                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
-                                            Скачать выбранные обои
-                                        </q-tooltip>
-                                    </q-btn>
-                                </div>
-                            </div>
-
-                            <div class="q-mt-sm" />
-                            <div class="item row">
-                                <div class="label-2"></div>
-                                <div class="col row items-center">
-                                    <q-checkbox v-model="wallpaperIgnoreStatusBar" size="xs" label="Не включать строку статуса в обои" />
-                                </div>
-                            </div>
-
-                            <input ref="file" type="file" style="display: none;" @change="loadWallpaperFile" />

+ 5 - 2
client/components/Reader/SettingsPage/ViewTab/Color/Color.vue

@@ -145,8 +145,11 @@ const componentOptions = {
     components: {
     },
     watch: {
-        form() {
-            this.formChanged();//no await
+        form: {
+            handler() {
+                this.formChanged();//no await
+            },
+            deep: true,
         },
         textColorFiltered(newValue) {
             if (!this.isFormChanged && this.helper.isHexColor(newValue))

+ 0 - 56
client/components/Reader/SettingsPage/ViewTab/Font.inc

@@ -1,56 +0,0 @@
-<!---------------------------------------------->
-<div class="hidden part-header">Шрифт</div>
-
-<div class="item row">
-    <div class="label-2">Локальный/веб</div>
-    <div class="col row">
-        <q-select class="col-left" v-model="fontName" :options="fontsOptions" :disable="webFontName != ''"
-            dropdown-icon="la la-angle-down la-sm"
-            outlined dense emit-value map-options
-        />
-
-        <div class="q-px-sm"/>
-        <q-select class="col" v-model="webFontName" :options="webFontsOptions"
-            dropdown-icon="la la-angle-down la-sm"
-            outlined dense emit-value map-options
-        >
-            <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                Веб шрифты дают большое разнообразие,<br>
-                однако есть шанс, что шрифт будет загружаться<br>
-                очень медленно или вовсе не загрузится
-            </q-tooltip>
-        </q-select>
-    </div>
-</div>
-
-<div class="item row">
-    <div class="label-2">Размер</div>
-    <div class="col row">
-        <NumInput class="col-left" v-model="fontSize" :min="5" :max="200"/>
-
-        <div class="col q-pt-xs text-right">
-            <a href="https://fonts.google.com/?subset=cyrillic" target="_blank">Примеры</a>
-        </div>
-    </div>
-</div>
-
-<div class="item row">
-    <div class="label-2">Сдвиг</div>
-    <div class="col row">
-        <NumInput class="col-left" v-model="vertShift" :min="-100" :max="100">
-            <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                Сдвиг шрифта по вертикали в процентах от размера.<br>
-                Отрицательное значение сдвигает вверх, положительное -<br>
-                вниз. Значение зависит от метрики шрифта.
-            </q-tooltip>
-        </NumInput>
-    </div>
-</div>
-
-<div class="item row">
-    <div class="label-2">Стиль</div>
-    <div class="col row">
-        <q-checkbox v-model="fontBold" size="xs" label="Жирный" />
-        <q-checkbox class="q-ml-sm" v-model="fontItalic" size="xs" label="Курсив" />
-    </div>
-</div>

+ 176 - 0
client/components/Reader/SettingsPage/ViewTab/Font/Font.vue

@@ -0,0 +1,176 @@
+<template>
+    <div class="fit sets-tab-panel">
+        <!---------------------------------------------->
+        <div class="hidden sets-part-header">
+            Шрифт
+        </div>
+
+        <div class="sets-item row">
+            <div class="sets-label label">
+                Локальный/веб
+            </div>
+            <div class="col row">
+                <q-select
+                    v-model="form.fontName" class="col-left" :options="fontsOptions" :disable="form.webFontName != ''"
+                    dropdown-icon="la la-angle-down la-sm"
+                    outlined dense emit-value map-options
+                />
+
+                <div class="q-px-sm" />
+                <q-select
+                    v-model="form.webFontName" class="col" :options="webFontsOptions"
+                    dropdown-icon="la la-angle-down la-sm"
+                    outlined dense emit-value map-options
+                >
+                    <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                        Веб шрифты дают большое разнообразие,<br>
+                        однако есть шанс, что шрифт будет загружаться<br>
+                        очень медленно или вовсе не загрузится
+                    </q-tooltip>
+                </q-select>
+            </div>
+        </div>
+
+        <div class="sets-item row">
+            <div class="sets-label label">
+                Размер
+            </div>
+            <div class="col row">
+                <NumInput v-model="form.fontSize" class="col-left" :min="5" :max="200" />
+
+                <div class="col q-pt-xs text-right">
+                    <a href="https://fonts.google.com/?subset=cyrillic" target="_blank">Примеры</a>
+                </div>
+            </div>
+        </div>
+
+        <div class="sets-item row">
+            <div class="sets-label label">
+                Сдвиг
+            </div>
+            <div class="col row">
+                <NumInput v-model="vertShift" class="col-left" :min="-100" :max="100">
+                    <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                        Сдвиг шрифта по вертикали в процентах от размера.<br>
+                        Отрицательное значение сдвигает вверх, положительное -<br>
+                        вниз. Значение зависит от метрики шрифта.
+                    </q-tooltip>
+                </NumInput>
+            </div>
+        </div>
+
+        <div class="sets-item row">
+            <div class="sets-label label">
+                Стиль
+            </div>
+            <div class="col row">
+                <q-checkbox v-model="fontBold" size="xs" label="Жирный" />
+                <q-checkbox v-model="fontItalic" class="q-ml-sm" size="xs" label="Курсив" />
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+//-----------------------------------------------------------------------------
+import vueComponent from '../../../../vueComponent.js';
+
+import NumInput from '../../../../share/NumInput.vue';
+import rstore from '../../../../../store/modules/reader';
+
+const componentOptions = {
+    components: {
+        NumInput,
+    },
+    watch: {
+        form: {
+            handler() {
+                this.formChanged();//no await
+            },
+            deep: true,
+        },
+        fontBold: function(newValue) {
+            if (!this.isFormChanged)
+                this.form.fontWeight = (newValue ? 'bold' : '');
+        },
+        fontItalic: function(newValue) {
+            if (!this.isFormChanged)
+                this.form.fontStyle = (newValue ? 'italic' : '');
+        },
+        vertShift: function(newValue) {
+            if (!this.isFormChanged) {
+                const font = (this.form.webFontName ? this.form.webFontName : this.form.fontName);
+                if (this.form.fontShifts[font] != newValue || this.form.fontVertShift != newValue) {
+                    this.form.fontShifts = Object.assign({}, this.form.fontShifts, {[font]: newValue});
+                    this.form.fontVertShift = newValue;
+                }
+            }
+        },
+    },
+};
+class Font {
+    _options = componentOptions;
+    _props = {
+        form: Object,
+    };
+
+    fontBold = false;
+    fontItalic = false;
+    vertShift = 0;
+    webFonts = [];
+    fonts = [];    
+
+    created() {
+        this.formChanged();//no await
+    }
+
+    mounted() {
+    }
+
+    async formChanged() {
+        this.isFormChanged = true;
+        try {
+            this.fontBold = (this.form.fontWeight == 'bold');
+            this.fontItalic = (this.form.fontStyle == 'italic');
+
+            this.fonts = rstore.fonts;
+            this.webFonts = rstore.webFonts;
+            const font = (this.form.webFontName ? this.form.webFontName : this.form.fontName);
+            this.vertShift = this.form.fontShifts[font] || 0;
+        } finally {
+            await this.$nextTick();
+            this.isFormChanged = false;
+        }
+    }
+
+    get fontsOptions() {
+        let result = [];
+        this.fonts.forEach(font => {
+            result.push({label: (font.label ? font.label : font.name), value: font.name});
+        });
+        return result;
+    }
+
+    get webFontsOptions() {
+        let result = [{label: 'Нет', value: ''}];
+        this.webFonts.forEach(font => {
+            result.push({label: font.name, value: font.name});
+        });
+        return result;
+    }
+
+}
+
+export default vueComponent(Font);
+//-----------------------------------------------------------------------------
+</script>
+
+<style scoped>
+.label {
+    width: 110px;
+}
+
+.col-left {
+    width: 150px;
+}
+</style>

+ 5 - 2
client/components/Reader/SettingsPage/ViewTab/Mode/Mode.vue

@@ -162,8 +162,11 @@ const componentOptions = {
         NumInput
     },
     watch: {
-        form() {
-            this.formChanged();//no await
+        form: {
+            handler() {
+                this.formChanged();//no await
+            },
+            deep: true,
         },
         dualDivColorFiltered(newValue) {
             if (!this.isFormChanged && this.helper.isHexColor(newValue))

+ 3 - 8
client/components/Reader/SettingsPage/ViewTab/ViewTab.vue

@@ -21,14 +21,7 @@
         <div class="col sets-tab-panel">
             <Mode v-if="selectedTab == 'mode'" :form="form" />
             <Color v-if="selectedTab == 'color'" :form="form" />
-
-            <!--div v-if="selectedViewTab == 'color'">
-                @@include('./ViewTab/Color.inc');
-            </div-->
-
-            <!--div v-if="selectedViewTab == 'font'">
-                @@include('./ViewTab/Font.inc');
-            </div-->
+            <Font v-if="selectedTab == 'font'" :form="form" />
 
             <!--div v-if="selectedViewTab == 'text'">
                 @@include('./ViewTab/Text.inc');
@@ -47,11 +40,13 @@ import vueComponent from '../../../vueComponent.js';
 
 import Mode from './Mode/Mode.vue';
 import Color from './Color/Color.vue';
+import Font from './Font/Font.vue';
 
 const componentOptions = {
     components: {
         Mode,
         Color,
+        Font,
     },
 };
 class ViewTab {