Fixed upload handling #72
@ -1,6 +1,6 @@
 | 
			
		||||
{% extends "app.html" %}
 | 
			
		||||
 | 
			
		||||
{% block header_text %}<h2 style="color:#fff">{{ name }}</h2>{% endblock %} 
 | 
			
		||||
{% block header_text %}<h2 style="color:#fff">{{ name }}</h2>{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block main %}
 | 
			
		||||
{% include "channel.html" %}
 | 
			
		||||
@ -8,11 +8,11 @@
 | 
			
		||||
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm/css/xterm.css">
 | 
			
		||||
    <script src="https://cdn.jsdelivr.net/npm/xterm/lib/xterm.js"></script>
 | 
			
		||||
    <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit/lib/xterm-addon-fit.js"></script>
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    <div id="terminal" class="hidden"></div>
 | 
			
		||||
        <message-list class="chat-messages">
 | 
			
		||||
        {% if not messages %}
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        <div>
 | 
			
		||||
          <h1>Welcome to your new channel!</h1>
 | 
			
		||||
          <p>This is the start of something great. Use the commands below to get started:</p>
 | 
			
		||||
@ -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();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user