From f648bcda13f1f687e99d9c6a1e17cc394982daf1 Mon Sep 17 00:00:00 2001 From: Book Pauk Date: Thu, 28 Mar 2019 14:05:13 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B8,=20=D0=BE=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20recentLast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reader/ServerStorage/ServerStorage.vue | 78 ++++++++++++++++++- client/components/Reader/share/bookManager.js | 8 +- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/client/components/Reader/ServerStorage/ServerStorage.vue b/client/components/Reader/ServerStorage/ServerStorage.vue index d59b598d..fb1bc747 100644 --- a/client/components/Reader/ServerStorage/ServerStorage.vue +++ b/client/components/Reader/ServerStorage/ServerStorage.vue @@ -50,6 +50,7 @@ class ServerStorage extends Vue { this.oldSettings = {}; this.oldRecent = {}; this.oldRecentLast = {}; + this.oldRecentLastDiff = {}; } async init() { @@ -353,13 +354,15 @@ class ServerStorage extends Vue { const oldRev = bookManager.recentRev; const oldLastRev = bookManager.recentLastRev; + const oldLastDiffRev = bookManager.recentLastDiffRev; //проверим ревизию на сервере let revs = null; if (!force) { try { - revs = await this.storageCheck({recent: {}, recentLast: {}}); + revs = await this.storageCheck({recent: {}, recentLast: {}, recentLastDiff: {}}); if (revs.state == 'success' && revs.items.recent.rev == oldRev && - revs.items.recentLast.rev == oldLastRev) { + revs.items.recentLast.rev == oldLastRev && + revs.items.recentLastDiff.rev == oldLastDiffRev) { return; } } catch(e) { @@ -391,24 +394,30 @@ class ServerStorage extends Vue { } } - if (force || revs.items.recentLast.rev != oldLastRev) { + if (force || revs.items.recentLast.rev != oldLastRev || revs.items.recentLastDiff.rev != oldLastDiffRev) { let recentLast = null; try { - recentLast = await this.storageGet({recentLast: {}}); + recentLast = await this.storageGet({recentLast: {}, recentLastDiff: {}}); } catch(e) { this.error(`Ошибка соединения с сервером: ${e.message}`); return; } if (recentLast.state == 'success') { + const recentLastDiff = recentLast.items.recentLastDiff; recentLast = recentLast.items.recentLast; if (recentLast.rev == 0) recentLast.data = {}; + if (recentLastDiff.rev == 0) + recentLastDiff.data = {}; + + recentLast.data = utils.applyObjDiff(recentLast.data, recentLastDiff.data); this.oldRecentLast = _.cloneDeep(recentLast.data); await bookManager.setRecentLast(recentLast.data); await bookManager.setRecentLastRev(recentLast.rev); + await bookManager.setRecentLastDiffRev(recentLastDiff.rev); } else { this.warning(`Неверный ответ сервера: ${recentLast.state}`); } @@ -476,6 +485,11 @@ class ServerStorage extends Vue { if (utils.isEmptyObjDiff(diff)) return; + if (JSON.stringify(recentLast) > JSON.stringify(diff)) { + await this.saveRecentLastDiff(diff, force); + return; + } + this.savingRecentLast = true; try { let result = {state: ''}; @@ -521,6 +535,62 @@ class ServerStorage extends Vue { } } + async saveRecentLastDiff(diff, force = false) { + if (!this.keyInited || !this.serverSyncEnabled || this.savingRecentLastDiff) + return; + + const bm = bookManager; + let lastRev = bm.recentLastDiffRev; + + const d = utils.getObjDiff(this.oldRecentLastDiff, diff); + if (utils.isEmptyObjDiff(d)) + return; + + this.savingRecentLastDiff = true; + try { + let result = {state: ''}; + let tries = 0; + while (result.state != 'success' && tries < maxSetTries) { + if (force) { + try { + const revs = await this.storageCheck({recentLastDiff: {}}); + if (revs.items.recentLastDiff.rev) + lastRev = revs.items.recentLastDiff.rev; + } catch(e) { + this.error(`Ошибка соединения с сервером: ${e.message}`); + return; + } + } + + try { + result = await this.storageSet({recentLastDiff: {rev: lastRev + 1, data: diff}}, force); + } catch(e) { + this.savingRecentLastDiff = false; + this.error(`Ошибка соединения с сервером: (${e.message}). Изменения не сохранены.`); + return; + } + + if (result.state == 'reject') { + await this.loadRecent(false); + this.savingRecentLastDiff = false; + return; + } + + tries++; + } + + if (tries >= maxSetTries) { + console.error(result); + this.error('Не удалось отправить данные на сервер. Данные не сохранены и могут быть перезаписаны.'); + } else { + this.oldRecentLastDiff = _.cloneDeep(diff); + await bm.setRecentLastDiffRev(lastRev + 1); + } + } finally { + this.savingRecentLastDiff = false; + } + } + async storageCheck(items) { return await this.storageApi('check', items); } diff --git a/client/components/Reader/share/bookManager.js b/client/components/Reader/share/bookManager.js index 59ad205e..0bb8972e 100644 --- a/client/components/Reader/share/bookManager.js +++ b/client/components/Reader/share/bookManager.js @@ -38,6 +38,7 @@ class BookManager { this.recent[this.recentLast.key] = this.recentLast; this.recentRev = await bmRecentStore.getItem('recent-rev') || 0; this.recentLastRev = await bmRecentStore.getItem('recent-last-rev') || 0; + this.recentLastDiffRev = await bmRecentStore.getItem('recent-last-diff-rev') || 0; this.books = Object.assign({}, this.booksCached); this.recentChanged2 = true; @@ -428,10 +429,15 @@ class BookManager { } async setRecentLastRev(value) { - bmRecentStore.setItem('recent-last-rev', value); + await bmRecentStore.setItem('recent-last-rev', value); this.recentLastRev = value; } + async setRecentLastDiffRev(value) { + await bmRecentStore.setItem('recent-last-diff-rev', value); + this.recentLastDiffRev = value; + } + addEventListener(listener) { if (this.eventListeners.indexOf(listener) < 0) this.eventListeners.push(listener);