My / public /chat.html
Reaperxxxx's picture
Update public/chat.html
27574b3 verified
Raw
History Blame Contribute Delete
9.15 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0">
<title>Chat</title>
</head>
<body style="margin: 0; font-family: Arial, sans-serif; background-color: #121212; color: #ffffff; display: flex; flex-direction: column; height: 100vh;">
<header style="background-color: #1e1e1e; padding: 10px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #333;">
<a href="/" style="color: #ffffff; text-decoration: none;">⬅ Back</a>
<h1 style="margin: 0; font-size: 1.2rem;">Chat</h1>
</header>
<main id="chat-box" style="flex: 1; overflow-y: auto; padding: 10px; display: flex; flex-direction: column; gap: 10px; background-color: #1c1c1c;"></main>
<footer style="display: flex; flex-direction: column; padding: 10px; background-color: #1e1e1e; border-top: 1px solid #333;">
<div id="reply-preview" style="display: none; margin-bottom: 10px; padding: 8px; background: #333; border-left: 4px solid #4caf50; border-radius: 5px; color: #bbb; font-size: 0.9rem;"></div>
<div style="display: flex; align-items: center; width: 100%;">
<input type="text" id="message-input" placeholder="Type a message" style="flex: 1; padding: 10px; border: 1px solid #444; border-radius: 20px; background: #2c2c2c; color: #fff; margin-right: 10px;">
<input type="file" id="image-input" style="display: none;">
<button id="send-image" style="background: #4caf50; border: none; color: white; padding: 10px 15px; border-radius: 50%; cursor: pointer;">📷</button>
<button id="send-message" style="background: #4caf50; border: none; color: white; padding: 10px 15px; border-radius: 50%; cursor: pointer;">Send</button>
</div>
</footer>
<!-- Key Input Modal -->
<div id="key-modal" style="display: flex; flex-direction: column; align-items: center; justify-content: center; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); z-index: 1000;">
<div style="background: #1e1e1e; padding: 20px; border-radius: 8px; text-align: center;">
<h2 style="color: #fff;">Enter Key</h2>
<input id="key-input" type="password" placeholder="Enter your key" style="padding: 10px; width: 100%; border: 1px solid #444; border-radius: 5px; margin-top: 10px; color: #fff; background: #2c2c2c;">
<button id="verify-key" style="margin-top: 10px; padding: 10px 20px; background: #4caf50; border: none; color: #fff; cursor: pointer; border-radius: 5px;">Verify</button>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
const chatBox = document.getElementById('chat-box');
const messageInput = document.getElementById('message-input');
const sendMessageButton = document.getElementById('send-message');
const sendImageButton = document.getElementById('send-image');
const imageInput = document.getElementById('image-input');
const replyPreview = document.getElementById('reply-preview');
const keyModal = document.getElementById('key-modal');
const keyInput = document.getElementById('key-input');
const verifyKeyButton = document.getElementById('verify-key');
const jid = window.location.pathname.split('/chat/')[1];
let replyTo = null;
let userKey = localStorage.getItem('userKey');
// Verify the key with the server
async function verifyKey(key) {
const res = await fetch('/validate-key', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key }),
});
return res.ok;
}
// Handle key submission
verifyKeyButton.addEventListener('click', async () => {
const enteredKey = keyInput.value.trim();
if (!enteredKey) return alert('Please enter a key.');
const isValid = await verifyKey(enteredKey);
if (isValid) {
userKey = enteredKey;
localStorage.setItem('userKey', userKey);
keyModal.style.display = 'none';
loadMessages();
} else {
alert('Invalid key. Please try again.');
}
});
// Add a message to the chat box
function addMessageToChat(msg) {
const messageDiv = document.createElement('div');
messageDiv.style = `
max-width: 70%;
padding: 10px;
border-radius: 8px;
background-color: ${msg.sender === 'You' ? '#4caf50' : '#2c2c2c'};
color: #ffffff;
align-self: ${msg.sender === 'You' ? 'flex-end' : 'flex-start'};
word-wrap: break-word;
cursor: pointer;
`;
// Add reply thumbnail if applicable
if (msg.replyTo) {
const replyDiv = document.createElement('div');
replyDiv.style = `
margin-bottom: 8px;
padding: 5px;
border-left: 4px solid #888;
font-size: 0.85rem;
color: #bbb;
`;
replyDiv.textContent = msg.replyTo;
messageDiv.appendChild(replyDiv);
}
// Add image if available
if (msg.imageUrl) {
const img = document.createElement('img');
img.src = msg.imageUrl;
img.alt = 'Image';
img.style = 'max-width: 100%; border-radius: 8px; margin-top: 10px;';
messageDiv.appendChild(img);
}
// Add sender and content
messageDiv.innerHTML += `<strong>${msg.sender}</strong><br>${msg.content || ''}`;
messageDiv.addEventListener('click', () => {
replyTo = msg.content;
replyPreview.textContent = `Replying to: ${msg.content}`;
replyPreview.style.display = 'block';
});
chatBox.appendChild(messageDiv);
chatBox.scrollTop = chatBox.scrollHeight;
}
// Load chat messages
async function loadMessages() {
try {
const res = await fetch(`/api/messages/${jid}`, {
headers: { Authorization: `Bearer ${userKey}` },
});
if (!res.ok) throw new Error('Failed to load messages');
const messages = await res.json();
chatBox.innerHTML = '';
messages.forEach(addMessageToChat);
} catch (error) {
console.error(error);
chatBox.innerHTML = '<p style="color: red;">Failed to load messages.</p>';
}
}
// Send a message
sendMessageButton.addEventListener('click', async () => {
const message = messageInput.value.trim();
if (!message) return;
try {
await fetch('/send-message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${userKey}`,
},
body: JSON.stringify({ jid, message, replyTo }),
});
messageInput.value = '';
replyTo = null;
replyPreview.style.display = 'none';
} catch (error) {
console.error('Failed to send message:', error);
}
});
sendImageButton.addEventListener('click', () => {
imageInput.click(); // Open file picker when the camera button is clicked
});
imageInput.addEventListener('change', async () => {
const file = imageInput.files[0];
if (!file) return;
const formData = new FormData();
formData.append('image', file); // Append the selected image
formData.append('jid', jid); // Add recipient JID
formData.append('caption', messageInput.value.trim()); // Optional caption
try {
const res = await fetch('/upload-image', {
method: 'POST',
headers: {
Authorization: `Bearer ${userKey}`, // Include user key for authentication
},
body: formData,
});
if (res.ok) {
imageInput.value = ''; // Clear file input
messageInput.value = ''; // Clear caption input
replyTo = null;
replyPreview.style.display = 'none';
} else {
const errorText = await res.text();
console.error('Failed to send image:', errorText);
alert(`Error: ${errorText}`);
}
} catch (error) {
console.error('Failed to send image:', error);
alert('An error occurred while sending the image.');
}
});
// Check if the user is already verified
if (userKey) {
verifyKey(userKey).then((isValid) => {
if (isValid) {
keyModal.style.display = 'none';
loadMessages();
} else {
localStorage.removeItem('userKey');
}
});
}
</script>
</body>
</html>