Spaces:
Running
Running
| <html lang="fa" dir="rtl"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>چتروم پیشرفته</title> | |
| <!-- اتصال فونت فارسی وزیرمتن --> | |
| <link href="https://cdn.jsdelivr.net/gh/rastikerdar/vazirmatn@v33.003/Vazirmatn-font-face.css" rel="stylesheet" type="text/css" /> | |
| <!-- اتصال کتابخانه آیکون FontAwesome --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --primary-color: #6C63FF; | |
| --secondary-color: #4CAF50; | |
| --danger-color: #FF5252; | |
| --bg-color: #f4f7f6; | |
| --chat-bg: #e5ddd5; | |
| --white: #ffffff; | |
| --text-dark: #333333; | |
| --text-light: #777777; | |
| --shadow: 0 4px 15px rgba(0,0,0,0.1); | |
| --radius: 12px; | |
| --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); | |
| } | |
| * { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| outline: none; | |
| } | |
| body { | |
| font-family: 'Vazirmatn', sans-serif; | |
| background-color: var(--bg-color); | |
| color: var(--text-dark); | |
| height: 100vh; | |
| overflow: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| /* --- Header / Branding --- */ | |
| .app-header { | |
| background: var(--white); | |
| padding: 10px 20px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| box-shadow: 0 2px 5px rgba(0,0,0,0.05); | |
| z-index: 100; | |
| } | |
| .brand-link { | |
| font-size: 0.8rem; | |
| color: var(--primary-color); | |
| text-decoration: none; | |
| font-weight: bold; | |
| } | |
| /* --- Views Management --- */ | |
| .view { | |
| display: none; | |
| height: calc(100vh - 50px); | |
| width: 100%; | |
| overflow-y: auto; | |
| position: relative; | |
| animation: fadeIn 0.4s ease; | |
| } | |
| .view.active { | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| /* --- Login View --- */ | |
| #login-view { | |
| justify-content: center; | |
| align-items: center; | |
| background: linear-gradient(135deg, var(--primary-color), #8E84FF); | |
| color: var(--white); | |
| } | |
| .login-card { | |
| background: var(--white); | |
| padding: 2rem; | |
| border-radius: var(--radius); | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.2); | |
| width: 90%; | |
| max-width: 400px; | |
| text-align: center; | |
| color: var(--text-dark); | |
| } | |
| .login-card h2 { | |
| margin-bottom: 1.5rem; | |
| color: var(--primary-color); | |
| } | |
| .form-group { | |
| margin-bottom: 1rem; | |
| text-align: right; | |
| } | |
| .form-group label { | |
| display: block; | |
| margin-bottom: 0.5rem; | |
| font-size: 0.9rem; | |
| color: var(--text-light); | |
| } | |
| .form-input { | |
| width: 100%; | |
| padding: 12px; | |
| border: 2px solid #eee; | |
| border-radius: 8px; | |
| font-family: inherit; | |
| transition: var(--transition); | |
| } | |
| .form-input:focus { | |
| border-color: var(--primary-color); | |
| } | |
| .captcha-container { | |
| display: flex; | |
| gap: 10px; | |
| align-items: center; | |
| margin-bottom: 1rem; | |
| } | |
| .captcha-code { | |
| background: #eee; | |
| padding: 10px 15px; | |
| border-radius: 8px; | |
| font-weight: bold; | |
| letter-spacing: 3px; | |
| font-family: monospace; | |
| user-select: none; | |
| } | |
| .btn { | |
| background: var(--primary-color); | |
| color: var(--white); | |
| border: none; | |
| padding: 12px 24px; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-family: inherit; | |
| font-size: 1rem; | |
| width: 100%; | |
| transition: var(--transition); | |
| } | |
| .btn:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 5px 15px rgba(108, 99, 255, 0.4); | |
| } | |
| .btn-secondary { | |
| background: var(--secondary-color); | |
| } | |
| .btn-danger { | |
| background: var(--danger-color); | |
| } | |
| /* --- Dashboard View --- */ | |
| #dashboard-view { | |
| background: var(--bg-color); | |
| } | |
| .dash-header { | |
| background: var(--white); | |
| padding: 15px 20px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| box-shadow: 0 2px 5px rgba(0,0,0,0.05); | |
| } | |
| .user-profile { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| cursor: pointer; | |
| } | |
| .user-avatar { | |
| width: 45px; | |
| height: 45px; | |
| border-radius: 50%; | |
| object-fit: cover; | |
| border: 2px solid var(--primary-color); | |
| } | |
| .user-info h3 { | |
| font-size: 1rem; | |
| margin-bottom: 2px; | |
| } | |
| .user-info p { | |
| font-size: 0.8rem; | |
| color: var(--text-light); | |
| } | |
| .room-list { | |
| padding: 20px; | |
| flex: 1; | |
| overflow-y: auto; | |
| } | |
| .room-card { | |
| background: var(--white); | |
| padding: 15px; | |
| border-radius: var(--radius); | |
| margin-bottom: 15px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| box-shadow: 0 2px 8px rgba(0,0,0,0.03); | |
| } | |
| .room-card:hover { | |
| transform: scale(1.02); | |
| box-shadow: 0 5px 15px rgba(0,0,0,0.08); | |
| } | |
| .room-details { | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| } | |
| .room-icon { | |
| width: 50px; | |
| height: 50px; | |
| background: #eef2ff; | |
| border-radius: 12px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: var(--primary-color); | |
| font-size: 1.2rem; | |
| } | |
| .room-text h4 { | |
| margin-bottom: 4px; | |
| } | |
| .room-text span { | |
| font-size: 0.8rem; | |
| color: var(--text-light); | |
| } | |
| .online-badge { | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| font-size: 0.8rem; | |
| background: #e8f5e9; | |
| color: var(--secondary-color); | |
| padding: 4px 8px; | |
| border-radius: 20px; | |
| } | |
| .dot { | |
| width: 8px; | |
| height: 8px; | |
| background: var(--secondary-color); | |
| border-radius: 50%; | |
| } | |
| .fab-create { | |
| position: absolute; | |
| bottom: 30px; | |
| left: 30px; | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 50%; | |
| background: var(--primary-color); | |
| color: var(--white); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.5rem; | |
| box-shadow: 0 5px 20px rgba(108, 99, 255, 0.5); | |
| cursor: pointer; | |
| transition: var(--transition); | |
| } | |
| .fab-create:hover { | |
| transform: rotate(90deg) scale(1.1); | |
| } | |
| /* --- Chat View --- */ | |
| #chat-view { | |
| background: var(--chat-bg); | |
| } | |
| .chat-header { | |
| background: var(--white); | |
| padding: 10px 15px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| box-shadow: 0 1px 5px rgba(0,0,0,0.1); | |
| z-index: 10; | |
| } | |
| .chat-info { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .btn-back { | |
| background: none; | |
| border: none; | |
| font-size: 1.2rem; | |
| color: var(--text-dark); | |
| cursor: pointer; | |
| padding: 5px; | |
| } | |
| .chat-stats { | |
| font-size: 0.75rem; | |
| color: var(--secondary-color); | |
| margin-top: 2px; | |
| } | |
| .chat-actions { | |
| position: relative; | |
| } | |
| .btn-menu { | |
| background: none; | |
| border: none; | |
| font-size: 1.2rem; | |
| color: var(--text-dark); | |
| cursor: pointer; | |
| padding: 5px 10px; | |
| } | |
| .menu-dropdown { | |
| position: absolute; | |
| top: 100%; | |
| left: 0; | |
| background: var(--white); | |
| border-radius: 8px; | |
| box-shadow: 0 5px 20px rgba(0,0,0,0.15); | |
| width: 150px; | |
| display: none; | |
| flex-direction: column; | |
| overflow: hidden; | |
| } | |
| .menu-dropdown.show { | |
| display: flex; | |
| } | |
| .menu-item { | |
| padding: 10px 15px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| font-size: 0.9rem; | |
| color: var(--text-dark); | |
| transition: background 0.2s; | |
| } | |
| .menu-item:hover { | |
| background: #f0f0f0; | |
| } | |
| .menu-item.danger { | |
| color: var(--danger-color); | |
| } | |
| .messages-container { | |
| flex: 1; | |
| padding: 15px; | |
| overflow-y: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 10px; | |
| } | |
| .message { | |
| max-width: 75%; | |
| padding: 10px 15px; | |
| border-radius: 12px; | |
| position: relative; | |
| font-size: 0.95rem; | |
| line-height: 1.5; | |
| animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); | |
| } | |
| @keyframes popIn { | |
| from { transform: scale(0.8); opacity: 0; } | |
| to { transform: scale(1); opacity: 1; } | |
| } | |
| .message.received { | |
| align-self: flex-start; | |
| background: var(--white); | |
| border-bottom-right-radius: 2px; | |
| box-shadow: 0 1px 2px rgba(0,0,0,0.1); | |
| } | |
| .message.sent { | |
| align-self: flex-end; | |
| background: #dcf8c6; | |
| border-bottom-left-radius: 2px; | |
| box-shadow: 0 1px 2px rgba(0,0,0,0.1); | |
| } | |
| .msg-meta { | |
| font-size: 0.7rem; | |
| color: #999; | |
| text-align: left; | |
| margin-top: 5px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .msg-actions { | |
| position: absolute; | |
| top: -10px; | |
| background: var(--white); | |
| border-radius: 20px; | |
| padding: 2px 8px; | |
| box-shadow: 0 2px 5px rgba(0,0,0,0.2); | |
| display: none; | |
| gap: 8px; | |
| font-size: 0.8rem; | |
| } | |
| .message:hover .msg-actions { | |
| display: flex; | |
| } | |
| .action-icon { | |
| cursor: pointer; | |
| color: var(--text-light); | |
| transition: color 0.2s; | |
| } | |
| .action-icon:hover { | |
| color: var(--primary-color); | |
| } | |
| .reply-preview { | |
| font-size: 0.8rem; | |
| color: var(--text-light); | |
| border-right: 3px solid var(--primary-color); | |
| padding-right: 8px; | |
| margin-bottom: 5px; | |
| background: rgba(0,0,0,0.05); | |
| padding: 4px; | |
| border-radius: 4px; | |
| } | |
| .chat-input-area { | |
| background: var(--white); | |
| padding: 10px; | |
| display: flex; | |
| align-items: flex-end; | |
| gap: 10px; | |
| } | |
| .reply-bar { | |
| background: #f0f0f0; | |
| width: 100%; | |
| padding: 5px 10px; | |
| font-size: 0.8rem; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| border-bottom: 1px solid #ddd; | |
| display: none; | |
| } | |
| .reply-bar.active { | |
| display: flex; | |
| } | |
| #message-input { | |
| flex: 1; | |
| padding: 10px; | |
| border: 1px solid #ddd; | |
| border-radius: 20px; | |
| resize: none; | |
| height: 40px; | |
| max-height: 100px; | |
| font-family: inherit; | |
| } | |
| .btn-send { | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 50%; | |
| background: var(--primary-color); | |
| color: var(--white); | |
| border: none; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| } | |
| .btn-send:hover { | |
| background: #5a52d5; | |
| } | |
| /* --- Modals --- */ | |
| .modal-overlay { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0,0,0,0.5); | |
| display: none; | |
| justify-content: center; | |
| align-items: center; | |
| z-index: 1000; | |
| backdrop-filter: blur(3px); | |
| } | |
| .modal-overlay.active { | |
| display: flex; | |
| } | |
| .modal-content { | |
| background: var(--white); | |
| padding: 20px; | |
| border-radius: var(--radius); | |
| width: 90%; | |
| max-width: 350px; | |
| animation: slideUp 0.3s ease; | |
| } | |
| @keyframes slideUp { | |
| from { transform: translateY(20px); opacity: 0; } | |
| to { transform: translateY(0); opacity: 1; } | |
| } | |
| .avatar-selection { | |
| display: flex; | |
| gap: 10px; | |
| margin-top: 10px; | |
| justify-content: center; | |
| flex-wrap: wrap; | |
| } | |
| .avatar-option { | |
| width: 50px; | |
| height: 50px; | |
| border-radius: 50%; | |
| cursor: pointer; | |
| border: 2px solid transparent; | |
| transition: var(--transition); | |
| } | |
| .avatar-option.selected { | |
| border-color: var(--primary-color); | |
| transform: scale(1.1); | |
| } | |
| /* --- Toast Notification --- */ | |
| .toast { | |
| position: fixed; | |
| bottom: 20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| background: rgba(50, 50, 50, 0.9); | |
| color: var(--white); | |
| padding: 10px 20px; | |
| border-radius: 30px; | |
| font-size: 0.9rem; | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity 0.3s; | |
| z-index: 2000; | |
| } | |
| .toast.show { | |
| opacity: 1; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Header --> | |
| <header class="app-header"> | |
| <div style="font-weight: bold; color: var(--primary-color);">چتروم من</div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="brand-link">Built with anycoder</a> | |
| </header> | |
| <main> | |
| <!-- LOGIN PAGE --> | |
| <section id="login-view" class="view active"> | |
| <div class="login-card"> | |
| <h2>ورود به حساب</h2> | |
| <form id="login-form"> | |
| <div class="form-group"> | |
| <label>شماره موبایل</label> | |
| <input type="tel" id="phone-input" class="form-input" placeholder="0912..." required> | |
| </div> | |
| <div class="form-group"> | |
| <label>کد امنیتی</label> | |
| <div class="captcha-container"> | |
| <div class="captcha-code" id="captcha-display">1234</div> | |
| <button type="button" class="btn" style="width: auto; padding: 5px 10px; font-size: 0.8rem;" onclick="generateCaptcha()"> | |
| <i class="fas fa-sync"></i> | |
| </button> | |
| <input type="text" id="captcha-input" class="form-input" placeholder="کد را وارد کنید" required> | |
| </div> | |
| </div> | |
| <button type="submit" class="btn">ورود به داشبورد</button> | |
| </form> | |
| </div> | |
| </section> | |
| <!-- DASHBOARD PAGE --> | |
| <section id="dashboard-view" class="view"> | |
| <div class="dash-header"> | |
| <div class="user-profile" onclick="openProfileModal()"> | |
| <img src="https://ui-avatars.com/api/?name=User&background=random" alt="Avatar" class="user-avatar" id="dash-avatar"> | |
| <div class="user-info"> | |
| <h3 id="dash-username">کاربر مهمان</h3> | |
| <p id="dash-phone">پروفایل</p> | |
| </div> | |
| <i class="fas fa-chevron-down" style="font-size: 0.8rem; margin-right: 5px;"></i> | |
| </div> | |
| <div> | |
| <i class="fas fa-cog" style="color: var(--text-light); cursor: pointer;" onclick="openProfileModal()"></i> | |
| </div> | |
| </div> | |
| <div class="room-list" id="room-list-container"> | |
| <!-- Rooms will be injected here via JS --> | |
| </div> | |
| <div class="fab-create" onclick="openCreateRoomModal()"> | |
| <i class="fas fa-plus"></i> | |
| </div> | |
| </section> | |
| <!-- CHAT ROOM PAGE --> | |
| <section id="chat-view" class="view"> | |
| <div class="chat-header"> | |
| <div class="chat-info"> | |
| <button class="btn-back" onclick="switchView('dashboard-view')"> | |
| <i class="fas fa-arrow-right"></i> | |
| </button> | |
| <div class="room-icon" id="chat-room-icon" style="width: 40px; height: 40px; font-size: 1rem;"> | |
| <i class="fas fa-users"></i> | |
| </div> | |
| <div> | |
| <h4 id="chat-room-name">نام اتاق</h4> | |
| <div class="chat-stats"> | |
| <span id="chat-online-count" style="display: flex; align-items: center; gap: 4px;"> | |
| <span class="dot"></span> 0 آنلاین | |
| </span> | |
| <span style="margin: 0 5px;">|</span> | |
| <span id="chat-total-count">0 عضو</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="chat-actions"> | |
| <button class="btn-menu" onclick="toggleChatMenu()"> | |
| <i class="fas fa-ellipsis-v"></i> | |
| </button> | |
| <div class="menu-dropdown" id="chat-menu-dropdown"> | |
| <div class="menu-item" onclick="shareGroup()"> | |
| <i class="fas fa-share-alt"></i> اشتراکگذاری | |
| </div> | |
| <div class="menu-item danger" onclick="deleteGroup()"> | |
| <i class="fas fa-trash"></i> حذف گروه | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="messages-container" id="messages-container"> | |
| <!-- Messages injected here --> | |
| </div> | |
| <div class="reply-bar" id="reply-bar"> | |
| <span id="reply-text-preview">در حال پاسخ به...</span> | |
| <i class="fas fa-times" style="cursor: pointer;" onclick="cancelReply()"></i> | |
| </div> | |
| <div class="chat-input-area"> | |
| <input type="text" id="message-input" placeholder="پیام خود را بنویسید..." autocomplete="off"> | |
| <button class="btn-send" onclick="sendMessage()"> | |
| <i class="fas fa-paper-plane"></i> | |
| </button> | |
| </div> | |
| </section> | |
| </main> | |
| <!-- Modals --> | |
| <!-- Profile Modal --> | |
| <div class="modal-overlay" id="profile-modal"> | |
| <div class="modal-content"> | |
| <h3>تنظیمات پروفایل</h3> | |
| <div class="form-group" style="margin-top: 15px;"> | |
| <label>نام نمایشی</label> | |
| <input type="text" id="edit-name" class="form-input"> | |
| </div> | |
| <div class="form-group"> | |
| <label>انتخاب آواتار</label> | |
| <div class="avatar-selection" id="avatar-selection"> | |
| <!-- Avatars generated via JS --> | |
| </div> | |
| </div> | |
| <div style="display: flex; gap: 10px; margin-top: 20px;"> | |
| <button class="btn btn-secondary" onclick="saveProfile()">ذخیره</button> | |
| <button class="btn" style="background: #ccc;" onclick="closeModal('profile-modal')">انصراف</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Create Room Modal --> | |
| <div class="modal-overlay" id="create-room-modal"> | |
| <div class="modal-content"> | |
| <h3>ساخت اتاق جدید</h3> | |
| <div class="form-group" style="margin-top: 15px;"> | |
| <label>نام اتاق</label> | |
| <input type="text" id="new-room-name" class="form-input" placeholder="مثلاً: برنامه نویسان"> | |
| </div> | |
| <div style="display: flex; gap: 10px; margin-top: 20px;"> | |
| <button class="btn btn-secondary" onclick="createRoom()">ایجاد</button> | |
| <button class="btn" style="background: #ccc;" onclick="closeModal('create-room-modal')">انصراف</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Toast --> | |
| <div id="toast" class="toast">پیام سیستم</div> | |
| <script> | |
| // --- State Management --- | |
| const state = { | |
| currentUser: { | |
| name: 'کاربر', | |
| phone: '', | |
| avatar: 'https://ui-avatars.com/api/?name=User&background=6C63FF&color=fff' | |
| }, | |
| currentCaptcha: '', | |
| currentRoomId: null, | |
| replyTo: null, // { text: '', id: '' } | |
| rooms: [ | |
| { id: 1, name: 'عمومی', online: 12, total: 145, icon: 'fa-globe', color: '#4CAF50' }, | |
| { id: 2, name: 'طراحی UI/UX', online: 5, total: 32, icon: 'fa-paint-brush', color: '#FF9800' }, | |
| { id: 3, name: 'برنامه نویسی', online: 8, total: 89, icon: 'fa-code', color: '#2196F3' } | |
| ], | |
| messages: { | |
| 1: [ | |
| { id: 101, sender: 'علی', text: 'سلام به همه!', time: '10:00', type: 'received', reactions: 2 }, | |
| { id: 102, sender: 'me', text: 'سلام علی، چطوری؟', time: '10:05', type: 'sent' } | |
| ], | |
| 2: [], | |
| 3: [] | |
| } | |
| }; | |
| // --- Initialization --- | |
| document.addEventListener('DOMContentLoaded', () => { | |
| generateCaptcha(); | |
| renderRooms(); | |
| setupAvatarSelection(); | |
| // Enter key for message input | |
| document.getElementById('message-input').addEventListener('keypress', function (e) { | |
| if (e.key === 'Enter') { | |
| sendMessage(); | |
| } | |
| }); | |
| }); | |
| // --- View Navigation --- | |
| function switchView(viewId) { | |
| document.querySelectorAll('.view').forEach(view => { | |
| view.classList.remove('active'); | |
| }); | |
| document.getElementById(viewId).classList.add('active'); | |
| // Close menu if open | |
| const menu = document.getElementById('chat-menu-dropdown'); | |
| if(menu) menu.classList.remove('show'); | |
| } | |
| // --- Login Logic --- | |
| function generateCaptcha() { | |
| const num = Math.floor(1000 + Math.random() * 9000); | |
| state.currentCaptcha = num; | |
| document.getElementById('captcha-display').innerText = num; | |
| } | |
| document.getElementById('login-form').addEventListener('submit', (e) => { | |
| e.preventDefault(); | |
| const phone = document.getElementById('phone-input').value; | |
| const captcha = document.getElementById('captcha-input').value; | |
| if (captcha != state.currentCaptcha) { | |
| showToast('کد امنیتی اشتباه است'); | |
| generateCaptcha(); | |
| return; | |
| } | |
| if(phone.length < 10) { | |
| showToast('شماره موبایل نامعتبر است'); | |
| return; | |
| } | |
| // Login Success | |
| state.currentUser.phone = phone; | |
| state.currentUser.name = phone; // Default name to phone initially | |
| updateDashboardProfile(); | |
| switchView('dashboard-view'); | |
| showToast('خوش آمدید!'); | |
| }); | |
| function updateDashboardProfile() { | |
| document.getElementById('dash-username').innerText = state.currentUser.name; | |
| document.getElementById('dash-phone').innerText = state.currentUser.phone; | |
| document.getElementById('dash-avatar').src = state.currentUser.avatar; | |
| } | |
| // --- Dashboard Logic --- | |
| function renderRooms() { | |
| const container = document.getElementById('room-list-container'); | |
| container.innerHTML = ''; | |
| state.rooms.forEach(room => { | |
| const card = document.createElement('div'); | |
| card.className = 'room-card'; | |
| card.onclick = () => enterRoom(room.id); | |
| card.innerHTML = ` | |
| <div class="room-details"> | |
| <div class="room-icon" style="color: ${room.color}; background: ${room.color}20;"> | |
| <i class="fas ${room.icon}"></i> | |
| </div> | |
| <div class="room-text"> | |
| <h4>${room.name}</h4> | |
| <span>برای مشاهده کلیک کنید</span> | |
| </div> | |
| </div> | |
| <div class="online-badge"> | |
| <span class="dot"></span> ${room.online} | |
| </div> | |
| `; | |
| container.appendChild(card); | |
| }); | |
| } | |
| function openCreateRoomModal() { | |
| document.getElementById('new-room-name').value = ''; | |
| document.getElementById('create-room-modal').classList.add('active'); | |
| } | |
| function createRoom() { | |
| const name = document.getElementById('new-room-name').value; | |
| if (!name) return showToast('لطفا نام اتاق را وارد کنید'); | |
| const newRoom = { | |
| id: Date.now(), | |
| name: name, | |
| online: 1, | |
| total: 1, | |
| icon: 'hashtag', // FontAwesome requires fa-hashtag usually, but handled dynamically | |
| color: '#9C27B0' | |
| }; | |
| // Fix icon class | |
| newRoom.icon = 'fa-hashtag'; | |
| state.rooms.unshift(newRoom); | |
| state.messages[newRoom.id] = []; | |
| renderRooms(); | |
| closeModal('create-room-modal'); | |
| showToast('اتاق با موفقیت ساخته شد'); | |
| } | |
| // --- Chat Room Logic --- | |
| function enterRoom(roomId) { | |
| state.currentRoomId = roomId; | |
| const room = state.rooms.find(r => r.id === roomId); | |
| // Update Header | |
| document.getElementById('chat-room-name').innerText = room.name; | |
| document.getElementById('chat-online-count').innerHTML = `<span class="dot"></span> ${room.online} آنلاین`; | |
| document.getElementById('chat-total-count').innerText = `${room.total} عضو`; | |
| const iconContainer = document.getElementById('chat-room-icon'); | |
| iconContainer.innerHTML = `<i class="fas ${room.icon}"></i>`; | |
| iconContainer.style.color = room.color; | |
| iconContainer.style.background = room.color + '20'; | |
| // Render Messages | |
| renderMessages(); | |
| switchView('chat-view'); | |
| } | |
| function renderMessages() { | |
| const container = document.getElementById('messages-container'); | |
| container.innerHTML = ''; | |
| const msgs = state.messages[state.currentRoomId] || []; | |
| msgs.forEach(msg => { | |
| const div = document.createElement('div'); | |
| div.className = `message ${msg.type}`; | |
| let replyHTML = ''; | |
| if(msg.replyTo) { | |
| replyHTML = `<div class="reply-preview"><i class="fas fa-reply"></i> ${msg.replyTo}</div>`; | |
| } | |
| div.innerHTML = ` | |
| ${replyHTML} | |
| ${msg.text} | |
| <div class="msg-meta"> | |
| <span>${msg.time}</span> | |
| ${msg.type === 'sent' ? '<i class="fas fa-check-double" style="color: #4CAF50;"></i>' : ''} | |
| ${msg.reactions ? `<span style="margin-right:5px; color:#FF5252;">❤️ ${msg.reactions}</span>` : ''} | |
| </div> | |
| <div class="msg-actions"> | |
| <i class="fas fa-reply action-icon" onclick="setReply('${msg.text}', ${msg.id})" title="پاسخ"></i> | |
| <i class="fas fa-heart action-icon" onclick="addReaction(${msg.id})" title="ریاکشن"></i> | |
| ${msg.type === 'sent' ? `<i class="fas fa-trash action-icon" onclick="deleteMessage(${msg.id})" title="حذف"></i>` : ''} | |
| </div> | |
| `; | |
| container.appendChild(div); | |
| }); | |
| // Scroll to bottom | |
| container.scrollTop = container.scrollHeight; | |
| } | |
| function sendMessage() { | |
| const input = document.getElementById('message-input'); | |
| const text = input.value.trim(); | |
| if (!text) return; | |
| const newMsg = { | |
| id: Date.now(), | |
| sender: 'me', | |
| text: text, | |
| time: new Date().toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'}), | |
| type: 'sent', | |
| replyTo: state.replyTo ? state.replyTo.text : null | |
| }; | |
| if (!state.messages[state.currentRoomId]) { | |
| state.messages[state.currentRoomId] = []; | |
| } | |
| state.messages[state.currentRoomId].push(newMsg); | |
| // Clear input and reply state | |
| input.value = ''; | |
| cancelReply(); | |
| renderMessages(); | |
| } | |
| // --- Chat Interactions --- | |
| function setReply(text, id) { | |
| state.replyTo = { text: text, id: id }; | |
| const bar = document.getElementById('reply-bar'); | |
| document.getElementById('reply-text-preview').innerText = `پاسخ به: ${text}`; | |
| bar.classList.add('active'); | |
| document.getElementById('message-input').focus(); | |
| } | |
| function cancelReply() { | |
| state.replyTo = null; | |
| document.getElementById('reply-bar').classList.remove('active'); | |
| } | |
| function addReaction(msgId) { | |
| const msgs = state.messages[state.currentRoomId]; | |
| const msg = msgs.find(m => m.id === msgId); | |
| if (msg) { | |
| msg.reactions = (msg.reactions || 0) + 1; | |
| renderMessages(); | |
| } | |
| } | |
| function deleteMessage(msgId) { | |
| const msgs = state.messages[state.currentRoomId]; | |
| const index = msgs.findIndex(m => m.id === msgId); | |
| if (index > -1) { | |
| msgs.splice(index, 1); | |
| renderMessages(); | |
| showToast('پیام حذف شد'); | |
| } | |
| } | |
| function toggleChatMenu() { | |
| document.getElementById('chat-menu-dropdown').classList.toggle('show'); | |
| } | |
| function deleteGroup() { | |
| if(confirm('آیا مطمئن هستید که میخواهید این گروه را حذف کنید؟')) { | |
| const index = state.rooms.findIndex(r => r.id === state.currentRoomId); | |
| if(index > -1) { | |
| state.rooms.splice(index, 1); | |
| delete state.messages[state.currentRoomId]; | |
| renderRooms(); | |
| switchView('dashboard-view'); | |
| showToast('گروه حذف شد'); | |
| } | |
| } | |
| } | |
| function shareGroup() { | |
| // Mock share | |
| const roomName = document.getElementById('chat-room-name').innerText; | |
| navigator.clipboard.writeText(`به گروه "${roomName}" بپیوندید!`).then(() => { | |
| showToast('لینک دعوت کپی شد'); | |
| }).catch(() => { | |
| showToast('اشتراکگذاری انجام شد'); | |
| }); | |
| document.getElementById('chat-menu-dropdown').classList.remove('show'); | |
| } | |
| // --- Profile Settings --- | |
| function openProfileModal() { | |
| document.getElementById('edit-name').value = state.currentUser.name; | |
| document.getElementById('profile-modal').classList.add('active'); | |
| } | |
| function setupAvatarSelection() { | |
| const colors = ['6C63FF', '4CAF50', 'FF5252', 'FF9800', '2196F3', '9C27B0']; | |
| const container = document.getElementById('avatar-selection'); | |
| container.innerHTML = ''; | |
| colors.forEach(color => { | |
| const url = `https://ui-avatars.com/api/?name=${state.currentUser.name}&background=${color}&color=fff`; | |
| const img = document.createElement('img'); | |
| img.src = url; | |
| img.className = 'avatar-option'; | |
| if(state.currentUser.avatar.includes(color)) img.classList.add('selected'); | |
| img.onclick = () => { | |
| document.querySelectorAll('.avatar-option').forEach(el => el.classList.remove('selected')); | |
| img.classList.add('selected'); | |
| state.currentUser.avatar = url; | |
| }; | |
| container.appendChild(img); | |
| }); | |
| } | |
| function saveProfile() { | |
| const name = document.getElementById(' |