forked from snxraven/LinkUp-P2P-Chat
Up to date fork #1
110
app.js
110
app.js
@ -54,6 +54,7 @@ async function initialize() {
|
|||||||
const removeRoomBtn = document.querySelector('#remove-room-btn');
|
const removeRoomBtn = document.querySelector('#remove-room-btn');
|
||||||
const attachFileButton = document.getElementById('attach-file');
|
const attachFileButton = document.getElementById('attach-file');
|
||||||
const fileInput = document.getElementById('file-input');
|
const fileInput = document.getElementById('file-input');
|
||||||
|
const talkButton = document.getElementById('talk-btn');
|
||||||
|
|
||||||
if (registerForm) {
|
if (registerForm) {
|
||||||
registerForm.addEventListener('submit', registerUser);
|
registerForm.addEventListener('submit', registerUser);
|
||||||
@ -87,6 +88,9 @@ async function initialize() {
|
|||||||
if (fileInput) {
|
if (fileInput) {
|
||||||
fileInput.addEventListener('change', handleFileInput);
|
fileInput.addEventListener('change', handleFileInput);
|
||||||
}
|
}
|
||||||
|
if (talkButton) {
|
||||||
|
setupTalkButton();
|
||||||
|
}
|
||||||
|
|
||||||
const configExists = fs.existsSync("./config.json");
|
const configExists = fs.existsSync("./config.json");
|
||||||
if (configExists) {
|
if (configExists) {
|
||||||
@ -138,6 +142,12 @@ async function initialize() {
|
|||||||
}
|
}
|
||||||
} else if (messageObj.type === 'message') {
|
} else if (messageObj.type === 'message') {
|
||||||
onMessageAdded(messageObj.name, messageObj.message, messageObj.avatar, messageObj.topic);
|
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 {
|
} else {
|
||||||
console.error('Received unknown message type:', messageObj);
|
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) {
|
function registerUser(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const regUsername = document.querySelector('#reg-username').value;
|
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) {
|
function truncateHash(hash) {
|
||||||
return `${hash.slice(0, 6)}...${hash.slice(-6)}`;
|
return `${hash.slice(0, 6)}...${hash.slice(-6)}`;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
<textarea id="message" rows="4"></textarea>
|
<textarea id="message" rows="4"></textarea>
|
||||||
<input type="file" id="file-input" style="display:none;">
|
<input type="file" id="file-input" style="display:none;">
|
||||||
<button type="button" id="attach-file">Attach File</button>
|
<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" />
|
<input type="submit" value="Send" />
|
||||||
</form>
|
</form>
|
||||||
<button id="remove-room-btn">Leave Room</button>
|
<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 */
|
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 container styles */
|
||||||
main {
|
main {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
Loading…
Reference in New Issue
Block a user