// VibeChat Messenger App const API = { me: '/api/auth/me', logout: '/api/auth/logout', users: '/api/users', chats: '/api/chats', updateProfile: '/api/users/me' }; let currentUser = null; let currentChat = null; let allChats = []; let allUsers = []; // Initialize app window.addEventListener('DOMContentLoaded', async () => { const token = localStorage.getItem('vibechat_token'); if (!token) { window.location.href = 'index.html'; return; } await loadCurrentUser(); await loadChats(); await loadUsers(); // Inject emoji picker HTML const emojis = ['😀','😂','😍','🥰','😎','🤔','👍','❤️','🔥','🎉','👋','🙏','💯','✨','🚀','💪','🎯','✅','📌','🔔']; document.getElementById('emojiPicker').innerHTML = `
Нет чатов
Нажмите + чтобы создать новый
Нет пользователей
'; return; } userList.innerHTML = allUsers.map(user => `Сообщений пока нет
'; return; } messagesList.innerHTML = messages.map(msg => ` `).join(''); // Scroll to bottom const container = document.getElementById('messagesContainer'); container.scrollTop = container.scrollHeight; } // Send message async function sendMessage() { const input = document.getElementById('messageInput'); const text = input.value.trim(); if (!text || !currentChat) return; try { const token = localStorage.getItem('vibechat_token'); const res = await fetch(`${API.chats}/${currentChat.id}/messages`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ text }) }); const json = await res.json(); if (json.ok) { input.value = ''; await loadMessages(currentChat.id); await loadChats(); // Update last message } else { alert('Ошибка отправки: ' + json.error); } } catch (e) { alert('Ошибка: ' + e.message); } } // Handle enter key function handleKeyPress(event) { if (event.key === 'Enter') { sendMessage(); } } // Emoji picker function toggleEmojiPicker() { const picker = document.getElementById('emojiPicker'); picker.classList.toggle('active'); } function insertEmoji(emoji) { const input = document.getElementById('messageInput'); input.value += emoji; input.focus(); document.getElementById('emojiPicker').classList.remove('active'); } // Close emoji picker on outside click document.addEventListener('click', (e) => { const picker = document.getElementById('emojiPicker'); const btn = document.querySelector('.btn-emoji'); if (!picker.contains(e.target) && !btn.contains(e.target)) { picker.classList.remove('active'); } }); // New chat modal function showNewChatModal() { document.getElementById('newChatModal').classList.add('active'); loadUsers(); } function closeNewChatModal() { document.getElementById('newChatModal').classList.remove('active'); } function switchTab(tab) { document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); event.target.classList.add('active'); document.getElementById('chatTab').style.display = tab === 'chat' ? 'block' : 'none'; document.getElementById('groupTab').style.display = tab === 'group' ? 'block' : 'none'; document.getElementById('channelTab').style.display = tab === 'channel' ? 'block' : 'none'; } // Create private chat async function createPrivateChat(userId) { try { const token = localStorage.getItem('vibechat_token'); const res = await fetch(API.chats, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ type: 'private', participantId: userId }) }); const json = await res.json(); if (json.ok) { closeNewChatModal(); await loadChats(); selectChat(json.chat.id); } } catch (e) { alert('Ошибка: ' + e.message); } } // Create group async function createGroup() { const name = document.getElementById('groupName').value.trim(); if (!name) return alert('Введите название группы'); try { const token = localStorage.getItem('vibechat_token'); const res = await fetch(API.chats, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ type: 'group', name }) }); const json = await res.json(); if (json.ok) { closeNewChatModal(); document.getElementById('groupName').value = ''; await loadChats(); selectChat(json.chat.id); } } catch (e) { alert('Ошибка: ' + e.message); } } // Create channel async function createChannel() { const name = document.getElementById('channelName').value.trim(); if (!name) return alert('Введите название канала'); try { const token = localStorage.getItem('vibechat_token'); const res = await fetch(API.chats, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ type: 'channel', name }) }); const json = await res.json(); if (json.ok) { closeNewChatModal(); document.getElementById('channelName').value = ''; await loadChats(); selectChat(json.chat.id); } } catch (e) { alert('Ошибка: ' + e.message); } } // Settings function openSettings() { const user = JSON.parse(localStorage.getItem('vibechat_user')); document.getElementById('settingsAvatar').src = user.avatar; document.getElementById('settingsUsername').value = user.username; document.getElementById('settingsBio').value = user.bio || ''; document.getElementById('settingsModal').classList.add('active'); } function closeSettings() { document.getElementById('settingsModal').classList.remove('active'); } async function updateProfile(event) { event.preventDefault(); const username = document.getElementById('settingsUsername').value; const bio = document.getElementById('settingsBio').value; try { const token = localStorage.getItem('vibechat_token'); const res = await fetch(API.updateProfile, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ username, bio }) }); const json = await res.json(); if (json.ok) { localStorage.setItem('vibechat_user', JSON.stringify(json.user)); currentUser = json.user; document.getElementById('currentUserName').textContent = currentUser.username; document.getElementById('currentUserAvatar').src = currentUser.avatar; closeSettings(); alert('Профиль обновлён! ✅'); } } catch (e) { alert('Ошибка: ' + e.message); } } function changeAvatar() { const url = prompt('Введите URL аватара:', currentUser.avatar); if (url) { updateProfile({ preventDefault: () => {} }); } } // Logout async function logout() { if (!confirm('Вы уверены, что хотите выйти?')) return; try { const token = localStorage.getItem('vibechat_token'); await fetch(API.logout, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); } catch (e) {} localStorage.removeItem('vibechat_token'); localStorage.removeItem('vibechat_user'); window.location.href = 'index.html'; } // Filter chats function filterChats() { const query = document.getElementById('searchInput').value.toLowerCase(); const filtered = allChats.filter(c => c.name.toLowerCase().includes(query)); const chatList = document.getElementById('chatList'); chatList.innerHTML = filtered.map(chat => `