#!/usr/bin/env python3 """ Search Screen for YouTube TUI """ from textual.app import ComposeResult from textual.containers import Container from textual.screen import Screen from textual.widgets import ( Button, Footer, Header, Input, Static, ) from youtube_tui.services.youtube import YouTubeService class SearchScreen(Screen): """Screen for searching YouTube videos""" CSS = """ SearchScreen { align: center middle; } #search-container { width: 80%; height: auto; border: double #555555; padding: 1 2; margin: 2 0; } #search-input { width: 100%; margin: 1 0; } #buttons { width: 100%; height: auto; dock: bottom; } Button { width: 20; margin: 1 1; } #status-bar { dock: bottom; height: 1; background: #333333; color: #aaaaaa; padding: 0 1; } #loading-indicator { height: 3; margin: 1 0; } """ BINDINGS = [ ("escape", "go_back", "Back"), ("enter", "search", "Search"), ("ctrl+f", "search_from_anywhere", "Search"), ] def __init__(self): super().__init__() self.youtube_service = YouTubeService() self.search_term = "" self.is_searching = False def compose(self) -> ComposeResult: """Compose the search screen""" yield Header() yield Container( Static("YouTube Search", id="search-title", classes="title"), Static("Enter a search term to find YouTube videos", id="search-hint"), Input(placeholder="Search for videos...", id="search-input"), Button("Search", id="search-button"), Button("Cancel", id="cancel-button"), id="search-container", ) yield Static(id="status-bar") yield Footer() def on_mount(self) -> None: """Called when screen is mounted""" self.query_one(Input).focus() self.update_status( "Ready to search - Press Enter to search, Ctrl+F to search from anywhere" ) def action_search_from_anywhere(self) -> None: """Open search from anywhere""" # This is a fallback for the key binding self.action_search() def update_status(self, message: str) -> None: """Update the status bar message""" status_bar = self.query_one("#status-bar", Static) status_bar.update(f"[bold white]{message}[/bold white]") def action_search(self) -> None: """Perform the search operation""" input_widget = self.query_one(Input) search_term = input_widget.value.strip() if not search_term: self.update_status("[red]Please enter a search term[/red]") return self.search_term = search_term self.update_status(f"[blue]Searching for: {search_term}[/blue]") # Trigger search - get the app and push results screen app = self.app if hasattr(app, "push_results_screen"): app.push_results_screen(search_term) else: # Fallback if app methods aren't available from youtube_tui.screens.results import ResultsScreen self.app.push_screen(ResultsScreen(search_term)) def action_cancel(self) -> None: """Handle cancel action""" self.action_go_back() def action_go_back(self) -> None: """Go back to previous screen""" self.app.pop_screen() def action_quit(self) -> None: """Quit the application""" # Only quit if we're at the root level if len(self.app.screen_stack) <= 2: # Header + Footer + Screen self.app.exit() else: self.action_go_back() def on_button_pressed(self, event: Button.Pressed) -> None: """Handle button presses""" if event.button.id == "search-button": self.action_search() elif event.button.id == "cancel-button": self.action_quit() def on_input_submitted(self, event: Input.Submitted) -> None: """Handle enter key in search input""" self.action_search()