Compare commits

..

No commits in common. "main" and "bugfix/video-handling-in-reply" have entirely different histories.

View File

@ -1,6 +1,6 @@
{% extends "app.html" %} {% 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 %} {% block main %}
{% include "channel.html" %} {% include "channel.html" %}
@ -8,11 +8,11 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm/css/xterm.css"> <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/lib/xterm.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit/lib/xterm-addon-fit.js"></script> <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit/lib/xterm-addon-fit.js"></script>
<div id="terminal" class="hidden"></div> <div id="terminal" class="hidden"></div>
<message-list class="chat-messages"> <message-list class="chat-messages">
{% if not messages %} {% if not messages %}
<div> <div>
<h1>Welcome to your new channel!</h1> <h1>Welcome to your new channel!</h1>
<p>This is the start of something great. Use the commands below to get started:</p> <p>This is the start of something great. Use the commands below to get started:</p>
@ -37,9 +37,10 @@
{% include "dialog_help.html" %} {% include "dialog_help.html" %}
{% include "dialog_online.html" %} {% include "dialog_online.html" %}
<script type="module"> <script type="module">
import {app} from "/app.js"; import { app } from "/app.js";
import { Schedule } from "/schedule.js";
// --- Cache selectors --- // --- Cache selectors ---
const chatInputField = document.querySelector("chat-input"); const chatInputField = document.querySelector("chat-input");
const messagesContainer = document.querySelector(".chat-messages"); const messagesContainer = document.querySelector(".chat-messages");
const chatArea = document.querySelector(".chat-area"); const chatArea = document.querySelector(".chat-area");
@ -51,7 +52,7 @@ chatInputField.autoCompletions = {
"/clear": () => { messagesContainer.innerHTML = ''; }, "/clear": () => { messagesContainer.innerHTML = ''; },
"/live": () => { chatInputField.liveType = !chatInputField.liveType; }, "/live": () => { chatInputField.liveType = !chatInputField.liveType; },
"/help": showHelp, "/help": showHelp,
"/container": async() =>{ "/container": async() =>{
containerDialog.openWithStatus() containerDialog.openWithStatus()
} }
}; };
@ -98,61 +99,21 @@ setInterval(() => requestIdleCallback(updateTimes), 30000);
// --- Paste & drag/drop uploads --- // --- Paste & drag/drop uploads ---
const textBox = chatInputField.textarea; const textBox = chatInputField.textarea;
function uploadDataTransfer(dt) {
if (dt.items.length > 0) {
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)
} else {
console.error("Failed to get file from DataTransferItem");
}
}
}
}
}
textBox.addEventListener("paste", async (e) => { textBox.addEventListener("paste", async (e) => {
try { try {
console.log("Pasted data:", e.clipboardData); const clipboardItems = await navigator.clipboard.read();
if (e.clipboardData.types.every(v => v.startsWith("text/"))) { const dt = new DataTransfer();
const codeType = e.clipboardData.types.find(t => !t.startsWith('text/plain') && !t.startsWith('text/html') && !t.startsWith('text/rtf')); for (const item of clipboardItems) {
const probablyCode = codeType ||e.clipboardData.types.some(t => !t.startsWith('text/plain')); for (const type of item.types.filter(t => !t.startsWith('text/'))) {
for (const item of e.clipboardData.items) { const blob = await item.getType(type);
if (item.kind === "string" && item.type === "text/plain") { dt.items.add(new File([blob], "image.png", { type }));
e.preventDefault();
item.getAsString(text => {
const value = chatInputField.value;
if (probablyCode) {
let code = 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')
text = `\`\`\`${codeType?.split('/')?.[1] ?? ''}\n${code}\n\`\`\`\n`;
}
const area = chatInputField.textarea
if(area){
const start = area.selectionStart
if ("\n" !== value[start - 1]) {
text = `\n${text}`;
}
document.execCommand('insertText', false, text);
}
});
break;
}
} }
} else { }
uploadDataTransfer(e.clipboardData); 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) { } catch (error) {
console.error("Failed to read clipboard contents: ", error); console.error("Failed to read clipboard contents: ", error);
@ -160,7 +121,13 @@ textBox.addEventListener("paste", async (e) => {
}); });
chatArea.addEventListener("drop", async (e) => { chatArea.addEventListener("drop", async (e) => {
e.preventDefault(); e.preventDefault();
uploadDataTransfer(e.dataTransfer); 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();
}
}); });
chatArea.addEventListener("dragover", e => { chatArea.addEventListener("dragover", e => {
e.preventDefault(); e.preventDefault();
@ -213,7 +180,7 @@ app.ws.addEventListener("starfield.render_word", (data) => {
// --- Channel message event --- // --- Channel message event ---
app.addEventListener("channel-message", (data) => { app.addEventListener("channel-message", (data) => {
let display = data.text && data.text.trim() ? 'block' : 'none'; let display = data.text && data.text.trim() ? 'block' : 'none';
if (data.channel_uid !== channelUid) { if (data.channel_uid !== channelUid) {
@ -254,7 +221,7 @@ document.addEventListener('keydown', function(event) {
clearTimeout(keyTimeout); clearTimeout(keyTimeout);
keyTimeout = setTimeout(() => { gPressCount = 0; }, 300); keyTimeout = setTimeout(() => { gPressCount = 0; }, 300);
if (gPressCount === 2) { if (gPressCount === 2) {
gPressCount = 0; gPressCount = 0;
messagesContainer.lastElementChild?.scrollIntoView({ block: "end", inline: "nearest" }); messagesContainer.lastElementChild?.scrollIntoView({ block: "end", inline: "nearest" });
loadExtra(); loadExtra();
} }