Gerald 9 лет назад
Родитель
Сommit
c7554ae378

+ 17 - 35
src/background/sync/index.js

@@ -19,46 +19,28 @@ var autoSync = _.debounce(function () {
 }, 60 * 60 * 1000);
 
 function ServiceConfig(name) {
-  this.prefix = name;
-  this.load();
+  this.name = name;
 }
+ServiceConfig.prototype.normalizeKeys = function (key) {
+  var keys = _.normalizeKeys(key);
+  keys.unshift(this.name);
+  return keys;
+};
 ServiceConfig.prototype.get = function (key, def) {
-  var val = this.data[key];
-  if (val == null) val = def;
-  return val;
+  var keys = this.normalizeKeys(key);
+  return _.options.get(keys, def);
 };
 ServiceConfig.prototype.set = function (key, val) {
-  if (typeof key === 'object') {
-    if (arguments.length === 1) {
-      Object.assign(this.data, key);
-      this.dump();
-    }
+  var _this = this;
+  if (arguments.length === 1) {
+    return _.options.set(_this.name, Object.assign(_.options.get(_this.name, {}), key));
   } else {
-    // val may be an object, so equal test does not work
-    this.data[key] = val;
-    this.dump();
+    var keys = this.normalizeKeys(key);
+    return _.options.set(keys, val);
   }
 };
 ServiceConfig.prototype.clear = function () {
-  this.data = {};
-  this.dump();
-};
-ServiceConfig.prototype.capitalize = function (string) {
-  return string[0].toUpperCase() + string.slice(1);
-};
-ServiceConfig.prototype.getOption = function (key, def) {
-  key = this.capitalize(key);
-  return _.options.get(this.prefix + key, def);
-};
-ServiceConfig.prototype.setOption = function (key, val) {
-  key = this.capitalize(key);
-  return _.options.set(this.prefix + key, val);
-};
-ServiceConfig.prototype.load = function () {
-  this.data = _.options.get(this.prefix, {});
-};
-ServiceConfig.prototype.dump = function () {
-  _.options.set(this.prefix, this.data);
+  _.options.set(this.name, {});
 };
 
 function serviceState(validStates, initialState, onChange) {
@@ -122,7 +104,7 @@ function syncOne(service) {
 }
 function syncAll() {
   return Promise.all(servicesReady.filter(function (service) {
-    return service.config.getOption('enabled') && !service.syncState.is(['ready', 'syncing']);
+    return service.config.get('enabled') && !service.syncState.is(['ready', 'syncing']);
   }).map(function (service) {
     return service.startSync();
   }));
@@ -218,7 +200,7 @@ var BaseService = serviceFactory({
     var _this = this;
     var promise, debouncedResolve;
     function shouldSync() {
-      return _this.authState.is('authorized') && _this.config.getOption('enabled');
+      return _this.authState.is('authorized') && _this.config.get('enabled');
     }
     function init() {
       if (!shouldSync()) return Promise.resolve();
@@ -262,7 +244,7 @@ var BaseService = serviceFactory({
           _this.authState.set('error');
         }
         _this.syncState.set('idle');
-        // _this.config.setOption('enabled', false);
+        // _this.config.set('enabled', false);
       } else {
         _this.authState.set('unauthorized');
       }

+ 47 - 6
src/common.js

@@ -1,22 +1,65 @@
 var _ = exports;
 _.i18n = chrome.i18n.getMessage;
 
+function normalizeKeys(key) {
+  if (!key) key = [];
+  if (!Array.isArray(key)) key = key.toString().split('.');
+  return key;
+}
+
+_.normalizeKeys = normalizeKeys;
+
+_.object = function () {
+  function get(obj, key, def) {
+    var keys = normalizeKeys(key);
+    for (var i = 0, len = keys.length; i < len; i ++) {
+      key = keys[i];
+      if (obj && (key in obj)) obj = obj[key];
+      else return def;
+    }
+    return obj;
+  }
+  function set(obj, key, val) {
+    var keys = normalizeKeys(key);
+    if (!keys.length) return val;
+    var sub = obj = obj || {};
+    for (var i = 0, len = keys.length - 1; i < len; i ++) {
+      key = keys[i];
+      sub = sub[key] = sub[key] || {};
+    }
+    sub[keys[keys.length - 1]] = val;
+    return obj;
+  }
+  return {
+    get: get,
+    set: set,
+  };
+}();
+
 _.options = function () {
   function getOption(key, def) {
+    var keys = normalizeKeys(key);
+    key = keys[0];
     var value = localStorage.getItem(key), obj;
-    if (value)
+    if (value) {
       try {
         obj = JSON.parse(value);
       } catch (e) {
-        obj = def;
+        // ignore invalid JSON
       }
-    else obj = def;
+    }
     if (obj == null) obj = defaults[key];
-    return obj;
+    if (obj == null) obj = def;
+    return keys.length > 1 ? _.object.get(obj, keys.slice(1), def) : obj;
   }
 
   function setOption(key, value) {
+    var keys = normalizeKeys(key);
+    key = keys[0];
     if (key in defaults) {
+      if (keys.length > 1) {
+        value = _.object.set(getOption(key), keys.slice(1), value);
+      }
       localStorage.setItem(key, JSON.stringify(value));
       [hooks[key], hooks['']].forEach(function (group) {
         group && group.forEach(function (cb) {
@@ -71,9 +114,7 @@ _.options = function () {
     trackLocalFile: false,
     autoReload: false,
     dropbox: {},
-    dropboxEnabled: false,
     onedrive: {},
-    onedriveEnabled: false,
     features: null,
   };
   var hooks = {};

+ 0 - 6
src/options/utils/settings.js

@@ -6,18 +6,12 @@ _.options.hook(function (value, key) {
   list && list.forEach(function (el) {
     el.checked = value;
   });
-  setTimeout(onChanged, 0, value, key);
 });
 
 function onSettingChange(e) {
   var target = e.target;
   _.options.set(target.dataset.setting, target.checked);
 }
-function onChanged(value, key) {
-  if (value && key === 'closeAfterInstall') {
-    _.options.set('trackLocalFile', false);
-  }
-}
 
 Vue.directive('setting', {
   bind: function (el, binding) {

+ 1 - 1
src/options/views/confirm.html

@@ -5,7 +5,7 @@
         <button dropdown-toggle v-text="i18n('buttonInstallOptions')"></button>
         <div class="dropdown-menu options-panel" @mousedown.stop>
           <label>
-            <input type=checkbox v-setting="'closeAfterInstall'">
+            <input type=checkbox v-setting="'closeAfterInstall'" @change="checkClose">
             <span v-text="i18n('installOptionClose')"></span>
           </label>
           <label>

+ 3 - 0
src/options/views/confirm.js

@@ -180,5 +180,8 @@ module.exports = {
         _this.trackLocalFile();
       });
     },
+    checkClose: function (e) {
+      e.target.checked && _.options.set('trackLocalFile', false);
+    },
   },
 };

+ 1 - 1
src/options/views/sync-service.html

@@ -1,6 +1,6 @@
 <div class="line">
   <label>
-    <input type=checkbox v-setting="service.name+'Enabled'" @change="update">
+    <input type=checkbox v-setting="keyEnabled" @change="update">
     <span v-text="labelText"></span>
   </label>
   <button @click="authenticate" v-text="labelAuthenticate"

+ 3 - 0
src/options/views/sync-service.js

@@ -7,6 +7,9 @@ module.exports = {
   props: ['service'],
   template: cache.get('./sync-service.html'),
   computed: {
+    keyEnabled: function () {
+      return this.service.name + '.enabled';
+    },
     labelText: function () {
       var service = this.service;
       return _.i18n('labelSyncTo', service.displayName || service.name);