diff --git a/client/components/Search/Search.vue b/client/components/Search/Search.vue
index 3692567..9405510 100644
--- a/client/components/Search/Search.vue
+++ b/client/components/Search/Search.vue
@@ -151,6 +151,7 @@
+
@@ -168,6 +169,7 @@ import vueComponent from '../vueComponent.js';
import { reactive } from 'vue';
import PageScroller from './PageScroller/PageScroller.vue';
+import authorBooksStorage from './authorBooksStorage';
import DivBtn from '../share/DivBtn.vue';
import Dialog from '../share/Dialog.vue';
@@ -218,6 +220,9 @@ const componentOptions = {
showDeleted(newValue) {
this.setSetting('showDeleted', newValue);
},
+ abCacheEnabled(newValue) {
+ this.setSetting('abCacheEnabled', newValue);
+ },
totalFound() {
this.updatePageCount();
},
@@ -250,11 +255,13 @@ class Search {
expanded = [];
showCounts = true;
showDeleted = false;
+ abCacheEnabled = true;
//stuff
queryFound = -1;
totalFound = 0;
bookRowsOnPage = 100;
+ inpxHash = '';
limitOptions = [
{label: '10', value: 10},
@@ -276,13 +283,17 @@ class Search {
}
mounted() {
- this.api = this.$root.api;
+ (async() => {
+ await authorBooksStorage.init();
- if (!this.$root.isMobileDevice)
- this.$refs.authorInput.focus();
+ this.api = this.$root.api;
- this.ready = true;
- this.refresh();//no await
+ if (!this.$root.isMobileDevice)
+ this.$refs.authorInput.focus();
+
+ this.ready = true;
+ this.refresh();//no await
+ })();
}
loadSettings() {
@@ -290,7 +301,9 @@ class Search {
this.limit = settings.limit;
this.expanded = _.cloneDeep(settings.expanded);
+ this.showCounts = settings.showCounts;
this.showDeleted = settings.showDeleted;
+ this.abCacheEnabled = settings.abCacheEnabled;
}
get config() {
@@ -438,9 +451,23 @@ class Search {
return `(${result})`;
}
- async loadBooks(author, authorId) {
+ async loadBooks(authorId) {
try {
- const result = await this.api.getBookList(authorId);
+ let result;
+
+ const key = `${authorId}-${this.inpxHash}`;
+
+ if (this.abCacheEnabled) {
+ const data = await authorBooksStorage.getData(key);
+ if (data) {
+ result = JSON.parse(data);
+ } else {
+ result = await this.api.getBookList(authorId);
+ await authorBooksStorage.setData(key, JSON.stringify(result));
+ }
+ } else {
+ result = await this.api.getBookList(authorId);
+ }
return JSON.parse(result.books);
} catch (e) {
@@ -470,7 +497,7 @@ class Search {
})();
}
- const loadedBooks = await this.loadBooks(item.author, item.key);
+ const loadedBooks = await this.loadBooks(item.key);
const filtered = this.filterBooks(loadedBooks);
@@ -561,6 +588,7 @@ class Search {
this.queryFound = result.author.length;
this.totalFound = result.totalFound;
+ this.inpxHash = result.inpxHash;
this.searchResult = result;
await this.updateTableData();
diff --git a/client/components/Search/authorBooksStorage.js b/client/components/Search/authorBooksStorage.js
new file mode 100644
index 0000000..b7a85bc
--- /dev/null
+++ b/client/components/Search/authorBooksStorage.js
@@ -0,0 +1,74 @@
+import localForage from 'localforage';
+//import _ from 'lodash';
+import * as utils from '../../share/utils';
+
+const maxDataSize = 100*1024*1024;
+
+const abStore = localForage.createInstance({
+ name: 'authorBooksStorage'
+});
+
+class AuthorBooksStorage {
+ constructor() {
+ }
+
+ async init() {
+ this.cleanStorage(); //no await
+ }
+
+ async setData(key, data) {
+ if (typeof data !== 'string')
+ throw new Error('AuthorBooksStorage: data must be a string');
+
+ await abStore.setItem(key, data);
+ await abStore.setItem(`addTime-${key}`, Date.now());
+ }
+
+ async getData(key) {
+ const item = await abStore.getItem(key);
+
+ //обновим addTime
+ if (item !== undefined)
+ abStore.setItem(`addTime-${key}`, Date.now());//no await
+
+ return item;
+ }
+
+ async removeData(key) {
+ await abStore.removeItem(key);
+ await abStore.removeItem(`addTime-${key}`);
+ }
+
+ async cleanStorage() {
+ await utils.sleep(5000);
+
+ while (1) {// eslint-disable-line no-constant-condition
+ let size = 0;
+ let min = Date.now();
+ let toDel = null;
+ for (const key of (await abStore.keys())) {
+ if (key.indexOf('addTime-') == 0)
+ continue;
+
+ const item = await abStore.getItem(key);
+ const addTime = await abStore.getItem(`addTime-${key}`);
+
+ size += item.length;
+
+ if (addTime < min) {
+ toDel = key;
+ min = addTime;
+ }
+ }
+
+ if (size > maxDataSize && toDel) {
+ await this.removeData(toDel);
+ } else {
+ break;
+ }
+ }
+ }
+
+}
+
+export default new AuthorBooksStorage();
\ No newline at end of file
diff --git a/client/store/root.js b/client/store/root.js
index b7cac00..b7c49a9 100644
--- a/client/store/root.js
+++ b/client/store/root.js
@@ -6,6 +6,7 @@ const state = {
expanded: [],
showCounts: true,
showDeleted: false,
+ abCacheEnabled: true,
},
};