import gradio as gr from model import multimodal_analyze from database import get_history, clear_history_db # ============================================== # HISTORY DISPLAY # ============================================== def fetch_history(): records = get_history() if not records: return "

No history yet.

" html = "" for r in records: html += f"""
πŸ•’ {r.get('timestamp')}
Text: {r.get('text')}
Image: {r.get('image')}
Audio Tone: {r.get('audio')}
Speech: {r.get('transcription')}
Fusion Score: {r.get('fusion_score')}
""" return html def show_loader(): return gr.update(value="""
AI is analyzing inputs...
""", visible=True) def hide_loader(): return gr.update(visible=False) # ============================================== # CSS (same styling) # ============================================== # ============================================== # Custom Dark Styling (UNCHANGED) # ============================================== custom_css = """ /* ===================================================== FULL DARK BACKGROUND ===================================================== */ html, body { background-color: #0b1220 !important; } .gradio-container { background-color: #0b1220 !important; } /* ===================================================== DARK CARD BLOCKS ===================================================== */ .gradio-container .block { background-color: #162033 !important; border: 1px solid #1f2a44 !important; border-radius: 14px !important; } /* ===================================================== INPUT FIELDS ===================================================== */ textarea, input, select { background-color: #1e293b !important; border: 1px solid #2a3a55 !important; color: #e2e8f0 !important; border-radius: 10px !important; } /* ===================================================== TEXT COLORS ===================================================== */ .gradio-container * { color: #e2e8f0 !important; } h1, h2, h3 { color: #ffffff !important; } /* ===================================================== MAIN BUTTON STYLE ===================================================== */ button { background: linear-gradient(135deg, #14b8a6, #8b5cf6) !important; border-radius: 10px !important; font-weight: 600 !important; color: white !important; border: none !important; } button:hover { filter: brightness(1.1); } /* Remove disabled fade */ button[disabled] { opacity: 1 !important; background: linear-gradient(135deg, #14b8a6, #8b5cf6) !important; color: white !important; } /* ===================================================== UPLOAD AREA FIX ===================================================== */ .gr-image > div:first-child, .gr-audio > div:first-child { background: transparent !important; border: none !important; } .gr-image .wrap, .gr-audio .wrap { background: transparent !important; } .gr-image label, .gr-audio label, .gr-image button, .gr-audio button { display: none !important; } .gr-image > div, .gr-audio > div { background: linear-gradient(135deg, #14b8a6, #8b5cf6) !important; border-radius: 14px !important; } .gr-file-preview, .gradio-container div[class*="file"], .gradio-container div[class*="upload"], .gradio-container div[class*="progress"] { background-color: #162033 !important; color: #e2e8f0 !important; } /* ===================================================== SCROLLBAR DARK ===================================================== */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: #0b1220; } ::-webkit-scrollbar-thumb { background: #2a3a55; border-radius: 10px; } /* ===================================================== OUTPUT BOX STYLING ===================================================== */ #fusion_box { background: linear-gradient(135deg, #0f172a, #1e293b); padding: 20px; border-radius: 16px; border: 1px solid #1f2a44; } #text_box, #image_box, #audio_box { background-color: #162033; padding: 16px; border-radius: 14px; border: 1px solid #1f2a44; margin-top: 12px; } #history_box { background-color: #162033; padding: 16px; border-radius: 14px; border: 1px solid #1f2a44; min-height: 200px; margin-top: 12px; } /* =========================== HISTORY CHATGPT STYLE =========================== */ #history_box{ background-color:#162033; border:1px solid #1f2a44; border-radius:14px; padding:16px; min-height:220px; max-height:450px; overflow-y:auto; } .history-card{ background:#1e293b; border:1px solid #2a3a55; border-radius:12px; padding:14px; margin-bottom:12px; transition:all 0.2s ease; } .history-card:hover{ transform:translateY(-2px); box-shadow:0 8px 20px rgba(0,0,0,0.25); } .history-time{ font-size:13px; opacity:0.7; margin-bottom:6px; } .history-item{ margin-bottom:4px; } .history-score{ margin-top:6px; font-weight:600; color:#14b8a6; } /* HISTORY CARDS */ #history_box{ max-height:450px; overflow-y:auto; } .history-card{ background:#1e293b; border:1px solid #2a3a55; padding:16px; border-radius:12px; margin-bottom:12px; } .history-time{ font-size:13px; opacity:0.7; margin-bottom:6px; } .history-section{ margin-bottom:4px; } .history-score{ margin-top:6px; font-weight:bold; color:#14b8a6; } .loader{ width:30px; height:30px; border:4px solid #2a3a55; border-top:4px solid #14b8a6; border-radius:50%; animation:spin 1s linear infinite; margin:auto; } @keyframes spin{ 0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);} } .ai-loader{ display:flex; align-items:center; gap:10px; font-size:16px; } .spinner{ width:18px; height:18px; border:3px solid #2a3a55; border-top:3px solid #14b8a6; border-radius:50%; animation:spin 1s linear infinite; } @keyframes spin{ 0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);} } """ # ============================================== # UI # ============================================== with gr.Blocks(css=custom_css) as demo: gr.Markdown("# πŸ€– Advanced Multimodal AI System") gr.Markdown("Analyze text, image and audio with AI") with gr.Row(): # LEFT SIDE with gr.Column(): text_input = gr.Textbox(label="πŸ“ Enter Text") gr.Markdown("## πŸ–ΌοΈ Upload Image") image_input = gr.Image(type="pil", show_label=False) gr.Markdown("## πŸŽΆπŸŽ™οΈ Upload Audio") audio_input = gr.Audio(type="filepath", show_label=False) analyze_btn = gr.Button("πŸš€ Run Analysis") loader = gr.Markdown("", visible=False) # RIGHT SIDE with gr.Column(): with gr.Tabs(): with gr.Tab("Results"): fusion_output = gr.Markdown(elem_id="fusion_box") text_output = gr.Markdown(elem_id="text_box") image_output = gr.Markdown(elem_id="image_box") audio_output = gr.Markdown(elem_id="audio_box") with gr.Tab("History"): history_output = gr.Markdown(elem_id="history_box") clear_btn = gr.Button("πŸ—‘ Clear History") # ANALYZE analyze_btn.click( show_loader, outputs=loader ).then( multimodal_analyze, inputs=[text_input, image_input, audio_input], outputs=[fusion_output, text_output, image_output, audio_output] ).then( hide_loader, outputs=loader ).then( fetch_history, outputs=history_output ) # CLEAR HISTORY clear_btn.click( clear_history_db ).then( fetch_history, outputs=history_output ) # LOAD HISTORY WHEN APP STARTS demo.load( fetch_history, outputs=history_output ) if __name__ == "__main__": demo.launch(allowed_paths=["saved_images"])