anycoder-e2b5b621 / index.html
samirerty's picture
Upload folder using huggingface_hub
9c062a7 verified
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>چت روم مینیمال | Minimal Chat</title>
<!-- Importing Vazirmatn Font -->
<link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet" type="text/css" />
<!-- Importing FontAwesome for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #6366f1;
--primary-dark: #4f46e5;
--secondary: #ec4899;
--bg-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
--glass-bg: rgba(255, 255, 255, 0.1);
--glass-border: rgba(255, 255, 255, 0.2);
--glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
--text-main: #ffffff;
--text-muted: #e2e8f0;
--danger: #ef4444;
--success: #10b981;
--msg-sent: rgba(99, 102, 241, 0.3);
--msg-received: rgba(255, 255, 255, 0.1);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
-webkit-tap-highlight-color: transparent;
}
body {
font-family: 'Vazirmatn', sans-serif;
background: var(--bg-gradient);
color: var(--text-main);
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
/* --- Glass Container --- */
.app-container {
width: 100%;
height: 100%;
max-width: 480px; /* Mobile App feel */
background: var(--glass-bg);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--glass-border);
border-radius: 20px;
box-shadow: var(--glass-shadow);
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
}
@media (min-width: 481px) {
.app-container {
height: 90vh;
margin: 20px;
}
}
/* --- Header --- */
header {
padding: 15px 20px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(0, 0, 0, 0.1);
border-bottom: 1px solid var(--glass-border);
z-index: 10;
}
.header-title {
font-size: 1.1rem;
font-weight: 700;
display: flex;
align-items: center;
gap: 10px;
}
.status-dot {
width: 10px;
height: 10px;
background: var(--success);
border-radius: 50%;
box-shadow: 0 0 10px var(--success);
}
.built-with {
font-size: 0.7rem;
color: rgba(255, 255, 255, 0.5);
text-decoration: none;
margin-top: 5px;
display: block;
text-align: center;
}
/* --- Screens Management --- */
.screen {
display: none;
flex: 1;
flex-direction: column;
height: 100%;
animation: fadeIn 0.4s ease;
}
.screen.active {
display: flex;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* --- Auth Screen --- */
.auth-screen {
justify-content: center;
align-items: center;
padding: 30px;
text-align: center;
}
.auth-icon {
font-size: 3rem;
margin-bottom: 20px;
color: var(--primary);
text-shadow: 0 0 20px rgba(99, 102, 241, 0.5);
}
.auth-input {
width: 100%;
padding: 15px;
margin: 10px 0;
background: rgba(255, 255, 255, 0.1);
border: 1px solid var(--glass-border);
border-radius: 12px;
color: white;
font-family: 'Vazirmatn', sans-serif;
font-size: 1rem;
text-align: center;
outline: none;
transition: 0.3s;
}
.auth-input:focus {
background: rgba(255, 255, 255, 0.2);
border-color: var(--primary);
}
.btn-primary {
width: 100%;
padding: 15px;
background: var(--primary);
border: none;
border-radius: 12px;
color: white;
font-family: 'Vazirmatn', sans-serif;
font-size: 1rem;
font-weight: bold;
cursor: pointer;
transition: 0.3s;
margin-top: 10px;
}
.btn-primary:active {
transform: scale(0.98);
background: var(--primary-dark);
}
/* --- Room List Screen --- */
.room-list {
padding: 20px;
overflow-y: auto;
flex: 1;
}
.room-card {
background: rgba(255, 255, 255, 0.1);
border: 1px solid var(--glass-border);
padding: 15px;
border-radius: 15px;
margin-bottom: 15px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: pointer;
transition: 0.3s;
}
.room-card:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateX(-5px);
}
.room-info h3 {
font-size: 1rem;
margin-bottom: 5px;
}
.room-info p {
font-size: 0.8rem;
color: var(--text-muted);
}
.add-room-btn {
width: 100%;
padding: 20px;
border: 2px dashed rgba(255, 255, 255, 0.3);
border-radius: 15px;
background: transparent;
color: white;
font-size: 1.2rem;
cursor: pointer;
transition: 0.3s;
}
.add-room-btn:hover {
border-color: var(--primary);
background: rgba(99, 102, 241, 0.1);
}
/* --- Chat Screen --- */
.chat-header {
padding: 10px 15px;
background: rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
gap: 10px;
border-bottom: 1px solid var(--glass-border);
}
.chat-back {
font-size: 1.2rem;
cursor: pointer;
padding: 5px;
}
.chat-messages {
flex: 1;
padding: 15px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 10px;
scroll-behavior: smooth;
}
.message {
max-width: 80%;
padding: 10px 15px;
border-radius: 18px;
font-size: 0.95rem;
position: relative;
word-wrap: break-word;
animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
@keyframes popIn {
from { opacity: 0; transform: scale(0.8); }
to { opacity: 1; transform: scale(1); }
}
.message.sent {
align-self: flex-end;
background: var(--msg-sent);
border-bottom-left-radius: 4px;
border: 1px solid rgba(99, 102, 241, 0.3);
}
.message.received {
align-self: flex-start;
background: var(--msg-received);
border-bottom-right-radius: 4px;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.message-meta {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 5px;
margin-top: 5px;
font-size: 0.7rem;
color: rgba(255, 255, 255, 0.6);
}
.message-actions {
display: flex;
gap: 8px;
opacity: 0;
transition: 0.2s;
}
.message:hover .message-actions {
opacity: 1;
}
.action-btn {
background: none;
border: none;
color: rgba(255, 255, 255, 0.6);
cursor: pointer;
padding: 2px;
}
.action-btn:hover {
color: white;
}
/* --- Reply Preview --- */
.reply-preview {
background: rgba(0, 0, 0, 0.2);
padding: 8px 15px;
border-radius: 10px;
margin-bottom: 10px;
font-size: 0.8rem;
display: none;
align-items: center;
justify-content: space-between;
border-right: 3px solid var(--primary);
}
/* --- Chat Input Area --- */
.chat-input-area {
padding: 10px;
background: rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
gap: 10px;
}
.emoji-trigger {
font-size: 1.5rem;
cursor: pointer;
padding: 5px;
}
.chat-input {
flex: 1;
background: rgba(255, 255, 255, 0.1);
border: none;
padding: 12px 15px;
border-radius: 25px;
color: white;
font-family: 'Vazirmatn', sans-serif;
outline: none;
}
.send-btn {
background: var(--primary);
width: 45px;
height: 45px;
border-radius: 50%;
border: none;
color: white;
font-size: 1.2rem;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: 0.3s;
}
.send-btn:hover {
background: var(--primary-dark);
transform: scale(1.1);
}
/* --- Emoji Picker --- */
.emoji-picker {
position: absolute;
bottom: 80px;
left: 20px;
background: rgba(0, 0, 0, 0.8);
backdrop-filter: blur(10px);
padding: 15px;
border-radius: 15px;
display: grid;
grid-template-columns: repeat(6, 1fr);
gap: 10px;
z-index: 100;
display: none; /* Hidden by default */
border: 1px solid var(--glass-border);
}
.emoji-picker.active {
display: grid;
}
.emoji-btn {
font-size: 1.5rem;
cursor: pointer;
transition: 0.2s;
}
.emoji-btn:hover {
transform: scale(1.2);
}
/* --- Modals --- */
.modal-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(5px);
display: flex;
justify-content: center;
align-items: center;
z-index: 200;
opacity: 0;
pointer-events: none;
transition: 0.3s;
}
.modal-overlay.active {
opacity: 1;
pointer-events: all;
}
.modal {
background: #1e1e2e;
width: 85%;
padding: 25px;
border-radius: 20px;
border: 1px solid var(--glass-border);
transform: scale(0.9);
transition: 0.3s;
}
.modal-overlay.active .modal {
transform: scale(1);
}
.modal h2 {
margin-bottom: 15px;
color: white;
}
.modal input {
width: 100%;
padding: 12px;
margin-bottom: 20px;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 10px;
color: white;
font-family: 'Vazirmatn', sans-serif;
}
.modal-actions {
display: flex;
gap: 10px;
}
.btn-cancel {
flex: 1;
padding: 12px;
background: rgba(255, 255, 255, 0.1);
border: none;
border-radius: 10px;
color: white;
cursor: pointer;
}
.btn-confirm {
flex: 1;
padding: 12px;
background: var(--primary);
border: none;
border-radius: 10px;
color: white;
cursor: pointer;
}
/* --- Toast Notification --- */
.toast {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%) translateY(-20px);
background: rgba(0, 0, 0, 0.8);
padding: 10px 20px;
border-radius: 20px;
font-size: 0.9rem;
opacity: 0;
transition: 0.3s;
pointer-events: none;
z-index: 300;
white-space: nowrap;
}
.toast.show {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
/* --- Reactions --- */
.reaction-bubble {
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%) scale(0);
font-size: 1.5rem;
transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
pointer-events: none;
z-index: 50;
}
.reaction-bubble.show {
transform: translateX(-50%) scale(1);
}
</style>
</head>
<body>
<div class="app-container">
<header>
<div class="header-title">
<div class="status-dot"></div>
<span id="app-title">چت روم</span>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">Built with anycoder</a>
</header>
<!-- Toast Notification -->
<div id="toast" class="toast">پیام سیستم</div>
<!-- Screen 1: Authentication -->
<div id="auth-screen" class="screen active auth-screen">
<i class="fas fa-comments auth-icon"></i>
<h2 style="margin-bottom: 20px;">خوش آمدید</h2>
<input type="tel" id="phone-input" class="auth-input" placeholder="شماره موبایل خود را وارد کنید" maxlength="11">
<button class="btn-primary" onclick="App.auth.login()">ورود / ثبت‌نام</button>
</div>
<!-- Screen 2: Room List -->
<div id="room-screen" class="screen">
<div class="room-list">
<div id="rooms-container">
<!-- Rooms injected here -->
</div>
<button class="add-room-btn" onclick="App.rooms.openCreateModal()">
<i class="fas fa-plus"></i> ایجاد اتاق جدید
</button>
</div>
</div>
<!-- Screen 3: Chat Room -->
<div id="chat-screen" class="screen">
<div class="chat-header">
<i class="fas fa-arrow-right chat-back" onclick="App.ui.navigate('room-screen')"></i>
<div style="flex:1">
<h3 id="chat-room-name" style="font-size: 1rem;">نام اتاق</h3>
<p id="chat-room-count" style="font-size: 0.7rem; color: var(--text-muted);">0 نفر آنلاین</p>
</div>
<i class="fas fa-share-alt" style="cursor: pointer;" onclick="App.chat.copyLink()" title="کپی لینک"></i>
</div>
<div class="chat-messages" id="chat-messages">
<!-- Messages injected here -->
</div>
<!-- Reply Preview -->
<div id="reply-preview" class="reply-preview">
<span id="reply-text">پاسخ به...</span>
<i class="fas fa-times" style="cursor: pointer;" onclick="App.chat.cancelReply()"></i>
</div>
<!-- Emoji Picker -->
<div class="emoji-picker" id="emoji-picker">
<div class="emoji-btn" onclick="App.chat.insertEmoji('😀')">😀</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('😂')">😂</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('😍')">😍</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('😎')">😎</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('🤔')">🤔</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('👍')">👍</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('👎')">👎</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('🎉')">🎉</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('❤️')">❤️</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('🔥')">🔥</div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('✨')"></div>
<div class="emoji-btn" onclick="App.chat.insertEmoji('👋')">👋</div>
</div>
<div class="chat-input-area">
<i class="fas fa-smile emoji-trigger" onclick="App.ui.toggleEmojiPicker()"></i>
<input type="text" id="message-input" class="chat-input" placeholder="پیام خود را بنویسید..." onkeypress="App.chat.handleKeyPress(event)">
<button class="send-btn" onclick="App.chat.sendMessage()">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
<!-- Create Room Modal -->
<div id="create-room-modal" class="modal-overlay">
<div class="modal">
<h2>ساخت اتاق جدید</h2>
<input type="text" id="new-room-name" placeholder="نام اتاق را وارد کنید">
<div class="modal-actions">
<button class="btn-cancel" onclick="App.rooms.closeModal()">انصراف</button>
<button class="btn-confirm" onclick="App.rooms.createRoom()">ساخت</button>
</div>
</div>
</div>
<!-- Delete Confirmation Modal -->
<div id="delete-modal" class="modal-overlay">
<div class="modal">
<h2>حذف پیام</h2>
<p style="margin-bottom: 20px; color: #ccc;">آیا از حذف این پیام اطمینان دارید؟</p>
<div class="modal-actions">
<button class="btn-cancel" onclick="App.chat.closeDeleteModal()">انصراف</button>
<button class="btn-confirm" style="background: var(--danger);" onclick="App.chat.confirmDelete()">حذف</button>
</div>
</div>
</div>
</div>
<script>
/**
* Main Application Logic
* Implements modular structure within a single file
*/
const App = {
state: {
user: null,
currentRoomId: null,
rooms: [],
messages: [],
replyingTo: null,
deletingMessageId: null
},
init: function() {
// Load data from localStorage or initialize defaults
const savedRooms = localStorage.getItem('chat_rooms');
const savedMessages = localStorage.getItem('chat_messages');
if (savedRooms) {
this.state.rooms = JSON.parse(savedRooms);
} else {
// Default rooms
this.state.rooms = [
{ id: 1, name: 'گفتگوی عمومی', lastMsg: 'سلام همه دوستان!', time: '10:30' },
{ id: 2, name: 'تکنولوژی', lastMsg: 'کدام گوشی را پیشنهاد می‌کنید؟', time: '09:15' }
];
}
if (savedMessages) {
this.state.messages = JSON.parse(savedMessages);
}
// Initialize UI
this.ui.renderRooms();
// Setup Swipe Gestures
this.gestures.init();
},
// --- Authentication Module ---
auth: {
login: function() {
const phoneInput = document.getElementById('phone-input');
const phone = phoneInput.value.trim();
if (phone.length < 10) {
App.ui.showToast('لطفاً شماره موبایل معتبر وارد کنید');
return;
}
// Simulate API Call
App.state.user = { phone: phone, name: 'کاربر ' + phone.slice(-4) };
App.ui.showToast(`خوش آمدید، ${App.state.user.name}`);
App.ui.navigate('room-screen');
}
},
// --- Room Management Module ---
rooms: {
openCreateModal: function() {
document.getElementById('create-room-modal').classList.add('active');
document.getElementById('new-room-name').focus();
},
closeModal: function() {
document.getElementById('create-room-modal').classList.remove('active');
document.getElementById('new-room-name').value = '';
},
createRoom: function() {
const nameInput = document.getElementById('new-room-name');
const name = nameInput.value.trim();
if (!name) {
App.ui.showToast('نام اتاق نمی‌تواند خالی باشد');
return;
}
const newRoom = {
id: Date.now(),
name: name,
lastMsg: 'اتاق ساخته شد',
time: new Date().toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'})
};
App.state.rooms.unshift(newRoom); // Add to top
App.utils.saveData();
App.ui.renderRooms();
App.rooms.closeModal();
App.ui.showToast('اتاق با موفقیت ساخته شد');
}
},
// --- Chat Module ---
chat: {
sendMessage: function() {
const input = document.getElementById('message-input');
const text = input.value.trim();
if (!text) return;
const msgData = {
id: Date.now(),
roomId: App.state.currentRoomId,
sender: App.state.user.name,
text: text,
timestamp: new Date().toISOString(),
reactions: []
};
// Add to local state
App.state.messages.push(msgData);
App.utils.saveData();
// Update room metadata
const roomIndex = App.state.rooms.findIndex(r => r.id === App.state.currentRoomId);
if (roomIndex > -1) {
App.state.rooms[roomIndex].lastMsg = text;
App.state.rooms[roomIndex].time = new Date().toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'});
App.utils.saveData();
}
// Render
App.ui.renderMessages();
App.ui.renderRooms(); // Update list preview
input.value = '';
App.chat.cancelReply();
},
handleKeyPress: function(e) {
if (e.key === 'Enter') {
App.chat.sendMessage();
}
},
openRoom: function(roomId) {
App.state.currentRoomId = roomId;
const room = App.state.rooms.find(r => r.id === roomId);
document.getElementById('chat-room-name').innerText = room.name;
document.getElementById('chat-room-count').innerText = Math.floor(Math.random() * 20 + 5) + ' نفر آنلاین';
App.ui.navigate('chat-screen');
App.ui.renderMessages();
},
renderMessages: function() {
const container = document.getElementById('chat-messages');
container.innerHTML = '';
const roomMessages = App.state.messages.filter(m => m.roomId === App.state.currentRoomId);
if (roomMessages.length === 0) {
container.innerHTML = '<div style="text-align:center; opacity:0.5; margin-top:20px;">هنوز پیامی وجود ندارد. شروع کنید!</div>';
return;
}
roomMessages.forEach(msg => {
const isSent = msg.sender === App.state.user.name;
const timeString = new Date(msg.timestamp).toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'});
const msgEl = document.createElement('div');
msgEl.className = `message ${isSent ? 'sent' : 'received'}`;
msgEl.innerHTML = `
${msg.text}
<div class="message-meta">
<span>${timeString}</span>
<div class="message-actions">
<button class="action-btn" onclick="App.chat.startReply(${msg.id})" title="پاسخ"><i class="fas fa-reply"></i></button>
<button class="action-btn" onclick="App.chat.openDeleteModal(${msg.id})" title="حذف"><i class="fas fa-trash"></i></button>
</div>
</div>
`;
// Reaction click listener
msgEl.addEventListener('click', (e) => {
if(!e.target.closest('.message-actions')) {
App.chat.showReactionPopup(msg.id);
}
});
container.appendChild(msgEl);
});
// Scroll to bottom
container.scrollTop = container.scrollHeight;
},
// Reply Functionality
startReply: function(msgId) {
const msg = App.state.messages.find(m => m.id === msgId);
App.state.replyingTo = msg;
const preview = document.getElementById('reply-preview');
const previewText = document.getElementById('reply-text');
previewText.innerText = `پاسخ به: ${msg.text}`;
preview.style.display = 'flex';
document.getElementById('message-input').focus();
},
cancelReply: function() {
App.state.replyingTo = null;
document.getElementById('reply-preview').style.display = 'none';
},
// Delete Functionality
openDeleteModal: function(msgId) {
App.state.deletingMessageId = msgId;
document.getElementById('delete-modal').classList.add('active');
},
closeDeleteModal: function() {
App.state.deletingMessageId = null;
document.getElementById('delete-modal').classList.remove('active');
},
confirmDelete: function() {
if (App.state.deletingMessageId) {
App.state.messages = App.state.messages.filter(m => m.id !== App.state.deletingMessageId);
App.utils.saveData();
App.ui.renderMessages();
App.ui.showToast('پیام حذف شد');
}
App.chat.closeDeleteModal();
},
// Emoji Functionality
insertEmoji: function(emoji) {
const input = document.getElementById('message-input');
input.value += emoji;
input.focus();
},
showReactionPopup: function(msgId) {
const emojis = ['👍', '❤️', '😂', '😮', '😢', '😡'];
const reactionsContainer = document.createElement('div');
reactionsContainer.style.position = 'absolute';
reactionsContainer.style.bottom = '20px';
reactionsContainer.style.left = '50%';
reactionsContainer.style.transform = 'translateX(-50%)';
reactionsContainer.style.display = 'flex';
reactionsContainer.style.gap = '10px';
reactionsContainer.style.background = 'rgba(0,0,0,0.7)';
reactionsContainer.style.padding = '10px';
reactionsContainer.style.borderRadius = '30px';
reactionsContainer.style.zIndex = '100';
emojis.forEach(emoji => {
const btn = document.createElement('button');
btn.innerText = emoji;
btn.style.background = 'none';
btn.style.border = 'none';
btn.style.fontSize = '1.5rem';
btn.style.cursor = 'pointer';
btn.onclick = () => App.chat.addReaction(msgId, emoji);
reactionsContainer.appendChild(btn);
});
document.getElementById('chat-screen').appendChild(reactionsContainer);
// Remove after 2 seconds
setTimeout(() => {
reactionsContainer.remove();
}, 2000);
},
addReaction: function(msgId, emoji) {
const msg = App.state.messages.find(m => m.id === msgId);
if (msg) {
// Simple reaction logic: just store it for now
// In a real app, we'd track users
App.ui.showToast(`واکنش ${emoji} ثبت شد`);
}
},
copyLink: function() {
const dummyLink = `${window.location.origin}?room=${App.state.currentRoomId}`;
navigator.clipboard.writeText(dummyLink).then(() => {
App.ui.showToast('لینک اتاق کپی شد');
});
}
},
// --- UI Module ---
ui: {
navigate: function(screenId) {
document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
document.getElementById(screenId).classList.add('active');
},
renderRooms: function() {
const container = document.getElementById('rooms-container');
container.innerHTML = '';
App.state.rooms.forEach(room => {
const card = document.createElement('div');
card.className = 'room-card';
card.onclick = () => App.chat.openRoom(room.id);
card.innerHTML = `
<div class="room-info">
<h3>${room.name}</h3>
<p>${room.lastMsg}</p>
</div>
<div style="text-align:left; color:var(--text-muted); font-size:0.8rem;">
<div>${room.time}</div>
<i class="fas fa-chevron-left"></i>
</div>
`;
container.appendChild(card);
});
},
renderMessages: function() {
App.chat.renderMessages();
},
toggleEmojiPicker: function() {
const picker = document.getElementById('emoji-picker');
picker.classList.toggle('active');
},
showToast: function(message) {
const toast = document.getElementById('toast');
toast.innerText = message;
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
},
// --- Gestures Module ---
gestures: {
init: function() {
let startX = 0;
let startY = 0;
const container = document.querySelector('.app-container');
container.addEventListener('touchstart', (e) => {
startX = e.changedTouches[0].screenX;
startY = e.changedTouches[0].screenY;
}, {passive: true});
container.addEventListener('touchend', (e) => {
const endX = e.changedTouches[0].screenX;
const endY = e.changedTouches[0].screenY;
const diffX = startX - endX;
const diffY = startY - endY;
// Swipe Right to go back (common mobile pattern)
if (Math.abs(diffX) > 50 && Math.abs(diffX) > Math.abs(diffY)) {
if (diffX > 0) {
// Swipe Right
if (document.getElementById('chat-screen').classList.contains('active')) {
App.ui.navigate('room-screen');
}
}
}
});
}
},
// --- Utilities ---
utils: {
saveData: function() {
localStorage.setItem('chat_rooms', JSON.stringify(App.state.rooms));
localStorage.setItem('chat_messages', JSON.stringify(App.state.messages));
}
}
};
// Start App
document.addEventListener('DOMContentLoaded', () => {
App.init();
});
</script>
</body>
</html>