first attempt at audio messages
This commit is contained in:
parent
060308ec92
commit
6b3f043332
110
app.js
110
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)}`;
|
||||
}
|
||||
|
@ -62,6 +62,7 @@
|
||||
<textarea id="message" rows="4"></textarea>
|
||||
<input type="file" id="file-input" style="display:none;">
|
||||
<button type="button" id="attach-file">Attach File</button>
|
||||
<button type="button" id="talk-btn">Talk</button> <!-- New Talk button -->
|
||||
<input type="submit" value="Send" />
|
||||
</form>
|
||||
<button id="remove-room-btn">Leave Room</button>
|
||||
|
16
style.css
16
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;
|
||||
|
Loading…
Reference in New Issue
Block a user