Работа над ServerStorage - профили

This commit is contained in:
Book Pauk
2019-03-15 17:56:19 +07:00
parent 3b9f3ea81d
commit 2ff94c1458
3 changed files with 190 additions and 41 deletions

View File

@@ -13,7 +13,14 @@ import readerApi from '../../../api/reader';
import * as utils from '../../../share/utils'; import * as utils from '../../../share/utils';
import * as cryptoUtils from '../../../share/cryptoUtils'; import * as cryptoUtils from '../../../share/cryptoUtils';
const maxSetTries = 5;
export default @Component({ export default @Component({
watch: {
profiles: function() {
this.saveProfiles();
},
},
}) })
class ServerStorage extends Vue { class ServerStorage extends Vue {
created() { created() {
@@ -27,9 +34,7 @@ class ServerStorage extends Vue {
} }
this.hashedStorageKey = utils.toBase58(await cryptoUtils.sha256(this.serverStorageKey)); this.hashedStorageKey = utils.toBase58(await cryptoUtils.sha256(this.serverStorageKey));
//console.log(await this.storageSet({'id1': {rev: 1, data: {test: 123}}})); await this.loadProfiles();
//console.log(await this.storageGet({'id1': {}}));
//console.log(await this.storageCheck({'id1': {rev: 1, data: {test: 123}}}));
} }
get settings() { get settings() {
@@ -40,6 +45,73 @@ class ServerStorage extends Vue {
return this.$store.state.reader.serverStorageKey; return this.$store.state.reader.serverStorageKey;
} }
get profiles() {
return this.$store.state.reader.profiles;
}
get profilesRev() {
return this.$store.state.reader.profilesRev;
}
notifySuccessIfNeeded(rev1, rev2) {
if (rev1 != rev2)
this.$notify.success({message: 'Данные синхронизированы с сервером'});
}
warning(message) {
this.$notify.warning({message});
}
error(message) {
this.$notify.error({message});
}
async loadProfiles() {
let prof = await this.storageGet({'profiles': {}});
if (prof.state == 'success') {
const oldRev = this.profilesRev;
prof = prof.items.profiles;
this.commit('reader/setProfiles', prof.data);
this.commit('reader/setProfilesRev', prof.rev);
this.oldProfiles = this.profiles;
this.notifySuccessIfNeeded(oldRev, prof.rev);
} else {
this.warning(`Неверный ответ сервера: ${prof.state}`);
}
}
async saveProfiles() {
if (!this.savingProfiles) {
this.savingProfiles = true;
const diff = utils.getObjDiff(this.oldProfiles, this.profiles);
let result = {state: ''};
let tries = 0;
while (result.state != 'success' && tries < maxSetTries) {
result = await this.storageSet({'profiles': {rev: this.profilesRev + 1, data: this.profiles}});
if (result.state == 'reject') {
await this.loadProfiles();
const newProfiles = utils.applyObjDiff(this.profiles, diff);
this.commit('reader/setProfiles', newProfiles);
this.commit('reader/setProfilesRev', result.items.profiles.rev);
}
tries++;
}
this.commit('reader/setProfilesRev', this.profilesRev + 1);
if (tries >= maxSetTries) {
throw new Error('Не удалось отправить данные на сервер');
}
this.savingProfiles = false;
}
}
generateNewServerStorageKey() { generateNewServerStorageKey() {
const key = utils.toBase58(utils.randomArray(32)); const key = utils.toBase58(utils.randomArray(32));
this.commit('reader/setServerStorageKey', key); this.commit('reader/setServerStorageKey', key);

View File

@@ -1,3 +1,4 @@
import _ from 'lodash';
import baseX from 'base-x'; import baseX from 'base-x';
import PAKO from 'pako'; import PAKO from 'pako';
import {Buffer} from 'safe-buffer'; import {Buffer} from 'safe-buffer';
@@ -92,3 +93,67 @@ export function toBase64(data) {
export function fromBase64(data) { export function fromBase64(data) {
return bs64.decode(data); return bs64.decode(data);
} }
export function getObjDiff(oldObj, newObj) {
const result = {__isDiff: true, change: {}, add: {}, del: []};
for (const key of Object.keys(oldObj)) {
if (newObj.hasOwnProperty(key)) {
if (!_.isEqual(oldObj[key], newObj[key])) {
if (_.isObject(oldObj[key]) && _.isObject(newObj[key])) {
result.change[key] = getObjDiff(oldObj[key], newObj[key]);
} else {
result.change[key] = _.cloneDeep(newObj[key]);
}
}
} else {
result.del.push(key);
}
}
for (const key of Object.keys(newObj)) {
if (!oldObj.hasOwnProperty(key)) {
result.add[key] = _.cloneDeep(newObj[key]);
}
}
return result;
}
export function isEmptyObjDiff(diff) {
return (!_.isObject(diff) || !diff.__isDiff ||
(!Object.keys(diff.change).length &&
!Object.keys(diff.add).length &&
!diff.del.length
)
);
}
export function applyObjDiff(obj, diff, isAddChanged) {
const result = _.cloneDeep(obj);
if (!diff.__isDiff)
return result;
const change = diff.change;
for (const key of Object.keys(change)) {
if (result.hasOwnProperty(key)) {
if (_.isObject(change[key])) {
result[key] = applyObjDiff(result[key], change[key], isAddChanged);
} else {
result[key] = _.cloneDeep(change[key]);
}
} else if (isAddChanged) {
result[key] = _.cloneDeep(change[key]);
}
}
for (const key of Object.keys(diff.add)) {
result[key] = _.cloneDeep(diff.add[key]);
}
for (const key of diff.del) {
delete result[key];
}
return result;
}

View File

@@ -178,6 +178,9 @@ for (const font of webFonts)
const state = { const state = {
toolBarActive: true, toolBarActive: true,
serverStorageKey: '', serverStorageKey: '',
profiles: [],
profilesRev: 0,
currentProfile: '',
settings: Object.assign({}, settingDefaults), settings: Object.assign({}, settingDefaults),
}; };
@@ -195,6 +198,15 @@ const mutations = {
setServerStorageKey(state, value) { setServerStorageKey(state, value) {
state.serverStorageKey = value; state.serverStorageKey = value;
}, },
setProfiles(state, value) {
state.profiles = value;
},
setProfilesRev(state, value) {
state.profilesRev = value;
},
setCurrentProfile(state, value) {
state.currentProfile = value;
},
setSettings(state, value) { setSettings(state, value) {
state.settings = Object.assign({}, state.settings, value); state.settings = Object.assign({}, state.settings, value);
} }