chatzonex / index.html
CodNikhil's picture
undefined - Initial Deployment
7ffb7d1 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChatzoneX - Private Anonymous Chat</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--neon-blue: #08f7fe;
--neon-pink: #fe53bb;
--neon-green: #09fbd3;
--dark-bg: #0f0e17;
}
body {
font-family: 'Inter', sans-serif;
background-color: var(--dark-bg);
color: white;
overflow-x: hidden;
}
.glass-card {
background: rgba(15, 14, 23, 0.7);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.neon-border {
box-shadow: 0 0 10px rgba(8, 247, 254, 0.5);
border: 1px solid rgba(8, 247, 254, 0.3);
}
.neon-text-blue {
text-shadow: 0 0 5px rgba(8, 247, 254, 0.8);
color: var(--neon-blue);
}
.neon-text-pink {
text-shadow: 0 0 5px rgba(254, 83, 187, 0.8);
color: var(--neon-pink);
}
.neon-text-green {
text-shadow: 0 0 5px rgba(9, 251, 211, 0.8);
color: var(--neon-green);
}
.glow-on-hover:hover {
box-shadow: 0 0 15px rgba(8, 247, 254, 0.7);
}
.typing-indicator::after {
content: '...';
animation: typing 1.5s infinite;
}
@keyframes typing {
0% { content: '.'; }
33% { content: '..'; }
66% { content: '...'; }
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 0.7; }
50% { opacity: 1; }
100% { opacity: 0.7; }
}
.badge-admin {
background: linear-gradient(45deg, #fe53bb, #08f7fe);
animation: badgeGlow 3s infinite alternate;
}
.badge-owner {
background: linear-gradient(45deg, #09fbd3, #08f7fe);
animation: badgeGlow 2s infinite alternate;
}
@keyframes badgeGlow {
0% { box-shadow: 0 0 5px rgba(8, 247, 254, 0.5); }
100% { box-shadow: 0 0 15px rgba(8, 247, 254, 0.9); }
}
.emoji-rain {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 100;
}
.emoji {
position: absolute;
font-size: 24px;
animation: fall linear forwards;
}
@keyframes fall {
to {
transform: translateY(100vh);
}
}
</style>
</head>
<body class="min-h-screen flex flex-col">
<!-- Hidden Admin Panel (not accessible via UI) -->
<div id="adminPanel" class="hidden fixed inset-0 z-50 bg-black bg-opacity-90 flex items-center justify-center p-4">
<div class="glass-card neon-border rounded-lg w-full max-w-4xl h-96 overflow-hidden">
<div class="flex justify-between items-center p-4 border-b border-gray-700">
<h2 class="text-xl font-bold neon-text-blue">Admin Control Panel</h2>
<button id="closeAdminPanel" class="text-gray-400 hover:text-white">&times;</button>
</div>
<div class="p-4 h-full overflow-y-auto">
<div id="adminContent" class="hidden">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="glass-card p-4 rounded-lg">
<h3 class="font-bold neon-text-pink mb-2">Room Controls</h3>
<div class="space-y-2">
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm">Join Any Room</button>
<button class="w-full bg-purple-600 hover:bg-purple-700 text-white py-1 px-3 rounded text-sm">Room Lockdown</button>
<button class="w-full bg-green-600 hover:bg-green-700 text-white py-1 px-3 rounded text-sm">Create Announcement</button>
</div>
</div>
<div class="glass-card p-4 rounded-lg">
<h3 class="font-bold neon-text-pink mb-2">User Moderation</h3>
<div class="space-y-2">
<input type="text" placeholder="Username" class="w-full bg-gray-800 text-white p-1 rounded text-sm mb-2">
<button class="w-full bg-red-600 hover:bg-red-700 text-white py-1 px-3 rounded text-sm">Kick User</button>
<button class="w-full bg-yellow-600 hover:bg-yellow-700 text-white py-1 px-3 rounded text-sm">Mute User</button>
<button class="w-full bg-orange-600 hover:bg-orange-700 text-white py-1 px-3 rounded text-sm">Ban User</button>
</div>
</div>
<div class="glass-card p-4 rounded-lg">
<h3 class="font-bold neon-text-pink mb-2">System Tools</h3>
<div class="space-y-2">
<button class="w-full bg-indigo-600 hover:bg-indigo-700 text-white py-1 px-3 rounded text-sm">Export Logs</button>
<button class="w-full bg-pink-600 hover:bg-pink-700 text-white py-1 px-3 rounded text-sm">Emoji Rain</button>
<button class="w-full bg-teal-600 hover:bg-teal-700 text-white py-1 px-3 rounded text-sm">Change Theme</button>
</div>
</div>
</div>
<div class="glass-card p-4 mt-4 rounded-lg">
<h3 class="font-bold neon-text-pink mb-2">Live Activity</h3>
<div class="h-32 overflow-y-auto text-sm">
<div class="flex justify-between py-1 border-b border-gray-700">
<span>User joined: MysticOwl42</span>
<span class="text-gray-400">2s ago</span>
</div>
<div class="flex justify-between py-1 border-b border-gray-700">
<span>Room created: TechTalk</span>
<span class="text-gray-400">1m ago</span>
</div>
<div class="flex justify-between py-1 border-b border-gray-700">
<span>Message deleted in #General</span>
<span class="text-gray-400">3m ago</span>
</div>
</div>
</div>
</div>
<div id="adminAuth" class="h-full flex flex-col items-center justify-center">
<h3 class="text-xl font-bold neon-text-green mb-4">Admin Authentication</h3>
<input type="password" id="adminCode" placeholder="Enter access code" class="bg-gray-800 text-white p-2 rounded mb-4 w-64 text-center">
<button id="submitAdminCode" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-6 rounded">Verify</button>
<p id="adminError" class="text-red-400 mt-2 text-sm hidden">Invalid access code</p>
</div>
</div>
</div>
</div>
<!-- Fake Admin Panel Trap -->
<div id="fakeAdminPanel" class="hidden fixed inset-0 z-50 bg-black bg-opacity-90 flex items-center justify-center">
<div class="glass-card p-8 rounded-lg max-w-md text-center">
<h2 class="text-2xl font-bold neon-text-pink mb-4">ACCESS DENIED</h2>
<p class="mb-6">Unauthorized access attempt has been logged.</p>
<button id="closeFakeAdmin" class="bg-red-600 hover:bg-red-700 text-white py-2 px-6 rounded">Close</button>
</div>
</div>
<!-- Unauthorized Page (hidden by default) -->
<div id="unauthorizedPage" class="hidden fixed inset-0 z-50 bg-black bg-opacity-90 flex items-center justify-center">
<div class="glass-card p-8 rounded-lg max-w-md text-center">
<h2 class="text-2xl font-bold neon-text-pink mb-4">UNAUTHORIZED</h2>
<p class="mb-6">You don't have permission to access this resource.</p>
<button id="goHome" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-6 rounded">Return Home</button>
</div>
</div>
<!-- Emoji Rain Container -->
<div id="emojiRain" class="emoji-rain hidden"></div>
<!-- Main App Container -->
<div id="app" class="flex-1 flex flex-col">
<!-- Header -->
<header class="glass-card p-4 shadow-md">
<div class="container mx-auto flex justify-between items-center">
<div class="flex items-center space-x-2">
<h1 id="logo" class="text-2xl font-bold neon-text-blue cursor-pointer">Chatzone<span class="neon-text-pink">X</span></h1>
<span id="connectionStatus" class="text-xs px-2 py-1 rounded-full bg-green-600">Connected</span>
</div>
<div class="flex items-center space-x-4">
<button id="createRoomBtn" class="bg-blue-600 hover:bg-blue-700 text-white py-1 px-3 rounded text-sm">Create Room</button>
<div id="userBadge" class="hidden flex items-center space-x-2">
<span id="usernameDisplay" class="font-medium"></span>
<span id="userRoleBadge" class="text-xs px-2 py-1 rounded-full hidden"></span>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1 container mx-auto p-4 flex flex-col md:flex-row gap-4">
<!-- Sidebar -->
<aside class="w-full md:w-64 glass-card rounded-lg p-4">
<div class="mb-4">
<h2 class="font-bold text-lg neon-text-green mb-2">Rooms</h2>
<div class="flex space-x-2 mb-2">
<button id="publicRoomsTab" class="flex-1 bg-blue-600 text-white py-1 px-2 rounded text-sm">Public</button>
<button id="privateRoomsTab" class="flex-1 bg-gray-700 hover:bg-gray-600 text-white py-1 px-2 rounded text-sm">Private</button>
</div>
<input type="text" id="roomSearch" placeholder="Search rooms..." class="w-full bg-gray-800 text-white p-2 rounded text-sm mb-2">
</div>
<div id="roomsList" class="space-y-2 max-h-96 overflow-y-auto">
<!-- Rooms will be populated here -->
<div class="p-2 rounded hover:bg-gray-700 cursor-pointer flex justify-between items-center">
<span>General</span>
<span class="text-xs text-gray-400">4/8</span>
</div>
<div class="p-2 rounded hover:bg-gray-700 cursor-pointer flex justify-between items-center">
<span>Tech Talk</span>
<span class="text-xs text-gray-400">2/8</span>
</div>
<div class="p-2 rounded hover:bg-gray-700 cursor-pointer flex justify-between items-center">
<span>Gaming</span>
<span class="text-xs text-gray-400">6/8</span>
</div>
</div>
<div class="mt-4">
<h2 class="font-bold text-lg neon-text-green mb-2">Online Users</h2>
<div id="onlineUsers" class="space-y-1 max-h-48 overflow-y-auto">
<!-- Users will be populated here -->
<div class="flex items-center space-x-2 p-1">
<div class="w-2 h-2 rounded-full bg-green-500"></div>
<span>SilentTurtle91</span>
</div>
<div class="flex items-center space-x-2 p-1">
<div class="w-2 h-2 rounded-full bg-green-500"></div>
<span>MysticOwl42</span>
</div>
</div>
</div>
</aside>
<!-- Chat Area -->
<div class="flex-1 flex flex-col glass-card rounded-lg overflow-hidden">
<!-- Room Header -->
<div class="p-3 border-b border-gray-700 flex justify-between items-center">
<h2 id="currentRoom" class="font-bold text-lg">Welcome to ChatzoneX</h2>
<div id="roomControls" class="hidden space-x-2">
<button class="bg-gray-700 hover:bg-gray-600 text-white py-1 px-2 rounded text-sm">Leave</button>
<button class="bg-blue-600 hover:bg-blue-700 text-white py-1 px-2 rounded text-sm">Invite</button>
</div>
</div>
<!-- Messages -->
<div id="messages" class="flex-1 p-4 overflow-y-auto space-y-3">
<!-- Messages will be populated here -->
<div class="flex flex-col">
<div class="text-center text-gray-400 text-sm mb-4">Today</div>
<div class="flex mb-3">
<div class="flex-shrink-0 w-10 h-10 rounded-full bg-gray-700 flex items-center justify-center mr-3">ST</div>
<div>
<div class="flex items-baseline">
<span class="font-bold mr-2">SilentTurtle91</span>
<span class="text-xs text-gray-400">12:34 PM</span>
</div>
<p class="text-sm">Hello everyone! πŸ‘‹</p>
</div>
</div>
<div class="flex mb-3">
<div class="flex-shrink-0 w-10 h-10 rounded-full bg-gray-700 flex items-center justify-center mr-3">MO</div>
<div>
<div class="flex items-baseline">
<span class="font-bold mr-2">MysticOwl42</span>
<span class="text-xs text-gray-400">12:35 PM</span>
</div>
<p class="text-sm">Hey there! How's everyone doing?</p>
</div>
</div>
</div>
</div>
<!-- Message Input -->
<div class="p-3 border-t border-gray-700">
<div id="typingIndicator" class="text-xs text-gray-400 mb-1 hidden">
<span class="typing-indicator"></span> is typing...
</div>
<div class="flex space-x-2">
<input type="text" id="messageInput" placeholder="Type your message..." class="flex-1 bg-gray-800 text-white p-2 rounded focus:outline-none focus:ring-1 focus:ring-blue-500">
<button id="sendMessage" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded">Send</button>
</div>
</div>
</div>
</main>
</div>
<!-- Welcome Modal -->
<div id="welcomeModal" class="fixed inset-0 z-50 bg-black bg-opacity-90 flex items-center justify-center p-4">
<div class="glass-card neon-border rounded-lg w-full max-w-md p-6">
<h2 class="text-2xl font-bold neon-text-blue mb-4">Welcome to ChatzoneX</h2>
<p class="mb-6">A completely private chat experience. No accounts, no tracking, just chat.</p>
<div class="mb-4">
<label for="username" class="block text-sm font-medium mb-1">Choose a name</label>
<input type="text" id="username" placeholder="e.g. SilentTurtle91" class="w-full bg-gray-800 text-white p-2 rounded focus:outline-none focus:ring-1 focus:ring-blue-500">
<button id="randomUsername" class="text-xs text-blue-400 hover:text-blue-300 mt-1">Generate random name</button>
</div>
<div class="mb-6">
<label for="roomCode" class="block text-sm font-medium mb-1">Room invite code (optional)</label>
<input type="text" id="roomCode" placeholder="Enter code to join private room" class="w-full bg-gray-800 text-white p-2 rounded focus:outline-none focus:ring-1 focus:ring-blue-500">
</div>
<div class="flex justify-end space-x-3">
<button id="joinPublic" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded">Join Public Chat</button>
</div>
</div>
</div>
<!-- Create Room Modal -->
<div id="createRoomModal" class="hidden fixed inset-0 z-50 bg-black bg-opacity-90 flex items-center justify-center p-4">
<div class="glass-card neon-border rounded-lg w-full max-w-md p-6">
<h2 class="text-2xl font-bold neon-text-blue mb-4">Create New Room</h2>
<div class="mb-4">
<label for="newRoomName" class="block text-sm font-medium mb-1">Room Name</label>
<input type="text" id="newRoomName" placeholder="e.g. Tech Talk" class="w-full bg-gray-800 text-white p-2 rounded focus:outline-none focus:ring-1 focus:ring-blue-500">
</div>
<div class="mb-4">
<label for="roomType" class="block text-sm font-medium mb-1">Room Type</label>
<select id="roomType" class="w-full bg-gray-800 text-white p-2 rounded focus:outline-none focus:ring-1 focus:ring-blue-500">
<option value="public">Public (listed in room directory)</option>
<option value="private">Private (invite only)</option>
</select>
</div>
<div id="privateRoomOptions" class="hidden mb-4">
<label for="inviteCode" class="block text-sm font-medium mb-1">Invite Code</label>
<div class="flex space-x-2">
<input type="text" id="inviteCode" placeholder="Leave blank to generate" class="flex-1 bg-gray-800 text-white p-2 rounded focus:outline-none focus:ring-1 focus:ring-blue-500">
<button id="generateCode" class="bg-gray-700 hover:bg-gray-600 text-white py-2 px-3 rounded text-sm">Generate</button>
</div>
</div>
<div class="flex justify-end space-x-3">
<button id="cancelCreateRoom" class="bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded">Cancel</button>
<button id="confirmCreateRoom" class="bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded">Create Room</button>
</div>
</div>
</div>
<script>
// App State
const state = {
currentUser: null,
currentRoom: null,
isAdmin: false,
isOwner: false,
adminCode: "openchatx", // In a real app, this would be more secure
ownerCode: "masterkeyx",
secretPhrase: "open sesame",
adminShortcutPressed: false,
ownerShortcutPressed: false,
logoClickCount: 0,
logoClickTimeout: null,
rooms: [
{ id: 'general', name: 'General', type: 'public', users: 4, maxUsers: 8 },
{ id: 'tech', name: 'Tech Talk', type: 'public', users: 2, maxUsers: 8 },
{ id: 'gaming', name: 'Gaming', type: 'public', users: 6, maxUsers: 8 },
{ id: 'secret', name: 'Secret Room', type: 'private', users: 3, maxUsers: 8, inviteCode: 'xyz123' }
],
users: [
{ name: 'SilentTurtle91', role: 'user', online: true },
{ name: 'MysticOwl42', role: 'admin', online: true },
{ name: 'QuantumFox', role: 'user', online: false },
{ name: 'NeonGhost', role: 'mod', online: true }
],
messages: {
general: [
{ user: 'SilentTurtle91', text: 'Hello everyone! πŸ‘‹', time: '12:34 PM' },
{ user: 'MysticOwl42', text: 'Hey there! How\'s everyone doing?', time: '12:35 PM' }
]
}
};
// DOM Elements
const elements = {
app: document.getElementById('app'),
welcomeModal: document.getElementById('welcomeModal'),
createRoomModal: document.getElementById('createRoomModal'),
adminPanel: document.getElementById('adminPanel'),
fakeAdminPanel: document.getElementById('fakeAdminPanel'),
unauthorizedPage: document.getElementById('unauthorizedPage'),
emojiRain: document.getElementById('emojiRain'),
username: document.getElementById('username'),
randomUsername: document.getElementById('randomUsername'),
roomCode: document.getElementById('roomCode'),
joinPublic: document.getElementById('joinPublic'),
createRoomBtn: document.getElementById('createRoomBtn'),
newRoomName: document.getElementById('newRoomName'),
roomType: document.getElementById('roomType'),
privateRoomOptions: document.getElementById('privateRoomOptions'),
inviteCode: document.getElementById('inviteCode'),
generateCode: document.getElementById('generateCode'),
cancelCreateRoom: document.getElementById('cancelCreateRoom'),
confirmCreateRoom: document.getElementById('confirmCreateRoom'),
publicRoomsTab: document.getElementById('publicRoomsTab'),
privateRoomsTab: document.getElementById('privateRoomsTab'),
roomSearch: document.getElementById('roomSearch'),
roomsList: document.getElementById('roomsList'),
onlineUsers: document.getElementById('onlineUsers'),
currentRoom: document.getElementById('currentRoom'),
roomControls: document.getElementById('roomControls'),
messages: document.getElementById('messages'),
typingIndicator: document.getElementById('typingIndicator'),
messageInput: document.getElementById('messageInput'),
sendMessage: document.getElementById('sendMessage'),
userBadge: document.getElementById('userBadge'),
usernameDisplay: document.getElementById('usernameDisplay'),
userRoleBadge: document.getElementById('userRoleBadge'),
logo: document.getElementById('logo'),
adminCode: document.getElementById('adminCode'),
submitAdminCode: document.getElementById('submitAdminCode'),
adminError: document.getElementById('adminError'),
adminContent: document.getElementById('adminContent'),
adminAuth: document.getElementById('adminAuth'),
closeAdminPanel: document.getElementById('closeAdminPanel'),
closeFakeAdmin: document.getElementById('closeFakeAdmin'),
goHome: document.getElementById('goHome'),
connectionStatus: document.getElementById('connectionStatus')
};
// Initialize the app
function init() {
// Check if user already has a name in localStorage
const savedName = localStorage.getItem('chatzonex_username');
if (savedName) {
state.currentUser = savedName;
joinRoom('general');
elements.welcomeModal.classList.add('hidden');
updateUserBadge();
} else {
elements.welcomeModal.classList.remove('hidden');
}
// Generate random username if button clicked
elements.randomUsername.addEventListener('click', generateRandomUsername);
// Join public chat
elements.joinPublic.addEventListener('click', () => {
const username = elements.username.value.trim();
if (username) {
state.currentUser = username;
localStorage.setItem('chatzonex_username', username);
const roomCode = elements.roomCode.value.trim();
if (roomCode) {
// Try to join private room
const room = state.rooms.find(r => r.inviteCode === roomCode);
if (room) {
joinRoom(room.id);
} else {
alert('Invalid room code. Joining public chat instead.');
joinRoom('general');
}
} else {
joinRoom('general');
}
elements.welcomeModal.classList.add('hidden');
updateUserBadge();
} else {
alert('Please choose a name');
}
});
// Create room button
elements.createRoomBtn.addEventListener('click', () => {
elements.createRoomModal.classList.remove('hidden');
});
// Room type change
elements.roomType.addEventListener('change', (e) => {
if (e.target.value === 'private') {
elements.privateRoomOptions.classList.remove('hidden');
} else {
elements.privateRoomOptions.classList.add('hidden');
}
});
// Generate invite code
elements.generateCode.addEventListener('click', () => {
elements.inviteCode.value = generateInviteCode();
});
// Cancel create room
elements.cancelCreateRoom.addEventListener('click', () => {
elements.createRoomModal.classList.add('hidden');
});
// Confirm create room
elements.confirmCreateRoom.addEventListener('click', () => {
const roomName = elements.newRoomName.value.trim();
if (!roomName) {
alert('Please enter a room name');
return;
}
const roomType = elements.roomType.value;
const roomId = roomName.toLowerCase().replace(/\s+/g, '-');
let inviteCode = '';
if (roomType === 'private') {
inviteCode = elements.inviteCode.value.trim() || generateInviteCode();
}
// Add new room to state
state.rooms.push({
id: roomId,
name: roomName,
type: roomType,
users: 1,
maxUsers: 8,
inviteCode: inviteCode
});
// Join the new room
joinRoom(roomId);
// Close modal
elements.createRoomModal.classList.add('hidden');
// Update rooms list
renderRoomsList();
});
// Send message
elements.sendMessage.addEventListener('click', sendMessage);
elements.messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
// Typing indicator
elements.messageInput.addEventListener('input', () => {
// In a real app, we'd send a "typing" event to the server
// For demo, we'll just show it locally
if (elements.messageInput.value.trim()) {
elements.typingIndicator.classList.remove('hidden');
elements.typingIndicator.innerHTML = `<span class="typing-indicator"></span> ${state.currentUser} is typing...`;
} else {
elements.typingIndicator.classList.add('hidden');
}
});
// Admin panel controls
elements.closeAdminPanel.addEventListener('click', () => {
elements.adminPanel.classList.add('hidden');
});
elements.submitAdminCode.addEventListener('click', verifyAdminCode);
elements.adminCode.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
verifyAdminCode();
}
});
elements.closeFakeAdmin.addEventListener('click', () => {
elements.fakeAdminPanel.classList.add('hidden');
});
elements.goHome.addEventListener('click', () => {
elements.unauthorizedPage.classList.add('hidden');
});
// Logo click (Easter egg)
elements.logo.addEventListener('click', handleLogoClick);
// Keyboard shortcuts for admin/owner panels
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
// Initial render
renderRoomsList();
renderOnlineUsers();
// Simulate connection status changes
simulateConnectionStatus();
}
// Generate a random username
function generateRandomUsername() {
const adjectives = ['Silent', 'Mystic', 'Quantum', 'Neon', 'Digital', 'Virtual', 'Cosmic', 'Lunar', 'Solar', 'Electric'];
const nouns = ['Turtle', 'Owl', 'Fox', 'Ghost', 'Phoenix', 'Dragon', 'Wolf', 'Eagle', 'Panther', 'Hawk'];
const number = Math.floor(Math.random() * 90) + 10;
const username = `${adjectives[Math.floor(Math.random() * adjectives.length)]}${nouns[Math.floor(Math.random() * nouns.length)]}${number}`;
elements.username.value = username;
}
// Generate an invite code
function generateInviteCode() {
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';
let code = '';
for (let i = 0; i < 6; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
return code;
}
// Join a room
function joinRoom(roomId) {
const room = state.rooms.find(r => r.id === roomId);
if (!room) return;
// Check if room is full (except for admins/owners)
if (room.users >= room.maxUsers && !state.isAdmin && !state.isOwner) {
alert('This room is full');
return;
}
state.currentRoom = roomId;
elements.currentRoom.textContent = room.name;
elements.roomControls.classList.remove('hidden');
// Update room user count
room.users += 1;
// Render messages for this room
renderMessages();
// Update rooms list to show current room as active
renderRoomsList();
}
// Render rooms list
function renderRoomsList() {
elements.roomsList.innerHTML = '';
const isPublicTab = elements.publicRoomsTab.classList.contains('bg-blue-600');
const searchTerm = elements.roomSearch.value.toLowerCase();
state.rooms.forEach(room => {
if ((isPublicTab && room.type !== 'public') || (!isPublicTab && room.type !== 'private')) {
return;
}
if (searchTerm && !room.name.toLowerCase().includes(searchTerm)) {
return;
}
const roomElement = document.createElement('div');
roomElement.className = `p-2 rounded hover:bg-gray-700 cursor-pointer flex justify-between items-center ${state.currentRoom === room.id ? 'bg-gray-700' : ''}`;
roomElement.innerHTML = `
<span>${room.name}</span>
<span class="text-xs ${room.users >= room.maxUsers ? 'text-red-400' : 'text-gray-400'}">${room.users}/${room.maxUsers}</span>
`;
roomElement.addEventListener('click', () => joinRoom(room.id));
elements.roomsList.appendChild(roomElement);
});
}
// Render online users
function renderOnlineUsers() {
elements.onlineUsers.innerHTML = '';
state.users.forEach(user => {
if (user.online) {
const userElement = document.createElement('div');
userElement.className = 'flex items-center space-x-2 p-1';
// Add role badge if current user is admin/owner
let roleBadge = '';
if ((state.isAdmin || state.isOwner) && user.role !== 'user') {
roleBadge = `<span class="text-xs px-1 rounded ${
user.role === 'admin' ? 'badge-admin' :
user.role === 'owner' ? 'badge-owner' : 'bg-gray-600'
}">${user.role === 'mod' ? 'MOD' : user.role.toUpperCase()}</span>`;
}
userElement.innerHTML = `
<div class="w-2 h-2 rounded-full bg-green-500"></div>
<span>${user.name}</span>
${roleBadge}
`;
elements.onlineUsers.appendChild(userElement);
}
});
}
// Render messages for current room
function renderMessages() {
elements.messages.innerHTML = '';
// Add date divider
const dateDivider = document.createElement('div');
dateDivider.className = 'text-center text-gray-400 text-sm mb-4';
dateDivider.textContent = 'Today';
elements.messages.appendChild(dateDivider);
// Add messages
const roomMessages = state.messages[state.currentRoom] || [];
roomMessages.forEach(msg => {
const messageElement = document.createElement('div');
messageElement.className = 'flex mb-3';
const initials = msg.user.substring(0, 2).toUpperCase();
messageElement.innerHTML = `
<div class="flex-shrink-0 w-10 h-10 rounded-full bg-gray-700 flex items-center justify-center mr-3">${initials}</div>
<div>
<div class="flex items-baseline">
<span class="font-bold mr-2">${msg.user}</span>
<span class="text-xs text-gray-400">${msg.time}</span>
</div>
<p class="text-sm">${msg.text}</p>
</div>
`;
elements.messages.appendChild(messageElement);
});
// Scroll to bottom
elements.messages.scrollTop = elements.messages.scrollHeight;
}
// Send a message
function sendMessage() {
const text = elements.messageInput.value.trim();
if (!text) return;
// Check for secret phrase to trigger admin panel
if (text.toLowerCase() === state.secretPhrase) {
showAdminPanel();
elements.messageInput.value = '';
return;
}
// Add message to state
if (!state.messages[state.currentRoom]) {
state.messages[state.currentRoom] = [];
}
const now = new Date();
const time = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
state.messages[state.currentRoom].push({
user: state.currentUser,
text: text,
time: time
});
// Render updated messages
renderMessages();
// Clear input and hide typing indicator
elements.messageInput.value = '';
elements.typingIndicator.classList.add('hidden');
}
// Update user badge in header
function updateUserBadge() {
if (state.currentUser) {
elements.userBadge.classList.remove('hidden');
elements.usernameDisplay.textContent = state.currentUser;
if (state.isAdmin || state.isOwner) {
elements.userRoleBadge.classList.remove('hidden');
elements.userRoleBadge.className = 'text-xs px-2 py-1 rounded-full ' +
(state.isOwner ? 'badge-owner' : 'badge-admin');
elements.userRoleBadge.textContent = state.isOwner ? 'OWNER' : 'ADMIN';
} else {
elements.userRoleBadge.classList.add('hidden');
}
} else {
elements.userBadge.classList.add('hidden');
}
}
// Handle logo click (Easter egg)
function handleLogoClick() {
state.logoClickCount++;
if (state.logoClickTimeout) {
clearTimeout(state.logoClickTimeout);
}
state.logoClickTimeout = setTimeout(() => {
state.logoClickCount = 0;
}, 2000);
if (state.logoClickCount >= 5) {
showAdminPanel();
state.logoClickCount = 0;
}
}
// Handle key down for admin shortcuts
function handleKeyDown(e) {
if (e.ctrlKey && e.shiftKey && e.key === 'A') {
state.adminShortcutPressed = true;
}
if (e.ctrlKey && e.shiftKey && e.key === 'O') {
state.ownerShortcutPressed = true;
}
}
// Handle key up for admin shortcuts
function handleKeyUp(e) {
if (state.adminShortcutPressed && e.key === 'A') {
showAdminPanel();
state.adminShortcutPressed = false;
}
if (state.ownerShortcutPressed && e.key === 'O') {
showAdminPanel(true);
state.ownerShortcutPressed = false;
}
if (e.key === 'Control' || e.key === 'Shift') {
state.adminShortcutPressed = false;
state.ownerShortcutPressed = false;
}
}
// Show admin panel
function showAdminPanel(isOwner = false) {
// If user is already admin/owner, show the panel directly
if ((isOwner && state.isOwner) || (!isOwner && state.isAdmin)) {
elements.adminPanel.classList.remove('hidden');
elements.adminAuth.classList.add('hidden');
elements.adminContent.classList.remove('hidden');
return;
}
// If trying to access owner panel without owner rights, show unauthorized
if (isOwner && !state.isOwner) {
elements.unauthorizedPage.classList.remove('hidden');
return;
}
// Otherwise show authentication
elements.adminPanel.classList.remove('hidden');
elements.adminAuth.classList.remove('hidden');
elements.adminContent.classList.add('hidden');
elements.adminError.classList.add('hidden');
elements.adminCode.focus();
}
// Verify admin code
function verifyAdminCode() {
const code = elements.adminCode.value.trim();
if (code === state.adminCode) {
state.isAdmin = true;
updateUserBadge();
elements.adminAuth.classList.add('hidden');
elements.adminContent.classList.remove('hidden');
renderOnlineUsers(); // Update to show role badges
} else if (code === state.ownerCode) {
state.isOwner = true;
state.isAdmin = true;
updateUserBadge();
elements.adminAuth.classList.add('hidden');
elements.adminContent.classList.remove('hidden');
renderOnlineUsers(); // Update to show role badges
} else {
elements.adminError.classList.remove('hidden');
}
}
// Create emoji rain effect
function createEmojiRain() {
const emojis = ['πŸ˜€', 'πŸ˜‚', '🀣', '❀️', 'πŸ”₯', 'πŸ‘', 'πŸŽ‰', 'πŸ€”', 'πŸ‘€', '🌈'];
elements.emojiRain.innerHTML = '';
elements.emojiRain.classList.remove('hidden');
for (let i = 0; i < 50; i++) {
const emoji = document.createElement('div');
emoji.className = 'emoji';
emoji.textContent = emojis[Math.floor(Math.random() * emojis.length)];
emoji.style.left = Math.random() * 100 + 'vw';
emoji.style.animationDuration = Math.random() * 3 + 2 + 's';
emoji.style.animationDelay = Math.random() * 2 + 's';
elements.emojiRain.appendChild(emoji);
}
setTimeout(() => {
elements.emojiRain.classList.add('hidden');
}, 5000);
}
// Simulate connection status changes
function simulateConnectionStatus() {
setInterval(() => {
if (Math.random() > 0.9) { // 10% chance to change status
if (elements.connectionStatus.classList.contains('bg-green-600')) {
elements.connectionStatus.classList.remove('bg-green-600');
elements.connectionStatus.classList.add('bg-yellow-600');
elements.connectionStatus.textContent = 'Reconnecting...';
} else {
elements.connectionStatus.classList.remove('bg-yellow-600');
elements.connectionStatus.classList.add('bg-green-600');
elements.connectionStatus.textContent = 'Connected';
}
}
}, 10000);
}
// Initialize the app when DOM is loaded
document.addEventListener('DOMContentLoaded', init);
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=CodNikhil/chatzonex" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>