chookchat/client-web/index.js

424 lines
14 KiB
JavaScript
Raw Normal View History

2024-11-23 18:10:56 +11:00
alert("Chookchat is currently in early development, expect bugs! Please don't try breaking the public server, do that with your own test server (read more in the Git repo). Thanks for trying Chookchat!")
2024-11-05 20:35:10 +11:00
let ws;
let username;
let password;
2024-11-24 16:07:45 +11:00
let typingTimeout;
let typingPeople = new Array();
2024-12-04 08:28:53 +11:00
let api;
2024-11-05 20:35:10 +11:00
2024-11-23 18:10:56 +11:00
function resizeMessaging() {
const messagingDiv = document.getElementById('messaging');
if (messagingDiv) {
2024-12-06 13:27:22 +11:00
messagingDiv.style.width = `${window.innerWidth - 40}px`;
messagingDiv.style.height = `${window.innerHeight - 40}px`;
2024-11-23 18:10:56 +11:00
}
}
resizeMessaging();
// Add resize listener to handle window resizing
window.addEventListener('resize', resizeMessaging);
2024-11-05 20:35:10 +11:00
function showConfig() {
const serverconfig = document.getElementById('serverconfig')
if (serverconfig) {
serverconfig.style.display = 'block';
}
}
function md5(string) {
return CryptoJS.MD5(string).toString();
}
function getUrl() {
const serverUrl = document.getElementById('serverUrl').value.trim();
const serverPort = document.getElementById('serverPort').value;
const useWss = document.getElementById('securityStatus').checked;
const protocol = useWss ? 'wss' : 'ws';
const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');
return `${protocol}://${cleanUrl}:${serverPort}/api/websocket`;
}
function getSignupUrl() {
const serverUrl = document.getElementById('serverUrl').value.trim();
const serverPort = document.getElementById('serverPort').value;
const useWss = document.getElementById('securityStatus').checked;
const protocol = useWss ? 'https' : 'http';
const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');
return `${protocol}://${cleanUrl}:${serverPort}/api/createaccount/`;
}
2024-11-25 14:25:42 +11:00
function getUploadUrl() {
const serverUrl = document.getElementById('serverUrl').value.trim();
const serverPort = document.getElementById('serverPort').value;
const useWss = document.getElementById('securityStatus').checked;
const protocol = useWss ? 'https' : 'http';
2024-11-05 20:35:10 +11:00
2024-11-25 14:25:42 +11:00
const cleanUrl = serverUrl.replace(/^(https?:\/\/|wss?:\/\/)/, '');
return `${protocol}://${cleanUrl}:${serverPort}/api/upload`;
}
2024-11-05 20:35:10 +11:00
function connect() {
username = document.getElementById('username').value;
password = document.getElementById('password').value;
if (!username || !password) {
alert('Please enter a username and password');
return;
}
const wsUrl = getUrl();
if (ws) {
ws.close();
}
ws = new WebSocket(wsUrl);
2024-11-23 18:10:56 +11:00
var incorrectDetail = 0;
2024-11-05 20:35:10 +11:00
ws.onopen = () => {
2024-11-24 14:13:05 +11:00
if (typeof Notification !== "undefined") {
Notification.requestPermission();
}
2024-11-05 20:35:10 +11:00
console.log('Connected!');
document.getElementById('login').style.display = 'none';
document.getElementById('messaging').style.display = 'block';
2024-11-23 18:10:56 +11:00
const connectMessage = {
"type": "connect",
"username": username,
"token": md5(password),
"content": `${username} joined the room!`
}
ws.send(JSON.stringify(connectMessage));
2024-11-05 20:35:10 +11:00
ws.onmessage = (event) => {
if (event.data === "ping") {
ws.send("pong");
return;
}
2024-11-23 18:10:56 +11:00
const message = JSON.parse(event.data);
if (message.type == "error") {
if (message.username == "system") {
if (message.content == "invalid-token") {
alert("Your password is incorrect! Please try putting in your password right.");
incorrectDetail = 1;
location.reload();
}
if (message.content == "unknown-account") {
alert("That username isn't on the server. Maybe try registering?");
incorrectDetail = 1;
location.reload();
}
2024-11-24 16:07:45 +11:00
if (message.content == "banned") {
alert("kiddo you're banned lol what did you do to get banned lmaooo");
incorrectDetail = 1;
location.reload();
}
}
}
2024-12-06 13:27:22 +11:00
else if (message.type == "typing" && message.content == "1") {
2024-11-24 16:07:45 +11:00
if (username !== message.username && !typingPeople.includes(message.username)) {
typingPeople.push(message.username);
updatePeopleTyping();
}
return;
}
2024-12-06 13:27:22 +11:00
else if (message.type == "typing" && message.content == "0") {
2024-11-24 16:07:45 +11:00
if (username !== message.username && typingPeople.includes(message.username)) {
const index = typingPeople.indexOf(message.username);
typingPeople.splice(index, 1);
updatePeopleTyping();
}
return;
}
2024-12-06 13:27:22 +11:00
else if (message.type == "users" && message.username == "system") {
2024-11-24 16:07:45 +11:00
usersDiv = document.getElementById("users");
if (usersDiv) {
usersDiv.textContent = `Online users: ${message.content}`
2024-11-23 18:10:56 +11:00
}
2024-11-24 16:07:45 +11:00
return;
2024-11-23 18:10:56 +11:00
}
2024-12-06 13:27:22 +11:00
else if (message.type == "file") {
2024-11-25 14:25:42 +11:00
const messagesDiv = document.getElementById('messagebox');
const fileElement = document.createElement('embed');
if (fileElement) {
if (messagesDiv) {
messagesDiv.appendChild(fileElement);
fileElement.className = "file";
fileElement.src = message.content;
fileElement.height = 200;
fileElement.addEventListener("click", function() {
window.open(message.content, "_blank");
});
2024-12-04 08:28:53 +11:00
messagesDiv.scrollTop = messagesDiv.scrollHeight;
2024-11-25 14:25:42 +11:00
}
}
return;
}
2024-12-06 13:27:22 +11:00
else if (message.type == "call") {
2024-12-04 08:28:53 +11:00
const messagesDiv = document.getElementById('messagebox');
const callButton = document.createElement('div');
if (callButton) {
if (messagesDiv) {
messagesDiv.appendChild(callButton)
callButton.className = "message call-notification";
callButton.textContent = `${message.username} started a Jitsi call! Click to join!`;
callButton.addEventListener('click', () => {
window.open(message.content, '_blank');
});
messagesDiv.scrollTop = messagesDiv.scrollHeight;
return;
}
}
}
2024-12-06 13:27:22 +11:00
else if (message.type == "connect") {
const messagesDiv = document.getElementById('messagebox');
const messageElement = document.createElement('div');
if (messageElement) {
if (messagesDiv) {
messagesDiv.appendChild(messageElement);
messageElement.className = 'message';
messageElement.textContent = message.content;
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
}
if (document.hidden) {
const notifiction = new Notification("Chookchat", {body: messageElement.textContent});
}
}
else if (message.type == "message") {
const messagesDiv = document.getElementById('messagebox');
const messageElement = document.createElement('div');
if (messageElement) {
if (messagesDiv) {
messagesDiv.appendChild(messageElement);
messageElement.className = 'message';
messageElement.textContent = `${message.username}: ${message.content}` ;
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
}
if (document.hidden) {
const notifiction = new Notification("Chookchat", {body: messageElement.textContent});
2024-11-05 20:35:10 +11:00
}
}
2024-12-06 13:27:22 +11:00
// Egg message logic
else {
return
2024-11-05 20:35:10 +11:00
}
};
}
2024-11-23 18:10:56 +11:00
ws.onclose = () => {
alert("Chookchat has disconnected :/ Refresh the page to try again");
}
2024-11-05 20:35:10 +11:00
}
function sendMessage() {
const messageInput = document.getElementById('messageInput');
const message = messageInput.value.trim();
2024-11-23 18:10:56 +11:00
const processedMessage = {
"type": "message",
"username": username,
"token": md5(password),
"content": message
2024-11-25 14:25:42 +11:00
}
2024-11-23 18:10:56 +11:00
if (processedMessage && ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(processedMessage));
2024-11-05 20:35:10 +11:00
messageInput.value = '';
2024-11-24 16:07:45 +11:00
if (typingTimeout) {
clearTimeout(typingTimeout);
}
const stoppedTypingMessage = {
"type": "typing",
"username": username,
"token": md5(password),
"content": "0"
};
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(stoppedTypingMessage));
}
}
const processedMessage2 = {
"type": "typing",
"username": username,
"token": md5(password),
"content": "0"
}
if (processedMessage && ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(processedMessage2));
2024-11-05 20:35:10 +11:00
}
}
2024-11-25 14:25:42 +11:00
function showFileUpload() {
const fileUploadElement = document.getElementById("upload");
if (fileUploadElement) {
fileUploadElement.style.display = "block";
}
}
async function uploadFile() {
const fileInput = document.getElementById("fileupload");
if (!fileInput.files.length) {
alert("Please add a file!");
return;
}
const formData = new FormData();
formData.append("file", fileInput.files[0]);
try {
const response = await fetch(getUploadUrl(), {
method: 'POST',
mode: "no-cors",
body: formData
});
if (response.ok) {
const result = await response.text();
const processedMessage = {
"type": "message",
"username": username,
"token": md5(password),
"content": `Sent a file`
}
if (processedMessage && ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(processedMessage));
}
} else {
alert("Something went wrong lmao");
}
} catch (error) {
alert(error);
}
const fileUploadElement = document.getElementById("upload");
if (fileUploadElement) {
fileUploadElement.style.display = "none";
}
}
2024-11-05 20:35:10 +11:00
document.getElementById('messageInput').addEventListener('keypress', (event) => {
if (event.key === 'Enter') {
sendMessage();
}
});
document.getElementById('password').addEventListener('keypress', (event) => {
if (event.key === 'Enter') {
connect();
}
});
function register() {
username = document.getElementById('username').value;
password = document.getElementById('password').value;
if (!username || !password) {
alert('Please enter a username and password');
return;
}
window.open(`${getSignupUrl()}username:{${username}}token:{${md5(password)}}`);
}
2024-11-24 16:07:45 +11:00
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function startTypingIndicator() {
if (typingTimeout) {
clearTimeout(typingTimeout);
}
const typingMessage = {
"type": "typing",
"username": username,
"token": md5(password),
"content": "1"
};
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(typingMessage));
}
typingTimeout = setTimeout(() => {
const stoppedTypingMessage = {
"type": "typing",
"username": username,
"token": md5(password),
"content": "0"
};
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(stoppedTypingMessage));
}
}, 5000);
}
function updatePeopleTyping() {
const typingDiv = document.getElementById('typing');
if (typingDiv) {
if (typingPeople.length === 0) {
typingDiv.textContent = '';
} else if (typingPeople.length === 1) {
typingDiv.textContent = `${typingPeople[0]} is typing...`;
} else if (typingPeople.length === 2) {
typingDiv.textContent = `${typingPeople[0]} and ${typingPeople[1]} are typing...`;
} else {
typingDiv.textContent = `${typingPeople.length} people are typing...`;
}
}
}
2024-12-04 08:28:53 +11:00
const characters ='abcdefghijklmnopqrstuvwxyz';
function generateString(length) {
let result = '';
const charactersLength = characters.length;
for ( let i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function startMeeting() {
const link = `https://meet.jit.si/chookchat-${generateString(15)}`;
alert("Note: You may need to sign in to Jitsi to start the meeting. We'll take you there in a moment...")
window.open(link, '_blank');
const processedMessage = {
"type": "call",
"username": username,
"token": md5(password),
"content": link
};
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(processedMessage));
} else {
alert("Something went wrong. Refreshing might do the trick :)")
}
}
2024-11-24 16:07:45 +11:00
document.getElementById('messageInput').addEventListener('input', startTypingIndicator);
2024-12-06 13:27:22 +11:00
function showEggs() {
const eggsPanel = document.getElementById('eggs');
eggsPanel.style.display = "block";
// Adjust main box width when eggs panel is toggled
const mainBox = document.querySelector('#messaging .box');
if (eggsPanel.classList.contains('visible')) {
mainBox.style.width = 'calc(100% - 310px)';
} else {
mainBox.style.width = '100%';
}
}
function closeEggs() {
const eggsPanel = document.getElementById('eggs');
eggsPanel.style.display = "block";
}
// Eggs begin here