diff --git a/client/api/reader.js b/client/api/reader.js index c83df6eb..28f2de07 100644 --- a/client/api/reader.js +++ b/client/api/reader.js @@ -12,6 +12,7 @@ const workerApi = axios.create({ class Reader { async loadBook(url, callback) { const refreshPause = 200; + if (!callback) callback = () => {}; let response = await api.post('/load-book', {type: 'url', url}); @@ -19,22 +20,14 @@ class Reader { if (!workerId) throw new Error('Неверный ответ api'); + callback({totalSteps: 4}); + let i = 0; while (1) {// eslint-disable-line no-constant-condition - if (callback) - callback(response.data); - if (response.data.state == 'finish') {//воркер закончил работу, можно скачивать - const options = { - onDownloadProgress: progress => { - if (callback) - callback(Object.assign({}, - response.data, - {state: 'loading', step: 4, progress: Math.round((progress.loaded*100)/progress.total)} - )); - } - } - //загрузка - const book = await axios.get(response.data.path, options); + callback(response.data); + + if (response.data.state == 'finish') {//воркер закончил работу, можно скачивать кешированный на сервере файл + const book = await this.loadCachedBook(response.data.path, callback); return Object.assign({}, response.data, {data: book.data}); } if (response.data.state == 'error') { @@ -50,7 +43,7 @@ class Reader { await sleep(refreshPause); i++; - if (i > 30*1000/refreshPause) { + if (i > 30*1000/refreshPause) {//30 сек ждем телодвижений воркера throw new Error('Слишком долгое время ожидания'); } //проверка воркера @@ -59,6 +52,17 @@ class Reader { i = (prevProgress != response.data.progress ? 1 : i); } } + + async loadCachedBook(url, callback){ + const options = { + onDownloadProgress: progress => { + if (callback) + callback({state: 'loading', step: 4, progress: Math.round((progress.loaded*100)/progress.total)}); + } + } + //загрузка + return await axios.get(url, options); + } } export default new Reader(); \ No newline at end of file diff --git a/client/components/Reader/Reader.vue b/client/components/Reader/Reader.vue index 348050b8..8273216c 100644 --- a/client/components/Reader/Reader.vue +++ b/client/components/Reader/Reader.vue @@ -233,15 +233,18 @@ class Reader extends Vue { progress.show(); progress.setState({state: 'parse'}); + // есть ли среди истории OpenedBook const key = bookManager.keyFromUrl(opts.url); let wasOpened = this.reader.openedBook[key]; wasOpened = (wasOpened ? wasOpened : {}); const bookPos = (opts.bookPos !== undefined ? opts.bookPos : wasOpened.bookPos); + // пытаемся загрузить и распарсить книгу в менеджере из локального кеша const bookParsed = await bookManager.getBook({url: opts.url}, (prog) => { progress.setState({progress: prog}); }); + // если есть в локальном кеше if (bookParsed) { this.commit('reader/setOpenedBook', Object.assign({bookPos}, bookManager.metaOnly(bookParsed))); this.loaderActive = false; @@ -249,17 +252,36 @@ class Reader extends Vue { return; } + // иначе идем на сервер + let book = null; progress.setState({totalSteps: 5}); - const book = await readerApi.loadBook(opts.url, (state) => { - progress.setState(state); - }); + // пытаемся загрузить готовый файл с сервера + if (wasOpened.path) { + try { + const resp = await readerApi.loadCachedBook(wasOpened.path, (state) => { + progress.setState(state); + }); + book = Object.assign({}, wasOpened, {data: resp.data}); + } catch (e) { + //молчим + } + } + // не удалось, скачиваем книгу полностью с конвертацией + if (!book) { + book = await readerApi.loadBook(opts.url, (state) => { + progress.setState(state); + }); + } + + // добавляем в bookManager progress.setState({state: 'parse', step: 5}); const addedBook = await bookManager.addBook(book, (prog) => { progress.setState({progress: prog}); }); + // добавляем в историю this.commit('reader/setOpenedBook', Object.assign({bookPos}, bookManager.metaOnly(addedBook))); this.updateRoute(true);