diff --git a/app.js b/app.js index 4c9a540..c6cb454 100644 --- a/app.js +++ b/app.js @@ -43,6 +43,8 @@ async function initialize() { const messageForm = document.querySelector('#message-form'); const toggleSetupBtn = document.querySelector('#toggle-setup-btn'); const removeRoomBtn = document.querySelector('#remove-room-btn'); + const attachFileButton = document.getElementById('attach-file'); + const fileInput = document.getElementById('file-input'); if (registerForm) { registerForm.addEventListener('submit', registerUser); @@ -67,6 +69,25 @@ async function initialize() { if (removeRoomBtn) { removeRoomBtn.addEventListener('click', leaveRoom); } + if (attachFileButton) { + attachFileButton.addEventListener('click', () => fileInput.click()); + } + if (fileInput) { + fileInput.addEventListener('change', async (event) => { + const file = event.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = async (event) => { + const buffer = new Uint8Array(event.target.result); + const filePath = `/files/${file.name}`; + await drive.put(filePath, buffer); + const fileUrl = `http://localhost:${servePort}${filePath}`; + sendFileMessage(userName, fileUrl, file.type, userAvatar); + }; + reader.readAsArrayBuffer(file); + } + }); + } const registerDiv = document.querySelector('#register'); if (registerDiv) { @@ -79,6 +100,8 @@ async function initialize() { const avatarBuffer = Buffer.from(messageObj.avatar, 'base64'); await drive.put(`/icons/${username}.png`, avatarBuffer); updateIcon(username, avatarBuffer); + } else if (messageObj.type === 'file') { + addFileMessage(messageObj.name, messageObj.fileName, messageObj.fileUrl, messageObj.fileType, messageObj.avatar); } else { onMessageAdded(messageObj.name, messageObj.message, messageObj.avatar); } @@ -249,6 +272,62 @@ function sendMessage(e) { } } +function sendFileMessage(name, fileUrl, fileType, avatar) { + const fileName = fileUrl.split('/').pop(); + const messageObj = JSON.stringify({ + type: 'file', + name, + fileName, + fileUrl, + fileType, + avatar, + timestamp: Date.now(), + }); + + const peers = [...swarm.connections]; + for (const peer of peers) { + peer.write(messageObj); + } + + addFileMessage(name, fileName, fileUrl, fileType, avatar); +} + +function addFileMessage(from, fileName, fileUrl, fileType, avatar) { + const $div = document.createElement('div'); + $div.classList.add('message'); + + const $img = document.createElement('img'); + $img.src = avatar || 'https://via.placeholder.com/40'; + $img.classList.add('avatar'); + $div.appendChild($img); + + const $content = document.createElement('div'); + $content.classList.add('message-content'); + + const $header = document.createElement('div'); + $header.classList.add('message-header'); + $header.textContent = from; + $content.appendChild($header); + + if (fileType.startsWith('image/')) { + const $image = document.createElement('img'); + $image.src = fileUrl; + $image.alt = fileName; + $image.classList.add('attached-image'); + $content.appendChild($image); + } else { + const $fileLink = document.createElement('a'); + $fileLink.href = fileUrl; + $fileLink.textContent = `File: ${fileName}`; + $fileLink.download = fileName; + $content.appendChild($fileLink); + } + + $div.appendChild($content); + document.querySelector('#messages').appendChild($div); + scrollToBottom(); +} + function updatePeerCount() { const peerCountElement = document.querySelector('#peers-count'); if (peerCountElement) { @@ -267,6 +346,7 @@ function onMessageAdded(from, message, avatar) { const $img = document.createElement('img'); $img.src = avatar || 'https://via.placeholder.com/40'; // Default to a placeholder image if avatar URL is not provided + $img.classList.add('avatar'); $div.appendChild($img); const $content = document.createElement('div'); diff --git a/index.html b/index.html index a4cb2d1..ffe7718 100644 --- a/index.html +++ b/index.html @@ -60,6 +60,8 @@
+ +
diff --git a/style.css b/style.css index 2a15006..53bb492 100644 --- a/style.css +++ b/style.css @@ -385,19 +385,16 @@ main { /* Message styles */ .message { display: flex; - align-items: center; + align-items: flex-start; margin-bottom: 0.5rem; /* Reduced margin */ } -.message img { +.message img.avatar { width: 32px; - /* Reduced size */ height: 32px; - /* Reduced size */ border-radius: 50%; margin-right: 0.5rem; - /* Reduced margin */ border: 2px solid #b0d944; } @@ -418,8 +415,15 @@ main { /* Reduced font size */ } -.message-time { - color: #a0a0a0; - font-size: 0.75rem; - margin-left: 0.5rem; +.message-text { + color: #e0e0e0; +} + +.attached-image { + max-width: 100%; + height: auto; + margin-top: 0.5rem; + border-radius: 4px; + /* Removed circular border */ + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); }