119 lines
2.8 KiB
JavaScript
119 lines
2.8 KiB
JavaScript
/* global dbToCloud styleManager chromeLocal prefs tokenManager */
|
|
/* exported sync */
|
|
|
|
'use strict';
|
|
|
|
const sync = (() => {
|
|
let currentDrive;
|
|
const ctrl = dbToCloud.dbToCloud({
|
|
onGet(id) {
|
|
return styleManager.getByUUID(id);
|
|
},
|
|
onPut(doc) {
|
|
return styleManager.putByUUID(doc);
|
|
},
|
|
onDelete(id, rev) {
|
|
return styleManager.deleteByUUID(id, rev);
|
|
},
|
|
onFirstSync() {
|
|
return styleManager.getAllStyles()
|
|
.then(styles => {
|
|
styles.forEach(i => ctrl.put(i._id, i._rev));
|
|
});
|
|
},
|
|
compareRevision(a, b) {
|
|
return styleManager.compareRevision(a, b);
|
|
},
|
|
getState(drive) {
|
|
const key = `sync/state/${drive.name}`;
|
|
return chromeLocal.get(key)
|
|
.then(obj => obj[key]);
|
|
},
|
|
setState(drive, state) {
|
|
const key = `sync/state/${drive.name}`;
|
|
return chromeLocal.set({
|
|
[key]: state
|
|
});
|
|
}
|
|
});
|
|
|
|
prefs.initializing
|
|
.then(() => {
|
|
const provider = prefs.get('sync.enabled');
|
|
if (provider === 'none') {
|
|
return;
|
|
}
|
|
return start(provider);
|
|
})
|
|
.catch(console.error);
|
|
|
|
chrome.alarms.onAlarm.addListener(info => {
|
|
if (info.name === 'syncNow') {
|
|
ctrl.syncNow()
|
|
.catch(handle401Error)
|
|
.catch(console.error);
|
|
}
|
|
});
|
|
|
|
return {
|
|
start,
|
|
stop,
|
|
put: ctrl.put,
|
|
delete: ctrl.delete,
|
|
syncNow: () => ctrl.syncNow().then(handle401Error)
|
|
};
|
|
|
|
function handle401Error(err) {
|
|
if (err.code === 401) {
|
|
return tokenManager.revokeToken(currentDrive.name)
|
|
.then(() => {
|
|
throw err;
|
|
});
|
|
}
|
|
throw err;
|
|
}
|
|
|
|
function start(name) {
|
|
return (currentDrive ? stop() : Promise.resolve())
|
|
.then(() => {
|
|
currentDrive = getDrive(name);
|
|
ctrl.use(currentDrive);
|
|
return ctrl.start()
|
|
.catch(err => {
|
|
if (/Authorization page could not be loaded/i.test(err.message)) {
|
|
// FIXME: Chrome always fail at the first login so we try again
|
|
return ctrl.syncNow();
|
|
}
|
|
throw err;
|
|
});
|
|
})
|
|
.catch(handle401Error)
|
|
.then(() => {
|
|
chrome.alarms.create('syncNow', {periodInMinutes: 30});
|
|
});
|
|
}
|
|
|
|
function getDrive(name) {
|
|
if (name === 'dropbox') {
|
|
return dbToCloud.drive.dropbox({
|
|
getAccessToken: () => tokenManager.getToken(name)
|
|
});
|
|
}
|
|
|
|
throw new Error(`unknown cloud name: ${name}`);
|
|
}
|
|
|
|
function stop() {
|
|
chrome.alarms.clear('syncNow');
|
|
if (!currentDrive) {
|
|
return Promise.resolve();
|
|
}
|
|
return ctrl.stop()
|
|
.then(() => tokenManager.revokeToken(currentDrive.name))
|
|
.then(() => chromeLocal.remove(`sync/state/${currentDrive.name}`))
|
|
.then(() => {
|
|
currentDrive = null;
|
|
});
|
|
}
|
|
})();
|