Browse Source

Работа с ServerStorage

Book Pauk 6 years ago
parent
commit
712bf405bb

+ 83 - 0
client/components/Reader/ServerStorage/ServerStorage.vue

@@ -20,9 +20,15 @@ export default @Component({
         serverStorageKey: function() {
         serverStorageKey: function() {
             this.serverStorageKeyChanged();
             this.serverStorageKeyChanged();
         },
         },
+        settings: function() {
+            this.saveSettings();
+        },
         profiles: function() {
         profiles: function() {
             this.saveProfiles();
             this.saveProfiles();
         },
         },
+        currentProfile: function() {
+            this.currentProfileChanged();
+        },
     },
     },
 })
 })
 class ServerStorage extends Vue {
 class ServerStorage extends Vue {
@@ -30,6 +36,9 @@ class ServerStorage extends Vue {
         this.commit = this.$store.commit;
         this.commit = this.$store.commit;
         this.prevServerStorageKey = null;
         this.prevServerStorageKey = null;
         this.$root.$on('generateNewServerStorageKey', () => {this.generateNewServerStorageKey()});
         this.$root.$on('generateNewServerStorageKey', () => {this.generateNewServerStorageKey()});
+
+        this.oldProfiles = {};
+        this.oldSettings = {};
     }
     }
 
 
     async init() {
     async init() {
@@ -39,6 +48,7 @@ class ServerStorage extends Vue {
         } else {
         } else {
             await this.serverStorageKeyChanged();
             await this.serverStorageKeyChanged();
         }
         }
+        await this.currentProfileChanged();
     }
     }
 
 
     async serverStorageKeyChanged() {
     async serverStorageKeyChanged() {
@@ -51,6 +61,13 @@ class ServerStorage extends Vue {
         }
         }
     }
     }
 
 
+    async currentProfileChanged() {
+        if (!this.currentProfile)
+            return;
+
+        await this.loadSettings();
+    }
+
     get serverSyncEnabled() {
     get serverSyncEnabled() {
         return this.$store.state.reader.serverSyncEnabled;
         return this.$store.state.reader.serverSyncEnabled;
     }
     }
@@ -59,6 +76,10 @@ class ServerStorage extends Vue {
         return this.$store.state.reader.settings;
         return this.$store.state.reader.settings;
     }
     }
 
 
+    get settingsRev() {
+        return this.$store.state.reader.settingsRev;
+    }
+
     get serverStorageKey() {
     get serverStorageKey() {
         return this.$store.state.reader.serverStorageKey;
         return this.$store.state.reader.serverStorageKey;
     }
     }
@@ -94,6 +115,68 @@ class ServerStorage extends Vue {
         this.$notify.error({message});
         this.$notify.error({message});
     }
     }
 
 
+    async loadSettings() {
+        if (!this.serverSyncEnabled || !this.currentProfile)
+            return;
+
+        const setsId = `settings-${this.currentProfile}`;
+        let sets = await this.storageGet({[setsId]: {}});
+
+        if (sets.state == 'success') {
+            const oldRev = this.settingsRev[setsId] || 0;
+            sets = sets.items[setsId];
+
+            if (sets.rev == 0)
+                sets.data = {};
+
+            this.oldSettings = sets.data;
+            this.commit('reader/setSettings', sets.data);
+            this.commit('reader/setSettingsRev', {[setsId]: sets.rev});
+
+            this.notifySuccessIfNeeded(oldRev, sets.rev);
+        } else {
+            this.warning(`Неверный ответ сервера: ${sets.state}`);
+        }
+    }
+
+    async saveSettings() {
+        if (!this.serverSyncEnabled || !this.currentProfile || this.savingSettings)
+            return;
+
+        const diff = utils.getObjDiff(this.oldSettings, this.settings);
+        if (utils.isEmptyObjDiff(diff))
+            return;
+
+        this.savingSettings = true;
+        try {
+            const setsId = `settings-${this.currentProfile}`;
+            let result = {state: ''};
+            let tries = 0;
+            while (result.state != 'success' && tries < maxSetTries) {
+                const oldRev = this.settingsRev[setsId] || 0;
+                result = await this.storageSet({[setsId]: {rev: oldRev + 1, data: this.settings}});
+
+                if (result.state == 'reject') {
+                    await this.loadSettings();
+                    const newSettings = utils.applyObjDiff(this.settings, diff);
+                    this.commit('reader/setSettings', newSettings);
+                }
+
+                tries++;
+            }
+
+            if (tries >= maxSetTries) {
+                this.commit('reader/setSettings', this.oldSettings);
+                this.error('Не удалось отправить данные на сервер');
+            } else {
+                this.oldSettings = this.settings;
+                this.commit('reader/setSettingsRev', {[setsId]: this.settingsRev[setsId] + 1});
+            }
+        } finally {
+            this.savingSettings = false;
+        }
+    }
+
     async loadProfiles() {
     async loadProfiles() {
         if (!this.serverSyncEnabled)
         if (!this.serverSyncEnabled)
             return;
             return;

+ 15 - 3
client/components/Reader/SettingsPage/SettingsPage.vue

@@ -99,7 +99,7 @@
                                 <div class="text">
                                 <div class="text">
                                     Рекомендуется сохранить ключ в надежном месте, чтобы всегда иметь возможность восстановить настройки,
                                     Рекомендуется сохранить ключ в надежном месте, чтобы всегда иметь возможность восстановить настройки,
                                     например, после переустановки ОС или чистки/смены браузера.<br>
                                     например, после переустановки ОС или чистки/смены браузера.<br>
-                                    <b>ПРЕДУПРЕЖДЕНИЕ!</b> При утере ключа, НИКТО не сможет восстановить ваши настройки, т.к. все данные сжимаются
+                                    <b>ПРЕДУПРЕЖДЕНИЕ!</b> При утере ключа, НИКТО не сможет восстановить ваши данные, т.к. они сжимаются
                                     и шифруются ключом доступа перед отправкой на сервер.
                                     и шифруются ключом доступа перед отправкой на сервер.
                                 </div>
                                 </div>
                             </el-form-item>
                             </el-form-item>
@@ -454,7 +454,7 @@
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 import Vue from 'vue';
 import Vue from 'vue';
 import Component from 'vue-class-component';
 import Component from 'vue-class-component';
-//import _ from 'lodash';
+import _ from 'lodash';
 
 
 import {copyTextToClipboard} from '../../../share/utils';
 import {copyTextToClipboard} from '../../../share/utils';
 import Window from '../../share/Window.vue';
 import Window from '../../share/Window.vue';
@@ -468,6 +468,9 @@ export default @Component({
         return Object.assign({}, rstore.settingDefaults);
         return Object.assign({}, rstore.settingDefaults);
     },
     },
     watch: {
     watch: {
+        settings: function() {
+            this.settingsChanged();
+        },
         form: function(newValue) {
         form: function(newValue) {
             this.commit('reader/setSettings', newValue);
             this.commit('reader/setSettings', newValue);
         },
         },
@@ -508,6 +511,13 @@ class SettingsPage extends Vue {
         this.commit = this.$store.commit;
         this.commit = this.$store.commit;
         this.reader = this.$store.state.reader;
         this.reader = this.$store.state.reader;
 
 
+        this.form = {};
+        this.settingsChanged();
+    }
+
+    settingsChanged() {
+        if (_.isEqual(this.form, this.settings))
+            return;
         this.form = Object.assign({}, this.settings);
         this.form = Object.assign({}, this.settings);
         for (let prop in rstore.settingDefaults) {
         for (let prop in rstore.settingDefaults) {
             this[prop] = this.form[prop];
             this[prop] = this.form[prop];
@@ -545,7 +555,9 @@ class SettingsPage extends Vue {
     }
     }
 
 
     get profilesArray() {
     get profilesArray() {
-        return Object.keys(this.profiles);
+        const result = Object.keys(this.profiles)
+        result.sort();
+        return result;
     }
     }
 
 
     get currentProfile() {
     get currentProfile() {

+ 5 - 1
client/store/modules/reader.js

@@ -183,6 +183,7 @@ const state = {
     profilesRev: 0,
     profilesRev: 0,
     currentProfile: '',
     currentProfile: '',
     settings: Object.assign({}, settingDefaults),
     settings: Object.assign({}, settingDefaults),
+    settingsRev: {},
 };
 };
 
 
 // getters
 // getters
@@ -213,7 +214,10 @@ const mutations = {
     },
     },
     setSettings(state, value) {
     setSettings(state, value) {
         state.settings = Object.assign({}, state.settings, value);
         state.settings = Object.assign({}, state.settings, value);
-    }
+    },
+    setSettingsRev(state, value) {
+        state.settingsRev = Object.assign({}, state.settingsRev, value);
+    },
 };
 };
 
 
 export default {
 export default {