""" Loader Widget Module. ===================== Handles the application initialization and model checks. Refactored for 2026 Premium Aesthetics. """ from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QProgressBar from PySide6.QtCore import Qt, QThread, Signal from PySide6.QtGui import QFont import os import logging from faster_whisper import download_model from src.core.paths import get_models_path from src.ui.styles import Theme, StyleGenerator, load_modern_fonts from src.ui.components import FramelessWindow, ModernFrame class DownloadWorker(QThread): """Background worker for model downloads.""" progress = Signal(str, int) download_finished = Signal() error = Signal(str) def run(self): try: model_path = get_models_path() self.progress.emit("Verifying AI Core...", 10) os.environ["HF_HOME"] = str(model_path) self.progress.emit("Downloading Model...", 30) download_model("small", output_dir=str(model_path)) self.progress.emit("System Ready!", 100) self.download_finished.emit() except Exception as e: logging.error(f"Loader failed: {e}") self.error.emit(str(e)) class LoaderWidget(FramelessWindow): """ Premium bootstrapper UI. Inherits from FramelessWindow for rounded glass look. """ ready_signal = Signal() def __init__(self): super().__init__() self.setFixedSize(400, 180) # Main Layout self.root = QVBoxLayout(self) self.root.setContentsMargins(10, 10, 10, 10) # Glass Card self.card = ModernFrame() self.card.setStyleSheet(StyleGenerator.get_glass_card(radius=20)) self.root.addWidget(self.card) # Content Layout self.layout = QVBoxLayout(self.card) self.layout.setContentsMargins(30,30,30,30) self.layout.setSpacing(15) # App Title/Brand self.brand = QLabel("WHISPER VOICE") self.brand.setFont(load_modern_fonts()) self.brand.setStyleSheet(f"color: {Theme.ACCENT_CYAN}; font-weight: 900; letter-spacing: 4px; font-size: 14px;") self.brand.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.brand) # Status Label self.status_label = QLabel("INITIALIZING...") self.status_label.setStyleSheet(f"color: {Theme.TEXT_SECONDARY}; font-weight: 600; font-size: 11px;") self.status_label.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.status_label) # Progress Bar (Modern Slim style) self.progress_bar = QProgressBar() self.progress_bar.setFixedHeight(4) self.progress_bar.setStyleSheet(f""" QProgressBar {{ background-color: {Theme.BG_DARK}; border-radius: 2px; border: none; text-align: center; color: transparent; }} QProgressBar::chunk {{ background-color: {Theme.ACCENT_CYAN}; border-radius: 2px; }} """) self.layout.addWidget(self.progress_bar) # Start Worker self.worker = DownloadWorker() self.worker.progress.connect(self.update_progress) self.worker.download_finished.connect(self.on_finished) self.worker.start() def update_progress(self, text: str, percent: int): self.status_label.setText(text.upper()) self.progress_bar.setValue(percent) def on_finished(self): self.ready_signal.emit() self.close()