0% found this document useful (0 votes)
7 views11 pages

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
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views11 pages

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
We take content rights seriously. If you suspect this is your content, claim it here.
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