scriptcssss
scriptcssss
js
let socket;
let currentUser = null;
let typingTimeout;
let mediaRecorder;
let audioChunks = [];
let isRecording = false;
let onlineUsers = [];
let rateLimit = {
messages: [],
maxMessages: 5,
timeWindow: 5000 // 5 detik
};
document.getElementById('light-mode-toggle').onclick = () => {
document.body.classList.add('light-mode');
document.body.classList.remove('dark-mode', 'custom-mode');
localStorage.setItem('theme', 'light');
};
document.getElementById('custom-color-toggle').onclick = () => {
document.body.classList.add('custom-mode');
document.body.classList.remove('dark-mode', 'light-mode');
localStorage.setItem('theme', 'custom');
};
// Toggle Sidebar
function toggleSidebar() {
const sidebar = document.getElementById('sidebar');
sidebar.classList.toggle('open');
}
// Login Function
async function login() {
const username = document.getElementById('login-username').value.trim();
const password = document.getElementById('login-password').value.trim();
// Register Function
async function register() {
const username = document.getElementById('register-username').value.trim();
const password = document.getElementById('register-password').value.trim();
const email = document.getElementById('register-email').value.trim();
if (email) {
try {
const response = await fetch('/reset-password', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email })
});
const result = await response.json();
if (result.success) {
alert('Link reset password telah dikirim ke email Anda.');
hideResetForm();
} else {
alert(result.message);
}
} catch (err) {
console.error('Error saat reset password:', err);
alert('Terjadi kesalahan saat reset password.');
}
} else {
alert('Silakan masukkan email Anda.');
}
}
// Typing Indicator
socket.on('typing', (username) => {
if (username !== currentUser) {
const typingIndicator = document.getElementById('typing-indicator');
typingIndicator.innerHTML = `${username} sedang mengetik <span
class="typing"><span></span><span></span><span></span></span>`;
typingIndicator.style.display = 'block';
}
});
// User Connected/Disconnected
socket.on('userConnected', (username) => {
if (username !== currentUser) {
onlineUsers.push(username);
updateOnlineUsers();
showNotification('Pengguna Online', `${username} telah online.`);
}
});
await createPeerConnection(data.from);
await peerConnection.setRemoteDescription(new
RTCSessionDescription(data.offer));
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);
messages.appendChild(messageElement);
messages.scrollTop = messages.scrollHeight;
}
// Show Profile
function showProfile() {
document.getElementById('edit-username').value = currentUser;
// Fetch and display other profile info if available
document.getElementById('profile-modal').style.display = 'flex';
}
// Save Profile
function saveProfile() {
const newUsername = document.getElementById('edit-username').value.trim();
const newStatus = document.getElementById('edit-status').value.trim();
const newEmail = document.getElementById('edit-email').value.trim();
const profilePicInput = document.getElementById('edit-profile-pic');
if (newUsername) {
currentUser = newUsername;
document.getElementById('username-display').textContent = newUsername;
}
if (newStatus) {
// Update status
document.getElementById('status-bubble').textContent = `(${newStatus})`;
}
if (newEmail) {
// Update email in profile
}
closeProfile();
}
// Show Contacts
function showContacts() {
alert('Fitur kontak belum diimplementasikan.');
}
// Logout Function
async function logout() {
if (currentUser) {
try {
const response = await fetch('/logout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
});
const result = await response.json();
if (result.success) {
socket.emit('userDisconnected', currentUser);
currentUser = null;
document.getElementById('chat-container').style.display = 'none';
document.getElementById('login-container').style.display = 'block';
socket.disconnect();
} else {
alert(result.message);
}
} catch (err) {
console.error('Error saat logout:', err);
alert('Terjadi kesalahan saat logout.');
}
}
}
// Notifications
function showNotification(title, message) {
if (Notification.permission === 'granted') {
new Notification(title, {
body: message,
icon: 'https://via.placeholder.com/40'
});
} else if (Notification.permission !== 'denied') {
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
showNotification(title, message);
}
});
}
}
// Before Unload
window.addEventListener('beforeunload', () => {
if (currentUser) {
socket.emit('userDisconnected', currentUser);
}
});
// Media Integration
function sendMedia() {
const mediaInput = document.getElementById('media-input');
const file = mediaInput.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
displayMessage({
username: currentUser,
type: 'media',
content: e.target.result,
mediaType: file.type
}, 'sent');
socket.emit('message', {
username: currentUser,
type: 'media',
content: e.target.result,
mediaType: file.type
});
};
reader.readAsDataURL(file);
}
}
// Voice Messages
function startRecording() {
if (isRecording) {
mediaRecorder.stop();
isRecording = false;
alert('Rekaman dihentikan.');
} else {
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = event => {
audioChunks.push(event.data);
if (mediaRecorder.state === 'inactive') {
const blob = new Blob(audioChunks, { type: 'audio/webm' });
const audioUrl = URL.createObjectURL(blob);
displayMessage({ username: currentUser, type: 'voice', content:
audioUrl }, 'sent');
socket.emit('message', { username: currentUser, type: 'voice',
content: audioUrl });
audioChunks = [];
}
};
mediaRecorder.start();
isRecording = true;
alert('Rekaman dimulai.');
}).catch(error => {
console.error('Error accessing microphone', error);
});
}
}
// Share Location
function shareLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
const locationUrl = `https://www.google.com/maps?q=$
{position.coords.latitude},${position.coords.longitude}`;
displayMessage({ username: currentUser, type: 'location', content:
locationUrl }, 'sent');
socket.emit('message', { username: currentUser, type: 'location',
content: locationUrl });
});
} else {
alert('Geolocation tidak didukung oleh browser Anda.');
}
}
// Emoji Picker
function toggleEmojiPicker() {
const emojiPicker = document.getElementById('emoji-picker');
emojiPicker.style.display = emojiPicker.style.display === 'flex' ? 'none' :
'flex';
}
function addEmoji(emoji) {
const messageInput = document.getElementById('message-input');
messageInput.value += emoji;
}
// Sticker Picker
function toggleStickerPicker() {
const stickerPicker = document.getElementById('sticker-picker');
stickerPicker.style.display = stickerPicker.style.display === 'flex' ? 'none' :
'flex';
}
function sendSticker(stickerUrl) {
displayMessage({ username: currentUser, type: 'sticker', content: stickerUrl },
'sent');
socket.emit('message', { username: currentUser, type: 'sticker', content:
stickerUrl });
toggleStickerPicker();
}
// Inisialisasi
function init() {
loadEmojis();
loadStickers();
}
window.onload = init;