Browse Source

feat(Sync): add UI for sync

Gerald 9 years ago
parent
commit
f0e5adb01d

+ 2 - 1
src/background/index.html

@@ -3,9 +3,10 @@
 	<head>
 		<meta charset="utf-8">
 		<title>ViolentMonkey</title>
+    <script src="/lib/underscore-min.js"></script>
+		<script src="/common.js"></script>
 	</head>
   <body>
-		<script src="/common.js"></script>
     <script src="app.js"></script>
   </body>
 </html>

+ 13 - 1
src/background/main.js

@@ -9,7 +9,10 @@ var commands = {
     return vmdb.removeScript(id);
   },
   GetData: function (data, src) {
-    return vmdb.getData();
+    return vmdb.getData().then(function (data) {
+      data.sync = sync.status();
+      return data;
+    });
   },
   GetInjected: function (url, src) {
     var data = {
@@ -108,6 +111,15 @@ var commands = {
     setBadge(num, src);
     return false;
   },
+  Authenticate: function (data, src) {
+    var service = sync.service(data);
+    service && service.authenticate && service.authenticate();
+    return false;
+  },
+  SyncStart: function (data, src) {
+    sync.start();
+    return false;
+  },
 };
 
 vmdb.initialized.then(function () {

+ 5 - 0
src/background/sync/dropbox.js

@@ -20,20 +20,25 @@ setTimeout(function () {
 
   function init() {
     dropbox.inst = null;
+    dropbox.status.set('initializing');
     var token = dropbox.config.get('token');
     if (token) {
       dropbox.inst = new Dropbox(token);
       dropbox.inst.fetch('https://api.dropboxapi.com/1/account/info')
       .then(function (res) {
+        dropbox.status.set('authorized');
         events.fire('init');
         //return res.json();
       }, function (res) {
         if (res.status > 300) {
           dropbox.inst = null;
           dropbox.config.clear();
+          dropbox.status.set('unauthorized');
         }
         dropbox.config.setOption('enabled', false);
       });
+    } else {
+      dropbox.status.set('unauthorized');
     }
   }
   function authenticate() {

+ 52 - 7
src/background/sync/index.js

@@ -49,16 +49,60 @@ var sync = function () {
     _.options.set(this.prefix, this.data);
   };
 
+  function serviceStatus() {
+    var validStatused = [
+      'idle',
+      'initializing',
+      'authorized',
+      'unauthorized',
+    ];
+    var status = 'idle';
+    return {
+      get: function () {return status;},
+      set: function (_status) {
+        if (~validStatused.indexOf(_status)) {
+          status = _status;
+          _.messenger.post({
+            cmd: 'sync',
+            data: getStatuses(),
+          });
+        }
+        return status;
+      },
+    };
+  }
   function service(name, methods) {
-    var service = _.assign({}, methods, {
-      config: new ServiceConfig(name),
-    });
-    setTimeout(function () {
-      services.push(service);
-      inited && initService(service);
-    });
+    var service;
+    if (methods) {
+      // initialize
+      service = _.assign({}, methods, {
+        name: name,
+        config: new ServiceConfig(name),
+        status: serviceStatus(),
+      });
+      setTimeout(function () {
+        services.push(service);
+        inited && initService(service);
+      });
+    } else {
+      // get existent instance
+      for (var i = services.length; i --; ) {
+        if (services[i].name === name) break;
+      }
+      // i may be -1 if not founded
+      service = services[i];
+    }
     return service;
   }
+  function getStatuses() {
+    return services.reduce(function (res, service) {
+      res[service.name] = {
+        status: service.status.get(),
+        timestamp: service.config.get('meta', {}).timestamp,
+      };
+      return res;
+    }, {});
+  }
   function start(service) {
     if (service) {
       service.config.getOption('enabled') && queue.push(service);
@@ -209,5 +253,6 @@ var sync = function () {
     init: init,
     start: start,
     service: service,
+    status: getStatuses,
   };
 }();

+ 0 - 20
src/background/utils.js

@@ -189,23 +189,3 @@ _.broadcast = function (data) {
     });
   });
 };
-
-_.forEach = function (arr, cb) {
-  var length = arr.length;
-  for (var i = 0; i < length; i ++) cb(arr[i], i, arr);
-  return arr;
-};
-_.slice = function () {
-  var empty = [];
-  var slice = empty.slice;
-  return function () {
-    return slice.apply(arguments[0] || empty, slice.call(arguments, 1));
-  };
-}();
-_.assign = Object.assign || function () {
-  var res = arguments[0];
-  res && _.forEach(_.slice(arguments, 1), function (obj) {
-    if (obj) for (var k in obj) res[k] = obj[k];
-  });
-  return res;
-};

+ 6 - 3
src/options/app.js

@@ -24,12 +24,15 @@ if (!Backbone.history.start())
 
 BaseView.prototype.initI18n.call(window);
 
-var scriptList;
+var scriptList, syncData;
 function initMain() {
-  scriptList = new ScriptList();
+  scriptList = new ScriptList;
+  syncData = new Backbone.Model;
   var port = chrome.runtime.connect({name: 'Options'});
   port.onMessage.addListener(function (res) {
-    if (res.cmd === 'add') {
+    if (res.cmd === 'sync') {
+      syncData.set(res.data);
+    } else if (res.cmd === 'add') {
       res.data.message = '';
       scriptList.push(res.data);
     } else if (res.data) {

+ 1 - 0
src/options/model.js

@@ -37,6 +37,7 @@ var ScriptList = Backbone.Collection.extend({
       _this.loading = false;
       _.assign(_this.cache, data.cache);
       _this.reset(data.scripts);
+      syncData.set(data.sync);
     });
   },
 });

+ 5 - 5
src/options/templates/tab-settings.html

@@ -40,17 +40,17 @@
     <legend data-i18n=labelSync></legend>
     <div>
       <label>
-        <input id=cbSyncDropbox type=checkbox data-check=dropboxEnabled <%=
+        <input id=cbSyncDropbox type=checkbox data-check=dropboxEnabled data-sync=dropbox <%=
         it.dropboxEnabled ? 'checked' : ''
         %> <%=
-        it.dropboxAuthorized ? '' : 'disabled'
+        it.sync.dropbox.authorized ? '' : 'disabled'
         %>>
         <span data-i18n=labelSyncDropbox></span>
       </label>
-      <button <%=
-        it.dropboxAuthorized ? 'disabled' : ''
+      <button data-auth=dropbox <%=
+        it.sync.dropbox.unauthorized ? '' : 'disabled'
       %>><%=
-        it.dropboxAuthorized ? _.i18n('buttonAuthorized') : _.i18n('buttonAuthorize')
+        it.sync.dropbox.authorized ? _.i18n('buttonAuthorized') : _.i18n('buttonAuthorize')
       %></button>
     </div>
   </fieldset>

+ 18 - 0
src/options/views/tab-settings.js

@@ -40,10 +40,22 @@ var SettingsTab = BaseView.extend({
     'click #bImport': 'importFile',
     'click #bExport': 'exportData',
     'click #bVacuum': 'onVacuum',
+    'click [data-auth]': 'authenticate',
+    'change [data-sync]': 'toggleSync',
   },
   templateUrl: '/options/templates/tab-settings.html',
+  initialize: function () {
+    BaseView.prototype.initialize.call(this);
+    this.listenTo(syncData, 'change', this.render);
+  },
   _render: function () {
     var options = _.options.getAll();
+    var sync = options.sync = syncData.toJSON();
+    ['dropbox'].forEach(function (name) {
+      var service = sync[name] = sync[name] || {};
+      service.authorized = service.status === 'authorized';
+      service.unauthorized = service.status === 'unauthorized';
+    });
     this.$el.html(this.templateFn(options));
     this.$('#sInjectMode').val(options.injectMode);
     this.updateInjectHint();
@@ -243,4 +255,10 @@ var SettingsTab = BaseView.extend({
       button.html(_.i18n('buttonVacuumed'));
     });
   },
+  authenticate: function (e) {
+    _.sendMessage({cmd: 'Authenticate', data: e.target.dataset.auth});
+  },
+  toggleSync: function (e) {
+    e.target.checked && _.sendMessage({cmd: 'SyncStart'});
+  },
 });