@@ -138,21 +142,40 @@
-
- {{ book.title }}
-
{{ book.src }}
+
+
+
+
+
+ Серия: {{ book.series }}
+
+
+
+
+
+
+
+
+
-
- +{{ hiddenCount }} результатов скрыты
+ {{ hiddenResultsMessage }}
+
@@ -203,6 +226,7 @@ import { reactive } from 'vue';
import PageScroller from './PageScroller/PageScroller.vue';
import SelectGenreDialog from './SelectGenreDialog/SelectGenreDialog.vue';
import SelectLangDialog from './SelectLangDialog/SelectLangDialog.vue';
+import BookView from './BookView/BookView.vue';
import authorBooksStorage from './authorBooksStorage';
import DivBtn from '../share/DivBtn.vue';
@@ -218,6 +242,7 @@ const componentOptions = {
PageScroller,
SelectGenreDialog,
SelectLangDialog,
+ BookView,
Dialog,
DivBtn
},
@@ -291,6 +316,7 @@ class Search {
//settings
expanded = [];
+ expandedSeries = [];
showCounts = true;
showDeleted = false;
abCacheEnabled = true;
@@ -353,6 +379,7 @@ class Search {
this.search.limit = settings.limit;
this.expanded = _.cloneDeep(settings.expanded);
+ this.expandedSeries = _.cloneDeep(settings.expandedSeries);
this.showCounts = settings.showCounts;
this.showDeleted = settings.showDeleted;
this.abCacheEnabled = settings.abCacheEnabled;
@@ -459,6 +486,10 @@ class Search {
return `Найден${utils.wordEnding(this.totalFound, 2)} ${this.totalFound} автор${utils.wordEnding(this.totalFound)}`;
}
+ get hiddenResultsMessage() {
+ return `+${this.hiddenCount} результат${utils.wordEnding(this.hiddenCount)} скрыты`;
+ }
+
updatePageCount() {
const prevPageCount = this.pageCount;
@@ -480,35 +511,47 @@ class Search {
this.scrollToTop();
}
- selectTitle(title) {
- this.search.title = `=${title}`;
+ selectSeries(series) {
+ this.search.series = `=${series}`;
+ }
+
+ bookEvent(event) {
+ switch (event.action) {
+ case 'titleClick':
+ this.search.title = `=${event.book.title}`;
+ break;
+ }
}
isExpanded(item) {
return this.expanded.indexOf(item.author) >= 0;
}
+ isExpandedSeries(seriesItem) {
+ return this.expandedSeries.indexOf(seriesItem.key) >= 0;
+ }
+
setSetting(name, newValue) {
this.commit('setSettings', {[name]: _.cloneDeep(newValue)});
}
expandAuthor(item) {
const expanded = _.cloneDeep(this.expanded);
- const author = item.author;
+ const key = item.author;
if (!this.isExpanded(item)) {
- expanded.push(author);
+ expanded.push(key);
this.getBooks(item);
- if (expanded.length > 10) {
+ if (expanded.length > 100) {
expanded.shift();
}
this.setSetting('expanded', expanded);
this.ignoreScroll();
} else {
- const i = expanded.indexOf(author);
+ const i = expanded.indexOf(key);
if (i >= 0) {
expanded.splice(i, 1);
this.setSetting('expanded', expanded);
@@ -516,6 +559,28 @@ class Search {
}
}
+ expandSeries(seriesItem) {
+ const expandedSeries = _.cloneDeep(this.expandedSeries);
+ const key = seriesItem.key;
+
+ if (!this.isExpandedSeries(seriesItem)) {
+ expandedSeries.push(key);
+
+ if (expandedSeries.length > 100) {
+ expandedSeries.shift();
+ }
+
+ this.setSetting('expandedSeries', expandedSeries);
+ this.ignoreScroll();
+ } else {
+ const i = expandedSeries.indexOf(key);
+ if (i >= 0) {
+ expandedSeries.splice(i, 1);
+ this.setSetting('expandedSeries', expandedSeries);
+ }
+ }
+ }
+
getBookCount(item) {
let result = '';
if (!this.showCounts || item.count === undefined)
@@ -665,13 +730,56 @@ class Search {
const filtered = this.filterBooks(loadedBooks);
- filtered.sort((a, b) => a.title.localeCompare(b.title));
+ const prepareBook = (book) => {
+ return {
+ key: book.id,
+ type: 'book',
+ title: book.title,
+ series: book.series,
+ }
+ };
+ //объединение по сериям
const books = [];
+ const seriesIndex = {};
for (const book of filtered) {
- books.push({key: book.id, title: book.title, src: book});
+ if (book.series) {
+ let index = seriesIndex[book.series];
+ if (index === undefined) {
+ index = books.length;
+ books.push({
+ key: `${item.author}-${book.series}`,
+ type: 'series',
+ series: book.series,
+ books: [],
+ });
+
+ seriesIndex[book.series] = index;
+ }
+
+ books[index].books.push(prepareBook(book));
+ } else {
+ books.push(prepareBook(book));
+ }
}
+ //сортировка
+ books.sort((a, b) => {
+ if (a.type == 'series') {
+ if (b.type == 'series')
+ return a.key.localeCompare(b.key);
+ else
+ return -1;
+ } else {
+ if (b.type == 'book')
+ return a.title.localeCompare(b.title);
+ else
+ return 1;
+ }
+ });
+
+ //сортировка внутри серий
+
item.books = books;
} finally {
this.getBooksFlag--;
@@ -909,6 +1017,6 @@ export default vueComponent(Search);
}
.book-row {
- margin-left: 50px;
+ margin-left: 70px;
}
diff --git a/client/store/root.js b/client/store/root.js
index 3226b5a..c335931 100644
--- a/client/store/root.js
+++ b/client/store/root.js
@@ -4,6 +4,7 @@ const state = {
settings: {
limit: 50,
expanded: [],
+ expandedSeries: [],
showCounts: true,
showDeleted: false,
abCacheEnabled: true,