mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 03:39:26 +00:00
Major refactor of admin view
This commit is contained in:
File diff suppressed because it is too large
Load Diff
2449
src/main/resources/static/js/admin/console.js
Normal file
2449
src/main/resources/static/js/admin/console.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,34 @@
|
||||
export function createCustomAssetModal({ broadcaster, showToast = globalThis.showToast, onAssetSaved }) {
|
||||
const assetModal = document.getElementById("custom-asset-modal");
|
||||
const userNameInput = document.getElementById("custom-asset-name");
|
||||
const userSourceTextArea = document.getElementById("custom-asset-code");
|
||||
const formErrorWrapper = document.getElementById("custom-asset-error");
|
||||
const jsErrorTitle = document.getElementById("js-error-title");
|
||||
const jsErrorDetails = document.getElementById("js-error-details");
|
||||
const form = document.getElementById("custom-asset-form");
|
||||
const cancelButton = document.getElementById("custom-asset-cancel");
|
||||
|
||||
function toggleCustomAssetModal(event) {
|
||||
if (event !== undefined && event.target !== event.currentTarget) {
|
||||
return;
|
||||
const resetErrors = () => {
|
||||
if (formErrorWrapper) {
|
||||
formErrorWrapper.classList.add("hidden");
|
||||
}
|
||||
if (assetModal.classList.contains("hidden")) {
|
||||
assetModal.classList.remove("hidden");
|
||||
if (jsErrorTitle) {
|
||||
jsErrorTitle.textContent = "";
|
||||
}
|
||||
if (jsErrorDetails) {
|
||||
jsErrorDetails.textContent = "";
|
||||
}
|
||||
};
|
||||
|
||||
const openModal = () => {
|
||||
assetModal?.classList.remove("hidden");
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
assetModal?.classList.add("hidden");
|
||||
};
|
||||
|
||||
const openNew = () => {
|
||||
if (userNameInput) {
|
||||
userNameInput.value = "";
|
||||
}
|
||||
@@ -21,38 +39,76 @@ function toggleCustomAssetModal(event) {
|
||||
userSourceTextArea.placeholder =
|
||||
"function init({ surface, assets, channel }) {\n\n}\n\nfunction tick() {\n\n}";
|
||||
}
|
||||
if (formErrorWrapper) {
|
||||
formErrorWrapper.classList.add("hidden");
|
||||
}
|
||||
if (jsErrorTitle) {
|
||||
jsErrorTitle.textContent = "";
|
||||
}
|
||||
if (jsErrorDetails) {
|
||||
jsErrorDetails.textContent = "";
|
||||
}
|
||||
} else {
|
||||
assetModal.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
resetErrors();
|
||||
openModal();
|
||||
};
|
||||
|
||||
function submitCodeAsset(formEvent) {
|
||||
const openEditor = (asset) => {
|
||||
if (!asset) {
|
||||
return;
|
||||
}
|
||||
resetErrors();
|
||||
if (userNameInput) {
|
||||
userNameInput.value = asset.name || "";
|
||||
}
|
||||
if (userSourceTextArea) {
|
||||
userSourceTextArea.value = "";
|
||||
userSourceTextArea.placeholder = "Loading script...";
|
||||
userSourceTextArea.disabled = true;
|
||||
userSourceTextArea.dataset.assetId = asset.id;
|
||||
}
|
||||
openModal();
|
||||
|
||||
fetch(asset.url)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to load script");
|
||||
}
|
||||
return response.text();
|
||||
})
|
||||
.then((text) => {
|
||||
if (userSourceTextArea) {
|
||||
userSourceTextArea.disabled = false;
|
||||
userSourceTextArea.value = text;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (userSourceTextArea) {
|
||||
userSourceTextArea.disabled = false;
|
||||
userSourceTextArea.value = "";
|
||||
}
|
||||
showToast?.("Unable to load script content.", "error");
|
||||
});
|
||||
};
|
||||
|
||||
const handleFormSubmit = (formEvent) => {
|
||||
formEvent.preventDefault();
|
||||
const src = userSourceTextArea.value;
|
||||
const src = userSourceTextArea?.value;
|
||||
const error = getUserJavaScriptSourceError(src);
|
||||
if (error) {
|
||||
if (jsErrorTitle) {
|
||||
jsErrorTitle.textContent = error.title;
|
||||
}
|
||||
if (jsErrorDetails) {
|
||||
jsErrorDetails.textContent = error.details;
|
||||
}
|
||||
if (formErrorWrapper) {
|
||||
formErrorWrapper.classList.remove("hidden");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
formErrorWrapper.classList.add("hidden");
|
||||
jsErrorTitle.textContent = "";
|
||||
jsErrorDetails.textContent = "";
|
||||
resetErrors();
|
||||
const name = userNameInput?.value?.trim();
|
||||
if (!name) {
|
||||
if (jsErrorTitle) {
|
||||
jsErrorTitle.textContent = "Missing name";
|
||||
}
|
||||
if (jsErrorDetails) {
|
||||
jsErrorDetails.textContent = "Please provide a name for your custom asset.";
|
||||
}
|
||||
if (formErrorWrapper) {
|
||||
formErrorWrapper.classList.remove("hidden");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const assetId = userSourceTextArea?.dataset?.assetId;
|
||||
@@ -63,32 +119,14 @@ function submitCodeAsset(formEvent) {
|
||||
}
|
||||
saveCodeAsset({ name, src, assetId })
|
||||
.then((asset) => {
|
||||
if (asset && typeof storeAsset === "function") {
|
||||
storeAsset(asset);
|
||||
if (typeof updateRenderState === "function") {
|
||||
updateRenderState(asset);
|
||||
}
|
||||
if (typeof selectedAssetId !== "undefined") {
|
||||
selectedAssetId = asset.id;
|
||||
}
|
||||
if (typeof updateSelectedAssetControls === "function") {
|
||||
updateSelectedAssetControls(asset);
|
||||
}
|
||||
if (typeof drawAndList === "function") {
|
||||
drawAndList();
|
||||
}
|
||||
}
|
||||
if (assetModal) {
|
||||
assetModal.classList.add("hidden");
|
||||
}
|
||||
if (typeof showToast === "function") {
|
||||
showToast(assetId ? "Custom asset updated." : "Custom asset created.", "success");
|
||||
if (asset) {
|
||||
onAssetSaved?.(asset);
|
||||
}
|
||||
closeModal();
|
||||
showToast?.(assetId ? "Custom asset updated." : "Custom asset created.", "success");
|
||||
})
|
||||
.catch((e) => {
|
||||
if (typeof showToast === "function") {
|
||||
showToast("Unable to save custom asset. Please try again.", "error");
|
||||
}
|
||||
showToast?.("Unable to save custom asset. Please try again.", "error");
|
||||
console.error(e);
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -98,7 +136,23 @@ function submitCodeAsset(formEvent) {
|
||||
}
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
if (assetModal) {
|
||||
assetModal.addEventListener("click", (event) => {
|
||||
if (event.target === assetModal) {
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (form) {
|
||||
form.addEventListener("submit", handleFormSubmit);
|
||||
}
|
||||
if (cancelButton) {
|
||||
cancelButton.addEventListener("click", () => closeModal());
|
||||
}
|
||||
|
||||
return { openNew, openEditor };
|
||||
|
||||
function saveCodeAsset({ name, src, assetId }) {
|
||||
const payload = { name, source: src };
|
||||
@@ -121,8 +175,13 @@ function saveCodeAsset({ name, src, assetId }) {
|
||||
function getUserJavaScriptSourceError(src) {
|
||||
let ast;
|
||||
|
||||
const parser = globalThis.acorn;
|
||||
if (!parser) {
|
||||
return { title: "Parser unavailable", details: "JavaScript parser is not available yet." };
|
||||
}
|
||||
|
||||
try {
|
||||
ast = acorn.parse(src, {
|
||||
ast = parser.parse(src, {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "script",
|
||||
});
|
||||
@@ -170,3 +229,4 @@ function getUserJavaScriptSourceError(src) {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
class="file-input-field"
|
||||
type="file"
|
||||
accept="image/*,video/*,audio/*,application/javascript,text/javascript,.js,.mjs"
|
||||
onchange="handleFileSelection(this)"
|
||||
/>
|
||||
<label for="asset-file" class="file-input-trigger">
|
||||
<span class="file-input-icon"><i class="fa-solid fa-cloud-arrow-up"></i></span>
|
||||
@@ -373,10 +372,10 @@
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div id="custom-asset-modal" class="modal hidden" onclick="toggleCustomAssetModal(event)">
|
||||
<div id="custom-asset-modal" class="modal hidden">
|
||||
<section class="modal-inner">
|
||||
<h1>Create Custom Asset</h1>
|
||||
<form id="custom-asset-form" onsubmit="submitCodeAsset(event)">
|
||||
<form id="custom-asset-form">
|
||||
<div class="form-group">
|
||||
<label for="custom-asset-name">Asset name</label>
|
||||
<input
|
||||
@@ -402,7 +401,7 @@
|
||||
<pre id="js-error-details"></pre>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="button" class="secondary" onclick="toggleCustomAssetModal(event)">Cancel</button>
|
||||
<button type="button" class="secondary" id="custom-asset-cancel">Cancel</button>
|
||||
<button type="submit" class="primary">Test and save</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -416,7 +415,6 @@
|
||||
</script>
|
||||
<script src="/js/cookie-consent.js"></script>
|
||||
<script src="/js/toast.js"></script>
|
||||
<script src="/js/customAssets.js"></script>
|
||||
<script type="module" src="/js/admin.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user