feature: file uploads and audio embedding

This commit is contained in:
Andy Burke 2025-08-20 11:48:16 -07:00
parent 2224e1abe0
commit 4c0a8bb700
7 changed files with 105 additions and 22 deletions

View file

@ -89,9 +89,16 @@
<div id="room-chat-content"></div>
<div id="room-chat-entry-container">
<form id="room-chat-entry" action="" data-smart="true" data-method="POST">
<button aria-label="Attach file">
<i class="icon attachment"></i>
</button>
<input
id="file-upload-and-share-input"
aria-label="Upload and share file"
type="file"
name="file-upload-and-share"
multiple
/>
<label for="file-upload-and-share-input">
<div class="icon attachment"></div>
</label>
<textarea
id="room-chat-input"
class="room-chat-input"
@ -101,10 +108,12 @@
<button id="room-chat-send" class="primary" aria-label="Send a message">
<i class="icon send"></i>
</button>
<script>
{
const form = document.currentScript.closest("form");
const file_input = document.querySelector(
'input[name="file-upload-and-share"]',
);
const chat_input = document.getElementById("room-chat-input");
const room_chat_container =
document.getElementById("room-chat-container");
@ -118,18 +127,48 @@
}
});
form.on_submit = (event) => {
const message = chat_input.value.trim();
if (message.length === 0) {
return false;
}
form.on_submit = async (event) => {
const user = JSON.parse(document.body.dataset.user);
const room_id = room_chat_container.dataset.room_id;
if (!room_id) {
alert("Failed to get room_id!");
return false;
}
form.uploaded_urls = [];
form.errors = [];
for await (const file of file_input.files) {
const body = new FormData();
body.append("file", file, encodeURIComponent(file.name));
const file_path = `/files/users/${user.id}/${encodeURIComponent(file.name)}`;
const file_upload_response = await api.fetch(file_path, {
method: "PUT",
body,
});
if (!file_upload_response.ok) {
const error = await file_upload_response.json();
form.errors.push(error?.error?.message ?? "Unknown error.");
continue;
}
const file_url = `${window.location.protocol}//${window.location.host}${file_path}`;
form.uploaded_urls.push(file_url);
}
if (form.errors.length) {
const errors = form.errors.join("\n\n");
alert(errors);
return false;
}
const message = chat_input.value.trim();
if (form.uploaded_urls.length === 0 && message.length === 0) {
return false;
}
form.action = `/api/rooms/${room_id}/events`;
};
@ -147,6 +186,15 @@
updated: now,
};
if (form.uploaded_urls.length) {
json.data = json.data ?? {};
json.data.message =
(typeof json.data.message === "string" &&
json.data.message.trim().length
? json.data.message.trim() + "\n"
: "") + form.uploaded_urls.join("\n");
}
const user = JSON.parse(document.body.dataset.user);
render_text_event(room_chat_content, json, user);
document