소스 검색

Переход на Vue 3, в процессе

Book Pauk 3 년 전
부모
커밋
ed46e91432

+ 1 - 0
client/components/App.vue

@@ -112,6 +112,7 @@ class App {
         document.addEventListener('keydown', (event) => {
             this.keyHook(event);
         });
+
         window.addEventListener('resize', () => {
             this.$root.$emit('resize');
         });

+ 50 - 33
client/components/ExternalLibs/BookmarkSettings/BookmarkSettings.vue

@@ -6,42 +6,56 @@
 
         <div class="col column fit">
             <div class="row items-center top-panel bg-grey-3">
-                <q-btn class="q-mr-md" round dense color="blue" icon="la la-check" @click.stop="openSelected" size="16px" :disabled="!selected">
-                    <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Открыть выбранную закладку</q-tooltip>
+                <q-btn :disabled="!selected" class="q-mr-md" round dense color="blue" icon="la la-check" size="16px" @click.stop="openSelected">
+                    <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                        Открыть выбранную закладку
+                    </q-tooltip>
                 </q-btn>
-                <q-input class="col" ref="search" rounded outlined dense bg-color="white" placeholder="Найти" v-model="search">
-                    <template v-slot:append>
-                        <q-icon v-if="search !== ''" name="la la-times" class="cursor-pointer" @click="resetSearch"/>
+                <q-input ref="search" v-model="search" class="col" rounded outlined dense bg-color="white" placeholder="Найти">
+                    <template #append>
+                        <q-icon v-if="search !== ''" name="la la-times" class="cursor-pointer" @click="resetSearch" />
                     </template>
                 </q-input>
             </div>
 
             <div class="col row">
                 <div class="left-panel column items-center no-wrap bg-grey-3">
-                    <q-btn class="q-my-sm" round dense color="blue" icon="la la-plus" @click.stop="addBookmark" size="14px">
-                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Добавить закладку</q-tooltip>
+                    <q-btn class="q-my-sm" round dense color="blue" icon="la la-plus" size="14px" @click.stop="addBookmark">
+                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                            Добавить закладку
+                        </q-tooltip>
                     </q-btn>
-                    <q-btn class="q-mb-sm" round dense color="blue" icon="la la-minus" @click.stop="delBookmark" size="14px" :disabled="!ticked.length">
-                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Удалить отмеченные закладки</q-tooltip>
+                    <q-btn :disabled="!ticked.length" class="q-mb-sm" round dense color="blue" icon="la la-minus" size="14px" @click.stop="delBookmark">
+                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                            Удалить отмеченные закладки
+                        </q-tooltip>
                     </q-btn>
-                    <q-btn class="q-mb-sm" round dense color="blue" icon="la la-edit" @click.stop="editBookmark" size="14px" :disabled="!selected || selected.indexOf('r-') == 0">
-                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Редактировать закладку</q-tooltip>
+                    <q-btn :disabled="!selected || selected.indexOf('r-') == 0" class="q-mb-sm" round dense color="blue" icon="la la-edit" size="14px" @click.stop="editBookmark">
+                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                            Редактировать закладку
+                        </q-tooltip>
                     </q-btn>
-                    <q-btn class="q-mb-sm" round dense color="blue" icon="la la-arrow-up" @click.stop="moveBookmark(false)" size="14px" :disabled="!ticked.length">
-                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Переместить отмеченные вверх</q-tooltip>
+                    <q-btn :disabled="!ticked.length" class="q-mb-sm" round dense color="blue" icon="la la-arrow-up" size="14px" @click.stop="moveBookmark(false)">
+                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                            Переместить отмеченные вверх
+                        </q-tooltip>
                     </q-btn>
-                    <q-btn class="q-mb-sm" round dense color="blue" icon="la la-arrow-down" @click.stop="moveBookmark(true)" size="14px" :disabled="!ticked.length">
-                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Переместить отмеченные вниз</q-tooltip>
+                    <q-btn :disabled="!ticked.length" class="q-mb-sm" round dense color="blue" icon="la la-arrow-down" size="14px" @click.stop="moveBookmark(true)">
+                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                            Переместить отмеченные вниз
+                        </q-tooltip>
                     </q-btn>
-                    <q-btn class="q-mb-sm" round dense color="blue" icon="la la-broom" @click.stop="setDefaultBookmarks" size="14px">
-                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Установить по умолчанию</q-tooltip>
+                    <q-btn class="q-mb-sm" round dense color="blue" icon="la la-broom" size="14px" @click.stop="setDefaultBookmarks">
+                        <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                            Установить по умолчанию
+                        </q-tooltip>
                     </q-btn>
-                    <div class="space"/>
+                    <div class="space" />
                 </div>
 
                 <div class="col fit tree">
                     <div v-show="nodes.length" class="checkbox-tick-all">
-                        <q-checkbox v-model="tickAll" @input="makeTickAll" size="36px" label="Выбрать все" />
+                        <q-checkbox v-model="tickAll" size="36px" label="Выбрать все" @input="makeTickAll" />
                     </div>
                     <q-tree
                         class="q-my-xs"
@@ -56,8 +70,10 @@
                         no-nodes-label="Закладок пока нет"
                         no-results-label="Ничего не найдено"
                     >
-                        <template v-slot:default-header="p">
-                            <div class="q-px-xs" :class="{selected: selected == p.key}">{{ p.node.label }}</div>
+                        <template #default-header="p">
+                            <div class="q-px-xs" :class="{selected: selected == p.key}">
+                                {{ p.node.label }}
+                            </div>
                         </template>
                     </q-tree>
                 </div>
@@ -68,22 +84,15 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
+
 import _ from 'lodash';
 
 import Window from '../../share/Window.vue';
 import * as lu from '../linkUtils';
 import rstore from '../../../store/modules/reader';
 
-const BookmarkSettingsProps = Vue.extend({
-    props: {
-        libs: Object,
-        addBookmarkVisible: Boolean,
-    }
-});
-
-export default @Component({
+const componentOptions = {
     components: {
         Window,
     },
@@ -92,8 +101,14 @@ export default @Component({
             this.checkAllTicked();
         },
     }    
-})
-class BookmarkSettings extends BookmarkSettingsProps {
+};
+class BookmarkSettings {
+    _options = componentOptions;
+    _props = {
+        libs: Object,
+        addBookmarkVisible: Boolean,
+    };
+
     search = '';
     selected = '';
     ticked = [];
@@ -308,6 +323,8 @@ class BookmarkSettings extends BookmarkSettingsProps {
     }
 
 }
+
+export default vueComponent(BookmarkSettings);
 //-----------------------------------------------------------------------------
 </script>
 

+ 86 - 47
client/components/ExternalLibs/ExternalLibs.vue

@@ -1,82 +1,101 @@
 <template>
-    <Window ref="window" @close="close" margin="2px">
+    <Window ref="window" margin="2px" @close="close">
         <template slot="header">
             {{ header }}
         </template>
 
         <template slot="buttons">
             <span class="full-screen-button row justify-center items-center" @mousedown.stop @click="fullScreenToggle">
-                <q-icon :name="(fullScreenActive ? 'la la-compress-arrows-alt': 'la la-expand-arrows-alt')" size="16px"/>
+                <q-icon :name="(fullScreenActive ? 'la la-compress-arrows-alt': 'la la-expand-arrows-alt')" size="16px" />
                 <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">На весь экран</q-tooltip>
             </span>
             <span class="full-screen-button row justify-center items-center" @mousedown.stop @click="changeScale(0.1)">
-                <q-icon name="la la-plus" size="16px"/>
+                <q-icon name="la la-plus" size="16px" />
                 <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Увеличить масштаб</q-tooltip>
             </span>
             <span class="full-screen-button row justify-center items-center" @mousedown.stop @click="changeScale(-0.1)">
-                <q-icon name="la la-minus" size="16px"/>
+                <q-icon name="la la-minus" size="16px" />
                 <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Уменьшить масштаб</q-tooltip>
             </span>
             <span class="full-screen-button row justify-center items-center" @mousedown.stop @click="showHelp">
-                <q-icon name="la la-question-circle" size="16px"/>
+                <q-icon name="la la-question-circle" size="16px" />
                 <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Справка</q-tooltip>
             </span>
         </template>
 
         <div v-show="ready" class="col column" style="min-width: 600px">
             <div class="row items-center q-px-sm" style="height: 50px">
-                <q-select class="q-mr-sm" ref="rootLink" v-model="rootLink" :options="rootLinkOptions" @input="rootLinkInput"
-                    @popup-show="onSelectPopupShow" @popup-hide="onSelectPopupHide"
+                <q-select ref="rootLink" v-model="rootLink" class="q-mr-sm" :options="rootLinkOptions"
                     style="width: 230px"
                     dropdown-icon="la la-angle-down la-sm"
                     rounded outlined dense emit-value map-options display-value-sanitize options-sanitize
+                    @input="rootLinkInput"
+                    @popup-show="onSelectPopupShow" @popup-hide="onSelectPopupHide"
                 >
-                    <template v-slot:prepend>
-                        <q-btn class="q-mr-xs" round dense color="blue" icon="la la-plus" @click.stop="addBookmark" size="12px">
-                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Добавить закладку</q-tooltip>
+                    <template #prepend>
+                        <q-btn class="q-mr-xs" round dense color="blue" icon="la la-plus" size="12px" @click.stop="addBookmark">
+                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                                Добавить закладку
+                            </q-tooltip>
                         </q-btn>
-                        <q-btn round dense color="blue" icon="la la-bars" @click.stop="bookmarkSettings" size="12px">
-                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Настроить закладки</q-tooltip>
+                        <q-btn round dense color="blue" icon="la la-bars" size="12px" @click.stop="bookmarkSettings">
+                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                                Настроить закладки
+                            </q-tooltip>
                         </q-btn>
                     </template>
-                    <template v-slot:selected>
-                        <div style="overflow: hidden; white-space: nowrap;">{{ rootLinkWithoutProtocol }}</div>
+                    <template #selected>
+                        <div style="overflow: hidden; white-space: nowrap;">
+                            {{ rootLinkWithoutProtocol }}
+                        </div>
                     </template>
                 </q-select>
 
-                <q-select class="q-mr-sm" ref="selectedLink" v-model="selectedLink" :options="selectedLinkOptions" @input="selectedLinkInput" style="width: 50px"
-                    @popup-show="onSelectPopupShow" @popup-hide="onSelectPopupHide"
+                <q-select ref="selectedLink" v-model="selectedLink" class="q-mr-sm" :options="selectedLinkOptions" style="width: 50px"
                     dropdown-icon="la la-angle-down la-sm"
                     rounded outlined dense emit-value map-options hide-selected display-value-sanitize options-sanitize
+                    @popup-show="onSelectPopupShow" @popup-hide="onSelectPopupHide"
+                    @input="selectedLinkInput"
                 >
-                    <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-select>
 
-                <q-input class="col q-mr-sm" ref="input" rounded outlined dense bg-color="white" v-model="bookUrl" placeholder="Скопируйте сюда URL книги"
+                <q-input ref="input" v-model="bookUrl" class="col q-mr-sm" rounded outlined dense bg-color="white" placeholder="Скопируйте сюда URL книги"
                     @focus="selectAllOnFocus" @keydown="bookUrlKeyDown"
                 >
-                    <template v-slot:prepend>
-                        <q-btn class="q-mr-xs" round dense color="blue" icon="la la-home" @click="goToLink(selectedLink)" size="12px">
-                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Вернуться на стартовую страницу</q-tooltip>
+                    <template #prepend>
+                        <q-btn class="q-mr-xs" round dense color="blue" icon="la la-home" size="12px" @click="goToLink(selectedLink)">
+                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                                Вернуться на стартовую страницу
+                            </q-tooltip>
                         </q-btn>
-                        <q-btn round dense color="blue" icon="la la-angle-double-down" @click="openBookUrlInFrame" size="12px" :disabled="!bookUrl">
-                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Загрузить URL во фрейм</q-tooltip>
+                        <q-btn :disabled="!bookUrl" round dense color="blue" icon="la la-angle-double-down" size="12px" @click="openBookUrlInFrame">
+                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                                Загрузить URL во фрейм
+                            </q-tooltip>
                         </q-btn>
                     </template>
-                    <template v-slot:append>
-                        <q-btn round dense color="blue" icon="la la-cog" @click.stop="optionsVisible = true" size="12px">
-                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Опции</q-tooltip>
+                    <template #append>
+                        <q-btn round dense color="blue" icon="la la-cog" size="12px" @click.stop="optionsVisible = true">
+                            <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                                Опции
+                            </q-tooltip>
                         </q-btn>
                     </template>
                 </q-input>
 
-                <q-btn rounded color="green-7" no-caps size="14px" @click="submitUrl" :disabled="!bookUrl">Открыть
-                    <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Открыть в читалке</q-tooltip>
+                <q-btn :disabled="!bookUrl" rounded color="green-7" no-caps size="14px" @click="submitUrl">
+                    Открыть
+                    <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">
+                        Открыть в читалке
+                    </q-tooltip>
                 </q-btn>
             </div>
             <div class="separator"></div>
 
-            <div class="col fit" ref="frameBox" style="position: relative;">
+            <div ref="frameBox" class="col fit" style="position: relative;">
                 <div ref="frameWrap" class="overflow-hidden">
                     <iframe v-if="frameVisible" ref="frame" :src="frameSrc" frameborder="0"></iframe>
                 </div>
@@ -87,33 +106,46 @@
                 <template slot="header">
                     <div class="row items-center">
                         <q-icon class="q-mr-sm" name="la la-bookmark" size="28px"></q-icon>
-                        <div v-if="addBookmarkMode == 'edit'">Редактировать закладку</div>
-                        <div v-else>Добавить закладку</div>
+                        <div v-if="addBookmarkMode == 'edit'">
+                            Редактировать закладку
+                        </div>
+                        <div v-else>
+                            Добавить закладку
+                        </div>
                     </div>
                 </template>
 
                 <div class="q-mx-md row">
-                    <q-input ref="bookmarkLink" class="col q-mr-sm" outlined dense bg-color="white" v-model="bookmarkLink" @keydown="bookmarkLinkKeyDown"
-                        placeholder="Ссылка для закладки" maxlength="2000" @focus="selectAllOnFocus">
+                    <q-input ref="bookmarkLink" v-model="bookmarkLink" class="col q-mr-sm" outlined dense bg-color="white"
+                        placeholder="Ссылка для закладки" maxlength="2000" @focus="selectAllOnFocus" @keydown="bookmarkLinkKeyDown"
+                    >
                     </q-input>
 
-                    <q-select class="q-mr-sm" ref="defaultRootLink" v-model="defaultRootLink" :options="defaultRootLinkOptions" @input="defaultRootLinkInput" style="width: 50px"
+                    <q-select ref="defaultRootLink" v-model="defaultRootLink" class="q-mr-sm" :options="defaultRootLinkOptions" style="width: 50px"
                         dropdown-icon="la la-angle-down la-sm"
                         outlined dense emit-value map-options hide-selected display-value-sanitize options-sanitize
+                        @input="defaultRootLinkInput"
                     >
-                        <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-select>
                 </div>
 
                 <div class="q-mx-md q-mt-md">
-                    <q-input class="col q-mr-sm" ref="bookmarkDesc" outlined dense bg-color="white" v-model="bookmarkDesc" @keydown="bookmarkDescKeyDown"
-                        placeholder="Описание" style="width: 400px" maxlength="100" @focus="selectAllOnFocus">
+                    <q-input ref="bookmarkDesc" v-model="bookmarkDesc" class="col q-mr-sm" outlined dense bg-color="white"
+                        placeholder="Описание" style="width: 400px" maxlength="100" @focus="selectAllOnFocus" @keydown="bookmarkDescKeyDown"
+                    >
                     </q-input>
                 </div>
 
                 <template slot="footer">
-                    <q-btn class="q-px-md q-ml-sm" dense no-caps v-close-popup>Отмена</q-btn>
-                    <q-btn class="q-px-md q-ml-sm" color="primary" dense no-caps @click="okAddBookmark" :disabled="!bookmarkLink">OK</q-btn>
+                    <q-btn v-close-popup class="q-px-md q-ml-sm" dense no-caps>
+                        Отмена
+                    </q-btn>
+                    <q-btn :disabled="!bookmarkLink" class="q-px-md q-ml-sm" color="primary" dense no-caps @click="okAddBookmark">
+                        OK
+                    </q-btn>
                 </template>
             </Dialog>
 
@@ -132,21 +164,24 @@
                 </div>
 
                 <template slot="footer">
-                    <q-btn class="q-px-md q-ml-sm" color="primary" dense no-caps @click="optionsVisible = false">OK</q-btn>
+                    <q-btn class="q-px-md q-ml-sm" color="primary" dense no-caps @click="optionsVisible = false">
+                        OK
+                    </q-btn>
                 </template>
             </Dialog>
         </div>
 
-        <BookmarkSettings v-if="bookmarkSettingsActive" ref="bookmarkSettings" :libs="libs" :addBookmarkVisible="addBookmarkVisible"
-            @do-action="doAction" @close="closeBookmarkSettings">
+        <BookmarkSettings v-if="bookmarkSettingsActive" ref="bookmarkSettings" :libs="libs" :add-bookmark-visible="addBookmarkVisible"
+            @do-action="doAction" @close="closeBookmarkSettings"
+        >
         </BookmarkSettings>
     </Window>
 </template>
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../vueComponent.js';
+
 import _ from 'lodash';
 
 import Window from '../share/Window.vue';
@@ -162,7 +197,7 @@ const proxySubst = {
     'http://fantasy-worlds.org': 'http://b.liberama.top:23580',
 };
 
-export default @Component({
+const componentOptions = {
     components: {
         Window,
         Dialog,
@@ -203,8 +238,10 @@ export default @Component({
             this.commitProp('openInFrameOnAdd', newValue);
         },
     }    
-})
-class ExternalLibs extends Vue {
+};
+class ExternalLibs {
+    _options = componentOptions;
+
     ready = false;
     frameVisible = false;
     rootLink = '';
@@ -836,6 +873,8 @@ class ExternalLibs extends Vue {
         return false;
     }
 }
+
+export default vueComponent(ExternalLibs);
 //-----------------------------------------------------------------------------
 </script>
 

+ 4 - 5
client/components/Reader/ClickMapPage/ClickMapPage.vue

@@ -6,15 +6,12 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
 
 import {sleep} from '../../../share/utils';
 import {clickMap, clickMapText} from '../share/clickMap';
 
-export default @Component({
-})
-class ClickMapPage extends Vue {
+class ClickMapPage {
     fontSize = '200%';
 
     created() {
@@ -53,6 +50,8 @@ class ClickMapPage extends Vue {
         await sleep(5000);
     }
 }
+
+export default vueComponent(ClickMapPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 102 - 86
client/components/Reader/ContentsPage/ContentsPage.vue

@@ -1,115 +1,123 @@
 <template>
-    <Window width="600px" ref="window" @close="close">
+    <Window ref="window" width="600px" @close="close">
         <template slot="header">
             Оглавление/закладки
         </template>
 
-    <div class="bg-grey-3 row">
-        <q-tabs
-            v-model="selectedTab"
-            active-color="black"
-            active-bg-color="white"
-            indicator-color="white"
-            dense
-            no-caps
-            inline-label
-            class="no-mp bg-grey-4 text-grey-7"
-        >
-            <q-tab name="contents" icon="la la-list" label="Оглавление" />
-            <q-tab name="images" icon="la la-image" label="Изображения" />
-            <q-tab name="bookmarks"  icon="la la-bookmark" label="Закладки" />
-        </q-tabs>
-    </div>
-
-    <div class="q-mb-sm"/>
-
-    <div class="tab-panel" v-show="selectedTab == 'contents'">
-        <div>
-            <div v-for="item in contents" :key="item.key" class="column" style="width: 540px">
-                <div class="row q-px-sm no-wrap" :class="{'item': !item.isBookPos, 'item-book-pos': item.isBookPos}">
-                    <div v-if="item.list.length" class="row justify-center items-center expand-button clickable" @click="expandClick(item.key)">
-                        <q-icon name="la la-caret-right" class="icon" :class="{'expanded-icon': item.expanded}" color="green-8" size="20px"/>
-                    </div>
-                    <div v-else class="no-expand-button clickable" @click="setBookPos(item.offset)">
-                        <q-icon name="la la-stop" class="icon" style="visibility: hidden" size="20px"/>
-                    </div>
-                    <div class="col row clickable" @click="setBookPos(item.offset)">
-                        <div :style="item.indentStyle"></div>
-                        <div class="q-mr-sm col overflow-hidden column justify-center" :style="item.labelStyle" v-html="item.label"></div>
-                        <div class="column justify-center">{{ item.perc }}%</div>
+        <div class="bg-grey-3 row">
+            <q-tabs
+                v-model="selectedTab"
+                active-color="black"
+                active-bg-color="white"
+                indicator-color="white"
+                dense
+                no-caps
+                inline-label
+                class="no-mp bg-grey-4 text-grey-7"
+            >
+                <q-tab name="contents" icon="la la-list" label="Оглавление" />
+                <q-tab name="images" icon="la la-image" label="Изображения" />
+                <q-tab name="bookmarks" icon="la la-bookmark" label="Закладки" />
+            </q-tabs>
+        </div>
+
+        <div class="q-mb-sm" />
+
+        <div v-show="selectedTab == 'contents'" class="tab-panel">
+            <div>
+                <div v-for="item in contents" :key="item.key" class="column" style="width: 540px">
+                    <div class="row q-px-sm no-wrap" :class="{'item': !item.isBookPos, 'item-book-pos': item.isBookPos}">
+                        <div v-if="item.list.length" class="row justify-center items-center expand-button clickable" @click="expandClick(item.key)">
+                            <q-icon name="la la-caret-right" class="icon" :class="{'expanded-icon': item.expanded}" color="green-8" size="20px" />
+                        </div>
+                        <div v-else class="no-expand-button clickable" @click="setBookPos(item.offset)">
+                            <q-icon name="la la-stop" class="icon" style="visibility: hidden" size="20px" />
+                        </div>
+                        <div class="col row clickable" @click="setBookPos(item.offset)">
+                            <div :style="item.indentStyle"></div>
+                            <div class="q-mr-sm col overflow-hidden column justify-center" :style="item.labelStyle" v-html="item.label"></div>
+                            <div class="column justify-center">
+                                {{ item.perc }}%
+                            </div>
+                        </div>
                     </div>
-                </div>
-                
-                <div v-if="item.expanded" :ref="`subitem${item.key}`" class="subitems-transition">
-                    <div v-for="subitem in item.list" :key="subitem.key" class="row q-px-sm no-wrap" :class="{'subitem': !subitem.isBookPos, 'subitem-book-pos': subitem.isBookPos}">
-                        <div class="col row clickable" @click="setBookPos(subitem.offset)">
-                            <div class="no-expand-button"></div>
-                            <div :style="subitem.indentStyle"></div>
-                            <div class="q-mr-sm col overflow-hidden column justify-center" :style="item.labelStyle" v-html="subitem.label"></div>
-                            <div class="column justify-center">{{ subitem.perc }}%</div>
+                    
+                    <div v-if="item.expanded" :ref="`subitem${item.key}`" class="subitems-transition">
+                        <div v-for="subitem in item.list" :key="subitem.key" class="row q-px-sm no-wrap" :class="{'subitem': !subitem.isBookPos, 'subitem-book-pos': subitem.isBookPos}">
+                            <div class="col row clickable" @click="setBookPos(subitem.offset)">
+                                <div class="no-expand-button"></div>
+                                <div :style="subitem.indentStyle"></div>
+                                <div class="q-mr-sm col overflow-hidden column justify-center" :style="item.labelStyle" v-html="subitem.label"></div>
+                                <div class="column justify-center">
+                                    {{ subitem.perc }}%
+                                </div>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
-            <div v-if="!contents.length" class="column justify-center items-center" style="height: 100px">
-                Оглавление отсутствует
+                <div v-if="!contents.length" class="column justify-center items-center" style="height: 100px">
+                    Оглавление отсутствует
+                </div>
             </div>
         </div>
-    </div>
-
-    <div class="tab-panel" v-show="selectedTab == 'images'">
-        <div>
-            <div v-for="item in images" :key="item.key" class="column" style="width: 540px">
-                <div class="row q-px-sm no-wrap" :class="{'item': !item.isBookPos, 'item-book-pos': item.isBookPos}">
-                    <div class="col row clickable" @click="setBookPos(item.offset)">
-                        <div class="image-thumb-box row justify-center items-center">
-                            <div v-show="!imageLoaded[item.id]" class="image-thumb column justify-center"><i class="loading-img-icon la la-images"></i></div>
-                            <img v-show="imageLoaded[item.id]" class="image-thumb" :src="imageSrc[item.id]"/>
-                        </div>
-                        <div class="no-expand-button column justify-center items-center">
-                            <div class="image-num">{{ item.num }}</div>
-                            <div v-show="item.type == 'image/jpeg'" class="image-type it-jpg-color row justify-center">JPG</div>
-                            <div v-show="item.type == 'image/png'" class="image-type it-png-color row justify-center">PNG</div>
-                            <div v-show="!item.local" class="image-type it-net-color row justify-center">INET</div>
+
+        <div v-show="selectedTab == 'images'" class="tab-panel">
+            <div>
+                <div v-for="item in images" :key="item.key" class="column" style="width: 540px">
+                    <div class="row q-px-sm no-wrap" :class="{'item': !item.isBookPos, 'item-book-pos': item.isBookPos}">
+                        <div class="col row clickable" @click="setBookPos(item.offset)">
+                            <div class="image-thumb-box row justify-center items-center">
+                                <div v-show="!imageLoaded[item.id]" class="image-thumb column justify-center">
+                                    <i class="loading-img-icon la la-images"></i>
+                                </div>
+                                <img v-show="imageLoaded[item.id]" class="image-thumb" :src="imageSrc[item.id]" />
+                            </div>
+                            <div class="no-expand-button column justify-center items-center">
+                                <div class="image-num">
+                                    {{ item.num }}
+                                </div>
+                                <div v-show="item.type == 'image/jpeg'" class="image-type it-jpg-color row justify-center">
+                                    JPG
+                                </div>
+                                <div v-show="item.type == 'image/png'" class="image-type it-png-color row justify-center">
+                                    PNG
+                                </div>
+                                <div v-show="!item.local" class="image-type it-net-color row justify-center">
+                                    INET
+                                </div>
+                            </div>
+                            <div :style="item.indentStyle"></div>
+                            <div class="q-mr-sm col overflow-hidden column justify-center" :style="item.labelStyle" v-html="item.label"></div>
+                            <div class="column justify-center">
+                                {{ item.perc }}%
+                            </div>
                         </div>
-                        <div :style="item.indentStyle"></div>
-                        <div class="q-mr-sm col overflow-hidden column justify-center" :style="item.labelStyle" v-html="item.label"></div>
-                        <div class="column justify-center">{{ item.perc }}%</div>
                     </div>
                 </div>
-            </div>
-            <div v-if="!images.length" class="column justify-center items-center" style="height: 100px">
-                Изображения отсутствуют
+                <div v-if="!images.length" class="column justify-center items-center" style="height: 100px">
+                    Изображения отсутствуют
+                </div>
             </div>
         </div>
-    </div>
 
-    <div class="tab-panel" v-show="selectedTab == 'bookmarks'">
-        <div class="column justify-center items-center" style="height: 100px">
-            Раздел находится в разработке
+        <div v-show="selectedTab == 'bookmarks'" class="tab-panel">
+            <div class="column justify-center items-center" style="height: 100px">
+                Раздел находится в разработке
+            </div>
         </div>
-    </div>
-
     </Window>
 </template>
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
+
 //import _ from 'lodash';
 
 import Window from '../../share/Window.vue';
 import * as utils from '../../../share/utils';
 
-const ContentsPageProps = Vue.extend({
-    props: {
-        bookPos: Number,
-        isVisible: Boolean,
-    }
-});
-
-export default @Component({
+const componentOptions = {
     components: {
         Window,
     },
@@ -118,8 +126,14 @@ export default @Component({
             this.updateBookPosSelection();
         }
     },
-})
-class ContentsPage extends ContentsPageProps {
+};
+class ContentsPage {
+    _options = componentOptions;
+    _props = {
+        bookPos: Number,
+        isVisible: Boolean,
+    };
+
     selectedTab = 'contents';
     contents = [];
     images = [];
@@ -342,6 +356,8 @@ class ContentsPage extends ContentsPageProps {
         return true;
     }
 }
+
+export default vueComponent(ContentsPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 8 - 5
client/components/Reader/CopyTextPage/CopyTextPage.vue

@@ -12,18 +12,19 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
 
 import Window from '../../share/Window.vue';
 import {sleep} from '../../../share/utils';
 
-export default @Component({
+const componentOptions = {
     components: {
         Window,
     },
-})
-class CopyTextPage extends Vue {
+};
+class CopyTextPage {
+    _options = componentOptions;
+
     text = null;
     initStep = null;
     initPercentage = 0;
@@ -101,6 +102,8 @@ class CopyTextPage extends Vue {
         return true;
     }
 }
+
+export default vueComponent(CopyTextPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 13 - 9
client/components/Reader/HelpPage/CommonHelpPage/CommonHelpPage.vue

@@ -18,15 +18,20 @@
             <li>поддерживаемые браузеры: Google Chrome, Mozilla Firefox последних версий</li>
         </ul>
 
-        <p>В качестве URL книги можно задавать html-страничку с книгой, либо прямую ссылку 
-        на файл из онлайн-библиотеки (например, скопировав адрес ссылки или кнопки "скачать fb2").</p>
+        <p>
+            В качестве URL книги можно задавать html-страничку с книгой, либо прямую ссылку 
+            на файл из онлайн-библиотеки (например, скопировав адрес ссылки или кнопки "скачать fb2").
+        </p>
         <p>Поддерживаемые форматы: <b>fb2, fb2.zip, html, txt</b> и другие.</p>
 
         <div v-show="mode == 'omnireader' || mode == 'liberama.top'">
-            <p>Вы можете добавить в свой браузер закладку, указав в ее свойствах вместо адреса следующий код:
+            <p>
+                Вы можете добавить в свой браузер закладку, указав в ее свойствах вместо адреса следующий код:
                 <br><strong>{{ bookmarkText }}</strong>
                 <q-icon class="copy-icon" name="la la-copy" @click="copyText(bookmarkText, 'Код для адреса закладки успешно скопирован в буфер обмена')">
-                    <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">Скопировать</q-tooltip>                    
+                    <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">
+                        Скопировать
+                    </q-tooltip>                    
                 </q-icon>
 
                 <br>или перетащив на панель закладок следующую ссылку:
@@ -41,14 +46,11 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../../vueComponent.js';
 
 import {copyTextToClipboard} from '../../../../share/utils';
 
-export default @Component({
-})
-class CommonHelpPage extends Vue {
+class CommonHelpPage {
     created() {
     }
 
@@ -69,6 +71,8 @@ class CommonHelpPage extends Vue {
             this.$root.notify.error(msg);
     }
 }
+
+export default vueComponent(CommonHelpPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 36 - 17
client/components/Reader/HelpPage/DonateHelpPage/DonateHelpPage.vue

@@ -1,49 +1,68 @@
 <template>
     <div class="page">
         <div class="box">
-            <p class="p">Вы можете пожертвовать на развитие проекта любую сумму:</p>
+            <p class="p">
+                Вы можете пожертвовать на развитие проекта любую сумму:
+            </p>
             <div class="address">
                 <img class="logo" src="./assets/yoomoney.png">
-                <q-btn class="q-ml-sm q-px-sm" dense no-caps @click="donateYooMoney">Пожертвовать</q-btn><br>
-                <div class="para">{{ yooAddress }}
+                <q-btn class="q-ml-sm q-px-sm" dense no-caps @click="donateYooMoney">
+                    Пожертвовать
+                </q-btn><br>
+                <div class="para">
+                    {{ yooAddress }}
                     <q-icon class="copy-icon" name="la la-copy" @click="copyAddress(yooAddress, 'Кошелёк ЮMoney')">
-                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">Скопировать</q-tooltip>                    
+                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">
+                            Скопировать
+                        </q-tooltip>                    
                     </q-icon>
                 </div>
             </div>
 
             <div class="address">                
                 <img class="logo" src="./assets/paypal.png">
-                <div class="para">{{ paypalAddress }}
+                <div class="para">
+                    {{ paypalAddress }}
                     <q-icon class="copy-icon" name="la la-copy" @click="copyAddress(paypalAddress, 'Paypal-адрес')">
-                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">Скопировать</q-tooltip>                    
+                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">
+                            Скопировать
+                        </q-tooltip>                    
                     </q-icon>
                 </div>
             </div>
 
             <div class="address">                
                 <img class="logo" src="./assets/bitcoin.png">
-                <div class="para">{{ bitcoinAddress }}
+                <div class="para">
+                    {{ bitcoinAddress }}
                     <q-icon class="copy-icon" name="la la-copy" @click="copyAddress(bitcoinAddress, 'Bitcoin-адрес')">
-                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">Скопировать</q-tooltip>                    
+                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">
+                            Скопировать
+                        </q-tooltip>                    
                     </q-icon>
                 </div>
             </div>
 
             <div class="address">                
                 <img class="logo" src="./assets/litecoin.png">
-                <div class="para">{{ litecoinAddress }}
+                <div class="para">
+                    {{ litecoinAddress }}
                     <q-icon class="copy-icon" name="la la-copy" @click="copyAddress(litecoinAddress, 'Litecoin-адрес')">
-                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">Скопировать</q-tooltip>                    
+                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">
+                            Скопировать
+                        </q-tooltip>                    
                     </q-icon>
                 </div>
             </div>
 
             <div class="address">                
                 <img class="logo" src="./assets/monero.png">
-                <div class="para">{{ moneroAddress }}
+                <div class="para">
+                    {{ moneroAddress }}
                     <q-icon class="copy-icon" name="la la-copy" @click="copyAddress(moneroAddress, 'Monero-адрес')">
-                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">Скопировать</q-tooltip>                    
+                        <q-tooltip :delay="1000" anchor="top middle" self="center middle" content-style="font-size: 80%">
+                            Скопировать
+                        </q-tooltip>                    
                     </q-icon>
                 </div>
             </div>
@@ -53,13 +72,11 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../../vueComponent.js';
+
 import {copyTextToClipboard} from '../../../../share/utils';
 
-export default @Component({
-})
-class DonateHelpPage extends Vue {
+class DonateHelpPage {
     yooAddress = '410018702323056';
     paypalAddress = 'bookpauk@gmail.com';
     bitcoinAddress = '3EbgZ7MK1UVaN38Gty5DCBtS4PknM4Ut85';
@@ -81,6 +98,8 @@ class DonateHelpPage extends Vue {
             this.$root.notify.error('Копирование не удалось');
     }
 }
+
+export default vueComponent(DonateHelpPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 9 - 7
client/components/Reader/HelpPage/HelpPage.vue

@@ -14,8 +14,7 @@
             <div class="separator"></div>
 
             <keep-alive>
-                <component ref="page" class="col" :is="activePage"
-                ></component>
+                <component :is="activePage" ref="page" class="col"></component>
             </keep-alive>
         </div>
     </Window>
@@ -23,8 +22,7 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
 
 import Window from '../../share/Window.vue';
 import CommonHelpPage from './CommonHelpPage/CommonHelpPage.vue';
@@ -49,10 +47,12 @@ const tabs = [
     ['DonateHelpPage', 'Помочь проекту'],
 ];
 
-export default @Component({
+const componentOptions = {
     components: Object.assign({ Window }, pages),
-})
-class HelpPage extends Vue {
+};
+class HelpPage {
+    _options = componentOptions;
+
     selectedTab = 'CommonHelpPage';
 
     close() {
@@ -87,6 +87,8 @@ class HelpPage extends Vue {
         return true;
     }
 }
+
+export default vueComponent(HelpPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 15 - 8
client/components/Reader/HelpPage/HotkeysHelpPage/HotkeysHelpPage.vue

@@ -1,29 +1,34 @@
 <template>
     <div class="page">
         <div style="font-size: 120%">
-            <div class="text-h6 text-bold">Доступны следующие клавиатурные команды:</div>
+            <div class="text-h6 text-bold">
+                Доступны следующие клавиатурные команды:
+            </div>
             <br>
         </div>
         <div class="q-mb-md" style="width: 550px">
-            <div class="text-right text-italic" style="font-size: 80%">* Изменить сочетания клавиш можно в настройках</div>
-            <UserHotKeys v-model="userHotKeys" readonly/>
+            <div class="text-right text-italic" style="font-size: 80%">
+                * Изменить сочетания клавиш можно в настройках
+            </div>
+            <UserHotKeys v-model="userHotKeys" readonly />
         </div>
     </div>
 </template>
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../../vueComponent.js';
 
 import UserHotKeys from '../../SettingsPage/UserHotKeys/UserHotKeys.vue';
 
-export default @Component({
+const componentOptions = {
     components: {
         UserHotKeys,
     },
-})
-class HotkeysHelpPage extends Vue {
+};
+class HotkeysHelpPage {
+    _options = componentOptions;
+
     created() {
     }
 
@@ -36,6 +41,8 @@ class HotkeysHelpPage extends Vue {
     }
 
 }
+
+export default vueComponent(HotkeysHelpPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 23 - 13
client/components/Reader/HelpPage/MouseHelpPage/MouseHelpPage.vue

@@ -3,21 +3,28 @@
         <span class="text-h6 text-bold">Управление с помощью мыши/тачскрина:</span>
         <ul>
             <li><b>ЛКМ/ТАЧ</b> по экрану в одну из областей - активация действия:</li>
-                <div class="click-map-page">
-                    <ClickMapPage ref="clickMapPage"></ClickMapPage>
-                </div>
+            <div class="click-map-page">
+                <ClickMapPage ref="clickMapPage"></ClickMapPage>
+            </div>
         
             <li><b>ПКМ</b> - показать/скрыть панель управления</li>
             <li><b>СКМ</b> - вкл./выкл. плавный скроллинг текста</li>
             <br>
             <li>Жесты для тачскрина:</li>
             <ul>
-                <li style="list-style-type: square">от центра вверх: на весь экран</li>
-                <li style="list-style-type: square">от центра вниз: плавный скроллинг</li>
-                <li style="list-style-type: square">от центра вправо: увеличить скорость скроллинга</li>
-                <li style="list-style-type: square">от центра влево: уменьшить скорость скроллинга</li>
+                <li style="list-style-type: square">
+                    от центра вверх: на весь экран
+                </li>
+                <li style="list-style-type: square">
+                    от центра вниз: плавный скроллинг
+                </li>
+                <li style="list-style-type: square">
+                    от центра вправо: увеличить скорость скроллинга
+                </li>
+                <li style="list-style-type: square">
+                    от центра влево: уменьшить скорость скроллинга
+                </li>
             </ul>
-
         </ul>
         * Для управления с помощью мыши/тачскрина необходимо установить галочку "Включить управление кликом" в настройках
     </div>
@@ -25,17 +32,18 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../../vueComponent.js';
 
 import ClickMapPage from '../../ClickMapPage/ClickMapPage.vue';
 
-export default @Component({
+const componentOptions = {
     components: {
         ClickMapPage,
     },
-})
-class MouseHelpPage extends Vue {
+};
+class MouseHelpPage {
+    _options = componentOptions;
+
     created() {
     }
 
@@ -44,6 +52,8 @@ class MouseHelpPage extends Vue {
         this.$refs.clickMapPage.$el.style.backgroundColor = '#478355';
     }
 }
+
+export default vueComponent(MouseHelpPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 7 - 7
client/components/Reader/HelpPage/VersionHistoryPage/VersionHistoryPage.vue

@@ -3,9 +3,9 @@
         <span class="text-h6 text-bold">История версий:</span>
         <br><br>
 
-        <span class="clickable" v-for="(item, index) in versionHeader" :key="index" @click="showRelease(item)">
+        <span v-for="(item, index) in versionHeader" :key="index" class="clickable" @click="showRelease(item)">
             <p>
-            {{ item }}
+                {{ item }}
             </p>
         </span>
 
@@ -20,13 +20,11 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
+
 import {versionHistory} from '../../versionHistory';
 
-export default @Component({
-})
-class VersionHistoryPage extends Vue {
+class VersionHistoryPage {
     versionHeader = [];
     versionContent = [];
 
@@ -54,6 +52,8 @@ class VersionHistoryPage extends Vue {
         }
     }
 }
+
+export default vueComponent(VersionHistoryPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 8 - 5
client/components/Reader/LibsPage/LibsPage.vue

@@ -4,14 +4,13 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
 
 import Window from '../../share/Window.vue';
 import * as utils from '../../../share/utils';
 //import rstore from '../../../store/modules/reader';
 
-export default @Component({
+const componentOptions = {
     components: {
         Window
     },
@@ -20,8 +19,10 @@ export default @Component({
             this.sendLibs();
         },
     }    
-})
-class LibsPage extends Vue {
+};
+class LibsPage {
+    _options = componentOptions;
+
     created() {
         this.popupWindow = null;
         this.commit = this.$store.commit;
@@ -120,6 +121,8 @@ class LibsPage extends Vue {
         this.$emit('libs-close');
     }
 }
+
+export default vueComponent(LibsPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 19 - 15
client/components/Reader/Reader.vue

@@ -115,7 +115,7 @@
                 ></component>
             </keep-alive>
 
-            <!--SetPositionPage v-if="setPositionActive" ref="setPositionPage" @set-position-toggle="setPositionToggle" @book-pos-changed="bookPosChanged"></SetPositionPage>
+            <SetPositionPage v-if="setPositionActive" ref="setPositionPage" @set-position-toggle="setPositionToggle" @book-pos-changed="bookPosChanged"></SetPositionPage>
             <SearchPage v-show="searchActive" ref="searchPage" 
                 @do-action="doAction"
                 @book-pos-changed="bookPosChanged"
@@ -128,9 +128,9 @@
             <SettingsPage v-show="settingsActive" ref="settingsPage" @do-action="doAction"></SettingsPage>
             <HelpPage v-if="helpActive" ref="helpPage" @do-action="doAction"></HelpPage>
             <ClickMapPage v-show="clickMapActive" ref="clickMapPage"></ClickMapPage>
-            <ServerStorage v-show="hidden" ref="serverStorage"></ServerStorage>
-            <ContentsPage v-show="contentsActive" ref="contentsPage" :book-pos="bookPos" :is-visible="contentsActive" @do-action="doAction" @book-pos-changed="bookPosChanged"></ContentsPage-->
+            <ContentsPage v-show="contentsActive" ref="contentsPage" :book-pos="bookPos" :is-visible="contentsActive" @do-action="doAction" @book-pos-changed="bookPosChanged"></ContentsPage>
 
+            <ServerStorage v-show="hidden" ref="serverStorage"></ServerStorage>
             <ReaderDialogs ref="dialogs" @donate-toggle="donateToggle" @version-history-toggle="versionHistoryToggle"></ReaderDialogs>
         </div>
     </div>
@@ -147,7 +147,7 @@ import LoaderPage from './LoaderPage/LoaderPage.vue';
 import TextPage from './TextPage/TextPage.vue';
 import ProgressPage from './ProgressPage/ProgressPage.vue';
 
-/*import SetPositionPage from './SetPositionPage/SetPositionPage.vue';
+import SetPositionPage from './SetPositionPage/SetPositionPage.vue';
 import SearchPage from './SearchPage/SearchPage.vue';
 import CopyTextPage from './CopyTextPage/CopyTextPage.vue';
 import LibsPage from './LibsPage/LibsPage.vue';
@@ -155,9 +155,9 @@ import RecentBooksPage from './RecentBooksPage/RecentBooksPage.vue';
 import SettingsPage from './SettingsPage/SettingsPage.vue';
 import HelpPage from './HelpPage/HelpPage.vue';
 import ClickMapPage from './ClickMapPage/ClickMapPage.vue';
-import ServerStorage from './ServerStorage/ServerStorage.vue';
-import ContentsPage from './ContentsPage/ContentsPage.vue';*/
+import ContentsPage from './ContentsPage/ContentsPage.vue';
 
+import ServerStorage from './ServerStorage/ServerStorage.vue';
 import ReaderDialogs from './ReaderDialogs/ReaderDialogs.vue';
 
 import bookManager from './share/bookManager';
@@ -177,7 +177,7 @@ const componentOptions = {
         TextPage,
         ProgressPage,
 
-        /*SetPositionPage,
+        SetPositionPage,
         SearchPage,
         CopyTextPage,
         LibsPage,
@@ -185,9 +185,9 @@ const componentOptions = {
         SettingsPage,
         HelpPage,
         ClickMapPage,
-        ServerStorage,
-        ContentsPage,*/
+        ContentsPage,
 
+        ServerStorage,
         ReaderDialogs,
     },
     watch: {
@@ -236,22 +236,26 @@ const componentOptions = {
 
 class Reader {
     _options = componentOptions;
+
     rstore = {};
+
     loaderActive = false;
-    offlineModeActive = false;
-    progressActive = false;
     fullScreenActive = false;
-
-    scrollingActive = false;
     setPositionActive = false;
     searchActive = false;
     copyTextActive = false;
+    convOptionsActive = false;
+    refreshActive = false;
+    contentsActive = false;    
     libsActive = false;
     recentBooksActive = false;
+    offlineModeActive = false;
     settingsActive = false;
-    helpActive = false;
+
     clickMapActive = false;
-    contentsActive = false;
+    helpActive = false;
+    scrollingActive = false;
+    progressActive = false;
 
     bookPos = null;
     allowUrlParamBookPos = false;

+ 36 - 24
client/components/Reader/RecentBooksPage/RecentBooksPage.vue

@@ -1,11 +1,13 @@
 <template>
-    <Window width="600px" ref="window" @close="close">
+    <Window ref="window" width="600px" @close="close">
         <template slot="header">
             <span v-show="!loading">{{ header }}</span>
-            <span v-if="loading"><q-spinner class="q-mr-sm" color="lime-12" size="20px" :thickness="7"/>Список загружается</span>
+            <span v-if="loading"><q-spinner class="q-mr-sm" color="lime-12" size="20px" :thickness="7" />
+                Список загружается
+            </span>
         </template>
 
-        <a ref="download" style='display: none;' target="_blank"></a>
+        <a ref="download" style="display: none;" target="_blank"></a>
 
         <q-table
             class="recent-books-table col"
@@ -18,18 +20,22 @@
             virtual-scroll
             dense
         > 
-            <template v-slot:header="props">
+            <template #header="props">
                 <q-tr :props="props">
-                    <q-th class="td-mp" style="width: 25px" key="num" :props="props"><span v-html="props.cols[0].label"></span></q-th>
-                    <q-th class="td-mp break-word" style="width: 77px" key="date" :props="props"><span v-html="props.cols[1].label"></span></q-th>
-                    <q-th class="td-mp" style="width: 332px" key="desc" :props="props" colspan="4">
-                        <q-input ref="input" outlined dense rounded style="position: absolute; top: 6px; left: 90px; width: 380px" bg-color="white"
-                            placeholder="Найти"
-                            v-model="search"
+                    <q-th key="num" class="td-mp" style="width: 25px" :props="props">
+                        <span v-html="props.cols[0].label"></span>
+                    </q-th>
+                    <q-th key="date" class="td-mp break-word" style="width: 77px" :props="props">
+                        <span v-html="props.cols[1].label"></span>
+                    </q-th>
+                    <q-th key="desc" class="td-mp" style="width: 332px" :props="props" colspan="4">
+                        <q-input ref="input" v-model="search"
+                            outlined dense rounded style="position: absolute; top: 6px; left: 90px; width: 380px" bg-color="white"
+                            placeholder="Найти"                            
                             @click.stop
                         >
-                            <template v-slot:append>
-                                <q-icon v-if="search !== ''" name="la la-times" class="cursor-pointer" @click.stop="resetSearch"/>
+                            <template #append>
+                                <q-icon v-if="search !== ''" name="la la-times" class="cursor-pointer" @click.stop="resetSearch" />
                             </template>
                         </q-input>
                         <span v-html="props.cols[2].label"></span>
@@ -37,7 +43,7 @@
                 </q-tr>
             </template>
 
-            <template v-slot:body="props">
+            <template #body="props">
                 <q-tr :props="props">
                     <q-td key="num" :props="props" class="td-mp" auto-width>
                         <div class="break-word" style="width: 25px">
@@ -45,16 +51,18 @@
                         </div>
                     </q-td>
 
-                    <q-td key="date" :props="props" class="td-mp clickable" @click="loadBook(props.row.url)" auto-width>
+                    <q-td key="date" auto-width :props="props" class="td-mp clickable" @click="loadBook(props.row.url)">
                         <div class="break-word" style="width: 68px">
                             {{ props.row.touchDate }}<br>
                             {{ props.row.touchTime }}
                         </div>
                     </q-td>
 
-                    <q-td key="desc" :props="props" class="td-mp clickable" @click="loadBook(props.row.url)" auto-width>
+                    <q-td key="desc" auto-width :props="props" class="td-mp clickable" @click="loadBook(props.row.url)">
                         <div class="break-word" style="width: 332px; font-size: 90%">
-                            <div style="color: green">{{ props.row.desc.author }}</div>
+                            <div style="color: green">
+                                {{ props.row.desc.author }}
+                            </div>
                             <div>{{ props.row.desc.title }}</div>
                             <div class="read-bar" :style="`width: ${332*props.row.readPart}px`"></div>
                         </div>
@@ -72,8 +80,9 @@
                             <q-btn
                                 dense
                                 style="width: 30px; height: 30px; padding: 7px 0 7px 0; margin-left: 4px"
-                                @click="handleDel(props.row.key)">
-                                <q-icon class="la la-times" size="14px" style="top: -6px"/>
+                                @click="handleDel(props.row.key)"
+                            >
+                                <q-icon class="la la-times" size="14px" style="top: -6px" />
                             </q-btn>
                         </div>
                     </q-td>
@@ -82,14 +91,13 @@
                 </q-tr>
             </template>
         </q-table>
-
     </Window>
 </template>
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
+
 import path from 'path';
 //import _ from 'lodash';
 
@@ -98,7 +106,7 @@ import Window from '../../share/Window.vue';
 import bookManager from '../share/bookManager';
 import readerApi from '../../../api/reader';
 
-export default @Component({
+const componentOptions = {
     components: {
         Window,
     },
@@ -107,8 +115,10 @@ export default @Component({
             this.updateTableData();
         }
     },
-})
-class RecentBooksPage extends Vue {
+};
+class RecentBooksPage {
+    _options = componentOptions;
+
     loading = false;
     search = '';
     tableData = [];
@@ -324,6 +334,8 @@ class RecentBooksPage extends Vue {
         return true;
     }
 }
+
+export default vueComponent(RecentBooksPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 20 - 10
client/components/Reader/SearchPage/SearchPage.vue

@@ -11,15 +11,22 @@
                 <!--input ref="input"
                     placeholder="что ищем"
                     :value="needle" @input="needle = $event.target.value"/-->
-                <q-input ref="input" class="col" outlined dense
+                <q-input ref="input" v-model="needle"
+                    class="col" outlined dense
                     placeholder="что ищем"
-                    v-model="needle" @keydown="inputKeyDown"
+                    @keydown="inputKeyDown"         
                 />
-                <div style="position: absolute; right: 10px; margin-top: 10px; font-size: 16px;">{{ foundText }}</div>
+                <div style="position: absolute; right: 10px; margin-top: 10px; font-size: 16px;">
+                    {{ foundText }}
+                </div>
             </div>
             <q-btn-group v-show="!initStep" class="button-group row no-wrap">
-                <q-btn class="button" dense stretch @click="showNext"><q-icon style="top: -6px" name="la la-angle-down" dense size="22px"/></q-btn>
-                <q-btn class="button" dense stretch @click="showPrev"><q-icon style="top: -4px" class="icon" name="la la-angle-up" dense size="22px"/></q-btn>
+                <q-btn class="button" dense stretch @click="showNext">
+                    <q-icon style="top: -6px" name="la la-angle-down" dense size="22px" />
+                </q-btn>
+                <q-btn class="button" dense stretch @click="showPrev">
+                    <q-icon style="top: -4px" class="icon" name="la la-angle-up" dense size="22px" />
+                </q-btn>
             </q-btn-group>
         </div>
     </Window>
@@ -27,13 +34,12 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
 
 import Window from '../../share/Window.vue';
 import {sleep} from '../../../share/utils';
 
-export default @Component({
+const componentOptions = {
     components: {
         Window,
     },
@@ -49,8 +55,10 @@ export default @Component({
                 el.style.paddingRight = newValue.length*12 + 'px';
         },
     },
-})
-class SearchPage extends Vue {
+};
+class SearchPage {
+    _options = componentOptions;
+
     header = null;
     initStep = null;
     initPercentage = 0;
@@ -180,6 +188,8 @@ class SearchPage extends Vue {
         return true;
     }
 }
+
+export default vueComponent(SearchPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 10 - 6
client/components/Reader/ServerStorage/ServerStorage.vue

@@ -4,8 +4,8 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
+
 import _ from 'lodash';
 
 import bookManager from '../share/bookManager';
@@ -18,7 +18,7 @@ const ssCacheStore = localForage.createInstance({
     name: 'ssCacheStore'
 });
 
-export default @Component({
+const componentOptions = {
     watch: {
         serverSyncEnabled: function() {
             this.serverSyncEnabledChanged();
@@ -39,14 +39,16 @@ export default @Component({
             this.debouncedSaveLibs();
         },
     },
-})
-class ServerStorage extends Vue {
+};
+class ServerStorage {
+    _options = componentOptions;
+
     created() {
         this.inited = false;
         this.keyInited = false;
         this.commit = this.$store.commit;
         this.prevServerStorageKey = null;
-        this.$root.$on('generateNewServerStorageKey', () => {this.generateNewServerStorageKey()});
+        this.$root.generateNewServerStorageKey = () => {this.generateNewServerStorageKey()};
 
         this.debouncedSaveSettings = _.debounce(() => {
             this.saveSettings();
@@ -734,5 +736,7 @@ class ServerStorage extends Vue {
         return result;
     }
 }
+
+export default vueComponent(ServerStorage);
 //-----------------------------------------------------------------------------
 </script>

+ 11 - 7
client/components/Reader/SetPositionPage/SetPositionPage.vue

@@ -6,11 +6,12 @@
 
         <div id="set-position-slider" class="slider q-px-md">
             <q-slider
-                thumb-path="M 2, 10 a 8.5,8.5 0 1,0 17,0 a 8.5,8.5 0 1,0 -17,0"
                 v-model="sliderValue"
+                thumb-path="M 2, 10 a 8.5,8.5 0 1,0 17,0 a 8.5,8.5 0 1,0 -17,0"
+                
                 :max="sliderMax"
                 label
-                :label-value="(sliderMax ? (sliderValue/this.sliderMax*100).toFixed(2) + '%' : 0)"
+                :label-value="(sliderMax ? (sliderValue/sliderMax*100).toFixed(2) + '%' : 0)"
                 color="primary"
             />
         </div>
@@ -19,12 +20,11 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
 
 import Window from '../../share/Window.vue';
 
-export default @Component({
+const componentOptions = {
     components: {
         Window,
     },
@@ -34,8 +34,10 @@ export default @Component({
                 this.$emit('book-pos-changed', {bookPos: newValue});
         },
     },
-})
-class SetPositionPage extends Vue {
+};
+class SetPositionPage {
+    _options = componentOptions;
+
     sliderValue = null;
     sliderMax = null;
 
@@ -67,6 +69,8 @@ class SetPositionPage extends Vue {
         return true;
     }
 }
+
+export default vueComponent(SetPositionPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 11 - 6
client/components/Reader/SettingsPage/SettingsPage.vue

@@ -74,8 +74,8 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../vueComponent.js';
+
 import _ from 'lodash';
 
 import * as utils from '../../../share/utils';
@@ -90,7 +90,7 @@ import defPalette from './defPalette';
 
 const hex = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/;
 
-export default @Component({
+const componentOptions = {
     components: {
         Window,
         NumInput,
@@ -165,8 +165,10 @@ export default @Component({
                 this.statusBarColor = newValue;
         },
     },
-})
-class SettingsPage extends Vue {
+};
+class SettingsPage {
+    _options = componentOptions;
+
     selectedTab = 'profiles';
     selectedViewTab = 'mode';
     selectedKeysTab = 'mouse';
@@ -550,7 +552,8 @@ class SettingsPage extends Vue {
             });
 
             if (result && result.value && result.value.toLowerCase() == 'да') {
-                this.$root.$emit('generateNewServerStorageKey');
+                if (this.$root.generateNewServerStorageKey)
+                    this.$root.generateNewServerStorageKey();
             }
         } catch (e) {
             //
@@ -630,6 +633,8 @@ class SettingsPage extends Vue {
         return true;
     }
 }
+
+export default vueComponent(SettingsPage);
 //-----------------------------------------------------------------------------
 </script>
 

+ 33 - 25
client/components/Reader/SettingsPage/UserHotKeys/UserHotKeys.vue

@@ -2,14 +2,19 @@
     <div class="table col column no-wrap">
         <!-- header -->
         <div class="table-row row">
-            <div class="desc q-pa-sm bg-blue-2">Команда</div>
+            <div class="desc q-pa-sm bg-blue-2">
+                Команда
+            </div>
             <div class="hotKeys col q-pa-sm bg-blue-2 row no-wrap">
-                <div style="width: 80px">Сочетание клавиш</div>
-                <q-input ref="input" class="q-ml-sm col"
+                <div style="width: 80px">
+                    Сочетание клавиш
+                </div>
+                <q-input ref="input"
+                    v-model="search"
+                    class="q-ml-sm col"
                     outlined dense rounded
                     bg-color="grey-4"
-                    placeholder="Найти"
-                    v-model="search"
+                    placeholder="Найти"                    
                     @click.stop
                 />
                 <div v-show="!readonly" class="q-ml-sm column justify-center">
@@ -23,35 +28,38 @@
         </div>
 
         <!-- body -->
-        <div class="table-row row" v-for="(action, index) in tableData" :key="index">
-            <div class="desc q-pa-sm">{{ rstore.readerActions[action] }}</div>
+        <div v-for="(action, index) in tableData" :key="index" class="table-row row">
+            <div class="desc q-pa-sm">
+                {{ rstore.readerActions[action] }}
+            </div>
             <div class="hotKeys col q-pa-sm">
                 <q-chip
+                    v-for="(code, index2) in value[action]" :key="index2"
                     :color="collisions[code] ? 'red' : 'grey-7'"
                     :removable="!readonly" :clickable="collisions[code] ? true : false"
-                    text-color="white" v-for="(code, index) in value[action]" :key="index" @remove="removeCode(action, code)"
+                    text-color="white" @remove="removeCode(action, code)"
                     @click="collisionWarning(code)"
-                    >
+                >
                     {{ code }}
                 </q-chip>
             </div>
             <div v-show="!readonly" class="column q-pa-xs">
                 <q-icon
-                    name="la la-plus-circle"
-                    class="button bg-green-8 text-white"
-                    @click="addHotKey(action)"
                     v-ripple
                     :disabled="value[action].length >= maxCodesLength"
+                    name="la la-plus-circle"
+                    class="button bg-green-8 text-white"
+                    @click="addHotKey(action)"                    
                 >
                     <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
                         Добавить сочетание клавиш
                     </q-tooltip>
                 </q-icon>
                 <q-icon
+                    v-ripple
                     name="la la-broom"
                     class="button text-grey-5"
                     @click="defaultHotKey(action)"
-                    v-ripple
                 >
                     <q-tooltip :delay="1000" anchor="top middle" self="bottom middle" content-style="font-size: 80%">
                         По умолчанию
@@ -64,20 +72,12 @@
 
 <script>
 //-----------------------------------------------------------------------------
-import Vue from 'vue';
-import Component from 'vue-class-component';
+import vueComponent from '../../../vueComponent.js';
 
 import rstore from '../../../../store/modules/reader';
 //import * as utils from '../../share/utils';
 
-const UserHotKeysProps = Vue.extend({
-    props: {
-        modelValue: Object,
-        readonly: Boolean,
-    }
-});
-
-export default @Component({
+const componentOptions = {
     watch: {
         search: function() {
             this.updateTableData();
@@ -87,8 +87,14 @@ export default @Component({
             this.updateTableData();
         }
     },
-})
-class UserHotKeys extends UserHotKeysProps {
+};
+class UserHotKeys {
+    _options = componentOptions;
+    _props = {
+        modelValue: Object,
+        readonly: Boolean,
+    };
+
     search = '';
     rstore = {};
     tableData = [];
@@ -211,6 +217,8 @@ class UserHotKeys extends UserHotKeysProps {
         }
     }
 }
+
+export default vueComponent(UserHotKeys);
 //-----------------------------------------------------------------------------
 </script>