Change: manage sync status in background
This commit is contained in:
parent
f6567eef12
commit
93698e728b
|
@ -1,9 +1,13 @@
|
||||||
/* global dbToCloud styleManager chromeLocal prefs tokenManager */
|
/* global dbToCloud styleManager chromeLocal prefs tokenManager msg */
|
||||||
/* exported sync */
|
/* exported sync */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const sync = (() => {
|
const sync = (() => {
|
||||||
|
const status = {
|
||||||
|
state: 'disconnected',
|
||||||
|
syncing: false
|
||||||
|
};
|
||||||
let currentDrive;
|
let currentDrive;
|
||||||
const ctrl = dbToCloud.dbToCloud({
|
const ctrl = dbToCloud.dbToCloud({
|
||||||
onGet(id) {
|
onGet(id) {
|
||||||
|
@ -58,9 +62,37 @@ const sync = (() => {
|
||||||
stop,
|
stop,
|
||||||
put: ctrl.put,
|
put: ctrl.put,
|
||||||
delete: ctrl.delete,
|
delete: ctrl.delete,
|
||||||
syncNow: () => ctrl.syncNow().catch(handle401Error)
|
syncNow
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function withFinally(p, cleanup) {
|
||||||
|
return p.then(
|
||||||
|
result => {
|
||||||
|
cleanup();
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
err => {
|
||||||
|
cleanup();
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncNow() {
|
||||||
|
if (status.syncing) {
|
||||||
|
return Promise.reject(new Error('still syncing'));
|
||||||
|
}
|
||||||
|
status.syncing = true;
|
||||||
|
emitChange();
|
||||||
|
return withFinally(
|
||||||
|
ctrl.syncNow().catch(handle401Error),
|
||||||
|
() => {
|
||||||
|
status.syncing = false;
|
||||||
|
emitChange();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function handle401Error(err) {
|
function handle401Error(err) {
|
||||||
if (err.code === 401) {
|
if (err.code === 401) {
|
||||||
return tokenManager.revokeToken(currentDrive.name)
|
return tokenManager.revokeToken(currentDrive.name)
|
||||||
|
@ -71,6 +103,10 @@ const sync = (() => {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function emitChange() {
|
||||||
|
msg.broadcastExtension({method: 'syncStatusUpdate', status});
|
||||||
|
}
|
||||||
|
|
||||||
function start(name) {
|
function start(name) {
|
||||||
if (currentDrive) {
|
if (currentDrive) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
|
@ -78,18 +114,26 @@ const sync = (() => {
|
||||||
currentDrive = getDrive(name);
|
currentDrive = getDrive(name);
|
||||||
ctrl.use(currentDrive);
|
ctrl.use(currentDrive);
|
||||||
prefs.set('sync.enabled', name);
|
prefs.set('sync.enabled', name);
|
||||||
return ctrl.start()
|
status.state = 'connecting';
|
||||||
.catch(err => {
|
status.syncing = true;
|
||||||
if (/Authorization page could not be loaded/i.test(err.message)) {
|
emitChange();
|
||||||
// FIXME: Chrome always fail at the first login so we try again
|
return withFinally(
|
||||||
return ctrl.syncNow();
|
ctrl.start()
|
||||||
}
|
.catch(err => {
|
||||||
throw err;
|
if (/Authorization page could not be loaded/i.test(err.message)) {
|
||||||
})
|
// FIXME: Chrome always fail at the first login so we try again
|
||||||
.catch(handle401Error)
|
return ctrl.syncNow();
|
||||||
.then(() => {
|
}
|
||||||
|
throw err;
|
||||||
|
})
|
||||||
|
.catch(handle401Error),
|
||||||
|
() => {
|
||||||
chrome.alarms.create('syncNow', {periodInMinutes: 30});
|
chrome.alarms.create('syncNow', {periodInMinutes: 30});
|
||||||
});
|
status.state = 'connected';
|
||||||
|
status.syncing = false;
|
||||||
|
emitChange();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDrive(name) {
|
function getDrive(name) {
|
||||||
|
@ -107,12 +151,18 @@ const sync = (() => {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
chrome.alarms.clear('syncNow');
|
chrome.alarms.clear('syncNow');
|
||||||
return ctrl.stop()
|
status.state = 'disconnecting';
|
||||||
.then(() => tokenManager.revokeToken(currentDrive.name))
|
emitChange();
|
||||||
.then(() => chromeLocal.remove(`sync/state/${currentDrive.name}`))
|
return withFinally(
|
||||||
.then(() => {
|
ctrl.stop()
|
||||||
|
.then(() => tokenManager.revokeToken(currentDrive.name))
|
||||||
|
.then(() => chromeLocal.remove(`sync/state/${currentDrive.name}`)),
|
||||||
|
() => {
|
||||||
currentDrive = null;
|
currentDrive = null;
|
||||||
prefs.set('sync.enabled', 'none');
|
prefs.set('sync.enabled', 'none');
|
||||||
});
|
status.state = 'disconnected';
|
||||||
|
emitChange();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -81,15 +81,21 @@ document.onclick = e => {
|
||||||
const disconnectButton = document.querySelector('.sync-options .disconnect');
|
const disconnectButton = document.querySelector('.sync-options .disconnect');
|
||||||
const syncButton = document.querySelector('.sync-options .sync-now');
|
const syncButton = document.querySelector('.sync-options .sync-now');
|
||||||
|
|
||||||
let connected = false;
|
let status = {};
|
||||||
let syncing = false;
|
|
||||||
|
|
||||||
prefs.subscribe(['sync.enabled'], (key, value) => {
|
msg.onExtension(e => {
|
||||||
cloud.value = value;
|
if (e.method === 'syncStatusUpdate') {
|
||||||
connected = value !== 'none';
|
status = e.status;
|
||||||
updateButtons();
|
updateButtons();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
API.getSyncStatus()
|
||||||
|
.then(_status => {
|
||||||
|
status = _status;
|
||||||
|
updateButtons();
|
||||||
|
});
|
||||||
|
|
||||||
function validClick(e) {
|
function validClick(e) {
|
||||||
return e.button === 0 && !e.ctrl && !e.alt && !e.shift;
|
return e.button === 0 && !e.ctrl && !e.alt && !e.shift;
|
||||||
}
|
}
|
||||||
|
@ -97,48 +103,27 @@ document.onclick = e => {
|
||||||
cloud.addEventListener('change', updateButtons);
|
cloud.addEventListener('change', updateButtons);
|
||||||
|
|
||||||
function updateButtons() {
|
function updateButtons() {
|
||||||
cloud.disabled = connected;
|
cloud.disabled = status.state !== 'disconnected';
|
||||||
connectButton.disabled = connected || cloud.value === 'none';
|
connectButton.disabled = status.state !== 'disconnected' || cloud.value === 'none';
|
||||||
disconnectButton.disabled = !connected || syncing;
|
disconnectButton.disabled = status.state !== 'connected' || status.syncing;
|
||||||
syncButton.disabled = !connected || syncing;
|
syncButton.disabled = status.state !== 'connected' || status.syncing;
|
||||||
}
|
}
|
||||||
|
|
||||||
connectButton.addEventListener('click', e => {
|
connectButton.addEventListener('click', e => {
|
||||||
if (validClick(e)) {
|
if (validClick(e)) {
|
||||||
syncing = true;
|
API.syncStart(cloud.value).catch(console.error);
|
||||||
updateButtons();
|
|
||||||
API.syncStart(cloud.value)
|
|
||||||
.catch(console.error)
|
|
||||||
.then(() => {
|
|
||||||
syncing = false;
|
|
||||||
updateButtons();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
disconnectButton.addEventListener('click', e => {
|
disconnectButton.addEventListener('click', e => {
|
||||||
if (validClick(e)) {
|
if (validClick(e)) {
|
||||||
syncing = true;
|
API.syncStop().catch(console.error);
|
||||||
updateButtons();
|
|
||||||
API.syncStop()
|
|
||||||
.catch(console.error)
|
|
||||||
.then(() => {
|
|
||||||
syncing = false;
|
|
||||||
updateButtons();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
syncButton.addEventListener('click', e => {
|
syncButton.addEventListener('click', e => {
|
||||||
if (validClick(e)) {
|
if (validClick(e)) {
|
||||||
syncing = true;
|
API.syncNow().catch(console.error);
|
||||||
updateButtons();
|
|
||||||
API.syncNow()
|
|
||||||
.catch(console.error)
|
|
||||||
.then(() => {
|
|
||||||
syncing = false;
|
|
||||||
updateButtons();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user