Перенес управление и хранение recentBooks из vuex в bookManager
This commit is contained in:
@@ -99,26 +99,34 @@ import _ from 'lodash';
|
|||||||
|
|
||||||
import {formatDate} from '../../../share/utils';
|
import {formatDate} from '../../../share/utils';
|
||||||
import Window from '../../share/Window.vue';
|
import Window from '../../share/Window.vue';
|
||||||
|
import bookManager from '../share/bookManager';
|
||||||
|
|
||||||
export default @Component({
|
export default @Component({
|
||||||
components: {
|
components: {
|
||||||
Window,
|
Window,
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
search: function() {
|
||||||
|
this.updateTableData();
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
class HistoryPage extends Vue {
|
class HistoryPage extends Vue {
|
||||||
search = null;
|
search = null;
|
||||||
|
tableData = null;
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.commit = this.$store.commit;
|
|
||||||
this.reader = this.$store.state.reader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get tableData() {
|
mounted() {
|
||||||
const state = this.reader;
|
this.updateTableData();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTableData() {
|
||||||
let result = [];
|
let result = [];
|
||||||
|
|
||||||
for (let bookKey in state.openedBook) {
|
for (let bookKey in bookManager.recent) {
|
||||||
const book = state.openedBook[bookKey];
|
const book = bookManager.recent[bookKey];
|
||||||
let d = new Date();
|
let d = new Date();
|
||||||
d.setTime(book.touchTime);
|
d.setTime(book.touchTime);
|
||||||
const t = formatDate(d).split(' ');
|
const t = formatDate(d).split(' ');
|
||||||
@@ -151,7 +159,7 @@ class HistoryPage extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const search = this.search;
|
const search = this.search;
|
||||||
return result.filter(item => {
|
this.tableData = result.filter(item => {
|
||||||
return !search ||
|
return !search ||
|
||||||
item.touchTime.includes(search) ||
|
item.touchTime.includes(search) ||
|
||||||
item.touchDate.includes(search) ||
|
item.touchDate.includes(search) ||
|
||||||
@@ -184,8 +192,9 @@ class HistoryPage extends Vue {
|
|||||||
window.open(path, '_blank');
|
window.open(path, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDel(key) {
|
async handleDel(key) {
|
||||||
this.commit('reader/delOpenedBook', {key});
|
await bookManager.delRecentBook({key});
|
||||||
|
this.updateTableData();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBook(url) {
|
loadBook(url) {
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export default @Component({
|
|||||||
if (textPage.bookPos != newValue) {
|
if (textPage.bookPos != newValue) {
|
||||||
textPage.bookPos = newValue;
|
textPage.bookPos = newValue;
|
||||||
}
|
}
|
||||||
this.debouncedCommitOpenedBook(newValue);
|
this.debouncedSetRecentBook(newValue);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
routeParamPos: function(newValue) {
|
routeParamPos: function(newValue) {
|
||||||
@@ -116,7 +116,7 @@ export default @Component({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
routeParamUrl: function(newValue) {
|
routeParamUrl: function(newValue) {
|
||||||
if (newValue !== '' && newValue !== this.lastOpenedBook.url) {
|
if (newValue !== '' && newValue !== this.mostRecentBook().url) {
|
||||||
this.loadBook({url: newValue, bookPos: this.routeParamPos});
|
this.loadBook({url: newValue, bookPos: this.routeParamPos});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -155,9 +155,10 @@ class Reader extends Vue {
|
|||||||
this.updateRoute();
|
this.updateRoute();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
this.debouncedCommitOpenedBook = _.debounce((newValue) => {
|
this.debouncedSetRecentBook = _.debounce(async(newValue) => {
|
||||||
if (this.lastOpenedBook && this.lastOpenedBook.bookPos != newValue) {
|
const recent = this.mostRecentBook();
|
||||||
this.commit('reader/setOpenedBook', Object.assign({}, this.lastOpenedBook, {bookPos: newValue, bookPosSeen: this.bookPosSeen}));
|
if (recent && recent.bookPos != newValue) {
|
||||||
|
await bookManager.setRecentBook(Object.assign({}, recent, {bookPos: newValue, bookPosSeen: this.bookPosSeen}));
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
@@ -169,14 +170,11 @@ class Reader extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
/*while (this.lastOpenedBook) {
|
|
||||||
this.commit('reader/delOpenedBook', this.lastOpenedBook);
|
|
||||||
}*/
|
|
||||||
if (this.$root.rootRoute == '/reader') {
|
if (this.$root.rootRoute == '/reader') {
|
||||||
if (this.routeParamUrl) {
|
if (this.routeParamUrl) {
|
||||||
this.loadBook({url: this.routeParamUrl, bookPos: this.routeParamPos});
|
this.loadBook({url: this.routeParamUrl, bookPos: this.routeParamPos});
|
||||||
} else if (this.lastOpenedBook) {
|
} else if (this.mostRecentBook()) {
|
||||||
this.loadBook({url: this.lastOpenedBook.url});
|
this.loadBook({url: this.this.mostRecentBook().url});
|
||||||
} else {
|
} else {
|
||||||
this.loaderActive = true;
|
this.loaderActive = true;
|
||||||
}
|
}
|
||||||
@@ -197,10 +195,11 @@ class Reader extends Vue {
|
|||||||
|
|
||||||
updateRoute(isNewRoute) {
|
updateRoute(isNewRoute) {
|
||||||
const pos = (this.bookPos != undefined && this.allowUrlParamBookPos ? `__p=${this.bookPos}&` : '');
|
const pos = (this.bookPos != undefined && this.allowUrlParamBookPos ? `__p=${this.bookPos}&` : '');
|
||||||
|
const url = (this.mostRecentBook() ? `url=${this.mostRecentBook().url}` : '');
|
||||||
if (isNewRoute)
|
if (isNewRoute)
|
||||||
this.$router.push(`/reader?${pos}url=${this.lastOpenedBook.url}`);
|
this.$router.push(`/reader?${pos}${url}`);
|
||||||
else
|
else
|
||||||
this.$router.replace(`/reader?${pos}url=${this.lastOpenedBook.url}`);
|
this.$router.replace(`/reader?${pos}${url}`);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,8 +225,8 @@ class Reader extends Vue {
|
|||||||
return this.reader.toolBarActive;
|
return this.reader.toolBarActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
get lastOpenedBook() {
|
mostRecentBook() {
|
||||||
const result = this.$store.getters['reader/lastOpenedBook'];
|
const result = bookManager.mostRecentBook();
|
||||||
if (!result)
|
if (!result)
|
||||||
this.closeAllTextPages();
|
this.closeAllTextPages();
|
||||||
return result;
|
return result;
|
||||||
@@ -281,13 +280,13 @@ class Reader extends Vue {
|
|||||||
|
|
||||||
setPositionToggle() {
|
setPositionToggle() {
|
||||||
this.setPositionActive = !this.setPositionActive;
|
this.setPositionActive = !this.setPositionActive;
|
||||||
if (this.setPositionActive && this.activePage == 'TextPage' && this.lastOpenedBook) {
|
if (this.setPositionActive && this.activePage == 'TextPage' && this.mostRecentBook()) {
|
||||||
this.closeAllTextPages();
|
this.closeAllTextPages();
|
||||||
this.setPositionActive = true;
|
this.setPositionActive = true;
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.setPositionPage.sliderMax = this.lastOpenedBook.textLength - 1;
|
this.$refs.setPositionPage.sliderMax = this.mostRecentBook().textLength - 1;
|
||||||
this.$refs.setPositionPage.sliderValue = this.lastOpenedBook.bookPos;
|
this.$refs.setPositionPage.sliderValue = this.mostRecentBook().bookPos;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setPositionActive = false;
|
this.setPositionActive = false;
|
||||||
@@ -329,7 +328,7 @@ class Reader extends Vue {
|
|||||||
searchToggle() {
|
searchToggle() {
|
||||||
this.searchActive = !this.searchActive;
|
this.searchActive = !this.searchActive;
|
||||||
const page = this.$refs.page;
|
const page = this.$refs.page;
|
||||||
if (this.searchActive && this.activePage == 'TextPage' && page.parsed && this.lastOpenedBook) {
|
if (this.searchActive && this.activePage == 'TextPage' && page.parsed && this.mostRecentBook()) {
|
||||||
this.closeAllTextPages();
|
this.closeAllTextPages();
|
||||||
this.searchActive = true;
|
this.searchActive = true;
|
||||||
|
|
||||||
@@ -383,8 +382,8 @@ class Reader extends Vue {
|
|||||||
this.historyToggle();
|
this.historyToggle();
|
||||||
break;
|
break;
|
||||||
case 'refresh':
|
case 'refresh':
|
||||||
if (this.lastOpenedBook) {
|
if (this.mostRecentBook()) {
|
||||||
this.loadBook({url: this.lastOpenedBook.url, force: true});
|
this.loadBook({url: this.mostRecentBook().url, force: true});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'settings':
|
case 'settings':
|
||||||
@@ -413,7 +412,7 @@ class Reader extends Vue {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.activePage == 'LoaderPage' || !this.lastOpenedBook) {
|
if (this.activePage == 'LoaderPage' || !this.mostRecentBook()) {
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case 'undoAction':
|
case 'undoAction':
|
||||||
case 'redoAction':
|
case 'redoAction':
|
||||||
@@ -425,7 +424,7 @@ class Reader extends Vue {
|
|||||||
break;
|
break;
|
||||||
case 'history':
|
case 'history':
|
||||||
case 'refresh':
|
case 'refresh':
|
||||||
if (!this.lastOpenedBook)
|
if (!this.mostRecentBook())
|
||||||
classResult = classDisabled;
|
classResult = classDisabled;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -441,7 +440,7 @@ class Reader extends Vue {
|
|||||||
result = 'ProgressPage';
|
result = 'ProgressPage';
|
||||||
else if (this.loaderActive)
|
else if (this.loaderActive)
|
||||||
result = 'LoaderPage';
|
result = 'LoaderPage';
|
||||||
else if (this.lastOpenedBook)
|
else if (this.mostRecentBook())
|
||||||
result = 'TextPage';
|
result = 'TextPage';
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -456,7 +455,7 @@ class Reader extends Vue {
|
|||||||
if (this.lastActivePage != result && result == 'TextPage') {
|
if (this.lastActivePage != result && result == 'TextPage') {
|
||||||
//акивируем страницу с текстом
|
//акивируем страницу с текстом
|
||||||
this.$nextTick(async() => {
|
this.$nextTick(async() => {
|
||||||
const last = this.lastOpenedBook;
|
const last = this.mostRecentBook();
|
||||||
|
|
||||||
const isParsed = await bookManager.hasBookParsed(last);
|
const isParsed = await bookManager.hasBookParsed(last);
|
||||||
if (!isParsed) {
|
if (!isParsed) {
|
||||||
@@ -489,9 +488,9 @@ class Reader extends Vue {
|
|||||||
progress.show();
|
progress.show();
|
||||||
progress.setState({state: 'parse'});
|
progress.setState({state: 'parse'});
|
||||||
|
|
||||||
// есть ли среди истории OpenedBook
|
// есть ли среди недавних
|
||||||
const key = bookManager.keyFromUrl(opts.url);
|
const key = bookManager.keyFromUrl(opts.url);
|
||||||
let wasOpened = this.reader.openedBook[key];
|
let wasOpened = bookManager.getRecentBook({key});
|
||||||
wasOpened = (wasOpened ? wasOpened : {});
|
wasOpened = (wasOpened ? wasOpened : {});
|
||||||
const bookPos = (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPos);
|
const bookPos = (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPos);
|
||||||
const bookPosSeen = (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPosSeen);
|
const bookPosSeen = (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPosSeen);
|
||||||
@@ -506,7 +505,7 @@ class Reader extends Vue {
|
|||||||
|
|
||||||
// если есть в локальном кеше
|
// если есть в локальном кеше
|
||||||
if (bookParsed) {
|
if (bookParsed) {
|
||||||
this.commit('reader/setOpenedBook', Object.assign({bookPos, bookPosSeen}, bookManager.metaOnly(bookParsed)));
|
await bookManager.setRecentBook(Object.assign({bookPos, bookPosSeen}, bookManager.metaOnly(bookParsed)));
|
||||||
this.loaderActive = false;
|
this.loaderActive = false;
|
||||||
progress.hide(); this.progressActive = false;
|
progress.hide(); this.progressActive = false;
|
||||||
this.blinkCachedLoadMessage();
|
this.blinkCachedLoadMessage();
|
||||||
@@ -545,7 +544,7 @@ class Reader extends Vue {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// добавляем в историю
|
// добавляем в историю
|
||||||
this.commit('reader/setOpenedBook', Object.assign({bookPos, bookPosSeen}, bookManager.metaOnly(addedBook)));
|
await bookManager.setRecentBook(Object.assign({bookPos, bookPosSeen}, bookManager.metaOnly(addedBook)));
|
||||||
this.updateRoute(true);
|
this.updateRoute(true);
|
||||||
|
|
||||||
this.loaderActive = false;
|
this.loaderActive = false;
|
||||||
|
|||||||
@@ -13,12 +13,17 @@ const bmDataStore = localForage.createInstance({
|
|||||||
name: 'bmDataStore'
|
name: 'bmDataStore'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const bmRecentStore = localForage.createInstance({
|
||||||
|
name: 'bmRecentStore'
|
||||||
|
});
|
||||||
|
|
||||||
class BookManager {
|
class BookManager {
|
||||||
async init() {
|
async init() {
|
||||||
this.books = {};
|
this.books = {};
|
||||||
|
this.recent = {};
|
||||||
|
this.recentChanged = true;
|
||||||
|
|
||||||
const len = await bmMetaStore.length();
|
let len = await bmMetaStore.length();
|
||||||
|
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
const key = await bmMetaStore.key(i);
|
const key = await bmMetaStore.key(i);
|
||||||
const keySplit = key.split('-');
|
const keySplit = key.split('-');
|
||||||
@@ -30,6 +35,13 @@ class BookManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
len = await bmRecentStore.length();
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const key = await bmRecentStore.key(i);
|
||||||
|
let r = await bmRecentStore.getItem(key);
|
||||||
|
this.recent[r.key] = r;
|
||||||
|
}
|
||||||
|
|
||||||
await this.cleanBooks();
|
await this.cleanBooks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,6 +154,75 @@ class BookManager {
|
|||||||
return utils.stringToHex(url);
|
return utils.stringToHex(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setRecentBook(value) {
|
||||||
|
if (!this.recent)
|
||||||
|
await this.init();
|
||||||
|
const result = Object.assign({}, value, {touchTime: Date.now()});
|
||||||
|
this.recent[result.key] = result;
|
||||||
|
|
||||||
|
await bmRecentStore.setItem(result.key, result);
|
||||||
|
await this.cleanRecentBooks();
|
||||||
|
|
||||||
|
this.recentChanged = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRecentBook(value) {
|
||||||
|
if (!this.recent)
|
||||||
|
await this.init();
|
||||||
|
return this.recent[value.key];
|
||||||
|
}
|
||||||
|
|
||||||
|
async delRecentBook(value) {
|
||||||
|
if (!this.recent)
|
||||||
|
await this.init();
|
||||||
|
|
||||||
|
await bmRecentStore.removeItem(value.key);
|
||||||
|
delete this.recent[value.key];
|
||||||
|
this.recentChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async cleanRecentBooks() {
|
||||||
|
if (!this.recent)
|
||||||
|
await this.init();
|
||||||
|
|
||||||
|
if (Object.keys(this.recent).length > 3) {
|
||||||
|
let min = Date.now();
|
||||||
|
let found = null;
|
||||||
|
for (let key in this.recent) {
|
||||||
|
const book = this.recent[key];
|
||||||
|
if (book.touchTime < min) {
|
||||||
|
min = book.touchTime;
|
||||||
|
found = book;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
await this.delRecentBook(found);
|
||||||
|
await this.cleanRecentBooks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mostRecentBook() {
|
||||||
|
if (!this.recentChanged && this.mostRecentCached) {
|
||||||
|
return this.mostRecentCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
let max = 0;
|
||||||
|
let result = null;
|
||||||
|
for (let key in this.recent) {
|
||||||
|
const book = this.recent[key];
|
||||||
|
if (book.touchTime > max) {
|
||||||
|
max = book.touchTime;
|
||||||
|
result = book;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.mostRecentCached = result;
|
||||||
|
this.recentChanged = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new BookManager();
|
export default new BookManager();
|
||||||
@@ -168,64 +168,20 @@ for (const font of webFonts)
|
|||||||
// initial state
|
// initial state
|
||||||
const state = {
|
const state = {
|
||||||
toolBarActive: true,
|
toolBarActive: true,
|
||||||
openedBook: {},
|
|
||||||
settings: Object.assign({}, settingDefaults),
|
settings: Object.assign({}, settingDefaults),
|
||||||
};
|
};
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
const getters = {
|
const getters = {};
|
||||||
lastOpenedBook: (state) => {
|
|
||||||
let max = 0;
|
|
||||||
let result = null;
|
|
||||||
for (let bookKey in state.openedBook) {
|
|
||||||
const book = state.openedBook[bookKey];
|
|
||||||
if (book.touchTime > max) {
|
|
||||||
max = book.touchTime;
|
|
||||||
result = book;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
const actions = {};
|
const actions = {};
|
||||||
|
|
||||||
function delBook(state, value) {
|
|
||||||
Vue.delete(state.openedBook, value.key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanBooks(state) {
|
|
||||||
if (Object.keys(state.openedBook).length > 100) {
|
|
||||||
let min = Date.now();
|
|
||||||
let found = null;
|
|
||||||
for (let bookKey in state.openedBook) {
|
|
||||||
const book = state.openedBook[bookKey];
|
|
||||||
if (book.touchTime < min) {
|
|
||||||
min = book.touchTime;
|
|
||||||
found = book;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
delBook(state, found);
|
|
||||||
cleanBooks(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mutations
|
// mutations
|
||||||
const mutations = {
|
const mutations = {
|
||||||
setToolBarActive(state, value) {
|
setToolBarActive(state, value) {
|
||||||
state.toolBarActive = value;
|
state.toolBarActive = value;
|
||||||
},
|
},
|
||||||
setOpenedBook(state, value) {
|
|
||||||
Vue.set(state.openedBook, value.key, Object.assign({}, value, {touchTime: Date.now()}));
|
|
||||||
cleanBooks(state);
|
|
||||||
},
|
|
||||||
delOpenedBook(state, value) {
|
|
||||||
delBook(state, value);
|
|
||||||
},
|
|
||||||
setSettings(state, value) {
|
setSettings(state, value) {
|
||||||
state.settings = Object.assign({}, state.settings, value);
|
state.settings = Object.assign({}, state.settings, value);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user