0% found this document useful (0 votes)
3 views

scriptcssss

The document is a JavaScript script for a chat application that includes features such as user login, registration, message sending, and real-time communication using WebSockets. It also implements media recording, video calls, and a theme toggle for user interface customization. Additionally, it handles user notifications and maintains an online user list, enhancing the overall user experience.

Uploaded by

alimudindrive
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

scriptcssss

The document is a JavaScript script for a chat application that includes features such as user login, registration, message sending, and real-time communication using WebSockets. It also implements media recording, video calls, and a theme toggle for user interface customization. Additionally, it handles user notifications and maintains an online user list, enhancing the overall user experience.

Uploaded by

alimudindrive
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 11

// script.

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
};

// Variabel untuk WebRTC


let peerConnection;
const config = {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' } // Menggunakan server STUN publik
]
};

// Terapkan tema yang tersimpan saat halaman dimuat


document.addEventListener('DOMContentLoaded', () => {
const savedTheme = localStorage.getItem('theme') || 'light';
document.body.classList.add(`${savedTheme}-mode`);
});

// Mode Toggle Functions


document.getElementById('dark-mode-toggle').onclick = () => {
document.body.classList.add('dark-mode');
document.body.classList.remove('light-mode', 'custom-mode');
localStorage.setItem('theme', 'dark');
};

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');
}

// Show Register Form


function showRegisterForm() {
document.getElementById('login-container').style.display = 'none';
document.getElementById('register-container').style.display = 'block';
}
// Hide Register Form
function hideRegisterForm() {
document.getElementById('register-container').style.display = 'none';
document.getElementById('login-container').style.display = 'block';
}

// Show Reset Password Form


function showResetForm() {
document.getElementById('login-container').style.display = 'none';
document.getElementById('reset-container').style.display = 'block';
}

// Hide Reset Password Form


function hideResetForm() {
document.getElementById('reset-container').style.display = 'none';
document.getElementById('login-container').style.display = 'block';
}

// Login Function
async function login() {
const username = document.getElementById('login-username').value.trim();
const password = document.getElementById('login-password').value.trim();

if (username && password) {


try {
const response = await fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
const result = await response.json();
if (result.success) {
currentUser = result.user.username;
document.getElementById('login-container').style.display = 'none';
document.getElementById('chat-container').style.display = 'flex';
document.getElementById('username-display').textContent =
currentUser;
document.getElementById('status-bubble').textContent = `($
{result.user.status})`;
document.getElementById('profile-pic').src =
result.user.profilePic;
initSocket(); // Inisialisasi socket setelah login berhasil
} else {
alert(result.message);
}
} catch (err) {
console.error('Error saat login:', err);
alert('Terjadi kesalahan saat login.');
}
} else {
alert('Silakan masukkan username dan password.');
}
}

// 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 (username && password && email) {


try {
const response = await fetch('/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password, email })
});
const result = await response.json();
if (result.success) {
alert('Registrasi berhasil! Silakan login.');
hideRegisterForm();
} else {
alert(result.message);
}
} catch (err) {
console.error('Error saat registrasi:', err);
alert('Terjadi kesalahan saat registrasi.');
}
} else {
alert('Silakan isi semua kolom.');
}
}

// Reset Password Function


async function resetPassword() {
const email = document.getElementById('reset-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.');
}
}

// Inisialisasi Socket.io setelah login


function initSocket() {
socket = io();

// Menerima pesan dari server


socket.on('message', (data) => {
if (data.username !== currentUser) {
displayMessage(data, 'received');
// Notifications
showNotification(data.username, data.message);
}
});

// 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';
}
});

socket.on('stopTyping', (username) => {


if (username !== currentUser) {
const typingIndicator = document.getElementById('typing-indicator');
typingIndicator.style.display = 'none';
}
});

// User Connected/Disconnected
socket.on('userConnected', (username) => {
if (username !== currentUser) {
onlineUsers.push(username);
updateOnlineUsers();
showNotification('Pengguna Online', `${username} telah online.`);
}
});

socket.on('userDisconnected', (username) => {


if (username !== currentUser) {
onlineUsers = onlineUsers.filter(user => user !== username);
updateOnlineUsers();
showNotification('Pengguna Offline', `${username} telah offline.`);
}
});

// Handler untuk panggilan masuk


socket.on('incomingCall', async (data) => {
const acceptCall = confirm(`${data.caller} menelepon Anda. Terima
panggilan?`);
if (!acceptCall) {
return;
}

await createPeerConnection(data.from);

await peerConnection.setRemoteDescription(new
RTCSessionDescription(data.offer));
const answer = await peerConnection.createAnswer();
await peerConnection.setLocalDescription(answer);

socket.emit('answerCall', { to: data.from, answer });


});

// Handler untuk jawaban panggilan


socket.on('callAnswered', async (data) => {
await peerConnection.setRemoteDescription(new
RTCSessionDescription(data.answer));
});

// Handler untuk ICE Candidate


socket.on('iceCandidate', async (data) => {
try {
await peerConnection.addIceCandidate(data.candidate);
} catch (e) {
console.error('Error adding received ice candidate', e);
}
});
}

// Send Message Function


function sendMessage() {
const messageInput = document.getElementById('message-input');
const message = messageInput.value.trim();
if (message) {
displayMessage({ username: currentUser, message }, 'sent');
socket.emit('message', { username: currentUser, message });
messageInput.value = '';
socket.emit('stopTyping', currentUser);
}
}

// Display Message Function


function displayMessage(data, type) {
const messages = document.getElementById('messages');
const messageElement = document.createElement('div');
messageElement.classList.add('message', type === 'sent' ? 'sent' : 'received');

if (data.type === 'media') {


if (data.mediaType.startsWith('image/')) {
const img = document.createElement('img');
img.src = data.content;
messageElement.appendChild(img);
} else if (data.mediaType.startsWith('video/')) {
const video = document.createElement('video');
video.src = data.content;
video.controls = true;
messageElement.appendChild(video);
}
} else if (data.type === 'voice') {
const audio = document.createElement('audio');
audio.src = data.content;
audio.controls = true;
messageElement.appendChild(audio);
} else if (data.type === 'location') {
const link = document.createElement('a');
link.href = data.content;
link.target = '_blank';
link.textContent = 'Lihat Lokasi';
messageElement.appendChild(link);
} else if (data.type === 'sticker') {
const img = document.createElement('img');
img.src = data.content;
messageElement.appendChild(img);
} else {
messageElement.textContent = `${data.username}: ${data.message}`;
}

messages.appendChild(messageElement);
messages.scrollTop = messages.scrollHeight;
}

// Send Typing Event


function sendTypingEvent() {
socket.emit('typing', currentUser);
clearTimeout(typingTimeout);
typingTimeout = setTimeout(() => {
socket.emit('stopTyping', currentUser);
}, 1000);
}

// Update Online Users List


function updateOnlineUsers() {
const onlineUsersList = document.getElementById('online-users-list');
onlineUsersList.innerHTML = '';
onlineUsers.forEach(user => {
const userItem = document.createElement('li');
userItem.textContent = user;
onlineUsersList.appendChild(userItem);
});
}

// Show Online Users


function showOnlineUsers() {
updateOnlineUsers();
document.getElementById('online-users-modal').style.display = 'flex';
}

// Close Online Users Modal


function closeOnlineUsers() {
document.getElementById('online-users-modal').style.display = 'none';
}

// 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
}

if (profilePicInput.files && profilePicInput.files[0]) {


const reader = new FileReader();
reader.onload = function(e) {
document.getElementById('profile-pic').src = e.target.result;
// Optionally, send the new profile pic to the server
};
reader.readAsDataURL(profilePicInput.files[0]);
}

closeProfile();
}

// Close Profile Modal


function closeProfile() {
document.getElementById('profile-modal').style.display = 'none';
}

// 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.');
}
}
}

// Check Enter Key


function checkEnter(event) {
if (event.key === 'Enter') {
sendMessage();
}
}

// 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);
});
}
}

// Start Voice Call


function startVoiceCall() {
const targetUsername = prompt('Masukkan username yang ingin dihubungi:');
if (targetUsername) {
startCall(targetUsername);
}
}

// Start Video Call


function startVideoCall() {
const targetUsername = prompt('Masukkan username yang ingin dihubungi:');
if (targetUsername) {
startCall(targetUsername);
}
}

// Start Call Function


async function startCall(targetUsername) {
// Cari socketId dari pengguna target
socket.emit('getSocketId', targetUsername, (targetSocketId) => {
if (targetSocketId) {
createPeerConnection(targetSocketId);
peerConnection.createOffer().then(offer => {
peerConnection.setLocalDescription(offer);
socket.emit('callUser', {
to: targetSocketId,
offer: offer,
caller: currentUser
});
});
} else {
alert('Pengguna tidak ditemukan atau tidak online.');
}
});
}

// Create Peer Connection


function createPeerConnection(targetSocketId) {
peerConnection = new RTCPeerConnection(config);

// Mengakses media stream


navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream
=> {
stream.getTracks().forEach(track => peerConnection.addTrack(track,
stream));
// Menampilkan video lokal
const localVideo = document.getElementById('local-video');
localVideo.srcObject = stream;
document.getElementById('video-call-container').style.display = 'flex';
}).catch(err => {
console.error('Error accessing media devices.', err);
});

// Handler untuk ICE Candidate


peerConnection.onicecandidate = event => {
if (event.candidate) {
socket.emit('iceCandidate', { to: targetSocketId, candidate:
event.candidate });
}
};

// Menangani stream remote


peerConnection.ontrack = event => {
const remoteVideo = document.getElementById('remote-video');
if (remoteVideo.srcObject !== event.streams[0]) {
remoteVideo.srcObject = event.streams[0];
}
};
}

// End Call Function


function endCall() {
if (peerConnection) {
peerConnection.close();
peerConnection = null;
document.getElementById('video-call-container').style.display = 'none';
}
}

// 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;
}

// Load Emojis Dynamically


function loadEmojis() {
const emojiPicker = document.getElementById('emoji-picker');
const emojis =
['😀','😁','😂','','
😃 😄','😅','😆','😉','😊','😋','😎','😍','😘','😗','😙','😚','😚 ','🙂'
,'🤗','🤩'];
emojis.forEach(emoji => {
const emojiSpan = document.createElement('span');
emojiSpan.textContent = emoji;
emojiSpan.onclick = () => addEmoji(emoji);
emojiPicker.appendChild(emojiSpan);
});
}

// 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();
}

// Load Stickers Dynamically


function loadStickers() {
const stickerPicker = document.getElementById('sticker-picker');
const stickers = ['sticker1.png', 'sticker2.png', 'sticker3.png'];
stickers.forEach(sticker => {
const img = document.createElement('img');
img.src = sticker;
img.alt = 'Sticker';
img.onclick = () => sendSticker(sticker);
stickerPicker.appendChild(img);
});
}

// Inisialisasi
function init() {
loadEmojis();
loadStickers();
}

window.onload = init;

You might also like