Przeglądaj źródła

Работа над LibsPage

Book Pauk 4 lat temu
rodzic
commit
0f81fa53d2

+ 117 - 11
client/components/Reader/LibsPage/LibsPage.vue

@@ -1,31 +1,36 @@
 <template>
 <template>
     <Window ref="window" @close="close">
     <Window ref="window" @close="close">
         <template slot="header">
         <template slot="header">
-            Библиотеки <span v-show="startLink">(выбрана {{ startLink }})</span>
+            Библиотеки <span v-show="startLink">(выбрано {{ startLink }})</span>
         </template>
         </template>
 
 
         <div class="col column" style="min-width: 600px">
         <div class="col column" style="min-width: 600px">
             <div class="row items-center q-px-sm" style="height: 50px">
             <div class="row items-center q-px-sm" style="height: 50px">
-                <q-select class="q-mr-sm" v-model="externalLib" :options="externalLibOptions"
-                    style="width: 250px"
+                <q-select class="q-mr-sm" v-model="rootLink" :options="rootLinkOptions"
+                    style="width: 230px"
                     dropdown-icon="la la-angle-down la-sm"
                     dropdown-icon="la la-angle-down la-sm"
-                    rounded outlined dense emit-value map-options
+                    rounded outlined dense emit-value map-options display-value-sanitize options-sanitize
                 >
                 >
                     <template v-slot:prepend>
                     <template v-slot:prepend>
                         <q-btn class="q-mr-xs" round dense color="blue" icon="la la-plus" size="12px"/>
                         <q-btn class="q-mr-xs" round dense color="blue" icon="la la-plus" size="12px"/>
                         <q-btn round dense color="blue" icon="la la-bars" size="12px"/>
                         <q-btn round dense color="blue" icon="la la-bars" size="12px"/>
                     </template>
                     </template>
+                    <template v-slot:selected>
+                        <div style="overflow: hidden; white-space: nowrap;">{{ removeProtocol(rootLink) }}</div>
+                    </template>
                 </q-select>
                 </q-select>
-                <q-select class="q-mr-sm" v-model="startPageModel" :options="startPageOptions" style="width: 50px"
+                <q-select class="q-mr-sm" v-model="selectedLink" :options="selectedLinkOptions" style="width: 50px"
                     dropdown-icon="la la-angle-down la-sm"
                     dropdown-icon="la la-angle-down la-sm"
-                    rounded outlined dense emit-value map-options
-                />                
-                <q-input ref="input" class="col" rounded outlined dense bg-color="white" v-model="bookUrl" placeholder="Скопируйте сюда URL книги" @focus="onInputFocus">
+                    rounded outlined dense emit-value map-options hide-selected display-value-sanitize options-sanitize
+                >
+                </q-select>
+                <q-input class="col q-mr-sm" ref="input" rounded outlined dense bg-color="white" v-model="bookUrl" placeholder="Скопируйте сюда URL книги" @focus="onInputFocus">
                     <template v-slot:prepend>
                     <template v-slot:prepend>
+                        <q-btn class="q-mr-xs" round dense color="blue" icon="la la-home" size="12px"/>
                         <q-btn round dense color="blue" icon="la la-angle-double-down" @click="openBookUrlInFrame" size="12px"/>
                         <q-btn round dense color="blue" icon="la la-angle-double-down" @click="openBookUrlInFrame" size="12px"/>
                     </template>
                     </template>
                 </q-input>
                 </q-input>
-                <q-btn class="q-mx-sm" rounded color="green-5" no-caps size="14px">Открыть</q-btn>
+                <q-btn rounded color="green-5" no-caps size="14px" @click="submitUrl">Открыть</q-btn>
             </div>
             </div>
             <div class="separator"></div>
             <div class="separator"></div>
             <iframe class="col fit" :src="frameSrc" frameborder="0"></iframe>
             <iframe class="col fit" :src="frameSrc" frameborder="0"></iframe>
@@ -37,24 +42,39 @@
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 import Vue from 'vue';
 import Vue from 'vue';
 import Component from 'vue-class-component';
 import Component from 'vue-class-component';
+import _ from 'lodash';
 
 
 import Window from '../../share/Window.vue';
 import Window from '../../share/Window.vue';
+//import rstore from '../../../store/modules/reader';
 
 
 export default @Component({
 export default @Component({
     components: {
     components: {
         Window
         Window
     },
     },
     watch: {
     watch: {
+        libs: function() {
+            this.loadLibs();
+        },
+        rootLink: function() {
+            this.updateSelectedLink();
+            this.updateStartLink();
+        },
+        selectedLink: function() {
+            this.updateStartLink();
+        }
     }    
     }    
 })
 })
 class LibsPage extends Vue {
 class LibsPage extends Vue {
     startLink = '';
     startLink = '';
+    rootLink = '';
+    selectedLink = '';
     frameSrc = '';
     frameSrc = '';
     bookUrl = '';
     bookUrl = '';
 
 
     created() {
     created() {
         this.commit = this.$store.commit;
         this.commit = this.$store.commit;
         this.loadLibs();
         this.loadLibs();
+        //this.commit('reader/setLibs', rstore.libsDefaults);
     }
     }
 
 
     init() {
     init() {
@@ -69,7 +89,49 @@ class LibsPage extends Vue {
 
 
     loadLibs() {
     loadLibs() {
         const libs = this.libs;
         const libs = this.libs;
-        this.startLink = this.removeProtocol(libs.startLink);
+        console.log(libs.comment);
+        this.startLink = (libs.comment ? libs.comment + ' ': '') + this.removeProtocol(libs.startLink);
+        this.rootLink = this.getOrigin(libs.startLink);
+        this.updateSelectedLink();
+    }
+
+    updateSelectedLink() {
+        const index = this.getRootIndexByUrl(this.rootLink);
+        if (index >= 0)
+            this.selectedLink = this.libs.groups[index].s;
+    }
+
+    updateStartLink() {
+        const index = this.getRootIndexByUrl(this.rootLink);
+        if (index >= 0) {
+            let libs = _.cloneDeep(this.libs);
+            libs.groups[index].s = this.selectedLink;
+            libs.startLink = this.selectedLink;
+            libs.comment = this.getCommentByLink(libs.groups[index].list, this.selectedLink);
+            this.frameSrc = this.selectedLink;
+            this.commit('reader/setLibs', libs);
+        }
+    }
+
+    get rootLinkOptions() {
+        let result = [];
+        this.libs.groups.forEach(group => {
+            result.push({label: this.removeProtocol(group.r), value: group.r});
+        });
+
+        return result;
+    }
+
+    get selectedLinkOptions() {
+        let result = [];
+        const index = this.getRootIndexByUrl(this.rootLink);
+        if (index >= 0) {
+            this.libs.groups[index].list.forEach(link => {
+                result.push({label: (link.c ? link.c + ' ': '') + this.removeOrigin(link.l), value: link.l});
+            });
+        }
+
+        return result;
     }
     }
 
 
     openBookUrlInFrame() {
     openBookUrlInFrame() {
@@ -87,15 +149,58 @@ class LibsPage extends Vue {
         return url.replace(/(^\w+:|^)\/\//, '');
         return url.replace(/(^\w+:|^)\/\//, '');
     }
     }
 
 
+    getOrigin(url) {
+        const parsed = new URL(url);
+        return parsed.origin;
+    }
+
+    removeOrigin(url) {
+        const parsed = new URL(url);
+        const result = url.substring(parsed.origin.length);
+        return (result ? result : '/');
+    }
+
+    getRootIndexByUrl(url) {
+        const origin = this.getOrigin(url);
+        const groups = this.libs.groups;
+        for (let i = 0; i < groups.length; i++) {
+            if (groups[i].r == origin)
+                return i;
+        }
+        return -1;
+    }
+
+    getCommentByLink(list, link) {
+        for (const item of list) {
+            if (item.l == link)
+                return item.c;
+        }
+        return '';
+    }
+
     onInputFocus() {
     onInputFocus() {
         this.$refs.input.select();
         this.$refs.input.select();
     }
     }
 
 
+    submitUrl() {
+        if (this.bookUrl) {
+            this.$emit('load-book', {url: this.bookUrl, force: true});
+            this.bookUrl = '';
+        }
+    }
+
     close() {
     close() {
         this.$emit('do-action', {action: 'libs'});
         this.$emit('do-action', {action: 'libs'});
     }
     }
 
 
     keyHook() {
     keyHook() {
+        //недостатки сторонних ui
+        const input = this.$refs.input.$refs.input;
+        if (document.activeElement === input && event.type == 'keydown' && event.code == 'Enter') {
+            this.submitUrl();
+            return true;
+        }
+
         if (event.type == 'keydown' && (event.code == 'Escape')) {
         if (event.type == 'keydown' && (event.code == 'Escape')) {
             this.close();
             this.close();
         }
         }
@@ -110,4 +215,5 @@ class LibsPage extends Vue {
 .separator {
 .separator {
     height: 1px;
     height: 1px;
     background-color: #A0A0A0;
     background-color: #A0A0A0;
-}</style>
+}
+</style>

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

@@ -85,7 +85,7 @@
                 @stop-text-search="stopTextSearch">
                 @stop-text-search="stopTextSearch">
             </SearchPage>
             </SearchPage>
             <CopyTextPage v-if="copyTextActive" ref="copyTextPage" @do-action="doAction"></CopyTextPage>
             <CopyTextPage v-if="copyTextActive" ref="copyTextPage" @do-action="doAction"></CopyTextPage>
-            <LibsPage v-show="libsActive" ref="libsPage" @do-action="doAction"></LibsPage>
+            <LibsPage v-show="libsActive" ref="libsPage" @load-book="loadBook" @do-action="doAction"></LibsPage>
             <RecentBooksPage v-show="recentBooksActive" ref="recentBooksPage" @load-book="loadBook" @recent-books-close="recentBooksClose"></RecentBooksPage>
             <RecentBooksPage v-show="recentBooksActive" ref="recentBooksPage" @load-book="loadBook" @recent-books-close="recentBooksClose"></RecentBooksPage>
             <SettingsPage v-show="settingsActive" ref="settingsPage" @do-action="doAction"></SettingsPage>
             <SettingsPage v-show="settingsActive" ref="settingsPage" @do-action="doAction"></SettingsPage>
             <HelpPage v-if="helpActive" ref="helpPage" @do-action="doAction"></HelpPage>
             <HelpPage v-if="helpActive" ref="helpPage" @do-action="doAction"></HelpPage>

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

@@ -255,12 +255,13 @@ const settingDefaults = {
 
 
 const libsDefaults = {
 const libsDefaults = {
     startLink: 'http://flibusta.is',
     startLink: 'http://flibusta.is',
-    links: [
+    comment: 'Флибуста - книжное братство',
+    groups: [
         {r: 'http://flibusta.is', s: 'http://flibusta.is', list: [
         {r: 'http://flibusta.is', s: 'http://flibusta.is', list: [
-            {l: 'http://flibusta.is', c: 'Флибуста - книжное братство'}
+            {l: 'http://flibusta.is', c: 'Флибуста - книжное братство'},
         ]},
         ]},
         {r: 'http://samlib.ru', s: 'http://samlib.ru', list: [
         {r: 'http://samlib.ru', s: 'http://samlib.ru', list: [
-            {l: 'http://samlib.ru', c: 'Журнал "Самиздат"'}
+            {l: 'http://samlib.ru', c: 'Журнал "Самиздат"'},
         ]},
         ]},
     ]
     ]
 };
 };
@@ -347,6 +348,7 @@ export default {
     fonts,
     fonts,
     webFonts,
     webFonts,
     settingDefaults,
     settingDefaults,
+    libsDefaults,
 
 
     namespaced: true,
     namespaced: true,
     state,
     state,