Add: webdav sync (#1363)
This commit is contained in:
parent
3ea7e45624
commit
f6e6a138db
|
@ -1200,6 +1200,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"optionsSyncUsername": {
|
||||||
|
"message": "Username"
|
||||||
|
},
|
||||||
|
"optionsSyncPassword": {
|
||||||
|
"message": "Password"
|
||||||
|
},
|
||||||
|
"optionsSyncUrl": {
|
||||||
|
"message": "URL"
|
||||||
|
},
|
||||||
"optionsSyncStatusRelogin": {
|
"optionsSyncStatusRelogin": {
|
||||||
"message": "Session expired, please login again."
|
"message": "Session expired, please login again."
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* global API msg */// msg.js
|
/* global API msg */// msg.js
|
||||||
/* global chromeLocal */// storage-util.js
|
/* global chromeLocal chromeSync */// storage-util.js
|
||||||
/* global compareRevision */// common.js
|
/* global compareRevision */// common.js
|
||||||
/* global iconMan */
|
/* global iconMan */
|
||||||
/* global prefs */
|
/* global prefs */
|
||||||
|
@ -18,6 +18,7 @@ const syncMan = (() => {
|
||||||
disconnecting: 'disconnecting',
|
disconnecting: 'disconnecting',
|
||||||
});
|
});
|
||||||
const STORAGE_KEY = 'sync/state/';
|
const STORAGE_KEY = 'sync/state/';
|
||||||
|
const NO_LOGIN = ['webdav'];
|
||||||
const status = /** @namespace SyncManager.Status */ {
|
const status = /** @namespace SyncManager.Status */ {
|
||||||
STATES,
|
STATES,
|
||||||
state: STATES.disconnected,
|
state: STATES.disconnected,
|
||||||
|
@ -85,19 +86,29 @@ const syncMan = (() => {
|
||||||
return ctrl.put(...args);
|
return ctrl.put(...args);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async setDriveOptions(driveName, options) {
|
||||||
|
const key = `secure/sync/driveOptions/${driveName}`;
|
||||||
|
await chromeSync.setValue(key, options);
|
||||||
|
},
|
||||||
|
|
||||||
|
async getDriveOptions(driveName) {
|
||||||
|
const key = `secure/sync/driveOptions/${driveName}`;
|
||||||
|
return await chromeSync.getValue(key) || {};
|
||||||
|
},
|
||||||
|
|
||||||
async start(name, fromPref = false) {
|
async start(name, fromPref = false) {
|
||||||
if (ready.then) await ready;
|
if (ready.then) await ready;
|
||||||
if (!ctrl) await initController();
|
if (!ctrl) await initController();
|
||||||
|
|
||||||
if (currentDrive) return;
|
if (currentDrive) return;
|
||||||
currentDrive = getDrive(name);
|
currentDrive = await getDrive(name);
|
||||||
ctrl.use(currentDrive);
|
ctrl.use(currentDrive);
|
||||||
|
|
||||||
status.state = STATES.connecting;
|
status.state = STATES.connecting;
|
||||||
status.currentDriveName = currentDrive.name;
|
status.currentDriveName = currentDrive.name;
|
||||||
emitStatusChange();
|
emitStatusChange();
|
||||||
|
|
||||||
if (fromPref) {
|
if (fromPref || NO_LOGIN.includes(currentDrive.name)) {
|
||||||
status.login = true;
|
status.login = true;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -240,11 +251,11 @@ const syncMan = (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDrive(name) {
|
async function getDrive(name) {
|
||||||
if (name === 'dropbox' || name === 'google' || name === 'onedrive') {
|
if (name === 'dropbox' || name === 'google' || name === 'onedrive' || name === 'webdav') {
|
||||||
return dbToCloud.drive[name]({
|
const options = await syncMan.getDriveOptions(name);
|
||||||
getAccessToken: () => tokenMan.getToken(name),
|
options.getAccessToken = () => tokenMan.getToken(name);
|
||||||
});
|
return dbToCloud.drive[name](options);
|
||||||
}
|
}
|
||||||
throw new Error(`unknown cloud name: ${name}`);
|
throw new Error(`unknown cloud name: ${name}`);
|
||||||
}
|
}
|
||||||
|
|
17
options.html
17
options.html
|
@ -199,10 +199,27 @@
|
||||||
<option value="dropbox">Dropbox</option>
|
<option value="dropbox">Dropbox</option>
|
||||||
<option value="google">Google Drive</option>
|
<option value="google">Google Drive</option>
|
||||||
<option value="onedrive">OneDrive</option>
|
<option value="onedrive">OneDrive</option>
|
||||||
|
<option value="webdav">WebDAV</option>
|
||||||
</select>
|
</select>
|
||||||
<svg class="svg-icon select-arrow"><use xlink:href="#svg-icon-select-arrow"/></svg>
|
<svg class="svg-icon select-arrow"><use xlink:href="#svg-icon-select-arrow"/></svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<fieldset class="drive-options">
|
||||||
|
<div class="webdav-options" data-drive="webdav">
|
||||||
|
<label class="url">
|
||||||
|
<span i18n-text="optionsSyncUrl"></span>
|
||||||
|
<input type="text" data-option="url">
|
||||||
|
</label>
|
||||||
|
<label class="username">
|
||||||
|
<span i18n-text="optionsSyncUsername"></span>
|
||||||
|
<input type="text" data-option="username">
|
||||||
|
</label>
|
||||||
|
<label class="password">
|
||||||
|
<span i18n-text="optionsSyncPassword"></span>
|
||||||
|
<input type="password" data-option="password">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="button" class="connect" i18n-text="optionsSyncConnect"></button>
|
<button type="button" class="connect" i18n-text="optionsSyncConnect"></button>
|
||||||
<button type="button" class="disconnect" i18n-text="optionsSyncDisconnect"></button>
|
<button type="button" class="disconnect" i18n-text="optionsSyncDisconnect"></button>
|
||||||
|
|
|
@ -163,7 +163,7 @@ label > :first-child {
|
||||||
}
|
}
|
||||||
|
|
||||||
label:not([disabled]),
|
label:not([disabled]),
|
||||||
label:not([disabled]) :not([type="number"]) {
|
label:not([disabled]) :not([type="number"]):not([type="text"]):not([type="password"]) {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +437,25 @@ input[type="radio"].radio:checked::after {
|
||||||
.sync-status::first-letter {
|
.sync-status::first-letter {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
.sync-options .drive-options {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.drive-options > :not([hidden]) {
|
||||||
|
display: table;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.drive-options > * > label {
|
||||||
|
display: table-row;
|
||||||
|
}
|
||||||
|
.drive-options > * > label > * {
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
.drive-options > * input {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
.sync-options .actions button {
|
.sync-options .actions button {
|
||||||
margin-top: .5em;
|
margin-top: .5em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ document.onclick = e => {
|
||||||
const elSyncNow = $('.sync-options .sync-now');
|
const elSyncNow = $('.sync-options .sync-now');
|
||||||
const elStatus = $('.sync-options .sync-status');
|
const elStatus = $('.sync-options .sync-status');
|
||||||
const elLogin = $('.sync-options .sync-login');
|
const elLogin = $('.sync-options .sync-login');
|
||||||
|
const elDriveOptions = $('.sync-options .drive-options');
|
||||||
/** @type {Sync.Status} */
|
/** @type {Sync.Status} */
|
||||||
let status = {};
|
let status = {};
|
||||||
msg.onExtension(e => {
|
msg.onExtension(e => {
|
||||||
|
@ -108,7 +109,10 @@ document.onclick = e => {
|
||||||
|
|
||||||
elCloud.on('change', updateButtons);
|
elCloud.on('change', updateButtons);
|
||||||
for (const [btn, fn] of [
|
for (const [btn, fn] of [
|
||||||
[elStart, () => API.sync.start(elCloud.value)],
|
[elStart, async () => {
|
||||||
|
await API.sync.setDriveOptions(elCloud.value, getDriveOptions());
|
||||||
|
await API.sync.start(elCloud.value);
|
||||||
|
}],
|
||||||
[elStop, API.sync.stop],
|
[elStop, API.sync.stop],
|
||||||
[elSyncNow, API.sync.syncNow],
|
[elSyncNow, API.sync.syncNow],
|
||||||
[elLogin, async () => {
|
[elLogin, async () => {
|
||||||
|
@ -123,12 +127,26 @@ document.onclick = e => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDriveOptions() {
|
||||||
|
const result = {};
|
||||||
|
for (const el of $$(`[data-drive=${elCloud.value}] [data-option]`)) {
|
||||||
|
result[el.dataset.option] = el.value;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDriveOptions(options) {
|
||||||
|
for (const el of $$(`[data-drive=${elCloud.value}] [data-option]`)) {
|
||||||
|
el.value = options[el.dataset.option] || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setStatus(newStatus) {
|
function setStatus(newStatus) {
|
||||||
status = newStatus;
|
status = newStatus;
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateButtons() {
|
async function updateButtons() {
|
||||||
const {state, STATES} = status;
|
const {state, STATES} = status;
|
||||||
const isConnected = state === STATES.connected;
|
const isConnected = state === STATES.connected;
|
||||||
const isDisconnected = state === STATES.disconnected;
|
const isDisconnected = state === STATES.disconnected;
|
||||||
|
@ -137,6 +155,7 @@ document.onclick = e => {
|
||||||
}
|
}
|
||||||
for (const [el, enable] of [
|
for (const [el, enable] of [
|
||||||
[elCloud, isDisconnected],
|
[elCloud, isDisconnected],
|
||||||
|
[elDriveOptions, isDisconnected],
|
||||||
[elStart, isDisconnected && elCloud.value !== 'none'],
|
[elStart, isDisconnected && elCloud.value !== 'none'],
|
||||||
[elStop, isConnected && !status.syncing],
|
[elStop, isConnected && !status.syncing],
|
||||||
[elSyncNow, isConnected && !status.syncing && status.login],
|
[elSyncNow, isConnected && !status.syncing && status.login],
|
||||||
|
@ -145,6 +164,10 @@ document.onclick = e => {
|
||||||
}
|
}
|
||||||
elStatus.textContent = getStatusText();
|
elStatus.textContent = getStatusText();
|
||||||
elLogin.hidden = !isConnected || status.login;
|
elLogin.hidden = !isConnected || status.login;
|
||||||
|
for (const el of elDriveOptions.children) {
|
||||||
|
el.hidden = el.dataset.drive !== elCloud.value;
|
||||||
|
}
|
||||||
|
setDriveOptions(await API.sync.getDriveOptions(elCloud.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStatusText() {
|
function getStatusText() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user