Spaces:
Build error
Build error
| import streamlit as st | |
| import streamlit.components.v1 as components | |
| # Set page config | |
| st.set_page_config( | |
| page_title="Perplexity AI Clone", | |
| page_icon="π", | |
| layout="wide", | |
| initial_sidebar_state="collapsed" | |
| ) | |
| # Custom CSS for dark theme and styling | |
| st.markdown(""" | |
| <style> | |
| /* Hide Streamlit default elements */ | |
| .stDeployButton {display: none;} | |
| header[data-testid="stHeader"] {display: none;} | |
| .stMainBlockContainer {padding-top: 0rem;} | |
| /* Dark theme background */ | |
| .stApp { | |
| background-color: #1a1a1a; | |
| color: white; | |
| } | |
| /* Main container styling */ | |
| .main-container { | |
| background-color: #1a1a1a; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
| } | |
| /* Header styling */ | |
| .header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 1rem 2rem; | |
| background-color: #1a1a1a; | |
| border-bottom: 1px solid #333; | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| font-size: 1.2rem; | |
| font-weight: 600; | |
| color: white; | |
| } | |
| .logo-icon { | |
| width: 24px; | |
| height: 24px; | |
| margin-right: 8px; | |
| background: linear-gradient(45deg, #00d4ff, #00a8cc); | |
| border-radius: 4px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .get-app-btn { | |
| background-color: #00d4ff; | |
| color: #1a1a1a; | |
| padding: 8px 16px; | |
| border-radius: 20px; | |
| border: none; | |
| font-weight: 600; | |
| cursor: pointer; | |
| font-size: 14px; | |
| } | |
| /* Center content */ | |
| .center-content { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 2rem; | |
| } | |
| /* Main heading */ | |
| .main-heading { | |
| font-size: 3.5rem; | |
| font-weight: 400; | |
| text-align: center; | |
| margin-bottom: 3rem; | |
| color: white; | |
| line-height: 1.2; | |
| } | |
| /* Chat input container */ | |
| .chat-container { | |
| width: 100%; | |
| max-width: 700px; | |
| position: relative; | |
| margin-bottom: 2rem; | |
| } | |
| /* Custom input styling */ | |
| .chat-input-wrapper { | |
| position: relative; | |
| background-color: #2d2d2d; | |
| border-radius: 12px; | |
| border: 1px solid #404040; | |
| overflow: hidden; | |
| } | |
| .chat-input { | |
| width: 100%; | |
| padding: 16px 120px 16px 20px; | |
| background: transparent; | |
| border: none; | |
| outline: none; | |
| color: white; | |
| font-size: 16px; | |
| font-family: inherit; | |
| resize: none; | |
| min-height: 24px; | |
| max-height: 200px; | |
| } | |
| .chat-input::placeholder { | |
| color: #888; | |
| } | |
| /* Button container */ | |
| .button-container { | |
| position: absolute; | |
| right: 8px; | |
| top: 50%; | |
| transform: translateY(-50%); | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| /* Individual buttons */ | |
| .action-btn { | |
| width: 32px; | |
| height: 32px; | |
| background: transparent; | |
| border: none; | |
| border-radius: 6px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: #888; | |
| transition: all 0.2s ease; | |
| } | |
| .action-btn:hover { | |
| background-color: #404040; | |
| color: white; | |
| } | |
| .search-btn { | |
| background-color: #00d4ff; | |
| color: #1a1a1a; | |
| border-radius: 6px; | |
| margin-right: 4px; | |
| } | |
| .search-btn:hover { | |
| background-color: #00b8e6; | |
| } | |
| /* Bottom navigation placeholder */ | |
| .bottom-nav { | |
| position: fixed; | |
| bottom: 0; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| background-color: #1a1a1a; | |
| padding: 1rem; | |
| display: flex; | |
| gap: 2rem; | |
| border-top: 1px solid #333; | |
| width: 200px; | |
| justify-content: center; | |
| } | |
| .nav-item { | |
| width: 24px; | |
| height: 24px; | |
| background-color: #333; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| } | |
| /* Responsive design */ | |
| @media (max-width: 768px) { | |
| .main-heading { | |
| font-size: 2.5rem; | |
| } | |
| .header { | |
| padding: 1rem; | |
| } | |
| .center-content { | |
| padding: 1rem; | |
| } | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Main HTML structure | |
| st.markdown(""" | |
| <div class="main-container"> | |
| <div class="header"> | |
| <div class="logo"> | |
| <div class="logo-icon">β‘</div> | |
| perplexity | |
| </div> | |
| <button class="get-app-btn">π± Get App</button> | |
| </div> | |
| <div class="center-content"> | |
| <h1 class="main-heading">What do you want to know?</h1> | |
| <div class="chat-container"> | |
| <div class="chat-input-wrapper"> | |
| <textarea | |
| class="chat-input" | |
| placeholder="Ask anything..." | |
| rows="1" | |
| id="chatInput" | |
| ></textarea> | |
| <div class="button-container"> | |
| <button class="action-btn search-btn" title="Search"> | |
| π | |
| </button> | |
| <button class="action-btn" title="Image"> | |
| πΌοΈ | |
| </button> | |
| <button class="action-btn" title="Globe"> | |
| π | |
| </button> | |
| <button class="action-btn" title="Attachment"> | |
| π | |
| </button> | |
| <button class="action-btn" title="Voice"> | |
| π€ | |
| </button> | |
| <button class="action-btn" title="Send"> | |
| β€ | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bottom-nav"> | |
| <div class="nav-item"></div> | |
| <div class="nav-item"></div> | |
| <div class="nav-item"></div> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # JavaScript for interactive functionality | |
| components.html(""" | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const chatInput = document.getElementById('chatInput'); | |
| const buttons = document.querySelectorAll('.action-btn'); | |
| // Auto-resize textarea | |
| chatInput.addEventListener('input', function() { | |
| this.style.height = 'auto'; | |
| this.style.height = Math.min(this.scrollHeight, 200) + 'px'; | |
| }); | |
| // Button click handlers | |
| buttons.forEach(button => { | |
| button.addEventListener('click', function() { | |
| const title = this.getAttribute('title'); | |
| console.log(`${title} button clicked`); | |
| // Add visual feedback | |
| this.style.transform = 'scale(0.95)'; | |
| setTimeout(() => { | |
| this.style.transform = 'scale(1)'; | |
| }, 100); | |
| // Handle specific button actions | |
| if (title === 'Send' && chatInput.value.trim()) { | |
| console.log('Sending message:', chatInput.value); | |
| // Here you would typically send the message | |
| chatInput.value = ''; | |
| chatInput.style.height = 'auto'; | |
| } | |
| }); | |
| }); | |
| // Enter key to send | |
| chatInput.addEventListener('keydown', function(e) { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| if (this.value.trim()) { | |
| console.log('Sending message:', this.value); | |
| // Here you would typically send the message | |
| this.value = ''; | |
| this.style.height = 'auto'; | |
| } | |
| } | |
| }); | |
| // Focus on input when page loads | |
| chatInput.focus(); | |
| }); | |
| </script> | |
| """, height=0) | |
| # Session state for chat history | |
| if 'messages' not in st.session_state: | |
| st.session_state.messages = [] | |
| # Handle form submission (alternative method using Streamlit) | |
| with st.form(key='chat_form', clear_on_submit=True): | |
| user_input = st.text_input("", placeholder="Ask anything...", label_visibility="hidden", key="user_input") | |
| submit_button = st.form_submit_button("Send", use_container_width=False) | |
| if submit_button and user_input: | |
| st.session_state.messages.append({"role": "user", "content": user_input}) | |
| # Here you would add your AI response logic | |
| st.session_state.messages.append({"role": "assistant", "content": f"You asked: {user_input}"}) | |
| # Display chat history (if any messages exist) | |
| if st.session_state.messages: | |
| st.markdown("### Chat History") | |
| for message in st.session_state.messages: | |
| if message["role"] == "user": | |
| st.markdown(f"**You:** {message['content']}") | |
| else: | |
| st.markdown(f"**Assistant:** {message['content']}") |