Remove server validation

This commit is contained in:
2026-01-08 14:04:49 +01:00
parent 6e29256ee9
commit 9f41ecce5a
8 changed files with 295 additions and 10 deletions

View File

@@ -126,6 +126,7 @@ function renderAssets(list) {
function storeAsset(asset, placement = "keep") {
if (!asset) return;
console.info(`Storing asset: ${asset.id}`);
const wasExisting = assets.has(asset.id);
assets.set(asset.id, asset);
ensureLayerPosition(asset.id, placement);
@@ -135,7 +136,7 @@ function storeAsset(asset, placement = "keep") {
}
}
function fetchCanvasSettings() {
async function fetchCanvasSettings() {
return fetch(`/api/channels/${encodeURIComponent(broadcaster)}/canvas`)
.then((r) => {
if (!r.ok) {
@@ -289,8 +290,8 @@ function applyPatch(assetId, patch) {
const targetLayer = Number.isFinite(patch.layer)
? patch.layer
: Number.isFinite(patch.zIndex)
? patch.zIndex
: null;
? patch.zIndex
: null;
if (!isAudio && Number.isFinite(targetLayer)) {
const currentOrder = getLayerOrder().filter((id) => id !== assetId);
const insertIndex = Math.max(0, currentOrder.length - Math.round(targetLayer));
@@ -793,7 +794,7 @@ function setVideoSource(element, asset) {
}
applyVideoSource(element, next.objectUrl, asset);
})
.catch(() => {});
.catch(() => { });
}
function applyVideoSource(element, objectUrl, asset) {

View File

@@ -1,2 +1,15 @@
function spawnUserJavaScriptWorker(jsSource, data) {
async function spawnUserJavaScriptWorker(asset) {
let assetSource;
try {
assetSource = await fetch(asset.url).then((r) => r.text());
} catch (error) {
console.error(`Unable to fetch asset with id:${id} from url:${asset.url}`, error);
return;
}
const blob = new Blob([assetSource], { type: 'application/javascript' });
const worker = new Worker(URL.createObjectURL(blob));
worker.onmessage = (event) => {
console.log('Message from worker:', event.data);
}
worker.postMessage(data);
}

View File

@@ -1,4 +1,5 @@
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");
@@ -10,6 +11,25 @@ function toggleCustomAssetModal(event) {
}
if (assetModal.classList.contains("hidden")) {
assetModal.classList.remove("hidden");
if (userNameInput) {
userNameInput.value = "";
}
if (userSourceTextArea) {
userSourceTextArea.value = "";
userSourceTextArea.disabled = false;
userSourceTextArea.dataset.assetId = "";
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");
}
@@ -28,9 +48,76 @@ function submitCodeAsset(formEvent) {
formErrorWrapper.classList.add("hidden");
jsErrorTitle.textContent = "";
jsErrorDetails.textContent = "";
const name = userNameInput?.value?.trim();
if (!name) {
jsErrorTitle.textContent = "Missing name";
jsErrorDetails.textContent = "Please provide a name for your custom asset.";
formErrorWrapper.classList.remove("hidden");
return false;
}
const assetId = userSourceTextArea?.dataset?.assetId;
const submitButton = formEvent.currentTarget?.querySelector('button[type="submit"]');
if (submitButton) {
submitButton.disabled = true;
submitButton.textContent = "Saving...";
}
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");
}
})
.catch((e) => {
if (typeof showToast === "function") {
showToast("Unable to save custom asset. Please try again.", "error");
}
console.error(e);
})
.finally(() => {
if (submitButton) {
submitButton.disabled = false;
submitButton.textContent = "Test and save";
}
});
return false;
}
function saveCodeAsset({ name, src, assetId }) {
const payload = { name, source: src };
const method = assetId ? "PUT" : "POST";
const url = assetId
? `/api/channels/${encodeURIComponent(broadcaster)}/assets/${assetId}/code`
: `/api/channels/${encodeURIComponent(broadcaster)}/assets/code`;
return fetch(url, {
method,
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
}).then((response) => {
if (!response.ok) {
throw new Error("Failed to save code asset");
}
return response.json();
});
}
function getUserJavaScriptSourceError(src) {
let ast;