diff --git a/app.js b/app.js
index 2fe4caa..565b1f7 100644
--- a/app.js
+++ b/app.js
@@ -54,6 +54,7 @@ async function initialize() {
const removeRoomBtn = document.querySelector('#remove-room-btn');
const attachFileButton = document.getElementById('attach-file');
const fileInput = document.getElementById('file-input');
+ const talkButton = document.getElementById('talk-btn');
if (registerForm) {
registerForm.addEventListener('submit', registerUser);
@@ -87,6 +88,9 @@ async function initialize() {
if (fileInput) {
fileInput.addEventListener('change', handleFileInput);
}
+ if (talkButton) {
+ setupTalkButton();
+ }
const configExists = fs.existsSync("./config.json");
if (configExists) {
@@ -138,6 +142,12 @@ async function initialize() {
}
} else if (messageObj.type === 'message') {
onMessageAdded(messageObj.name, messageObj.message, messageObj.avatar, messageObj.topic);
+ } else if (messageObj.type === 'audio') {
+ const audioBuffer = b4a.from(messageObj.audio, 'base64');
+ const filePath = `/audio/${Date.now()}.webm`;
+ await drive.put(filePath, audioBuffer);
+ const audioUrl = `http://localhost:${servePort}${filePath}`;
+ addAudioMessage(messageObj.name, audioUrl, messageObj.avatar, messageObj.topic);
} else {
console.error('Received unknown message type:', messageObj);
}
@@ -185,6 +195,68 @@ async function initialize() {
});
}
+function setupTalkButton() {
+ const talkButton = document.getElementById('talk-btn');
+ if (!talkButton) return;
+
+ let mediaRecorder;
+ let audioChunks = [];
+
+ talkButton.addEventListener('mousedown', async () => {
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
+ mediaRecorder = new MediaRecorder(stream);
+ mediaRecorder.start();
+
+ mediaRecorder.addEventListener('dataavailable', event => {
+ audioChunks.push(event.data);
+ });
+
+ mediaRecorder.addEventListener('stop', async () => {
+ const audioBlob = new Blob(audioChunks);
+ audioChunks = [];
+
+ const arrayBuffer = await audioBlob.arrayBuffer();
+ const buffer = new Uint8Array(arrayBuffer);
+
+ const topic = document.querySelector('#chat-room-topic').innerText;
+ const filePath = `/audio/${Date.now()}.webm`;
+ await drive.put(filePath, buffer);
+
+ const audioUrl = `http://localhost:${servePort}${filePath}`;
+
+ const audioMessage = {
+ type: 'audio',
+ name: config.userName,
+ audio: b4a.toString(buffer, 'base64'),
+ audioType: audioBlob.type,
+ avatar: updatePortInUrl(config.userAvatar),
+ topic: topic
+ };
+
+ console.log('Sending audio message:', audioMessage); // Debugging log
+
+ const peers = [...swarm.connections];
+ for (const peer of peers) {
+ peer.write(JSON.stringify(audioMessage));
+ }
+
+ addAudioMessage(config.userName, audioUrl, config.userAvatar, topic);
+ });
+ });
+
+ talkButton.addEventListener('mouseup', () => {
+ if (mediaRecorder) {
+ mediaRecorder.stop();
+ }
+ });
+
+ talkButton.addEventListener('mouseleave', () => {
+ if (mediaRecorder && mediaRecorder.state === 'recording') {
+ mediaRecorder.stop();
+ }
+ });
+}
+
function registerUser(e) {
e.preventDefault();
const regUsername = document.querySelector('#reg-username').value;
@@ -557,6 +629,44 @@ function onMessageAdded(from, message, avatar, topic) {
}
}
+function addAudioMessage(from, audioUrl, avatar, topic) {
+ console.log('Adding audio message:', { from, audioUrl, avatar, topic }); // Debugging log
+ const $div = document.createElement('div');
+ $div.classList.add('message');
+
+ const $img = document.createElement('img');
+ $img.src = updatePortInUrl(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);
+
+ const $audio = document.createElement('audio');
+ $audio.controls = true;
+ if (from !== config.userName) {
+ $audio.autoplay = true; // Add autoplay attribute for peers only
+ }
+ $audio.src = audioUrl;
+ $audio.classList.add('attached-audio');
+ $content.appendChild($audio);
+
+ $div.appendChild($content);
+
+ // Only render the message if it's for the current room
+ const currentTopic = document.querySelector('#chat-room-topic').innerText;
+ if (currentTopic === topic) {
+ document.querySelector('#messages').appendChild($div);
+ scrollToBottom();
+ } else {
+ console.log(`Message for topic ${topic} not rendered because current topic is ${currentTopic}`); // Debugging log
+ }
+}
function truncateHash(hash) {
return `${hash.slice(0, 6)}...${hash.slice(-6)}`;
}
diff --git a/index.html b/index.html
index 0f31c1b..2a8d905 100644
--- a/index.html
+++ b/index.html
@@ -62,6 +62,7 @@
+
diff --git a/style.css b/style.css
index 6567450..22f2c79 100644
--- a/style.css
+++ b/style.css
@@ -268,6 +268,22 @@ textarea::placeholder {
margin-left: 0.5rem; /* Add margin between buttons */
}
+#talk-btn {
+ padding: 0.5rem 1rem; /* Add padding to the button */
+ margin-left: 0.5rem; /* Add margin between buttons */
+ font-size: 14px;
+ border-radius: 5px;
+ cursor: pointer;
+}
+
+#talk-btn:active {
+ color : #fff; /* White text when clicked */
+ background-color: #f04747; /* Red color when clicked */
+}
+
+#talk-btn:hover {
+}
+
/* Main container styles */
main {
display: flex;