diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index c65b08a7..3e6a9326 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -1200,6 +1200,15 @@
}
}
},
+ "optionsSyncUsername": {
+ "message": "Username"
+ },
+ "optionsSyncPassword": {
+ "message": "Password"
+ },
+ "optionsSyncUrl": {
+ "message": "URL"
+ },
"optionsSyncStatusRelogin": {
"message": "Session expired, please login again."
},
diff --git a/background/sync-manager.js b/background/sync-manager.js
index cb51498d..e1aafd4e 100644
--- a/background/sync-manager.js
+++ b/background/sync-manager.js
@@ -1,5 +1,5 @@
/* global API msg */// msg.js
-/* global chromeLocal */// storage-util.js
+/* global chromeLocal chromeSync */// storage-util.js
/* global compareRevision */// common.js
/* global iconMan */
/* global prefs */
@@ -18,6 +18,7 @@ const syncMan = (() => {
disconnecting: 'disconnecting',
});
const STORAGE_KEY = 'sync/state/';
+ const NO_LOGIN = ['webdav'];
const status = /** @namespace SyncManager.Status */ {
STATES,
state: STATES.disconnected,
@@ -85,19 +86,29 @@ const syncMan = (() => {
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) {
if (ready.then) await ready;
if (!ctrl) await initController();
if (currentDrive) return;
- currentDrive = getDrive(name);
+ currentDrive = await getDrive(name);
ctrl.use(currentDrive);
status.state = STATES.connecting;
status.currentDriveName = currentDrive.name;
emitStatusChange();
- if (fromPref) {
+ if (fromPref || NO_LOGIN.includes(currentDrive.name)) {
status.login = true;
} else {
try {
@@ -240,11 +251,11 @@ const syncMan = (() => {
}
}
- function getDrive(name) {
- if (name === 'dropbox' || name === 'google' || name === 'onedrive') {
- return dbToCloud.drive[name]({
- getAccessToken: () => tokenMan.getToken(name),
- });
+ async function getDrive(name) {
+ if (name === 'dropbox' || name === 'google' || name === 'onedrive' || name === 'webdav') {
+ const options = await syncMan.getDriveOptions(name);
+ options.getAccessToken = () => tokenMan.getToken(name);
+ return dbToCloud.drive[name](options);
}
throw new Error(`unknown cloud name: ${name}`);
}
diff --git a/options.html b/options.html
index a6170f82..7705accf 100644
--- a/options.html
+++ b/options.html
@@ -199,10 +199,27 @@
+
+
diff --git a/options/options.css b/options/options.css
index 283522bd..8ace53b5 100644
--- a/options/options.css
+++ b/options/options.css
@@ -163,7 +163,7 @@ label > :first-child {
}
label:not([disabled]),
-label:not([disabled]) :not([type="number"]) {
+label:not([disabled]) :not([type="number"]):not([type="text"]):not([type="password"]) {
cursor: pointer;
}
@@ -437,7 +437,25 @@ input[type="radio"].radio:checked::after {
.sync-status::first-letter {
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 {
margin-top: .5em;
}
diff --git a/options/options.js b/options/options.js
index 9d8c061e..fbaa7f12 100644
--- a/options/options.js
+++ b/options/options.js
@@ -96,6 +96,7 @@ document.onclick = e => {
const elSyncNow = $('.sync-options .sync-now');
const elStatus = $('.sync-options .sync-status');
const elLogin = $('.sync-options .sync-login');
+ const elDriveOptions = $('.sync-options .drive-options');
/** @type {Sync.Status} */
let status = {};
msg.onExtension(e => {
@@ -108,7 +109,10 @@ document.onclick = e => {
elCloud.on('change', updateButtons);
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],
[elSyncNow, API.sync.syncNow],
[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) {
status = newStatus;
updateButtons();
}
- function updateButtons() {
+ async function updateButtons() {
const {state, STATES} = status;
const isConnected = state === STATES.connected;
const isDisconnected = state === STATES.disconnected;
@@ -137,6 +155,7 @@ document.onclick = e => {
}
for (const [el, enable] of [
[elCloud, isDisconnected],
+ [elDriveOptions, isDisconnected],
[elStart, isDisconnected && elCloud.value !== 'none'],
[elStop, isConnected && !status.syncing],
[elSyncNow, isConnected && !status.syncing && status.login],
@@ -145,6 +164,10 @@ document.onclick = e => {
}
elStatus.textContent = getStatusText();
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() {