Преглед на файлове

Работа над группировкой файлов

Book Pauk преди 3 години
родител
ревизия
988c959eba
променени са 2 файла, в които са добавени 128 реда и са изтрити 19 реда
  1. 125 19
      client/components/Reader/RecentBooksPage/RecentBooksPage.vue
  2. 3 0
      client/store/modules/reader.js

+ 125 - 19
client/components/Reader/RecentBooksPage/RecentBooksPage.vue

@@ -10,11 +10,15 @@
         <a ref="download" style="display: none;" target="_blank"></a>
         <a ref="download" style="display: none;" target="_blank"></a>
 
 
         <div id="vs-container" ref="vsContainer" class="recent-books-scroll col">
         <div id="vs-container" ref="vsContainer" class="recent-books-scroll col">
-            <div ref="header" class="scroll-header bg-blue-2">
+            <div ref="header" class="scroll-header row bg-blue-2">
+                <q-btn class="bg-white" rounded style="width: 35px; height: 35px; margin: 6px 6px 0px 6px" @click="showSameBookClick">
+                    <q-icon name="la la-caret-right" class="icon" :class="{'expanded-icon': showSameBook}" color="green-8" size="24px" />
+                </q-btn>
+
                 <q-input 
                 <q-input 
                     ref="input" v-model="search"
                     ref="input" v-model="search"
                     outlined dense
                     outlined dense
-                    style="position: relative; top: 4px; left: 200px; width: 350px" bg-color="white"
+                    style="position: absolute; top: 4px; left: 200px; width: 350px" bg-color="white"
                     placeholder="Найти"
                     placeholder="Найти"
                     @click.stop
                     @click.stop
                 >
                 >
@@ -31,22 +35,47 @@
                 virtual-scroll-item-size="80"
                 virtual-scroll-item-size="80"
                 @virtual-scroll="onScroll"
                 @virtual-scroll="onScroll"
             >
             >
-                <div class="table-row row" :class="{even: index % 2 > 0, 'active-book': item.active}">
-                    <div class="row-part row justify-center items-center" style="width: 80px">
-                        {{ item.num }}
+                <div class="table-row row" :class="{even: index % 2 > 0, 'active-book': item.active, 'active-parent-book': item.activeParent}">
+                    <div v-show="item.inGroup" class="row-part column justify-center items-center" style="width: 40px; border-right: 1px solid #cccccc">                        
+                        <q-icon name="la la-code-branch" size="24px" style="color: green" />
+                    </div>
+
+                    <div class="row-part column justify-center items-stretch" style="width: 80px">
+                        <div class="col row justify-center items-center clickable" @click="loadBook(item)">
+                            <q-icon name="la la-book" size="40px" style="color: #dddddd" />
+                        </div>
+
+                        <div v-show="!showSameBook && item.group && item.group.length > 0" class="row justify-center" style="font-size: 70%">
+                            {{ (item.group ? item.group.length + 1 : 0) }} верси{{ wordEnding((item.group ? item.group.length : 0), 1) }}
+                        </div>
                     </div>
                     </div>
 
 
-                    <div class="row-part column items-stretch break-word clickable" style="width: 350px; font-size: 80%" @click="loadBook(item)">
-                        <div class="column col">
+                    <div class="row-part column items-stretch clickable" :style="{ 'width': (350 - 40*(+item.inGroup)) + 'px' }" style="font-size: 75%" @click="loadBook(item)">
+                        <div class="row" style="font-size: 90%">
+                            <div class="row justify-center row-info-panel" style="width: 40px">
+                                {{ item.num }}
+                            </div>
+                            <div class="row justify-center row-info-panel" style="width: 130px">
+                                Чит: {{ item.touchTime }}
+                            </div>
+                            <div class="row justify-center row-info-panel" style="width: 130px">
+                                Загр: {{ item.addTime }}
+                            </div>
+                            <div class="row justify-center row-info-panel" style="width: 1px">
+                            </div>
+                        </div>
+
+                        <div class="column col q-mt-xs break-word">
                             <div style="color: green">
                             <div style="color: green">
                                 {{ item.desc.author }}
                                 {{ item.desc.author }}
                             </div>
                             </div>
                             <div>{{ item.desc.title }}</div>
                             <div>{{ item.desc.title }}</div>
                         </div>
                         </div>
-                        <div class="read-bar" :style="`width: ${340*item.readPart}px`"></div>
+
+                        <div class="read-bar" :style="`width: ${(340 - 40*(+item.inGroup))*item.readPart}px`"></div>
                     </div>
                     </div>
 
 
-                    <div class="row-part column justify-center" style="width: 80px; font-size: 80%">
+                    <div class="row-part column justify-center" style="width: 80px; font-size: 75%">
                         <a v-show="isUrl(item.url)" :href="item.url" target="_blank">Оригинал</a><br>
                         <a v-show="isUrl(item.url)" :href="item.url" target="_blank">Оригинал</a><br>
                         <a :href="item.path" @click.prevent="downloadBook(item.path, item.fullTitle)">Скачать FB2</a>
                         <a :href="item.path" @click.prevent="downloadBook(item.path, item.fullTitle)">Скачать FB2</a>
                     </div>
                     </div>
@@ -155,7 +184,7 @@
 import vueComponent from '../../vueComponent.js';
 import vueComponent from '../../vueComponent.js';
 
 
 import path from 'path-browserify';
 import path from 'path-browserify';
-//import _ from 'lodash';
+import _ from 'lodash';
 
 
 import * as utils from '../../../share/utils';
 import * as utils from '../../../share/utils';
 import LockQueue from '../../../share/LockQueue';
 import LockQueue from '../../../share/LockQueue';
@@ -168,9 +197,12 @@ const componentOptions = {
         Window,
         Window,
     },
     },
     watch: {
     watch: {
-        search: function() {
+        search() {
             this.updateTableData();
             this.updateTableData();
-        }
+        },
+        settings() {
+            this.loadSettings();
+        },
     },
     },
 };
 };
 class RecentBooksPage {
 class RecentBooksPage {
@@ -180,12 +212,17 @@ class RecentBooksPage {
     search = '';
     search = '';
     tableData = [];
     tableData = [];
     sortMethod = '';
     sortMethod = '';
+    showSameBook = false;
 
 
     created() {
     created() {
+        this.commit = this.$store.commit;
+
         this.lastScrollTop1 = 0;
         this.lastScrollTop1 = 0;
         this.lastScrollTop2 = 0;
         this.lastScrollTop2 = 0;
 
 
         this.lock = new LockQueue(100);
         this.lock = new LockQueue(100);
+
+        this.loadSettings();
     }
     }
 
 
     init() {
     init() {
@@ -198,6 +235,16 @@ class RecentBooksPage {
         this.updateTableData();//no await
         this.updateTableData();//no await
     }
     }
 
 
+    loadSettings() {
+        const settings = this.settings;
+        this.showSameBook = settings.recentShowSameBook;
+        this.sortMethod = settings.recentSortMethod || 'addTimeDesc';
+    }
+
+    get settings() {
+        return this.$store.state.reader.settings;
+    }
+
     async updateTableData() {
     async updateTableData() {
         await this.lock.get();
         await this.lock.get();
         try {
         try {
@@ -214,6 +261,8 @@ class RecentBooksPage {
                 let d = new Date();
                 let d = new Date();
                 d.setTime(book.touchTime);
                 d.setTime(book.touchTime);
                 const touchTime = utils.formatDate(d);
                 const touchTime = utils.formatDate(d);
+                d.setTime(book.addTime);
+                const addTime = utils.formatDate(d);
 
 
                 let readPart = 0;
                 let readPart = 0;
                 let perc = '';
                 let perc = '';
@@ -233,6 +282,7 @@ class RecentBooksPage {
 
 
                 result.push({
                 result.push({
                     touchTime,
                     touchTime,
+                    addTime,
                     desc: {
                     desc: {
                         author,
                         author,
                         title: `${title}${perc}${textLen}`,
                         title: `${title}${perc}${textLen}`,
@@ -244,6 +294,8 @@ class RecentBooksPage {
                     key: book.key,
                     key: book.key,
                     sameBookKey: book.sameBookKey,
                     sameBookKey: book.sameBookKey,
                     active: (activeBook.key == book.key),
                     active: (activeBook.key == book.key),
+                    activeParent: false,
+                    inGroup: false,
 
 
                     //для сортировки
                     //для сортировки
                     addTimeRaw: book.addTime,
                     addTimeRaw: book.addTime,
@@ -290,14 +342,21 @@ class RecentBooksPage {
 
 
             //группировка
             //группировка
             const groups = {};
             const groups = {};
-            const newResult = [];
+            const parents = {};
+            let newResult = [];
             for (const book of result) {
             for (const book of result) {
                 if (book.sameBookKey !== undefined) {
                 if (book.sameBookKey !== undefined) {
                     if (!groups[book.sameBookKey]) {
                     if (!groups[book.sameBookKey]) {
                         groups[book.sameBookKey] = [];
                         groups[book.sameBookKey] = [];
+                        parents[book.sameBookKey] = book;
+
                         book.group = groups[book.sameBookKey];
                         book.group = groups[book.sameBookKey];
                         newResult.push(book);
                         newResult.push(book);
                     } else {
                     } else {
+                        book.inGroup = true;
+                        if (book.active)
+                            parents[book.sameBookKey].activeParent = true;
+
                         groups[book.sameBookKey].push(book);
                         groups[book.sameBookKey].push(book);
                     }
                     }
                 } else {
                 } else {
@@ -306,6 +365,21 @@ class RecentBooksPage {
             }
             }
             result = newResult;
             result = newResult;
 
 
+            //showSameBook
+            if (this.showSameBook) {
+                newResult = [];
+                for (const book of result) {
+                    newResult.push(book);
+                    if (book.group) {
+                        for (const sameBook of book.group) {
+                            newResult.push(sameBook);
+                        }
+                    }
+                }
+
+                result = newResult;
+            }
+
             //другие стадии
             //другие стадии
             //.....
             //.....
 
 
@@ -388,13 +462,16 @@ class RecentBooksPage {
         this.$refs.input.focus();
         this.$refs.input.focus();
     }
     }
 
 
-    wordEnding(num) {
-        const endings = ['ов', '', 'а', 'а', 'а', 'ов', 'ов', 'ов', 'ов', 'ов'];
+    wordEnding(num, type = 0) {
+        const endings = [
+            ['ов', '', 'а', 'а', 'а', 'ов', 'ов', 'ов', 'ов', 'ов'],
+            ['й', 'я', 'и', 'и', 'и', 'й', 'й', 'й', 'й', 'й']
+        ];
         const deci = num % 100;
         const deci = num % 100;
         if (deci > 10 && deci < 20) {
         if (deci > 10 && deci < 20) {
-            return 'ов';
+            return endings[type][0];
         } else {
         } else {
-            return endings[num % 10];
+            return endings[type][num % 10];
         }
         }
     }
     }
 
 
@@ -463,6 +540,16 @@ class RecentBooksPage {
         this.lastScrollTop2 = curScrollTop;
         this.lastScrollTop2 = curScrollTop;
     }
     }
 
 
+    showSameBookClick() {
+        this.showSameBook = !this.showSameBook;
+
+        const newSettings = _.cloneDeep(this.settings);
+        newSettings.recentShowSameBook = this.showSameBook;
+        this.commit('reader/setSettings', newSettings);
+
+        this.updateTableData();
+    }
+
     close() {
     close() {
         this.$emit('recent-books-close');
         this.$emit('recent-books-close');
     }
     }
@@ -508,7 +595,7 @@ export default vueComponent(RecentBooksPage);
 }
 }
 
 
 .break-word {
 .break-word {
-    line-height: 150%;
+    line-height: 180%;
     overflow-wrap: break-word;
     overflow-wrap: break-word;
     word-wrap: break-word;
     word-wrap: break-word;
     white-space: normal;
     white-space: normal;
@@ -517,13 +604,32 @@ export default vueComponent(RecentBooksPage);
 .read-bar {
 .read-bar {
     height: 3px;
     height: 3px;
     background-color: #aaaaaa;
     background-color: #aaaaaa;
+    margin-bottom: 2px;
 }
 }
 
 
 .even {
 .even {
-    background-color: #f0f0f0;
+    background-color: #f2f2f2;
 }
 }
 
 
 .active-book {
 .active-book {
     background-color: #b0f0b0 !important;
     background-color: #b0f0b0 !important;
 }
 }
+
+.active-parent-book {
+    background-color: #ffbbbb !important;
+}
+
+.icon {
+    transition: transform 0.2s;
+}
+
+.expanded-icon {
+    transform: rotate(90deg);
+}
+
+.row-info-panel {
+    line-height: 110%;
+    border-left: 1px solid #cccccc;
+    border-bottom: 1px solid #cccccc;
+}
 </style>
 </style>

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

@@ -188,6 +188,9 @@ const settingDefaults = {
     toolBarHideOnScroll: true,
     toolBarHideOnScroll: true,
     userHotKeys: {},
     userHotKeys: {},
     userWallpapers: [],
     userWallpapers: [],
+
+    recentShowSameBook: false,
+    recentSortMethod: '',
 };
 };
 
 
 for (const font of fonts)
 for (const font of fonts)