Download index.html from defaultdolphin/anycoder-7c0fd5aa: direct link, hf CLI and curl.
- Browser
- Download file 23.6 kB
-
https://huggingface.co/spaces/defaultdolphin/anycoder-7c0fd5aa/resolve/main/index.html
- Command line
-
hf download hf://spaces/defaultdolphin/anycoder-7c0fd5aa/index.html
-
curl -L -o index.html https://huggingface.co/spaces/defaultdolphin/anycoder-7c0fd5aa/resolve/main/index.html
23.6 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Modern Message UI Simulator</title> | |
| <!-- Importing FontAwesome for Icons --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| /* | |
| * MODERN CSS RESET & VARIABLES | |
| * Using CSS Custom Properties for easy theming | |
| */ | |
| :root { | |
| --primary-color: #4f46e5; | |
| --primary-hover: #4338ca; | |
| --secondary-bg: #f3f4f6; | |
| --white: #ffffff; | |
| --text-dark: #111827; | |
| --text-gray: #6b7280; | |
| --text-light: #9ca3af; | |
| --border-color: #e5e7eb; | |
| --incoming-bubble: #e5e7eb; | |
| --outgoing-bubble: #4f46e5; | |
| --outgoing-text: #ffffff; | |
| --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); | |
| --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); | |
| --font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; | |
| --header-height: 60px; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| body { | |
| font-family: var(--font-family); | |
| background-color: #f9fafb; | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| color: var(--text-dark); | |
| } | |
| /* | |
| * HEADER SECTION | |
| */ | |
| header { | |
| background-color: var(--white); | |
| height: var(--header-height); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 0 20px; | |
| border-bottom: 1px solid var(--border-color); | |
| box-shadow: var(--shadow-sm); | |
| z-index: 10; | |
| } | |
| .logo { | |
| font-size: 1.25rem; | |
| font-weight: 700; | |
| color: var(--primary-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .brand-link { | |
| text-decoration: none; | |
| color: var(--text-light); | |
| font-size: 0.9rem; | |
| transition: color 0.2s; | |
| } | |
| .brand-link:hover { | |
| color: var(--primary-color); | |
| } | |
| /* | |
| * MAIN LAYOUT | |
| * Using CSS Grid for 2-column layout (Sidebar + Chat) | |
| */ | |
| main { | |
| display: grid; | |
| grid-template-columns: 320px 1fr; | |
| flex: 1; | |
| height: calc(100vh - var(--header-height)); | |
| overflow: hidden; | |
| } | |
| /* | |
| * SIDEBAR (Contact List) | |
| */ | |
| .sidebar { | |
| background-color: var(--white); | |
| border-right: 1px solid var(--border-color); | |
| display: flex; | |
| flex-direction: column; | |
| overflow-y: auto; | |
| } | |
| .search-bar { | |
| padding: 15px; | |
| border-bottom: 1px solid var(--border-color); | |
| position: sticky; | |
| top: 0; | |
| background: var(--white); | |
| z-index: 5; | |
| } | |
| .search-input-wrapper { | |
| position: relative; | |
| } | |
| .search-input-wrapper i { | |
| position: absolute; | |
| left: 12px; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| color: var(--text-light); | |
| font-size: 0.9rem; | |
| } | |
| .search-input { | |
| width: 100%; | |
| padding: 10px 10px 10px 35px; | |
| border-radius: 8px; | |
| border: 1px solid var(--border-color); | |
| background-color: var(--secondary-bg); | |
| font-size: 0.9rem; | |
| outline: none; | |
| transition: border-color 0.2s; | |
| } | |
| .search-input:focus { | |
| border-color: var(--primary-color); | |
| background-color: var(--white); | |
| } | |
| .contact-list { | |
| list-style: none; | |
| } | |
| .contact-item { | |
| display: flex; | |
| align-items: center; | |
| padding: 15px; | |
| cursor: pointer; | |
| transition: background-color 0.2s; | |
| border-bottom: 1px solid transparent; | |
| } | |
| .contact-item:hover { | |
| background-color: var(--secondary-bg); | |
| } | |
| .contact-item.active { | |
| background-color: #eef2ff; | |
| border-left: 4px solid var(--primary-color); | |
| } | |
| .avatar { | |
| width: 48px; | |
| height: 48px; | |
| border-radius: 50%; | |
| object-fit: cover; | |
| margin-right: 15px; | |
| border: 2px solid var(--white); | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| } | |
| .contact-info { | |
| flex: 1; | |
| min-width: 0; /* Enables truncation */ | |
| } | |
| .contact-name { | |
| font-weight: 600; | |
| font-size: 1rem; | |
| margin-bottom: 4px; | |
| color: var(--text-dark); | |
| display: flex; | |
| justify-content: space-between; | |
| } | |
| .last-message-time { | |
| font-size: 0.75rem; | |
| color: var(--text-light); | |
| font-weight: 400; | |
| } | |
| .last-message { | |
| font-size: 0.85rem; | |
| color: var(--text-gray); | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| /* | |
| * CHAT AREA | |
| */ | |
| .chat-area { | |
| background-color: #f0f2f5; | |
| display: flex; | |
| flex-direction: column; | |
| position: relative; | |
| } | |
| /* Chat Header */ | |
| .chat-header { | |
| background-color: var(--white); | |
| padding: 15px 20px; | |
| display: flex; | |
| align-items: center; | |
| border-bottom: 1px solid var(--border-color); | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .chat-user-info { | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| } | |
| .user-status { | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .status-dot { | |
| display: inline-block; | |
| width: 8px; | |
| height: 8px; | |
| background-color: #10b981; | |
| border-radius: 50%; | |
| margin-right: 5px; | |
| } | |
| .status-text { | |
| font-size: 0.8rem; | |
| color: var(--text-gray); | |
| } | |
| .chat-actions { | |
| margin-left: auto; | |
| display: flex; | |
| gap: 20px; | |
| color: var(--primary-color); | |
| font-size: 1.2rem; | |
| cursor: pointer; | |
| } | |
| /* Messages Container */ | |
| .messages-container { | |
| flex: 1; | |
| padding: 20px; | |
| overflow-y: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 15px; | |
| background-image: radial-gradient(#d1d5db 1px, transparent 1px); | |
| background-size: 20px 20px; | |
| } | |
| .message { | |
| display: flex; | |
| max-width: 70%; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .message.incoming { | |
| align-self: flex-start; | |
| } | |
| .message.outgoing { | |
| align-self: flex-end; | |
| flex-direction: row-reverse; | |
| } | |
| .message-content { | |
| padding: 12px 16px; | |
| border-radius: 18px; | |
| font-size: 0.95rem; | |
| line-height: 1.4; | |
| position: relative; | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .message.incoming .message-content { | |
| background-color: var(--white); | |
| color: var(--text-dark); | |
| border-top-left-radius: 4px; | |
| } | |
| .message.outgoing .message-content { | |
| background-color: var(--outgoing-bubble); | |
| color: var(--outgoing-text); | |
| border-top-right-radius: 4px; | |
| } | |
| .message-time { | |
| font-size: 0.7rem; | |
| margin-top: 5px; | |
| opacity: 0.7; | |
| text-align: right; | |
| display: block; | |
| } | |
| .message.outgoing .message-time { | |
| color: rgba(255, 255, 255, 0.8); | |
| } | |
| /* Input Area */ | |
| .input-area { | |
| background-color: var(--white); | |
| padding: 20px; | |
| border-top: 1px solid var(--border-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| } | |
| .attach-btn { | |
| color: var(--text-gray); | |
| font-size: 1.2rem; | |
| cursor: pointer; | |
| transition: color 0.2s; | |
| } | |
| .attach-btn:hover { | |
| color: var(--primary-color); | |
| } | |
| .message-input { | |
| flex: 1; | |
| padding: 12px 20px; | |
| border-radius: 25px; | |
| border: 1px solid var(--border-color); | |
| background-color: var(--secondary-bg); | |
| font-size: 1rem; | |
| outline: none; | |
| transition: all 0.2s; | |
| } | |
| .message-input:focus { | |
| background-color: var(--white); | |
| border-color: var(--primary-color); | |
| box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1); | |
| } | |
| .send-btn { | |
| background-color: var(--primary-color); | |
| color: var(--white); | |
| width: 45px; | |
| height: 45px; | |
| border-radius: 50%; | |
| border: none; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| transition: background-color 0.2s, transform 0.1s; | |
| } | |
| .send-btn:hover { | |
| background-color: var(--primary-hover); | |
| } | |
| .send-btn:active { | |
| transform: scale(0.95); | |
| } | |
| /* | |
| * RESPONSIVE DESIGN | |
| * Mobile Layout Adjustments | |
| */ | |
| @media (max-width: 768px) { | |
| main { | |
| grid-template-columns: 1fr; | |
| } | |
| .sidebar { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 20; | |
| transform: translateX(0); | |
| transition: transform 0.3s ease-in-out; | |
| } | |
| .sidebar.hidden { | |
| transform: translateX(-100%); | |
| } | |
| .back-btn { | |
| display: block ; | |
| margin-right: 10px; | |
| cursor: pointer; | |
| color: var(--text-dark); | |
| } | |
| } | |
| .back-btn { | |
| display: none; | |
| font-size: 1.2rem; | |
| } | |
| /* Empty State */ | |
| .empty-state { | |
| display: none; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| height: 100%; | |
| color: var(--text-gray); | |
| text-align: center; | |
| } | |
| .empty-state i { | |
| font-size: 4rem; | |
| margin-bottom: 20px; | |
| color: var(--text-light); | |
| } | |
| .no-chat-selected .empty-state { | |
| display: flex; | |
| } | |
| .no-chat-selected .chat-header, | |
| .no-chat-selected .messages-container, | |
| .no-chat-selected .input-area { | |
| display: none; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <div class="logo"> | |
| <i class="fa-solid fa-comments"></i> | |
| <span>MsgReader</span> | |
| </div> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="brand-link"> | |
| Built with anycoder | |
| </a> | |
| </header> | |
| <main> | |
| <!-- Sidebar: Contact List --> | |
| <aside class="sidebar" id="sidebar"> | |
| <div class="search-bar"> | |
| <div class="search-input-wrapper"> | |
| <i class="fa-solid fa-search"></i> | |
| <input type="text" class="search-input" placeholder="Search conversations..." id="searchInput"> | |
| </div> | |
| </div> | |
| <ul class="contact-list" id="contactList"> | |
| <!-- Contacts will be injected here via JS --> | |
| </ul> | |
| </aside> | |
| <!-- Main Chat Area --> | |
| <section class="chat-area no-chat-selected" id="chatArea"> | |
| <!-- Empty State (Shown when no chat is selected) --> | |
| <div class="empty-state"> | |
| <i class="fa-regular fa-paper-plane"></i> | |
| <h2>Select a conversation</h2> | |
| <p>Choose a contact from the list to view messages.</p> | |
| </div> | |
| <!-- Active Chat Interface --> | |
| <div class="chat-header"> | |
| <div class="chat-user-info"> | |
| <i class="fa-solid fa-arrow-left back-btn" id="backBtn"></i> | |
| <img src="" alt="User" class="avatar" id="currentAvatar"> | |
| <div class="user-status"> | |
| <span class="contact-name" id="currentName">User Name</span> | |
| <span class="status-text"><span class="status-dot"></span>Online</span> | |
| </div> | |
| </div> | |
| <div class="chat-actions"> | |
| <i class="fa-solid fa-phone"></i> | |
| <i class="fa-solid fa-video"></i> | |
| <i class="fa-solid fa-circle-info"></i> | |
| </div> | |
| </div> | |
| <div class="messages-container" id="messagesContainer"> | |
| <!-- Messages will be injected here via JS --> | |
| </div> | |
| <div class="input-area"> | |
| <i class="fa-solid fa-paperclip attach-btn"></i> | |
| <i class="fa-regular fa-image attach-btn"></i> | |
| <input type="text" class="message-input" placeholder="Type a message..." id="messageInput"> | |
| <button class="send-btn" id="sendBtn"> | |
| <i class="fa-solid fa-paper-plane"></i> | |
| </button> | |
| </div> | |
| </section> | |
| </main> | |
| <script> | |
| // Mock Data: Contacts and their message history | |
| const contactsData = [ | |
| { | |
| id: 1, | |
| name: "Alice Johnson", | |
| avatar: "https://picsum.photos/seed/alice/100/100", | |
| time: "10:30 AM", | |
| messages: [ | |
| { id: 1, text: "Hey! Are we still on for lunch?", type: "incoming", time: "10:28 AM" }, | |
| { id: 2, text: "Yes, definitely. 12:30 at the usual spot?", type: "outgoing", time: "10:29 AM" }, | |
| { id: 3, text: "Perfect. See you there!", type: "incoming", time: "10:30 AM" } | |
| ] | |
| }, | |
| { | |
| id: 2, | |
| name: "Bob Smith", | |
| avatar: "https://picsum.photos/seed/bob/100/100", | |
| time: "Yesterday", | |
| messages: [ | |
| { id: 1, text: "Did you see the game last night?", type: "incoming", time: "Yesterday" }, | |
| { id: 2, text: "No, I missed it. Who won?", type: "outgoing", time: "Yesterday" }, | |
| { id: 3, text: "It was incredible! We won by 2 points.", type: "incoming", time: "Yesterday" } | |
| ] | |
| }, | |
| { | |
| id: 3, | |
| name: "Charlie Davis", | |
| avatar: "https://picsum.photos/seed/charlie/100/100", | |
| time: "Monday", | |
| messages: [ | |
| { id: 1, text: "Can you send me the project files?", type: "incoming", time: "Monday" }, | |
| { id: 2, text: "Sure thing, uploading them now.", type: "outgoing", time: "Monday" } | |
| ] | |
| }, | |
| { | |
| id: 4, | |
| name: "Diana Evans", | |
| avatar: "https://picsum.photos/seed/diana/100/100", | |
| time: "Sunday", | |
| messages: [ | |
| { id: 1, text: "Happy Birthday! 🎂", type: "incoming", time: "Sunday" }, | |
| { id: 2, text: "Thank you so much! 🥳", type: "outgoing", time: "Sunday" } | |
| ] | |
| }, | |
| { | |
| id: 5, | |
| name: "Ethan Hunt", | |
| avatar: "https://picsum.photos/seed/ethan/100/100", | |
| time: "Jan 20", | |
| messages: [ | |
| { id: 1, text: "Mission accomplished.", type: "incoming", time: "Jan 20" }, | |
| ] | |
| } | |
| ]; | |
| let activeContactId = null; | |
| // DOM Elements | |
| const contactListEl = document.getElementById('contactList'); | |
| const messagesContainerEl = document.getElementById('messagesContainer'); | |
| const messageInputEl = document.getElementById('messageInput'); | |
| const sendBtnEl = document.getElementById('sendBtn'); | |
| const currentAvatarEl = document.getElementById('currentAvatar'); | |
| const currentNameEl = document.getElementById('currentName'); | |
| const chatAreaEl = document.getElementById('chatArea'); | |
| const sidebarEl = document.getElementById('sidebar'); | |
| const backBtnEl = document.getElementById('backBtn'); | |
| const searchInputEl = document.getElementById('searchInput'); | |
| // Initialize App | |
| function init() { | |
| renderContacts(contactsData); | |
| setupEventListeners(); | |
| } | |
| // Render Contact List | |
| function renderContacts(contacts) { | |
| contactListEl.innerHTML = ''; | |
| contacts.forEach(contact => { | |
| const lastMsg = contact.messages[contact.messages.length - 1]; | |
| const li = document.createElement('li'); | |
| li.className = `contact-item ${activeContactId === contact.id ? 'active' : ''}`; | |
| li.onclick = () => selectContact(contact.id); | |
| li.innerHTML = ` | |
| <img src="${contact.avatar}" alt="${contact.name}" class="avatar"> | |
| <div class="contact-info"> | |
| <div class="contact-name"> | |
| ${contact.name} | |
| <span class="last-message-time">${contact.time}</span> | |
| </div> | |
| <div class="last-message">${lastMsg ? lastMsg.text : 'No messages'}</div> | |
| </div> | |
| `; | |
| contactListEl.appendChild(li); | |
| }); | |
| } | |
| // Select a Contact | |
| function selectContact(id) { | |
| activeContactId = id; | |
| const contact = contactsData.find(c => c.id === id); | |
| // Update UI State | |
| chatAreaEl.classList.remove('no-chat-selected'); | |
| // Mobile Responsive: Hide sidebar | |
| if (window.innerWidth <= 768) { | |
| sidebarEl.classList.add('hidden'); | |
| } | |
| // Update Header Info | |
| currentNameEl.textContent = contact.name; | |
| currentAvatarEl.src = contact.avatar; | |
| // Highlight active contact in sidebar | |
| renderContacts(contactsData.filter(c => c.name.toLowerCase().includes(searchInputEl.value.toLowerCase()))); | |
| // Render Messages | |
| renderMessages(contact.messages); | |
| // Scroll to bottom | |
| scrollToBottom(); | |
| // Focus input | |
| messageInputEl.focus(); | |
| } | |
| // Render Messages | |
| function renderMessages(messages) { | |
| messagesContainerEl.innerHTML = ''; | |
| messages.forEach(msg => { | |
| const div = document.createElement('div'); | |
| div.className = `message ${msg.type}`; | |
| div.innerHTML = ` | |
| <div class="message-content"> | |
| ${msg.text} | |
| <span class="message-time">${msg.time}</span> | |
| </div> | |
| `; | |
| messagesContainerEl.appendChild(div); | |
| }); | |
| } | |
| // Send Message | |
| function sendMessage() { | |
| const text = messageInputEl.value.trim(); | |
| if (!text || !activeContactId) return; | |
| const contact = contactsData.find(c => c.id === activeContactId); | |
| const now = new Date(); | |
| const timeString = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | |
| // Add outgoing message to data | |
| const newMessage = { | |
| id: contact.messages.length + 1, | |
| text: text, | |
| type: 'outgoing', | |
| time: timeString | |
| }; | |
| contact.messages.push(newMessage); | |
| // Update UI | |
| renderMessages(contact.messages); | |
| messageInputEl.value = ''; | |
| scrollToBottom(); | |
| // Update contact list preview (sort by last message logic could go here) | |
| renderContacts(contactsData); | |
| // Simulate Reply after 1.5 seconds | |
| setTimeout(() => { | |
| simulateReply(contact); | |
| }, 1500); | |
| } | |
| // Simulate Incoming Reply | |
| function simulateReply(contact) { | |
| // Only reply if still looking at this chat | |
| if (activeContactId !== contact.id) return; | |
| const responses = ["That sounds great!", "I'll check and get back to you.", "Interesting...", "Ok.", "Can you elaborate?"]; | |
| const randomResponse = responses[Math.floor(Math.random() * responses.length)]; | |
| const now = new Date(); | |
| const timeString = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | |
| const replyMsg = { | |
| id: contact.messages.length + 1, | |
| text: randomResponse, | |
| type: 'incoming', | |
| time: timeString | |
| }; | |
| contact.messages.push(replyMsg); | |
| renderMessages(contact.messages); | |
| scrollToBottom(); | |
| renderContacts(contactsData); | |
| } | |
| function scrollToBottom() { | |
| messagesContainerEl.scrollTop = messagesContainerEl.scrollHeight; | |
| } | |
| // Event Listeners | |
| function setupEventListeners() { | |
| sendBtnEl.addEventListener('click', sendMessage); | |
| messageInputEl.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| sendMessage(); | |
| } | |
| }); | |
| // Search Filter | |
| searchInputEl.addEventListener('input', (e) => { | |
| const term = e.target.value.toLowerCase(); | |
| const filtered = contactsData.filter(c => c.name.toLowerCase().includes(term)); | |
| renderContacts(filtered); | |
| }); | |
| // Mobile Back Button | |
| backBtnEl.addEventListener('click', () => { | |
| sidebarEl.classList.remove('hidden'); | |
| activeContactId = null; | |
| chatAreaEl.classList.add('no-chat-selected'); | |
| // Remove active class from list | |
| document.querySelectorAll('.contact-item').forEach(el => el.classList.remove('active')); | |
| }); | |
| } | |
| // Start | |
| init(); | |
| </script> | |
| </body> | |
| </html> |