pack/templates/js/default.js

248 lines
7.2 KiB
JavaScript

const STATES = { // Either the non-d
auth: "{{ state.auth }}",
error: "{{ state.error }}",
loading: "{{ state.loading }}",
repoSelected: "{{ state.repo_selected }}",
repoCreated: "{{ state.repo_created }}",
buttonOn: "{{ state.button_on }}",
featureOn: "{{ state.feature_on }}",
confirmOn: "{{ state.confirm_on }}",
}
var G_REPO_VALUE = "",
G_CONFIRM_VALUE = "",
G_CONFIRM = -1;
// UTILITY //
// Parse a query string into an object
function parseQueryString(string) {
if(string == "") { return {}; }
var segments = string.split("&").map(s => s.split("=") );
var queryString = {};
segments.forEach(s => queryString[s[0]] = s[1]);
return queryString;
}
// BUTTON ONCLICK MIDDLEWARE //
// Refresh token if necessary.
function tryAuth(f) {
return async (e) => {
e.preventDefault();
if (!G_AUTH) return;
await tryRefresh();
await f(e);
}
}
// Adds loading classes for UI while awaiting.
function doLoading(f) {
return async (e) => {
if (e.target.hasClass("loading")) return;
e.target.addClass(STATES["loading"]);
await f(e);
e.target.delClass(STATES["loading"]);
}
}
// BUTTON ONCLICK HELPERS //
function setRepoError(s, err) {
const input = get("#repoSelectInput"),
error = get("#repoSelectError"),
info = get("#repoInfo");
error.innerText = s;
info.setClass(STATES["repoSelected"], !err);
input.setClass(STATES["error"], err);
}
function setRepoActions(s) {
get("#repoCreate").setClass(STATES["buttonOn"], !s);
get("#repoDelete").setClass(STATES["buttonOn"], s);
get("#repoSecret").setClass(STATES["buttonOn"], s);
get("#repoFeatures").setClass(STATES["repoCreated"], s);
}
async function getConfirm() {
get("#confirmOverlay").addClass(STATES["confirmOn"]);
return new Promise((resolve, reject) => {
const check = function() {
if (G_CONFIRM == -1) {
setTimeout(check, 100);
} else {
get("#confirmOverlay").delClass(STATES["confirmOn"]);
resolve(G_CONFIRM);
G_CONFIRM = -1;
}
}
check();
});
}
document.on("keydown", (e) => {
if (e.keyCode == 27) get("#confirmOverlay").delClass(STATES["confirmOn"]);
});
// BUTTON ONCLICK FUNCTIONS //
get("#repoSelectInput").on("keydown", (e) => {
if (e.keyCode === 13) {
get("#repoSelectButton").click();
return;
}
let value = e.target.value;
if (value !== G_REPO_VALUE) {
get("#repoSelectError").innerText = ""; // Delete error text.
get("#repoSelectInput").delClass(STATES["error"]); // Remove error class.
get("#repoInfo").delClass(STATES["repoSelected"]); // Remove repoSelect class.
setRepoActions(false); // Set actions to default.
get(".feature").forEach((feature) => feature.delClass(STATES["featureOn"]));
G_REPO_VALUE = value;
}
});
get("#repoSelectButton").on("click", tryAuth(doLoading(selectRepo)));
async function selectRepo(e) {
const input = get("#repoSelectInput");
let repo = input.value.trim();
input.value = repo;
if (repo === "") {
setRepoError("Field cannot be empty.", true);
return;
}
await jfetch("/api/repo/" + repo, "GET")
.then((json) => {
setRepoError("OK", false);
setRepoActions(json["exists"]);
if (json["exists"]) {
json["features"].forEach((feature) => {
get(`.feature[data-tag=${feature}]`).addClass(STATES["featureOn"]);
});
}
get("#repoLinkInput").value = CONFIG["redirect_uri"] + repo;
get("#repoInfo").addClass(STATES["repoSelected"]);
})
.catch(getErr((err) => {
console.log(err);
setRepoError("Unable to find repository or you have insufficient permissions.", true);
}));
}
get("#repoCreate").on("click", tryAuth(doLoading(createRepo)));
async function createRepo(e) {
const input = get("#repoSelectInput");
await jfetch("/api/repo/" + input.value, "POST")
.then((json) => {
setRepoActions(true);
})
.catch(getErr((err) => {
console.log(err);
alert("An unexpected error occurred! Check console for more details.");
}));
}
get("#repoDelete").on("click", tryAuth(doLoading(deleteRepo)));
async function deleteRepo(e) {
const input = get("#repoSelectInput");
if (!(await getConfirm())) return;
await jfetch("/api/repo/" + input.value, "DELETE")
.then((json) => {
setRepoActions(false);
})
.catch(getErr((err) => {
console.log(err);
alert("An unexpected error occurred! Check console for more details.");
}));
}
get("#repoSecret").on("click", tryAuth(doLoading(regenSecret)));
async function regenSecret(e) {
const input = get("#repoSelectInput");
await jfetch("/api/repo/" + input.value, "PATCH", { secret: true, feature: "" })
.then((json) => {
setRepoActions(true);
})
.catch(getErr((err) => {
console.log(err);
alert("An unexpected error occurred! Check console for more details.");
}));
}
get("#repoLinkButton").on("click", async (e) => {
const input = get("#repoLinkInput");
input.select();
input.setSelectionRange(0, 99999);
navigator.clipboard.writeText(input.value);
});
get(".feature").forEach((el) => el.on("click", tryAuth(doLoading(toggleFeature))));
async function toggleFeature(e) {
const input = get("#repoSelectInput");
let attr = e.target.getAttribute("data-tag");
if (e.target.hasClass(STATES["featureOn"]) && !(await getConfirm())) return;
await jfetch("/api/repo/" + input.value, "PATCH", { secret: false, feature: attr })
.then((json) => {
e.target.setClass(STATES["featureOn"]);
})
.catch(getErr((err) => {
console.log(err);
alert("An unexpected error occurred! Check console for more details.");
}));
}
get("#confirmInput").on("keydown", function(e) {
if (e.keyCode === 13) {
get("#confirmButtonYes").click();
return;
}
if (e.keyCode === 27) {
get("#confirmButtonNo").click();
return;
}
let value = e.target.value;
if (value !== G_CONFIRM_VALUE) {
get("#confirmInput").delClass(STATES["error"]);
G_REPO_VALUE = value;
}
});
get("#confirmButtonNo").on("click", (e) => {
G_CONFIRM = false;
get("#confirmInput").value = "";
});
get("#confirmButtonYes").on("click", (e) => {
let confirmValue = get("#confirmInput").value.trim();
let repoValue = get("#repoSelectInput").value;
if (confirmValue === repoValue) {
G_CONFIRM = true;
get("#confirmInput").value = "";
} else {
get("#confirmInput").addClass(STATES["error"]);
}
});
async function init() {
// Get query and delete URL parameters.
if(G_QUERY.error) alert("Error returned from authorization server: "+q.error); // Check for auth errors.
if(G_QUERY.code) {
await getToken();
G_AUTH = true;
window.history.replaceState({}, document.title, window.location.pathname);
}
get("body").setClass(STATES["auth"], G_AUTH);
}
var G_QUERY = parseQueryString(window.location.search.substring(1));
init();