| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Reiker Wa-Web</title> |
| <style> |
| |
| .key-input-container { |
| position: fixed; |
| top: 0; |
| left: 0; |
| right: 0; |
| bottom: 0; |
| background: rgba(0, 0, 0, 0.5); |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| z-index: 1000; |
| } |
| .key-input-form { |
| background: #111621; |
| padding: 20px; |
| border-radius: 8px; |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| } |
| .key-input-form input { |
| padding: 10px; |
| font-size: 16px; |
| margin-bottom: 10px; |
| width: 200px; |
| text-align: center; |
| } |
| .key-input-form button { |
| padding: 10px; |
| font-size: 16px; |
| cursor: pointer; |
| } |
| </style> |
| </head> |
| <body style="margin: 0; font-family: Arial, sans-serif; background-color: #121212; color: #e0e0e0;"> |
| <header style="background-color: #2a2a2a; padding: 10px 20px; text-align: center; border-bottom: 1px solid #333; color: #fff;"> |
| <h1>Reiker Wa-Web</h1> |
| </header> |
| <main style="padding: 10px;"> |
| |
| <div id="loading" style="display: none; text-align: center; margin-top: 50px;"> |
| <div class="spinner" style="border: 4px solid #444; border-top: 4px solid #1a73e8; border-radius: 50%; width: 30px; height: 30px; animation: spin 1s linear infinite;"></div> |
| <p>Loading messages...</p> |
| </div> |
| |
| <div id="chat-list"></div> |
| </main> |
|
|
| |
| <div id="keyInputContainer" class="key-input-container"> |
| <div class="key-input-form"> |
| <h2>Reiker Verify 1.6</h2> |
| <input type="text" id="keyInput" placeholder="Enter your password"> |
| <button onclick="submitKey()">Submit</button> |
| </div> |
| </div> |
|
|
| <script src="/socket.io/socket.io.js"></script> |
| <script> |
| const chatList = document.getElementById('chat-list'); |
| const loadingSpinner = document.getElementById('loading'); |
| const keyInputContainer = document.getElementById("keyInputContainer"); |
| const socket = io(); |
| |
| function toggleLoading(show) { |
| loadingSpinner.style.display = show ? 'block' : 'none'; |
| chatList.style.display = show ? 'none' : 'block'; |
| } |
| |
| function truncateContent(content) { |
| const words = content.split(' '); |
| if (words.length > 3) { |
| return words.slice(0, 3).join(' ') + '...'; |
| } |
| return content; |
| } |
| |
| function formatChatName(chatName) { |
| return chatName.includes('@s.whatsapp.net') |
| ? chatName.replace('@s.whatsapp.net', '') |
| : chatName; |
| } |
| |
| function groupMessagesByChat(messages) { |
| const grouped = {}; |
| messages.forEach(message => { |
| message.chatName = formatChatName(message.chatName); |
| grouped[message.chatName] = message; |
| }); |
| return grouped; |
| } |
| |
| function renderGroupedChats(chats) { |
| chatList.innerHTML = ''; |
| const groupedChats = groupMessagesByChat(chats); |
| |
| Object.entries(groupedChats).forEach(([chatName, latestMessage]) => { |
| const chatDiv = document.createElement('div'); |
| chatDiv.className = 'chat'; |
| chatDiv.setAttribute('data-jid', latestMessage.jid); |
| chatDiv.style.cssText = ` |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| background-color: #1e1e1e; |
| padding: 15px; |
| border-radius: 8px; |
| margin-bottom: 10px; |
| cursor: pointer; |
| transition: background-color 0.2s ease; |
| `; |
| chatDiv.addEventListener('mouseover', () => chatDiv.style.backgroundColor = '#2c2c2c'); |
| chatDiv.addEventListener('mouseout', () => chatDiv.style.backgroundColor = '#1e1e1e'); |
| |
| const chatInfo = document.createElement('div'); |
| chatInfo.className = 'chat-info'; |
| chatInfo.innerHTML = ` |
| <h2 style="margin: 0; font-size: 1rem; font-weight: bold; color: #fff;">${chatName}</h2> |
| <p style="margin: 5px 0 0; font-size: 0.9rem; color: #aaa;">${truncateContent(latestMessage.content)}</p> |
| `; |
| chatDiv.appendChild(chatInfo); |
| |
| chatDiv.addEventListener('click', () => { |
| window.location.href = `/chat/${latestMessage.jid}`; |
| }); |
| |
| chatList.appendChild(chatDiv); |
| }); |
| } |
| |
| async function loadChatList() { |
| toggleLoading(true); |
| try { |
| const res = await fetch('/messages.json'); |
| if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); |
| const chats = await res.json(); |
| renderGroupedChats(chats); |
| } catch (err) { |
| console.error('Failed to load chat list:', err); |
| chatList.innerHTML = '<p>Failed to load chats. Try again later.</p>'; |
| } finally { |
| toggleLoading(false); |
| } |
| } |
| |
| async function submitKey() { |
| const userKey = document.getElementById("keyInput").value; |
| console.log("Key Sent to Server:", userKey); |
| if (userKey) { |
| |
| try { |
| const res = await fetch('/validate-key', { |
| method: 'POST', |
| headers: { 'Content-Type': 'application/json' }, |
| body: JSON.stringify({ key: userKey }) |
| }); |
| |
| if (res.ok) { |
| |
| keyInputContainer.style.display = 'none'; |
| loadChatList(); |
| } else { |
| alert("Invalid key. Please try again."); |
| } |
| } catch (error) { |
| console.error('Error verifying key:', error); |
| alert("Error verifying the key."); |
| } |
| } else { |
| alert("Please enter a valid key."); |
| } |
| } |
| |
| socket.on('new_message', (newMessage) => { |
| const currentChats = Array.from(chatList.children).map(chat => ({ |
| jid: chat.getAttribute('data-jid'), |
| chatName: chat.querySelector('h2').innerText, |
| content: chat.querySelector('p').innerText, |
| })); |
| |
| updateChatList(currentChats, newMessage); |
| }); |
| |
| |
| loadChatList(); |
| </script> |
|
|
| <style> |
| @keyframes spin { |
| 0% { transform: rotate(0deg); } |
| 100% { transform: rotate(360deg); } |
| } |
| </style> |
| </body> |
| </html> |