Jarian Cottingham 06877fb2fc feat: add TUI (Textual User Interface) with download queue system
- New TUI using Textual framework with responsive interface
- Search, results, download, and queue screens for YouTube video management
- Download queue system with sequential background downloads
- Status bar with queue count and download progress indicators
- Comprehensive test suite (97 tests) with 100% pass rate
- Modern Python packaging with pyproject.toml and uv support
- Added requirements-tui.txt for TUI-specific dependencies
- Updated setup.py and install.sh for TUI integration
- Enhanced README.md with TUI usage documentation
2026-02-25 15:59:15 -06:00

184 lines
5.4 KiB
Python

"""
Help Screen for YouTube TUI
"""
from textual.app import ComposeResult
from textual.containers import Container, VerticalScroll
from textual.screen import ModalScreen
from textual.widgets import Footer, Header, Static
class HelpScreen(ModalScreen):
"""Help screen with keyboard shortcuts documentation"""
CSS = """
HelpScreen {
align: center middle;
}
#help-container {
width: 80%;
height: 80%;
border: solid #555555;
background: $surface;
padding: 1;
}
#help-title {
width: 100%;
height: 3;
dock: top;
background: $primary;
content-align: center middle;
color: $text;
}
.section-title {
width: 100%;
height: 2;
margin: 1 0;
color: $primary;
text-style: bold;
}
.shortcut-row {
height: 2;
padding: 0 1;
}
.shortcut-key {
width: 20;
color: $accent;
text-style: bold;
}
.shortcut-desc {
width: 100%;
color: $text;
}
#app-description {
width: 100%;
height: 6;
margin: 1 0;
color: $text;
}
#config-info {
width: 100%;
height: auto;
margin: 1 0;
color: $text-muted;
}
#close-hint {
width: 100%;
height: 2;
dock: bottom;
text-align: center;
color: $text-muted;
}
"""
BINDINGS = [
("escape", "close_help", "Close"),
("q", "close_help", "Close"),
]
def compose(self) -> ComposeResult:
"""Compose the help screen"""
yield Header()
yield Container(
Static("YouTube TUI Help", id="help-title"),
VerticalScroll(
Static(
"A Text-based User Interface for browsing and downloading YouTube videos",
id="app-description",
),
Static("Global Keyboard Shortcuts", classes="section-title"),
Static(
"[key]q[/key] [desc]Quit application[/desc]",
classes="shortcut-row",
),
Static(
"[key]escape[/key] [desc]Cancel current operation / go back[/desc]",
classes="shortcut-row",
),
Static(
"[key]ctrl+p[/key] [desc]Open command palette[/desc]",
classes="shortcut-row",
),
Static(
"[key]ctrl+h[/key] [desc]Show this help screen[/desc]",
classes="shortcut-row",
),
Static(
"[key]ctrl+t[/key] [desc]Toggle theme (dark/light)[/desc]",
classes="shortcut-row",
),
Static(
"[key]ctrl+r[/key] [desc]Refresh current screen[/desc]",
classes="shortcut-row",
),
Static(
"[key]ctrl+f[/key] [desc]Open search from any screen[/desc]",
classes="shortcut-row",
),
Static("Search Screen Shortcuts", classes="section-title"),
Static(
"[key]enter[/key] [desc]Perform search[/desc]",
classes="shortcut-row",
),
Static("Results Screen Shortcuts", classes="section-title"),
Static(
"[key]n[/key] [desc]Next page[/desc]",
classes="shortcut-row",
),
Static(
"[key]p[/key] [desc]Previous page[/desc]",
classes="shortcut-row",
),
Static(
"[key]enter[/key] [desc]Download selected video[/desc]",
classes="shortcut-row",
),
Static(
"[key]escape[/key] [desc]Go back to search[/desc]",
classes="shortcut-row",
),
Static(
"Category Selection Modal Shortcuts",
classes="section-title",
),
Static(
"[key]arrow keys[/key] [desc]Navigate options[/desc]",
classes="shortcut-row",
),
Static(
"[key]enter[/key] [desc]Select category[/desc]",
classes="shortcut-row",
),
Static(
"[key]escape[/key] [desc]Cancel[/desc]",
classes="shortcut-row",
),
Static("Configuration", classes="section-title"),
Static(
"Configuration file: [path]~/.config/youtube_cli/config.json[/path]",
classes="config-info",
),
Static(
"Archive file: [path]~/.config/youtube_cli/downloaded_videos.json[/path]",
classes="config-info",
),
id="help-content",
),
Static("Press [key]ESC[/key] or [key]Q[/key] to close", id="close-hint"),
id="help-container",
)
yield Footer()
def action_close_help(self) -> None:
"""Close the help screen"""
self.app.pop_screen()