feat: Add comprehensive help screen modal
- Create HelpScreen with all keyboard shortcuts - Add hardcoded sections for instructions - Add binding for '?' key to show help - Support ESC/q/? to close help screen - Document notification compression feature in help - Format help with colors and sections (Navigation, Actions, View, Search) Features: - Shows all keyboard shortcuts in organized sections - Quick Actions section explains notification compression - Configuration instructions for mail.toml - Modal dialog with close button - Extracts bindings automatically for display
This commit is contained in:
146
src/mail/screens/HelpScreen.py
Normal file
146
src/mail/screens/HelpScreen.py
Normal file
@@ -0,0 +1,146 @@
|
||||
"""Help screen modal for mail app."""
|
||||
|
||||
from textual.screen import Screen
|
||||
from textual.containers import Vertical, Horizontal, Center, ScrollableContainer
|
||||
from textual.widgets import Static, Button, Footer
|
||||
from textual.app import ComposeResult
|
||||
from textual.binding import Binding
|
||||
|
||||
|
||||
class HelpScreen(Screen):
|
||||
"""Help screen showing all keyboard shortcuts and app information."""
|
||||
|
||||
BINDINGS = [
|
||||
Binding("escape", "pop_screen", "Close", show=False),
|
||||
Binding("q", "pop_screen", "Close", show=False),
|
||||
Binding("?", "pop_screen", "Close", show=False),
|
||||
]
|
||||
|
||||
def __init__(self, app_bindings: list[Binding], **kwargs):
|
||||
"""Initialize help screen with app bindings.
|
||||
|
||||
Args:
|
||||
app_bindings: List of bindings from the main app
|
||||
"""
|
||||
super().__init__(**kwargs)
|
||||
self.app_bindings = app_bindings
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
"""Compose the help screen."""
|
||||
|
||||
with Vertical(id="help_container"):
|
||||
# Header
|
||||
yield Static(
|
||||
"╔══════════════════════════════════════════════════════════════════╗\n"
|
||||
"║" + " " * 68 + "║\n"
|
||||
"║" + " LUK Mail - Keyboard Shortcuts & Help".center(68) + " ║\n"
|
||||
"╚════════════════════════════════════════════════════════════════════╝"
|
||||
)
|
||||
|
||||
# Custom instructions section
|
||||
yield Static("", id="spacer")
|
||||
yield Static("[b cyan]Quick Actions[/b cyan]", id="instructions_title")
|
||||
yield Static("─" * 70, id="instructions_separator")
|
||||
yield Static("")
|
||||
yield Static(
|
||||
" The mail app automatically compresses notification emails from:"
|
||||
)
|
||||
yield Static(" • GitLab (pipelines, MRs, mentions)")
|
||||
yield Static(" • GitHub (PRs, issues, reviews)")
|
||||
yield Static(" • Jira (issues, status changes)")
|
||||
yield Static(" • Confluence (page updates, comments)")
|
||||
yield Static(" • Datadog (alerts, incidents)")
|
||||
yield Static(" • Renovate (dependency updates)")
|
||||
yield Static("")
|
||||
yield Static(
|
||||
" [yellow]Tip:[/yellow] Toggle between compressed and full view with [b]m[/b]"
|
||||
)
|
||||
yield Static("")
|
||||
|
||||
# Auto-generated keybindings section
|
||||
yield Static("", id="spacer")
|
||||
yield Static("[b cyan]Keyboard Shortcuts[/b cyan]", id="bindings_title")
|
||||
yield Static("─" * 70, id="bindings_separator")
|
||||
yield Static("")
|
||||
yield Static("[b green]Navigation[/b green]")
|
||||
yield Static(" j/k - Next/Previous message")
|
||||
yield Static(" g - Go to oldest message")
|
||||
yield Static(" G - Go to newest message")
|
||||
yield Static(" PageDown/PageUp - Scroll page down/up")
|
||||
yield Static("")
|
||||
|
||||
yield Static("[b green]Message Actions[/b green]")
|
||||
yield Static(" # - Delete message(s)")
|
||||
yield Static(" e - Archive message(s)")
|
||||
yield Static(" u - Toggle read/unread")
|
||||
yield Static(" t - Create task from message")
|
||||
yield Static(" l - Show links in message")
|
||||
yield Static("")
|
||||
|
||||
yield Static("[b green]View Options[/b green]")
|
||||
yield Static(" w - Toggle message view window")
|
||||
yield Static(" m - Toggle markdown/html view mode")
|
||||
yield Static(" h - Toggle envelope header")
|
||||
yield Static("")
|
||||
|
||||
yield Static("[b green]Search & Filter[/b green]")
|
||||
yield Static(" / - Search messages")
|
||||
yield Static(" s - Toggle sort order")
|
||||
yield Static(" x - Toggle selection mode")
|
||||
yield Static(" Space - Select/deselect message")
|
||||
yield Static(" Escape - Clear selection")
|
||||
yield Static("")
|
||||
|
||||
yield Static("[b green]Calendar Actions (when applicable)[/b green]")
|
||||
yield Static(" A - Accept invite")
|
||||
yield Static(" D - Decline invite")
|
||||
yield Static(" T - Tentative")
|
||||
yield Static("")
|
||||
|
||||
yield Static("[b green]Application[/b green]")
|
||||
yield Static(" r - Reload message list")
|
||||
yield Static(
|
||||
" 1-4 - Focus panel (Accounts, Folders, Messages, Content)"
|
||||
)
|
||||
yield Static(" q - Quit application")
|
||||
yield Static("")
|
||||
|
||||
# Notification compression section
|
||||
yield Static("", id="spacer")
|
||||
yield Static(
|
||||
"[b cyan]Notification Email Compression[/b cyan]",
|
||||
id="compression_title",
|
||||
)
|
||||
yield Static("─" * 70, id="compression_separator")
|
||||
yield Static("")
|
||||
yield Static(
|
||||
" Notification emails are automatically detected and compressed"
|
||||
)
|
||||
yield Static(" into terminal-friendly summaries showing:")
|
||||
yield Static(" • Notification type and icon")
|
||||
yield Static(" • Key details (ID, title, status)")
|
||||
yield Static(" • Action items")
|
||||
yield Static(" • Important links")
|
||||
yield Static("")
|
||||
yield Static(" [yellow]Configuration:[/yellow]")
|
||||
yield Static(" Edit ~/.config/luk/mail.toml to customize:")
|
||||
yield Static(" [dim]compress_notifications = true[/dim]")
|
||||
yield Static(" [dim]notification_compression_mode = 'summary'[/dim]")
|
||||
yield Static(" # Options: 'summary', 'detailed', 'off'")
|
||||
yield Static("")
|
||||
|
||||
# Footer
|
||||
yield Static("─" * 70, id="footer_separator")
|
||||
yield Static(
|
||||
"[dim]Press [b]ESC[/b], [b]q[/b], or [b]?[/b] to close this help screen[/dim]",
|
||||
id="footer_text",
|
||||
)
|
||||
|
||||
# Close button at bottom
|
||||
with Horizontal(id="button_container"):
|
||||
yield Button("Close", id="close_button", variant="primary")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
"""Handle button press to close help screen."""
|
||||
if event.button.id == "close_button":
|
||||
self.dismiss()
|
||||
Reference in New Issue
Block a user