Browse Source

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

Book Pauk 2 years ago
parent
commit
528b32ccf7

+ 1 - 3
client/components/Reader/Reader.vue

@@ -543,9 +543,7 @@ class Reader {
 
             //обновим settings, если загружали обои из /upload/
             if (updated) {
-                const newSettings = _.cloneDeep(this.settings);
-                newSettings.needUpdateSettingsView = (newSettings.needUpdateSettingsView < 10 ? newSettings.needUpdateSettingsView + 1 : 0);
-                this.commit('reader/setSettings', newSettings);
+                this.commit('reader/setSettings', {});
             }
 
             dynamicCss.replace('wallpapers', newCss);

+ 7 - 131
client/components/Reader/SettingsPage/SettingsPage.vue

@@ -23,7 +23,6 @@
                     stretch
                     inline-label
                 >
-                    <div v-show="tabsScrollable" class="q-pt-lg" />
                     <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="Панель" />
@@ -33,7 +32,6 @@
                     <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="Сброс" />
-                    <div v-show="tabsScrollable" class="q-pt-lg" />
                 </q-tabs>
             </div>
 
@@ -41,47 +39,7 @@
                 <!-- Профили --------------------------------------------------------------------->
                 <ProfilesTab v-if="selectedTab == 'profiles'" :form="form" />
                 <!-- Вид ------------------------------------------------------------------------->                    
-                <!--div v-if="selectedTab == 'view'" class="fit column">
-                    <q-tabs
-                        v-model="selectedViewTab"
-                        active-color="black"
-                        active-bg-color="white"
-                        indicator-color="white"
-                        dense
-                        no-caps
-                        class="no-mp bg-grey-4 text-grey-7"
-                    >
-                        <q-tab name="mode" label="Режим" />
-                        <q-tab name="color" label="Цвет" />
-                        <q-tab name="font" label="Шрифт" />
-                        <q-tab name="text" label="Текст" />
-                        <q-tab name="status" label="Строка статуса" />
-                    </q-tabs>
-
-                    <div class="q-mb-sm" />
-
-                    <div class="col tab-panel">
-                        <div v-if="selectedViewTab == 'mode'">
-                            @@include('./ViewTab/Mode.inc');
-                        </div>
-
-                        <div v-if="selectedViewTab == 'color'">
-                            @@include('./ViewTab/Color.inc');
-                        </div>
-
-                        <div v-if="selectedViewTab == 'font'">
-                            @@include('./ViewTab/Font.inc');
-                        </div>
-
-                        <div v-if="selectedViewTab == 'text'">
-                            @@include('./ViewTab/Text.inc');
-                        </div>
-
-                        <div v-if="selectedViewTab == 'status'">
-                            @@include('./ViewTab/Status.inc');
-                        </div>
-                    </div>
-                </div-->
+                <ViewTab v-if="selectedTab == 'view'" :form="form" />
                 <!-- Кнопки ---------------------------------------------------------------------->
                 <ToolBarTab v-if="selectedTab == 'toolbar'" :form="form" />
                 <!-- Управление ------------------------------------------------------------------>
@@ -115,10 +73,10 @@ import wallpaperStorage from '../share/wallpaperStorage';
 
 import readerApi from '../../../api/reader';
 import rstore from '../../../store/modules/reader';
-import defPalette from './defPalette';
 
 //pages
 import ProfilesTab from './ProfilesTab/ProfilesTab.vue';
+import ViewTab from './ViewTab/ViewTab.vue';
 import ToolBarTab from './ToolBarTab/ToolBarTab.vue';
 import KeysTab from './KeysTab/KeysTab.vue';
 import PageMoveTab from './PageMoveTab/PageMoveTab.vue';
@@ -134,6 +92,7 @@ const componentOptions = {
         Window,
         //pages
         ProfilesTab,
+        ViewTab,
         ToolBarTab,
         KeysTab,
         PageMoveTab,
@@ -200,13 +159,6 @@ const componentOptions = {
             if (hex.test(newValue))
                 this.backgroundColor = newValue;
         },
-        dualDivColor(newValue) {
-            this.dualDivColorFiltered = newValue;
-        },
-        dualDivColorFiltered(newValue) {
-            if (hex.test(newValue))
-                this.dualDivColor = newValue;
-        },
         statusBarColor(newValue) {
             this.statusBarColorFiltered = newValue;
         },
@@ -222,39 +174,29 @@ class SettingsPage {
     form = {};
 
     selectedTab = 'profiles';
-    selectedViewTab = 'mode';
+
+    setsChanged = false;
+
     fontBold = false;
     fontItalic = false;
     vertShift = 0;
-    tabsScrollable = false;
     textColorFiltered = '';
     bgColorFiltered = '';
-    dualDivColorFiltered = '';
     statusBarColorFiltered = '';
-
     webFonts = [];
     fonts = [];    
 
-    setsChanged = false;
-
     created() {
         this.commit = this.$store.commit;
-        this.reader = this.$store.state.reader;
 
         this.debouncedCommitSettings = _.debounce(() => {
             this.commit('reader/setSettings', _.cloneDeep(this.form));
-        }, 100);
+        }, 50);
 
         this.settingsChanged();//no await
     }
 
     mounted() {
-        this.$watch(
-            '$refs.tabs.scrollable',
-            (newValue) => {
-                this.tabsScrollable = newValue && !this.$root.isMobileDevice;
-            }
-        );
     }
 
     init() {
@@ -263,9 +205,6 @@ class SettingsPage {
     }
 
     async settingsChanged() {
-        if (_.isEqual(this.form, this.settings))
-            return;
-
         this.setsChanged = true;
         try {
             this.form = _.cloneDeep(this.settings);
@@ -326,55 +265,6 @@ class SettingsPage {
         return result;
     }
 
-    get predefineTextColors() {
-        return defPalette.concat([
-          '#ffffff',
-          '#000000',
-          '#202020',
-          '#323232',
-          '#aaaaaa',
-          '#00c0c0',
-          '#ebe2c9',
-          '#cfdc99',
-          '#478355',
-          '#909080',
-        ]);
-    }
-
-    get predefineBackgroundColors() {
-        return defPalette.concat([
-          '#ffffff',
-          '#000000',
-          '#202020',
-          '#ebe2c9',
-          '#cfdc99',
-          '#478355',
-          '#a6caf0',
-          '#909080',
-          '#808080',
-          '#c8c8c8',
-        ]);
-    }
-
-    colorPanStyle(type) {
-        let result = 'width: 30px; height: 30px; border: 1px solid black; border-radius: 4px;';
-        switch (type) {
-            case 'text':
-                result += `background-color: ${this.textColor};`
-                break;
-            case 'bg':
-                result += `background-color: ${this.backgroundColor};`
-                break;
-            case 'div':
-                result += `background-color: ${this.dualDivColor};`
-                break;
-            case 'statusbar':
-                result += `background-color: ${this.statusBarColor};`
-                break;
-        }
-        return result;
-    }
-
     needReload() {
         this.$root.notify.warning('Необходимо обновить страницу (F5), чтобы изменения возымели эффект');
     }
@@ -517,20 +407,6 @@ export default vueComponent(SettingsPage);
 .tab {
     justify-content: initial;
 }
-
-.label-2 {
-    width: 110px;
-}
-
-.input {
-    max-width: 150px;
-}
-
-.no-mp {
-    margin: 0;
-    padding: 0;
-}
-
 </style>
 
 <style>

+ 0 - 124
client/components/Reader/SettingsPage/ViewTab/Mode.inc

@@ -1,124 +0,0 @@
-<!---------------------------------------------->
-<div class="hidden part-header">Режим</div>
-
-<div class="item row">
-    <div class="label-2"></div>
-    <div class="col row">
-        <q-checkbox v-model="dualPageMode" size="xs" label="Двухстраничный режим" />
-    </div>
-</div>
-
-<div class="part-header">Страницы</div>
-<div class="item row">
-    <div class="label-2">Отступ границ</div>
-    <div class="col row">
-        <NumInput class="col-left" v-model="indentLR" :min="0" :max="2000">
-            <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                Слева/справа от края экрана
-            </q-tooltip>
-        </NumInput>
-        <div class="q-px-sm"/>
-        <NumInput class="col" v-model="indentTB" :min="0" :max="2000">
-            <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                Сверху/снизу от края экрана
-            </q-tooltip>
-        </NumInput>
-    </div>
-</div>
-
-<div v-show="dualPageMode" class="item row">
-    <div class="label-2">Отступ внутри</div>
-    <div class="col row">
-        <NumInput class="col-left" v-model="dualIndentLR" :min="0" :max="2000">
-            <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                Слева/справа внутри страницы
-            </q-tooltip>
-        </NumInput>
-    </div>
-</div>
-
-<div v-show="dualPageMode">
-    <div class="part-header">Разделитель</div>
-
-    <div class="item row no-wrap">
-        <div class="label-2">Цвет</div>
-        <div class="col-left row">
-            <q-input class="col-left no-mp"
-                outlined dense
-                v-model="dualDivColorFiltered"
-                :rules="['hexColor']"
-                style="max-width: 150px"
-                :disable="dualDivColorAsText"
-            >
-                <template v-slot:prepend>
-                    <q-icon name="la la-angle-down la-xs" class="cursor-pointer text-white" :style="colorPanStyle('div')">
-                        <q-popup-proxy anchor="bottom middle" self="top middle">
-                            <div>
-                                <q-color v-model="dualDivColor"
-                                    no-header default-view="palette" :palette="predefineTextColors"
-                                />
-                            </div>
-                        </q-popup-proxy>
-                    </q-icon>
-                </template>
-            </q-input>
-        </div>
-        
-        <div class="q-px-xs"/>
-        <q-checkbox v-model="dualDivColorAsText" size="xs" label="Как у текста" />
-    </div>
-
-    <div class="item row">
-        <div class="label-2">Прозрачность</div>
-        <div class="col row">
-            <NumInput class="col-left" v-model="dualDivColorAlpha" :min="0" :max="1" :digits="2" :step="0.1"/>
-        </div>
-    </div>
-
-    <div class="item row">
-        <div class="label-2">Ширина (px)</div>
-        <div class="col row">
-            <NumInput class="col-left" v-model="dualDivWidth" :min="0" :max="100">
-                <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                    Ширина разделителя
-                </q-tooltip>
-            </NumInput>
-        </div>
-    </div>
-
-    <div class="item row">
-        <div class="label-2">Высота (%)</div>
-        <div class="col row">
-            <NumInput class="col-left" v-model="dualDivHeight" :min="0" :max="100">
-                <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                    Высота разделителя
-                </q-tooltip>
-            </NumInput>
-        </div>
-    </div>
-
-    <div class="item row">
-        <div class="label-2">Пунктир</div>
-        <div class="col row">
-            <NumInput class="col-left" v-model="dualDivStrokeFill" :min="0" :max="2000">
-                <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                    Заполнение пунктира
-                </q-tooltip>
-            </NumInput>
-            <div class="q-px-sm"/>
-            <NumInput class="col" v-model="dualDivStrokeGap" :min="0" :max="2000">
-                <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
-                    Промежуток пунктира
-                </q-tooltip>
-            </NumInput>
-        </div>
-    </div>
-
-    <div class="item row">
-        <div class="label-2">Ширина тени</div>
-        <div class="col row">
-            <NumInput class="col-left" v-model="dualDivShadowWidth" :min="0" :max="100"/>
-        </div>
-    </div>    
-
-</div>

+ 214 - 0
client/components/Reader/SettingsPage/ViewTab/Mode/Mode.vue

@@ -0,0 +1,214 @@
+<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-checkbox v-model="form.dualPageMode" size="xs" label="Двухстраничный режим" />
+            </div>
+        </div>
+
+        <div class="sets-part-header">
+            Страницы
+        </div>
+        <div class="sets-item row">
+            <div class="sets-label label">
+                Отступ границ
+            </div>
+            <div class="col row">
+                <NumInput v-model="form.indentLR" class="col-left" :min="0" :max="2000">
+                    <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                        Слева/справа от края экрана
+                    </q-tooltip>
+                </NumInput>
+                <div class="q-px-sm" />
+                <NumInput v-model="form.indentTB" class="col" :min="0" :max="2000">
+                    <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                        Сверху/снизу от края экрана
+                    </q-tooltip>
+                </NumInput>
+            </div>
+        </div>
+
+        <div v-show="form.dualPageMode" class="sets-item row">
+            <div class="sets-label label">
+                Отступ внутри
+            </div>
+            <div class="col row">
+                <NumInput v-model="form.dualIndentLR" class="col-left" :min="0" :max="2000">
+                    <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                        Слева/справа внутри страницы
+                    </q-tooltip>
+                </NumInput>
+            </div>
+        </div>
+
+        <div v-show="form.dualPageMode">
+            <div class="sets-part-header">
+                Разделитель
+            </div>
+
+            <div class="sets-item row no-wrap">
+                <div class="sets-label label">
+                    Цвет
+                </div>
+                <div class="col-left row">
+                    <q-input 
+                        v-model="dualDivColorFiltered"
+                        class="col-left no-mp"
+                        outlined dense
+                        :rules="['hexColor']"
+                        style="max-width: 150px"
+                        :disable="form.dualDivColorAsText"
+                    >
+                        <template #prepend>
+                            <q-icon name="la la-angle-down la-xs" class="cursor-pointer text-white" :style="helper.colorPanStyle(form.dualDivColor)">
+                                <q-popup-proxy anchor="bottom middle" self="top middle">
+                                    <div>
+                                        <q-color
+                                            v-model="form.dualDivColor"
+                                            no-header default-view="palette" :palette="defPalette.predefineTextColors"
+                                        />
+                                    </div>
+                                </q-popup-proxy>
+                            </q-icon>
+                        </template>
+                    </q-input>
+                </div>
+                
+                <div class="q-px-xs" />
+                <q-checkbox v-model="form.dualDivColorAsText" size="xs" label="Как у текста" />
+            </div>
+
+            <div class="sets-item row">
+                <div class="sets-label label">
+                    Прозрачность
+                </div>
+                <div class="col row">
+                    <NumInput v-model="form.dualDivColorAlpha" class="col-left" :min="0" :max="1" :digits="2" :step="0.1" />
+                </div>
+            </div>
+
+            <div class="sets-item row">
+                <div class="sets-label label">
+                    Ширина (px)
+                </div>
+                <div class="col row">
+                    <NumInput v-model="form.dualDivWidth" class="col-left" :min="0" :max="100">
+                        <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                            Ширина разделителя
+                        </q-tooltip>
+                    </NumInput>
+                </div>
+            </div>
+
+            <div class="sets-item row">
+                <div class="sets-label label">
+                    Высота (%)
+                </div>
+                <div class="col row">
+                    <NumInput v-model="form.dualDivHeight" class="col-left" :min="0" :max="100">
+                        <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                            Высота разделителя
+                        </q-tooltip>
+                    </NumInput>
+                </div>
+            </div>
+
+            <div class="sets-item row">
+                <div class="sets-label label">
+                    Пунктир
+                </div>
+                <div class="col row">
+                    <NumInput v-model="form.dualDivStrokeFill" class="col-left" :min="0" :max="2000">
+                        <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                            Заполнение пунктира
+                        </q-tooltip>
+                    </NumInput>
+                    <div class="q-px-sm" />
+                    <NumInput v-model="form.dualDivStrokeGap" class="col" :min="0" :max="2000">
+                        <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
+                            Промежуток пунктира
+                        </q-tooltip>
+                    </NumInput>
+                </div>
+            </div>
+
+            <div class="sets-item row">
+                <div class="sets-label label">
+                    Ширина тени
+                </div>
+                <div class="col row">
+                    <NumInput v-model="form.dualDivShadowWidth" class="col-left" :min="0" :max="100" />
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+//-----------------------------------------------------------------------------
+import vueComponent from '../../../../vueComponent.js';
+import NumInput from '../../../../share/NumInput.vue';
+import * as helper from '../helper';
+import defPalette from '../defPalette';
+
+const componentOptions = {
+    components: {
+        NumInput
+    },
+    watch: {
+        form() {
+            this.formChanged();
+        },
+        dualDivColorFiltered(newValue) {
+            if (this.helper.isHexColor(newValue))
+                this.form.dualDivColor = newValue;
+        },
+    }
+};
+class Mode {
+    _options = componentOptions;
+    _props = {
+        form: Object,
+    };
+
+    helper = helper;
+    defPalette = defPalette;
+
+    dualDivColorFiltered = '';
+
+    created() {
+        this.formChanged();
+    }
+
+    mounted() {
+    }
+
+    formChanged() {
+        this.dualDivColorFiltered = this.form.dualDivColor;
+    }
+}
+
+export default vueComponent(Mode);
+//-----------------------------------------------------------------------------
+</script>
+
+<style scoped>
+.label {
+    width: 110px;
+}
+
+.col-left {
+    width: 150px;
+}
+
+.no-mp {
+    margin: 0;
+    padding: 0;
+}
+</style>

+ 79 - 0
client/components/Reader/SettingsPage/ViewTab/ViewTab.vue

@@ -0,0 +1,79 @@
+<template>
+    <div class="fit column">
+        <q-tabs
+            v-model="selectedTab"
+            active-color="black"
+            active-bg-color="white"
+            indicator-color="white"
+            dense
+            no-caps
+            class="no-mp bg-grey-4 text-grey-7"
+        >
+            <q-tab name="mode" label="Режим" />
+            <q-tab name="color" label="Цвет" />
+            <q-tab name="font" label="Шрифт" />
+            <q-tab name="text" label="Текст" />
+            <q-tab name="status" label="Строка статуса" />
+        </q-tabs>
+
+        <div class="q-mb-sm" />
+
+        <div class="col sets-tab-panel">
+            <Mode v-if="selectedTab == 'mode'" :form="form" />
+
+            <!--div v-if="selectedViewTab == 'color'">
+                @@include('./ViewTab/Color.inc');
+            </div-->
+
+            <!--div v-if="selectedViewTab == 'font'">
+                @@include('./ViewTab/Font.inc');
+            </div-->
+
+            <!--div v-if="selectedViewTab == 'text'">
+                @@include('./ViewTab/Text.inc');
+            </div-->
+
+            <!--div v-if="selectedViewTab == 'status'">
+                @@include('./ViewTab/Status.inc');
+            </div-->
+        </div>
+    </div>
+</template>
+
+<script>
+//-----------------------------------------------------------------------------
+import vueComponent from '../../../vueComponent.js';
+
+import Mode from './Mode/Mode.vue';
+
+const componentOptions = {
+    components: {
+        Mode,
+    },
+};
+class ViewTab {
+    _options = componentOptions;
+    _props = {
+        form: Object,
+    };
+
+    selectedTab = 'mode';
+
+    created() {
+    }
+
+    mounted() {
+    }
+
+}
+
+export default vueComponent(ViewTab);
+//-----------------------------------------------------------------------------
+</script>
+
+<style scoped>
+.label {
+    width: 75px;
+}
+
+</style>

+ 29 - 1
client/components/Reader/SettingsPage/defPalette.js → client/components/Reader/SettingsPage/ViewTab/defPalette.js

@@ -14,4 +14,32 @@ const defPalette = [
     'rgb(255,255,255)', 'rgb(205,205,205)', 'rgb(178,178,178)', 'rgb(153,153,153)', 'rgb(127,127,127)', 'rgb(102,102,102)', 'rgb(76,76,76)', 'rgb(51,51,51)', 'rgb(25,25,25)', 'rgb(0,0,0)'
 ];
 
-export default defPalette;
+export default {
+    predefinePalette: defPalette,
+
+    predefineTextColors: defPalette.concat([
+        '#ffffff',
+        '#000000',
+        '#202020',
+        '#323232',
+        '#aaaaaa',
+        '#00c0c0',
+        '#ebe2c9',
+        '#cfdc99',
+        '#478355',
+        '#909080',
+    ]),
+
+    predefineBackgroundColors: defPalette.concat([
+        '#ffffff',
+        '#000000',
+        '#202020',
+        '#ebe2c9',
+        '#cfdc99',
+        '#478355',
+        '#a6caf0',
+        '#909080',
+        '#808080',
+        '#c8c8c8',
+    ]),
+};

+ 9 - 0
client/components/Reader/SettingsPage/ViewTab/helper.js

@@ -0,0 +1,9 @@
+const hex = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;
+
+export function colorPanStyle(bgColor) {
+    return `width: 30px; height: 30px; border: 1px solid black; border-radius: 4px; background-color: ${bgColor}`;
+}
+
+export function isHexColor(value) {
+    return hex.test(value);
+}

+ 0 - 4
client/store/modules/reader.js

@@ -198,10 +198,6 @@ const settingDefaults = {
     bucSetOnNew: true, // автоматически включать проверку обновлений для вновь загружаемых файлов
     bucCancelEnabled: true, // вкл/выкл отмену проверки книг через bucCancelDays
     bucCancelDays: 90, // количество дней, через которое отменяется проверка книги, при условии отсутствия обновлений за это время
-
-    //для SettingsPage
-    needUpdateSettingsView: 0,
-
 };
 
 for (const font of fonts)

+ 7 - 7
package-lock.json

@@ -29,7 +29,7 @@
         "pako": "^2.0.4",
         "path-browserify": "^1.0.1",
         "pidusage": "^3.0.0",
-        "quasar": "^2.7.7",
+        "quasar": "^2.9.2",
         "safe-buffer": "^5.2.1",
         "sanitize-html": "^2.7.1",
         "sjcl": "^1.0.8",
@@ -8009,9 +8009,9 @@
       }
     },
     "node_modules/quasar": {
-      "version": "2.7.7",
-      "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.7.7.tgz",
-      "integrity": "sha512-tegG6EmEmv5i24MoNopRkhZOdT5kdLSAxQMA0V/fG04oco52hk2xwvB0EVS8WzT0bZZbc/9iXlAm1c29rZ3yVA==",
+      "version": "2.9.2",
+      "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.9.2.tgz",
+      "integrity": "sha512-Z4QWJDC4vFILKRJJdE0j/jnRTo94A2k403G6LtTiSIRSmV8dUl4YWqqNRH6lQQ01Vwjj06kKtN81fi3ontBt0w==",
       "engines": {
         "node": ">= 10.18.1",
         "npm": ">= 6.13.4",
@@ -16394,9 +16394,9 @@
       }
     },
     "quasar": {
-      "version": "2.7.7",
-      "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.7.7.tgz",
-      "integrity": "sha512-tegG6EmEmv5i24MoNopRkhZOdT5kdLSAxQMA0V/fG04oco52hk2xwvB0EVS8WzT0bZZbc/9iXlAm1c29rZ3yVA=="
+      "version": "2.9.2",
+      "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.9.2.tgz",
+      "integrity": "sha512-Z4QWJDC4vFILKRJJdE0j/jnRTo94A2k403G6LtTiSIRSmV8dUl4YWqqNRH6lQQ01Vwjj06kKtN81fi3ontBt0w=="
     },
     "querystringify": {
       "version": "2.2.0",

+ 1 - 1
package.json

@@ -67,7 +67,7 @@
     "pako": "^2.0.4",
     "path-browserify": "^1.0.1",
     "pidusage": "^3.0.0",
-    "quasar": "^2.7.7",
+    "quasar": "^2.9.2",
     "safe-buffer": "^5.2.1",
     "sanitize-html": "^2.7.1",
     "sjcl": "^1.0.8",