mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
dropbox - load script dynamically
This commit is contained in:
parent
8e480be704
commit
aee78071c6
5 changed files with 100 additions and 88 deletions
31
dropbox.html
31
dropbox.html
|
|
@ -7,35 +7,34 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
/*
|
// open this page in a new window without query parameter to start auth
|
||||||
open this page in a new window without query parameter to start auth
|
// setDropBoxToken(token) will be called on the opener window
|
||||||
window.opener.setDropBoxToken(token) will be called on the opener
|
|
||||||
window.
|
|
||||||
*/
|
|
||||||
const REDIRECT_URI = window.location.origin + window.location.pathname;
|
const REDIRECT_URI = window.location.origin + window.location.pathname;
|
||||||
const dbxAuth = new Dropbox.DropboxAuth({clientId: "pdr9ae64ip0qno4"});
|
const auth = new Dropbox.DropboxAuth({clientId: "pdr9ae64ip0qno4"});
|
||||||
|
|
||||||
const spObj = new URLSearchParams(window.location.search);
|
const params = new URLSearchParams(window.location.search);
|
||||||
const searchParams = Object.fromEntries(spObj.entries());
|
const code = params.get("code");
|
||||||
|
const error = params.get("error");
|
||||||
|
|
||||||
if (searchParams.code) getToken();
|
if (code) getToken();
|
||||||
else doAuth(); // start authentication
|
else if (error) window.opener.Cloud.providers.dropbox.returnError(params.get("error_description"));
|
||||||
|
else startAuth();
|
||||||
|
|
||||||
function doAuth() {
|
function startAuth() {
|
||||||
dbxAuth
|
auth
|
||||||
.getAuthenticationUrl(REDIRECT_URI, undefined, "code", "offline", undefined, undefined, true)
|
.getAuthenticationUrl(REDIRECT_URI, undefined, "code", "offline", undefined, undefined, true)
|
||||||
.then(authUrl => {
|
.then(authUrl => {
|
||||||
window.sessionStorage.clear();
|
window.sessionStorage.clear();
|
||||||
window.sessionStorage.setItem("codeVerifier", dbxAuth.codeVerifier);
|
window.sessionStorage.setItem("codeVerifier", auth.codeVerifier);
|
||||||
window.location.href = authUrl;
|
window.location.href = authUrl;
|
||||||
})
|
})
|
||||||
.catch(error => console.error(error));
|
.catch(error => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getToken() {
|
function getToken() {
|
||||||
dbxAuth.setCodeVerifier(window.sessionStorage.getItem("codeVerifier"));
|
auth.setCodeVerifier(window.sessionStorage.getItem("codeVerifier"));
|
||||||
dbxAuth
|
auth
|
||||||
.getAccessTokenFromCode(REDIRECT_URI, searchParams.code)
|
.getAccessTokenFromCode(REDIRECT_URI, code)
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
const token = resp.result.access_token;
|
const token = resp.result.access_token;
|
||||||
window.opener.Cloud.providers.dropbox.setDropBoxToken(token);
|
window.opener.Cloud.providers.dropbox.setDropBoxToken(token);
|
||||||
|
|
|
||||||
14
index.html
14
index.html
|
|
@ -3586,12 +3586,15 @@
|
||||||
<button onclick="quickLoad()" data-tip="Load map from browser storage (if saved before)">storage</button>
|
<button onclick="quickLoad()" data-tip="Load map from browser storage (if saved before)">storage</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="loadFromDropbox">
|
<div id="loadFromDropbox">
|
||||||
<p style="margin-bottom: .3em">From your Dropbox account</p>
|
<p style="margin-bottom: .3em">
|
||||||
<select id="loadFromDropboxSelect" style="width: 22em"></select>
|
From your Dropbox account
|
||||||
|
<button id="dropboxConnectButton" onclick="connectToDropbox()" data-tip="Connect your Dropbox account to be able to load maps from it">Connect</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
<div id="loadFromDropboxButtons" style="margin-bottom: .3em">
|
<select id="loadFromDropboxSelect" style="width: 22em"></select>
|
||||||
<button onclick="loadFromDropbox()" data-tip="Load .map file from your Dropbox">Open</button>
|
<div id="loadFromDropboxButtons" style="margin-bottom: .6em">
|
||||||
<button onclick="createSharableDropboxLink()" data-tip="Select file and create a link to share with your friends">Create link</button>
|
<button onclick="loadFromDropbox()" data-tip="Load .map file from your Dropbox">Load</button>
|
||||||
|
<button onclick="createSharableDropboxLink()" data-tip="Select file and create a link to share with your friends">Share</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top: .3em">
|
<div style="margin-top: .3em">
|
||||||
|
|
@ -4547,7 +4550,6 @@
|
||||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||||
<script defer src="libs/pell.min.js"></script>
|
<script defer src="libs/pell.min.js"></script>
|
||||||
<script defer src="libs/jszip.min.js"></script>
|
<script defer src="libs/jszip.min.js"></script>
|
||||||
<script defer src="https://unpkg.com/dropbox@10.8.0/dist/Dropbox-sdk.min.js"></script>
|
|
||||||
|
|
||||||
<script defer src="modules/io/save.js"></script>
|
<script defer src="modules/io/save.js"></script>
|
||||||
<script defer src="modules/io/load.js"></script>
|
<script defer src="modules/io/load.js"></script>
|
||||||
|
|
|
||||||
4
main.js
4
main.js
|
|
@ -213,7 +213,9 @@ function checkLoadParameters() {
|
||||||
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
|
||||||
const valid = pattern.test(maplink);
|
const valid = pattern.test(maplink);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
loadMapFromURL(maplink, 1);
|
setTimeout(() => {
|
||||||
|
loadMapFromURL(maplink, 1);
|
||||||
|
}, 1000);
|
||||||
return;
|
return;
|
||||||
} else showUploadErrorMessage("Map link is not a valid URL", maplink);
|
} else showUploadErrorMessage("Map link is not a valid URL", maplink);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ async load(filename): load filename from provider
|
||||||
async list(): list available filenames at provider
|
async list(): list available filenames at provider
|
||||||
async getLink(filePath): get shareable link for file
|
async getLink(filePath): get shareable link for file
|
||||||
restore(): restore access tokens from storage if possible
|
restore(): restore access tokens from storage if possible
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window.Cloud = (function () {
|
window.Cloud = (function () {
|
||||||
|
|
@ -32,38 +31,40 @@ window.Cloud = (function () {
|
||||||
token: null, // Access token
|
token: null, // Access token
|
||||||
api: null,
|
api: null,
|
||||||
|
|
||||||
restore() {
|
|
||||||
this.token = getToken(this.name);
|
|
||||||
if (this.token) this.connect(this.token);
|
|
||||||
},
|
|
||||||
|
|
||||||
async call(name, param) {
|
async call(name, param) {
|
||||||
try {
|
try {
|
||||||
|
if (!this.api) await this.initialize();
|
||||||
return await this.api[name](param);
|
return await this.api[name](param);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.name !== "DropboxResponseError") throw e;
|
if (e.name !== "DropboxResponseError") throw e;
|
||||||
// retry with auth
|
await this.auth(); // retry with auth
|
||||||
await this.auth();
|
|
||||||
return await this.api[name](param);
|
return await this.api[name](param);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
connect(token) {
|
initialize() {
|
||||||
const clientId = this.clientId;
|
const token = getToken(this.name);
|
||||||
const auth = new Dropbox.DropboxAuth({clientId});
|
if (token) {
|
||||||
|
return this.connect(token);
|
||||||
|
} else {
|
||||||
|
return this.auth();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async connect(token) {
|
||||||
|
await import("https://unpkg.com/dropbox@10.8.0/dist/Dropbox-sdk.min.js");
|
||||||
|
const auth = new Dropbox.DropboxAuth({clientId: this.clientId});
|
||||||
auth.setAccessToken(token);
|
auth.setAccessToken(token);
|
||||||
this.api = new Dropbox.Dropbox({auth});
|
this.api = new Dropbox.Dropbox({auth});
|
||||||
},
|
},
|
||||||
|
|
||||||
async save(fileName, contents) {
|
async save(fileName, contents) {
|
||||||
if (!this.api) await this.auth();
|
const resp = await this.call("filesUpload", {path: "/" + fileName, contents});
|
||||||
const resp = this.call("filesUpload", {path: "/" + fileName, contents});
|
|
||||||
DEBUG && console.log("Dropbox response:", resp);
|
DEBUG && console.log("Dropbox response:", resp);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
async load(path) {
|
async load(path) {
|
||||||
if (!this.api) await this.auth();
|
|
||||||
const resp = await this.call("filesDownload", {path});
|
const resp = await this.call("filesDownload", {path});
|
||||||
const blob = resp.result.fileBlob;
|
const blob = resp.result.fileBlob;
|
||||||
if (!blob) throw new Error("Invalid response from dropbox.");
|
if (!blob) throw new Error("Invalid response from dropbox.");
|
||||||
|
|
@ -71,22 +72,23 @@ window.Cloud = (function () {
|
||||||
},
|
},
|
||||||
|
|
||||||
async list() {
|
async list() {
|
||||||
if (!this.api) return null;
|
|
||||||
const resp = await this.call("filesListFolder", {path: ""});
|
const resp = await this.call("filesListFolder", {path: ""});
|
||||||
return resp.result.entries.map(e => ({name: e.name, path: e.path_lower}));
|
return resp.result.entries.map(e => ({name: e.name, path: e.path_lower}));
|
||||||
},
|
},
|
||||||
|
|
||||||
auth() {
|
auth() {
|
||||||
const url = window.location.origin + window.location.pathname + "dropbox.html";
|
const width = 640;
|
||||||
this.authWindow = window.open(url, "auth", "width=640,height=480");
|
const height = 480;
|
||||||
// child window expected to call
|
const left = window.innerWidth / 2 - width / 2;
|
||||||
// window.opener.Cloud.providers.dropbox.setDropBoxToken (see below)
|
const top = window.innerHeight / 2 - height / 2.5;
|
||||||
|
this.authWindow = window.open("./dropbox.html", "auth", `width=640, height=${height}, top=${top}, left=${left}}`);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const watchDog = () => {
|
const watchDog = setTimeout(() => {
|
||||||
this.authWindow.close();
|
this.authWindow.close();
|
||||||
reject(new Error("Timeout. No auth for dropbox."));
|
reject(new Error("Timeout. No auth for Dropbox"));
|
||||||
};
|
}, 120 * 1000);
|
||||||
setTimeout(watchDog, 120 * 1000);
|
|
||||||
window.addEventListener("dropboxauth", e => {
|
window.addEventListener("dropboxauth", e => {
|
||||||
clearTimeout(watchDog);
|
clearTimeout(watchDog);
|
||||||
resolve();
|
resolve();
|
||||||
|
|
@ -94,46 +96,34 @@ window.Cloud = (function () {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Callback function for auth window.
|
// Callback function for auth window
|
||||||
setDropBoxToken(token) {
|
async setDropBoxToken(token) {
|
||||||
DEBUG && console.log("Access token:", token);
|
DEBUG && console.log("Access token:", token);
|
||||||
setToken(this.name, token);
|
setToken(this.name, token);
|
||||||
this.connect(token);
|
await this.connect(token);
|
||||||
this.authWindow.close();
|
this.authWindow.close();
|
||||||
window.dispatchEvent(new Event("dropboxauth"));
|
window.dispatchEvent(new Event("dropboxauth"));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
returnError(errorDescription) {
|
||||||
|
console.error(errorDescription);
|
||||||
|
tip(errorDescription.replaceAll("+", " "), true, "error", 4000);
|
||||||
|
this.authWindow.close();
|
||||||
|
},
|
||||||
|
|
||||||
async getLink(path) {
|
async getLink(path) {
|
||||||
if (!this.api) await this.auth();
|
// return existitng shared link
|
||||||
let resp;
|
const sharedLinks = await this.call("sharingListSharedLinks", {path});
|
||||||
|
if (sharedLinks.result.links.length) return resp.result.links[0].url;
|
||||||
|
|
||||||
// already exists?
|
// create new shared link
|
||||||
resp = await this.call("sharingListSharedLinks", {path});
|
const settings = {require_password: false, audience: "public", access: "viewer", requested_visibility: "public", allow_download: true};
|
||||||
if (resp.result.links.length) return resp.result.links[0].url;
|
const resp = await this.call("sharingCreateSharedLinkWithSettings", {path, settings});
|
||||||
|
|
||||||
// create new
|
|
||||||
resp = await this.call("sharingCreateSharedLinkWithSettings", {
|
|
||||||
path,
|
|
||||||
settings: {
|
|
||||||
require_password: false,
|
|
||||||
audience: "public",
|
|
||||||
access: "viewer",
|
|
||||||
requested_visibility: "public",
|
|
||||||
allow_download: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
DEBUG && console.log("Dropbox link object:", resp.result);
|
DEBUG && console.log("Dropbox link object:", resp.result);
|
||||||
return resp.result.url;
|
return resp.result.url;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// register providers here:
|
const providers = {dropbox: DBP};
|
||||||
const providers = {
|
|
||||||
dropbox: DBP
|
|
||||||
};
|
|
||||||
|
|
||||||
// restore all providers at startup
|
|
||||||
for (const p of Object.values(providers)) p.restore();
|
|
||||||
|
|
||||||
return {providers};
|
return {providers};
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -737,24 +737,43 @@ async function showLoadPane() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadFromDropboxButtons = document.getElementById("loadFromDropboxButtons");
|
// already connected to Dropbox: list saved maps
|
||||||
const fileSelect = document.getElementById("loadFromDropboxSelect");
|
if (Cloud.providers.dropbox.api) {
|
||||||
const files = await Cloud.providers.dropbox.list();
|
document.getElementById("dropboxConnectButton").style.display = "none";
|
||||||
|
document.getElementById("loadFromDropboxSelect").style.display = "block";
|
||||||
|
const loadFromDropboxButtons = document.getElementById("loadFromDropboxButtons");
|
||||||
|
const fileSelect = document.getElementById("loadFromDropboxSelect");
|
||||||
|
fileSelect.innerHTML = `<option value="" disabled selected>Loading...</option>`;
|
||||||
|
|
||||||
|
const files = await Cloud.providers.dropbox.list();
|
||||||
|
|
||||||
|
if (!files) {
|
||||||
|
loadFromDropboxButtons.style.display = "none";
|
||||||
|
fileSelect.innerHTML = `<option value="" disabled selected>Save files to Dropbox first</option>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadFromDropboxButtons.style.display = "block";
|
||||||
|
fileSelect.innerHTML = "";
|
||||||
|
files.forEach(file => {
|
||||||
|
const opt = document.createElement("option");
|
||||||
|
opt.innerText = file.name;
|
||||||
|
opt.value = file.path;
|
||||||
|
fileSelect.appendChild(opt);
|
||||||
|
});
|
||||||
|
|
||||||
if (!files) {
|
|
||||||
loadFromDropboxButtons.style.display = "none";
|
|
||||||
fileSelect.innerHTML = `<option value="" disabled selected>Save files to Dropbox first</option>`;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFromDropboxButtons.style.display = "block";
|
// not connected to Dropbox: show connect button
|
||||||
fileSelect.innerHTML = "";
|
document.getElementById("dropboxConnectButton").style.display = "inline-block";
|
||||||
files.forEach(file => {
|
document.getElementById("loadFromDropboxButtons").style.display = "none";
|
||||||
const opt = document.createElement("option");
|
document.getElementById("loadFromDropboxSelect").style.display = "none";
|
||||||
opt.innerText = file.name;
|
}
|
||||||
opt.value = file.path;
|
|
||||||
fileSelect.appendChild(opt);
|
async function connectToDropbox() {
|
||||||
});
|
await Cloud.providers.dropbox.initialize();
|
||||||
|
if (Cloud.providers.dropbox.api) showLoadPane();
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadURL() {
|
function loadURL() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue