Files
website/tools/content/app.py
T

119 lines
3.8 KiB
Python

import sys
from textual import on
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.widgets import DataTable, Footer, Header, TabbedContent, TabPane
import portfolio
from tui.books_pane import BooksPane
from tui.games_pane import GamesPane
from tui.media_pane import MediaPane
from tui.music_pane import MusicPane
from tui.profile_pane import ProfilePane
from tui.projects_pane import ProjectsPane
from tui.record_pane import RecordListPane
from tui.themes import default_theme_id, load_site_themes
from tui.themes_pane import ThemesPane
TABS = [
("music", "Music"),
("shows", "Shows"),
("movies", "Movies"),
("books", "Books"),
("games", "Games"),
("profile", "Profile"),
("experience", "Experience"),
("leadership", "Leadership"),
("projects", "Projects"),
("themes", "Themes"),
]
def tab_key(number: int) -> str:
return str(number % 10)
class ContentApp(App):
TITLE = "sirblob@engineering"
SUB_TITLE = "~/content"
CSS_PATH = "tui/app.tcss"
BINDINGS = [
Binding("q", "quit", "Quit"),
Binding("t", "next_theme", "Theme"),
*[Binding(tab_key(number), f"show_tab('{tab_id}')", label, show=False) for number, (tab_id, label) in enumerate(TABS, start=1)],
]
def __init__(self):
super().__init__()
self.site_theme_ids: list[str] = []
self.reload_site_themes(default_theme_id())
def reload_site_themes(self, show_theme_id: str | None = None):
self.site_theme_ids = []
for theme in load_site_themes():
self.register_theme(theme)
self.site_theme_ids.append(theme.name)
if not self.site_theme_ids:
return
target = show_theme_id if show_theme_id in self.site_theme_ids else self.site_theme_ids[0]
if target == self.theme:
fallback = next(theme for theme in self.available_themes if theme != target)
self.theme = fallback
self.theme = target
def action_next_theme(self):
if not self.site_theme_ids:
return
current = self.site_theme_ids.index(self.theme) if self.theme in self.site_theme_ids else -1
self.theme = self.site_theme_ids[(current + 1) % len(self.site_theme_ids)]
self.notify(f"Theme: {self.theme}")
def compose(self) -> ComposeResult:
yield Header()
with TabbedContent(initial="music"):
with TabPane("1 Music", id="music"):
yield MusicPane()
with TabPane("2 Shows", id="shows"):
yield MediaPane("show")
with TabPane("3 Movies", id="movies"):
yield MediaPane("movie")
with TabPane("4 Books", id="books"):
yield BooksPane()
with TabPane("5 Games", id="games"):
yield GamesPane()
with TabPane("6 Profile", id="profile"):
yield ProfilePane()
with TabPane("7 Experience", id="experience"):
yield RecordListPane(portfolio.EXPERIENCE)
with TabPane("8 Leadership", id="leadership"):
yield RecordListPane(portfolio.LEADERSHIP)
with TabPane("9 Projects", id="projects"):
yield ProjectsPane()
with TabPane("0 Themes", id="themes"):
yield ThemesPane()
yield Footer()
def on_mount(self):
self.focus_active_table()
def action_show_tab(self, tab_id: str):
self.query_one(TabbedContent).active = tab_id
@on(TabbedContent.TabActivated)
def tab_changed(self):
self.focus_active_table()
def focus_active_table(self):
tabs = self.query_one(TabbedContent)
tabs.get_pane(tabs.active).query_one(DataTable).focus()
def main() -> int:
ContentApp().run()
return 0
if __name__ == "__main__":
sys.exit(main())