Spaces:
Running
Running
| """ | |
| VoiceForge - Processing Animation Component | |
| Premium animated loading states with time tracking | |
| """ | |
| import streamlit as st | |
| import time | |
| def render_processing_animation(title: str = "PROCESSING", step: str = "Initializing...", | |
| progress: int = 0, elapsed_time: float = 0): | |
| """ | |
| Render a premium ROG-style processing animation with time tracking. | |
| Args: | |
| title: Main title to display | |
| step: Current step description | |
| progress: Progress percentage (0-100) | |
| elapsed_time: Time elapsed in seconds | |
| """ | |
| # Format elapsed time | |
| minutes = int(elapsed_time // 60) | |
| seconds = int(elapsed_time % 60) | |
| time_str = f"{minutes:02d}:{seconds:02d}" | |
| # Calculate gradient position based on progress | |
| gradient_pos = progress * 3.6 # For rotation effect | |
| st.markdown(f""" | |
| <div style=" | |
| background: linear-gradient(145deg, #0a0a0a 0%, #1a1a1a 100%); | |
| border: 1px solid #2a2a2a; | |
| border-radius: 12px; | |
| padding: 40px; | |
| text-align: center; | |
| position: relative; | |
| overflow: hidden; | |
| margin: 20px 0; | |
| "> | |
| <!-- Animated border glow --> | |
| <div style=" | |
| position: absolute; | |
| inset: -2px; | |
| background: linear-gradient({gradient_pos}deg, #ff0033, #00d4ff, #ff0033); | |
| border-radius: 14px; | |
| z-index: -1; | |
| opacity: 0.5; | |
| animation: borderGlow 2s linear infinite; | |
| "></div> | |
| <!-- Inner container --> | |
| <div style=" | |
| background: linear-gradient(145deg, #0a0a0a 0%, #1a1a1a 100%); | |
| border-radius: 10px; | |
| padding: 30px; | |
| position: relative; | |
| "> | |
| <!-- Spinning ring --> | |
| <div style=" | |
| width: 80px; | |
| height: 80px; | |
| margin: 0 auto 20px; | |
| border: 3px solid #2a2a2a; | |
| border-top: 3px solid #ff0033; | |
| border-radius: 50%; | |
| animation: spin 1s linear infinite; | |
| "></div> | |
| <!-- Title --> | |
| <div style=" | |
| font-family: 'Orbitron', sans-serif; | |
| font-size: 1.5rem; | |
| font-weight: 700; | |
| color: #ff0033; | |
| text-transform: uppercase; | |
| letter-spacing: 4px; | |
| margin-bottom: 10px; | |
| ">{title}</div> | |
| <!-- Step description --> | |
| <div style=" | |
| color: #888; | |
| font-size: 0.9rem; | |
| margin-bottom: 20px; | |
| ">{step}</div> | |
| <!-- Progress bar --> | |
| <div style=" | |
| background: #1a1a1a; | |
| border-radius: 4px; | |
| height: 8px; | |
| overflow: hidden; | |
| margin: 0 auto 15px; | |
| max-width: 300px; | |
| border: 1px solid #333; | |
| "> | |
| <div style=" | |
| width: {progress}%; | |
| height: 100%; | |
| background: linear-gradient(90deg, #ff0033, #ff6600); | |
| border-radius: 4px; | |
| transition: width 0.3s ease; | |
| box-shadow: 0 0 10px rgba(255, 0, 51, 0.5); | |
| "></div> | |
| </div> | |
| <!-- Stats row --> | |
| <div style=" | |
| display: flex; | |
| justify-content: center; | |
| gap: 40px; | |
| margin-top: 20px; | |
| "> | |
| <div> | |
| <div style="color: #00d4ff; font-family: 'Orbitron', sans-serif; font-size: 1.5rem; font-weight: 600;"> | |
| {progress}% | |
| </div> | |
| <div style="color: #666; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 1px;"> | |
| PROGRESS | |
| </div> | |
| </div> | |
| <div> | |
| <div style="color: #ff6600; font-family: 'Orbitron', sans-serif; font-size: 1.5rem; font-weight: 600;"> | |
| {time_str} | |
| </div> | |
| <div style="color: #666; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 1px;"> | |
| ELAPSED | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <style> | |
| @keyframes spin {{ | |
| 0% {{ transform: rotate(0deg); }} | |
| 100% {{ transform: rotate(360deg); }} | |
| }} | |
| @keyframes borderGlow {{ | |
| 0% {{ opacity: 0.3; }} | |
| 50% {{ opacity: 0.6; }} | |
| 100% {{ opacity: 0.3; }} | |
| }} | |
| </style> | |
| """, unsafe_allow_html=True) | |
| def render_success_animation(title: str = "COMPLETE", subtitle: str = "Processing finished successfully", | |
| stats: dict = None): | |
| """ | |
| Render a success state animation. | |
| Args: | |
| title: Success title | |
| subtitle: Description text | |
| stats: Dictionary of stats to display (e.g., {"Speakers": 3, "Segments": 135}) | |
| """ | |
| stats_html = "" | |
| if stats: | |
| stats_items = [] | |
| for key, value in stats.items(): | |
| stats_items.append(f""" | |
| <div style="text-align: center;"> | |
| <div style="color: #00ff88; font-family: 'Orbitron', sans-serif; font-size: 1.8rem; font-weight: 600;"> | |
| {value} | |
| </div> | |
| <div style="color: #666; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 1px;"> | |
| {key} | |
| </div> | |
| </div> | |
| """) | |
| stats_html = f""" | |
| <div style="display: flex; justify-content: center; gap: 40px; margin-top: 25px;"> | |
| {''.join(stats_items)} | |
| </div> | |
| """ | |
| st.markdown(f""" | |
| <div style=" | |
| background: linear-gradient(145deg, #0a0a0a 0%, #0d1a0d 100%); | |
| border: 1px solid #00ff88; | |
| border-radius: 12px; | |
| padding: 40px; | |
| text-align: center; | |
| margin: 20px 0; | |
| box-shadow: 0 0 30px rgba(0, 255, 136, 0.2); | |
| "> | |
| <!-- Success checkmark --> | |
| <div style=" | |
| width: 80px; | |
| height: 80px; | |
| margin: 0 auto 20px; | |
| background: linear-gradient(135deg, #00ff88, #00cc6a); | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 2.5rem; | |
| box-shadow: 0 0 20px rgba(0, 255, 136, 0.4); | |
| ">✓</div> | |
| <!-- Title --> | |
| <div style=" | |
| font-family: 'Orbitron', sans-serif; | |
| font-size: 1.5rem; | |
| font-weight: 700; | |
| color: #00ff88; | |
| text-transform: uppercase; | |
| letter-spacing: 4px; | |
| margin-bottom: 10px; | |
| ">{title}</div> | |
| <!-- Subtitle --> | |
| <div style="color: #888; font-size: 0.9rem;">{subtitle}</div> | |
| {stats_html} | |
| </div> | |
| """, unsafe_allow_html=True) | |