Pārlūkot izejas kodu

Доделки сохранения recentLast

Book Pauk 6 gadi atpakaļ
vecāks
revīzija
92d929b704

+ 12 - 2
client/components/Reader/Reader.vue

@@ -203,6 +203,12 @@ class Reader extends Vue {
             await serverStorage.saveRecent();
         }, 1000);
 
+        this.debouncedSaveRecentLast = _.debounce(async() => {
+            const serverStorage = this.$refs.serverStorage;
+            while (!serverStorage.inited) await utils.sleep(1000);
+            await serverStorage.saveRecentLast();
+        }, 1000);
+
         document.addEventListener('fullscreenchange', () => {
             this.fullScreenActive = (document.fullscreenElement !== null);
         });
@@ -303,7 +309,7 @@ class Reader extends Vue {
                 this.debouncedSaveRecent();
         }
 
-        if (eventName == 'recent-changed') {
+        if (eventName == 'recent-changed' || eventName == 'save-recent') {
             (async() => {
                 const oldBook = this.mostRecentBookReactive;
                 const newBook = bookManager.mostRecentBook();
@@ -316,7 +322,11 @@ class Reader extends Vue {
                     }
                 }
 
-                this.debouncedSaveRecent();
+                if (eventName == 'recent-changed') {
+                    this.debouncedSaveRecentLast();
+                } else {
+                    this.debouncedSaveRecent();
+                }
             })();
         }
     }

+ 101 - 23
client/components/Reader/ServerStorage/ServerStorage.vue

@@ -48,6 +48,7 @@ class ServerStorage extends Vue {
         this.oldProfiles = {};
         this.oldSettings = {};
         this.oldRecent = {};
+        this.oldRecentLast = {};
     }
 
     async init() {
@@ -60,6 +61,8 @@ class ServerStorage extends Vue {
             }
             await this.currentProfileChanged();
             await this.loadRecent();
+            this.oldRecent = _.cloneDeep(bookManager.recent);
+            this.oldRecentLast = _.cloneDeep(bookManager.recentLast);
         } finally {
             this.inited = true;
         }
@@ -85,6 +88,7 @@ class ServerStorage extends Vue {
 
             await this.loadProfiles(force);
             this.checkCurrentProfile();
+            await this.loadRecent();
         }
     }
 
@@ -133,9 +137,8 @@ class ServerStorage extends Vue {
         }
     }
 
-    notifySuccessIfNeeded(rev1, rev2) {
-        if (rev1 != rev2)
-            this.success('Данные синхронизированы с сервером');
+    notifySuccess() {
+        this.success('Данные синхронизированы с сервером');
     }
 
     success(message) {
@@ -190,7 +193,7 @@ class ServerStorage extends Vue {
             this.commit('reader/setSettings', sets.data);
             this.commit('reader/setSettingsRev', {[setsId]: sets.rev});
 
-            this.notifySuccessIfNeeded(oldRev, sets.rev);
+            this.notifySuccess();
         } else {
             this.warning(`Неверный ответ сервера: ${sets.state}`);
         }
@@ -278,7 +281,7 @@ class ServerStorage extends Vue {
             this.commit('reader/setProfiles', prof.data);
             this.commit('reader/setProfilesRev', prof.rev);
 
-            this.notifySuccessIfNeeded(oldRev, prof.rev);
+            this.notifySuccess();
         } else {
             this.warning(`Неверный ответ сервера: ${prof.state}`);
         }
@@ -341,11 +344,14 @@ class ServerStorage extends Vue {
             return;
 
         const oldRev = bookManager.recentRev;
+        const oldLastRev = bookManager.recentLastRev;
         //проверим ревизию на сервере
+        let revs = null;
         if (!force) {
             try {
-                const revs = await this.storageCheck({recent: {}});
-                if (revs.state == 'success' && revs.items.recent.rev == oldRev) {
+                revs = await this.storageCheck({recent: {}, recentLast: {}});
+                if (revs.state == 'success' && revs.items.recent.rev == oldRev &&
+                    revs.items.recentLast.rev == oldLastRev) {
                     return;
                 }
             } catch(e) {
@@ -354,28 +360,53 @@ class ServerStorage extends Vue {
             }
         }
 
-        let recent = null;
-        try {
-            recent = await this.storageGet({recent: {}});
-        } catch(e) {
-            this.error(`Ошибка соединения с сервером: ${e.message}`);
-            return;
+        if (force || revs.items.recent.rev != oldRev) {
+            let recent = null;
+            try {
+                recent = await this.storageGet({recent: {}});
+            } catch(e) {
+                this.error(`Ошибка соединения с сервером: ${e.message}`);
+                return;
+            }
+
+            if (recent.state == 'success') {
+                recent = recent.items.recent;
+
+                if (recent.rev == 0)
+                    recent.data = {};
+
+                this.oldRecent = _.cloneDeep(recent.data);
+                await bookManager.setRecent(recent.data);
+                await bookManager.setRecentRev(recent.rev);
+            } else {
+                this.warning(`Неверный ответ сервера: ${recent.state}`);
+            }
         }
 
-        if (recent.state == 'success') {
-            recent = recent.items.recent;
+        if (force || revs.items.recentLast.rev != oldLastRev) {
+            let recentLast = null;
+            try {
+                recentLast = await this.storageGet({recentLast: {}});
+            } catch(e) {
+                this.error(`Ошибка соединения с сервером: ${e.message}`);
+                return;
+            }
 
-            if (recent.rev == 0)
-                recent.data = {};
+            if (recentLast.state == 'success') {
+                recentLast = recentLast.items.recentLast;
 
-            this.oldRecent = _.cloneDeep(recent.data);
-            await bookManager.setRecent(recent.data);
-            await bookManager.setRecentRev(recent.rev);
+                if (recentLast.rev == 0)
+                    recentLast.data = {};
 
-            this.notifySuccessIfNeeded(oldRev, recent.rev);
-        } else {
-            this.warning(`Неверный ответ сервера: ${recent.state}`);
+                this.oldRecentLast = _.cloneDeep(recentLast.data);
+                await bookManager.setRecentLast(recentLast.data);
+                await bookManager.setRecentLastRev(recentLast.rev);
+            } else {
+                this.warning(`Неверный ответ сервера: ${recentLast.state}`);
+            }
         }
+
+        this.notifySuccess();
     }
 
     async saveRecent() {
@@ -417,12 +448,59 @@ class ServerStorage extends Vue {
             } else {
                 this.oldRecent = _.cloneDeep(bm.recent);
                 await bm.setRecentRev(bm.recentRev + 1);
+                await this.saveRecentLast(true);
             }
         } finally {
             this.savingRecent = false;
         }
     }
 
+    async saveRecentLast(force = false) {
+        if (!this.serverSyncEnabled || this.savingRecentLast)
+            return;
+
+        const bm = bookManager;
+        let recentLast = bm.recentLast;
+        recentLast = (recentLast ? recentLast : {});
+
+        const diff = utils.getObjDiff(this.oldRecentLast, recentLast);
+        if (utils.isEmptyObjDiff(diff))
+            return;
+
+        this.savingRecentLast = true;
+        try {
+            let result = {state: ''};
+            let tries = 0;
+            while (result.state != 'success' && tries < maxSetTries) {
+                try {
+                    result = await this.storageSet({recentLast: {rev: bm.recentLastRev + 1, data: recentLast}}, force);
+                } catch(e) {
+                    this.savingRecentLast = false;
+                    this.error(`Ошибка соединения с сервером: (${e.message}). Изменения не сохранены.`);
+                    return;
+                }
+
+                if (result.state == 'reject') {
+                    await this.loadRecent(false);
+                    this.savingRecentLast = false;//!!!
+                    return;//!!!
+                }
+
+                tries++;
+            }
+
+            if (tries >= maxSetTries) {
+                console.error(result);
+                this.error('Не удалось отправить данные на сервер. Данные не сохранены и могут быть перезаписаны.');
+            } else {
+                this.oldRecentLast = _.cloneDeep(recentLast);
+                await bm.setRecentLastRev(bm.recentLastRev + 1);
+            }
+        } finally {
+            this.savingRecentLast = false;
+        }
+    }
+
     async storageCheck(items) {
         return await this.storageApi('check', items);
     }

+ 20 - 6
client/components/Reader/share/bookManager.js

@@ -83,10 +83,12 @@ class BookManager {
         len = await bmRecentStore.length();
         for (let i = 0; i < len; i++) {
             key = await bmRecentStore.key(i);
-            let r = await bmRecentStore.getItem(key);
-            if (_.isObject(r)) {
-                this.recent[r.key] = r;
-            } else {
+            if (key) {
+                let r = await bmRecentStore.getItem(key);
+                if (_.isObject(r) && r.key) {
+                    this.recent[r.key] = r;
+                }
+            } else  {
                 await bmRecentStore.removeItem(key);
             }
         }
@@ -309,7 +311,7 @@ class BookManager {
         this.mostRecentCached = null;
         this.recentChanged2 = true;
 
-        this.emit('recent-changed');
+        this.emit('save-recent');
     }
 
     async cleanRecentBooks() {
@@ -379,7 +381,7 @@ class BookManager {
         await bmCacheStore.setItem('recent', this.recent);
 
         this.recentLast = null;
-        await bmCacheStore.setItem('recent-last', null);
+        await bmCacheStore.setItem('recent-last', this.recentLast);
 
         this.mostRecentCached = null;
         this.emit('recent-changed');
@@ -391,7 +393,19 @@ class BookManager {
     }
 
     async setRecentLast(value) {
+        if (!value.key)
+            value = null;
+
         this.recentLast = value;
+        await bmCacheStore.setItem('recent-last', this.recentLast);
+        if (value && value.key) {
+            this.recent[value.key] = value;
+            await bmRecentStore.setItem(value.key, value);
+            await bmCacheStore.setItem('recent', this.recent);
+        }
+
+        this.mostRecentCached = null;
+        this.emit('recent-changed');
     }
 
     async setRecentLastRev(value) {