From b99339ea93f873985f8a95afb42f371082d31680 Mon Sep 17 00:00:00 2001 From: BordedDev <> Date: Sat, 4 Oct 2025 16:30:54 +0200 Subject: [PATCH] Fixed upload handling --- src/snek/templates/web.html | 70 ++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/src/snek/templates/web.html b/src/snek/templates/web.html index 0e60bec..217ddb4 100644 --- a/src/snek/templates/web.html +++ b/src/snek/templates/web.html @@ -1,6 +1,6 @@ {% extends "app.html" %} -{% block header_text %}

{{ name }}

{% endblock %} +{% block header_text %}

{{ name }}

{% endblock %} {% block main %} {% include "channel.html" %} @@ -8,11 +8,11 @@ - + {% if not messages %} - +

Welcome to your new channel!

This is the start of something great. Use the commands below to get started:

@@ -52,7 +52,7 @@ chatInputField.autoCompletions = { "/clear": () => { messagesContainer.innerHTML = ''; }, "/live": () => { chatInputField.liveType = !chatInputField.liveType; }, "/help": showHelp, - "/container": async() =>{ + "/container": async() =>{ containerDialog.openWithStatus() } }; @@ -101,19 +101,40 @@ setInterval(() => requestIdleCallback(updateTimes), 30000); const textBox = chatInputField.textarea; textBox.addEventListener("paste", async (e) => { try { - const clipboardItems = await navigator.clipboard.read(); - const dt = new DataTransfer(); + e.preventDefault(); + const uploadButton = chatInputField.fileUploadGrid; + + const clipboardItems = await navigator.clipboard.read() + for (const item of clipboardItems) { - for (const type of item.types.filter(t => !t.startsWith('text/'))) { - const blob = await item.getType(type); - dt.items.add(new File([blob], "image.png", { type })); + if (item.types.every(v => v === "text/plain")) { + const text = await (await item.getType("text/plain")).text(); + chatInputField.value += text; + continue + } + + if (item.types.every(t => t.startsWith('text/'))) { + console.log("All types are text:", item.types); + const codeType = item.types.find(t => !t.startsWith('text/plain') && !t.startsWith('text/html')); + let code = await(await item.getType(codeType ?? 'text/plain')).text(); + + const minIndentDepth = code.split('\n').reduce((acc, line) => { + if (!line.trim()) return acc; + const match = line.match(/^(\s*)/); + return match ? Math.min(acc, match[1].length) : acc; + }, 9000) + + code = code.split('\n').map(line => line.slice(minIndentDepth)).join('\n') + + chatInputField.value += `\`\`\`${codeType?.split('/')?.[1] ?? ''}\n${code}\n\`\`\`\n`; + } else { + for (const type of item.types.filter(t => !t.startsWith('text/'))) { + const blob = await item.getType(type); + const name = type.replace('/', '.') + uploadButton.uploadsStarted++ + uploadButton.createTile(new File([blob], name, {type})) + } } - } - if (dt.items.length > 0) { - const uploadButton = chatInputField.uploadButton; - const input = uploadButton.shadowRoot.querySelector('.file-input'); - input.files = dt.files; - await uploadButton.uploadFiles(); } } catch (error) { console.error("Failed to read clipboard contents: ", error); @@ -123,10 +144,17 @@ chatArea.addEventListener("drop", async (e) => { e.preventDefault(); const dt = e.dataTransfer; if (dt.items.length > 0) { - const uploadButton = chatInputField.uploadButton; - const input = uploadButton.shadowRoot.querySelector('.file-input'); - input.files = dt.files; - await uploadButton.uploadFiles(); + const uploadButton = chatInputField.fileUploadGrid; + + for (const item of dt.items) { + if (item.kind === "file") { + const file = item.getAsFile(); + if (file) { + uploadButton.uploadsStarted++ + uploadButton.createTile(file) + } + } + } } }); chatArea.addEventListener("dragover", e => { @@ -180,7 +208,7 @@ app.ws.addEventListener("starfield.render_word", (data) => { // --- Channel message event --- app.addEventListener("channel-message", (data) => { - + let display = data.text && data.text.trim() ? 'block' : 'none'; if (data.channel_uid !== channelUid) { @@ -221,7 +249,7 @@ document.addEventListener('keydown', function(event) { clearTimeout(keyTimeout); keyTimeout = setTimeout(() => { gPressCount = 0; }, 300); if (gPressCount === 2) { - gPressCount = 0; + gPressCount = 0; messagesContainer.lastElementChild?.scrollIntoView({ block: "end", inline: "nearest" }); loadExtra(); }