Просмотр исходного кода

Работа над ServerStorage

Book Pauk 6 лет назад
Родитель
Сommit
826ee18666

+ 52 - 17
client/components/Reader/ServerStorage/ServerStorage.vue

@@ -21,7 +21,7 @@ export default @Component({
             this.serverSyncEnabledChanged();
         },
         serverStorageKey: function() {
-            this.serverStorageKeyChanged();
+            this.serverStorageKeyChanged(true);
         },
         settings: function() {
             this.debouncedSaveSettings();
@@ -30,7 +30,7 @@ export default @Component({
             this.saveProfiles();
         },
         currentProfile: function() {
-            this.currentProfileChanged();
+            this.currentProfileChanged(true);
         },
     },
 })
@@ -58,28 +58,34 @@ class ServerStorage extends Vue {
         await this.currentProfileChanged();
     }
 
+    async generateNewServerStorageKey() {
+        const key = utils.toBase58(utils.randomArray(32));
+        this.commit('reader/setServerStorageKey', key);
+        await this.serverStorageKeyChanged();
+    }
+
     async serverSyncEnabledChanged() {
         if (this.serverSyncEnabled) {
             this.prevServerStorageKey = null;
-            await this.serverStorageKeyChanged();
+            await this.serverStorageKeyChanged(true);
         }
     }
 
-    async serverStorageKeyChanged() {
+    async serverStorageKeyChanged(force) {
         if (this.prevServerStorageKey != this.serverStorageKey) {
             this.prevServerStorageKey = this.serverStorageKey;
             this.hashedStorageKey = utils.toBase58(cryptoUtils.sha256(this.serverStorageKey));
 
-            await this.loadProfiles();
+            await this.loadProfiles(force);
             this.checkCurrentProfile();
         }
     }
 
-    async currentProfileChanged() {
+    async currentProfileChanged(force) {
         if (!this.currentProfile)
             return;
 
-        await this.loadSettings();
+        await this.loadSettings(force);
     }
 
     get serverSyncEnabled() {
@@ -140,11 +146,25 @@ class ServerStorage extends Vue {
             this.$notify.error({message});
     }
 
-    async loadSettings() {
+    async loadSettings(force) {
         if (!this.serverSyncEnabled || !this.currentProfile)
             return;
 
         const setsId = `settings-${this.currentProfile}`;
+        const oldRev = this.settingsRev[setsId] || 0;
+        //проверим ревизию на сервере
+        if (!force) {
+            try {
+                const revs = await this.storageCheck({[setsId]: {}});
+                if (revs.state == 'success' && revs.items[setsId].rev == oldRev) {
+                    return;
+                }
+            } catch(e) {
+                this.error(`Ошибка соединения с сервером: ${e.message}`);
+                return;
+            }
+        }
+
         let sets = null;
         try {
             sets = await this.storageGet({[setsId]: {}});
@@ -154,7 +174,6 @@ class ServerStorage extends Vue {
         }
 
         if (sets.state == 'success') {
-            const oldRev = this.settingsRev[setsId] || 0;
             sets = sets.items[setsId];
 
             if (sets.rev == 0)
@@ -194,7 +213,7 @@ class ServerStorage extends Vue {
                 }
 
                 if (result.state == 'reject') {
-                    await this.loadSettings();
+                    await this.loadSettings(true);
                     const newSettings = utils.applyObjDiff(this.settings, diff);
                     this.commit('reader/setSettings', newSettings);
                 }
@@ -216,10 +235,24 @@ class ServerStorage extends Vue {
         }
     }
 
-    async loadProfiles() {
+    async loadProfiles(force) {
         if (!this.serverSyncEnabled)
             return;
 
+        const oldRev = this.profilesRev;
+        //проверим ревизию на сервере
+        if (!force) {
+            try {
+                const revs = await this.storageCheck({'profiles': {}});
+                if (revs.state == 'success' && revs.items.profiles.rev == oldRev) {
+                    return;
+                }
+            } catch(e) {
+                this.error(`Ошибка соединения с сервером: ${e.message}`);
+                return;
+            }
+        }
+
         let prof = null;
         try {
             prof = await this.storageGet({'profiles': {}});
@@ -229,7 +262,6 @@ class ServerStorage extends Vue {
         }
 
         if (prof.state == 'success') {
-            const oldRev = this.profilesRev;
             prof = prof.items.profiles;
 
             if (prof.rev == 0)
@@ -253,6 +285,12 @@ class ServerStorage extends Vue {
         if (utils.isEmptyObjDiff(diff))
             return;
 
+        //обнуляются профили во время разработки, подстраховка
+        if (!this.$store.state.reader.allowProfilesSave) {
+            console.error('Сохранение профилей не санкционировано');
+            return;
+        }
+
         this.savingProfiles = true;
         try {
             let result = {state: ''};
@@ -269,7 +307,7 @@ class ServerStorage extends Vue {
                 }
 
                 if (result.state == 'reject') {
-                    await this.loadProfiles();
+                    await this.loadProfiles(true);
                     const newProfiles = utils.applyObjDiff(this.profiles, diff);
                     this.commit('reader/setProfiles', newProfiles);
                 }
@@ -291,10 +329,7 @@ class ServerStorage extends Vue {
         }
     }
 
-    async generateNewServerStorageKey() {
-        const key = utils.toBase58(utils.randomArray(32));
-        this.commit('reader/setServerStorageKey', key);
-        await this.serverStorageKeyChanged();
+    async loadRecent() {
     }
 
     async storageCheck(items) {

+ 12 - 0
client/components/Reader/SettingsPage/SettingsPage.vue

@@ -658,7 +658,11 @@ class SettingsPage extends Vue {
                     this.$alert('Такой профиль уже существует', 'Ошибка');
                 } else {
                     const newProfiles = Object.assign({}, this.profiles, {[result.value]: 1});
+                    this.commit('reader/setAllowProfilesSave', true);
+                    await this.$nextTick();//ждем обработчики watch
                     this.commit('reader/setProfiles', newProfiles);
+                    await this.$nextTick();//ждем обработчики watch
+                    this.commit('reader/setAllowProfilesSave', false);
                     this.currentProfile = result.value;
                 }
             }
@@ -686,7 +690,11 @@ class SettingsPage extends Vue {
                 if (this.profiles[this.currentProfile]) {
                     const newProfiles = Object.assign({}, this.profiles);
                     delete newProfiles[this.currentProfile];
+                    this.commit('reader/setAllowProfilesSave', true);
+                    await this.$nextTick();//ждем обработчики watch
                     this.commit('reader/setProfiles', newProfiles);
+                    await this.$nextTick();//ждем обработчики watch
+                    this.commit('reader/setAllowProfilesSave', false);
                     this.currentProfile = '';
                 }
             }
@@ -710,7 +718,11 @@ class SettingsPage extends Vue {
             });
 
             if (result.value && result.value.toLowerCase() == 'да') {
+                this.commit('reader/setAllowProfilesSave', true);
+                await this.$nextTick();//ждем обработчики watch
                 this.commit('reader/setProfiles', {});
+                await this.$nextTick();//ждем обработчики watch
+                this.commit('reader/setAllowProfilesSave', false);
                 this.currentProfile = '';
             }
         } catch (e) {

+ 41 - 1
client/components/Reader/share/bookManager.js

@@ -25,6 +25,8 @@ class BookManager {
     async init(settings) {
         this.settings = settings;
 
+        this.eventListeners = [];
+
         //bmCacheStore нужен только для ускорения загрузки читалки
         this.booksCached = await bmCacheStore.getItem('books');
         if (!this.booksCached)
@@ -33,7 +35,8 @@ class BookManager {
         this.recentLast = await bmCacheStore.getItem('recent-last');
         if (this.recentLast)
             this.recent[this.recentLast.key] = this.recentLast;
-
+        this.recentRev = bmRecentStore.getItem('recent-rev') || 0;
+        this.recentLastRev = bmRecentStore.getItem('recent-last-rev') || 0;
         this.books = Object.assign({}, this.booksCached);
 
         this.recentChanged1 = true;
@@ -255,9 +258,11 @@ class BookManager {
         //кэшируем, аккуратно
         if (!(this.recentLast && this.recentLast.key == result.key)) {
             await bmCacheStore.setItem('recent', this.recent);
+            this.emit('recent-changed');
         }
         this.recentLast = result;
         await bmCacheStore.setItem('recent-last', this.recentLast);
+        this.emit('recent-last-changed');
 
         this.recentChanged1 = true;
         this.recentChanged2 = true;
@@ -277,6 +282,7 @@ class BookManager {
         this.recent[value.key].deleted = 1;
         await bmRecentStore.setItem(value.key, this.recent[value.key].deleted);
         await bmCacheStore.setItem('recent', this.recent);
+        this.emit('recent-changed');
 
         this.recentChanged1 = true;
         this.recentChanged2 = true;
@@ -339,6 +345,40 @@ class BookManager {
         return result;
     }
 
+    setRecent(newRecent) {
+        this.recent = newRecent;
+    }
+
+    setRecentLast(newRecentLast) {
+        this.recentLast = newRecentLast;
+    }
+
+    setRecentRev(newRecentRev) {
+        bmRecentStore.setItem('recent-rev', newRecentRev);
+        this.recentRev = newRecentRev;
+    }
+
+    setRecentLastRev(newRecentLastRev) {
+        bmRecentStore.setItem('recent-last-rev', newRecentLastRev);
+        this.recentLastRev = newRecentLastRev;
+    }
+
+    addEventListener(listener) {
+        if (this.eventListeners.indexOf(listener) < 0)
+            this.eventListeners.push(listener);        
+    }
+
+    removeEventListener(listener) {
+        const i = this.eventListeners.indexOf(listener);
+        if (i >= 0)
+            this.eventListeners.splice(i, 1);
+    }
+
+    emit(eventName, value) {
+        for (const listener of this.eventListeners)
+            listener(eventName, value);
+    }
+
 }
 
 export default new BookManager();

+ 4 - 0
client/store/modules/reader.js

@@ -182,6 +182,7 @@ const state = {
     serverStorageKey: '',
     profiles: {},
     profilesRev: 0,
+    allowProfilesSave: false,//подстраховка для разработки
     currentProfile: '',
     settings: Object.assign({}, settingDefaults),
     settingsRev: {},
@@ -210,6 +211,9 @@ const mutations = {
     setProfilesRev(state, value) {
         state.profilesRev = value;
     },
+    setAllowProfilesSave(state, value) {
+        state.allowProfilesSave = value;
+    },
     setCurrentProfile(state, value) {
         state.currentProfile = value;
     },