diff --git a/auditui/app.py b/auditui/app.py index 266925c..2ba75c9 100644 --- a/auditui/app.py +++ b/auditui/app.py @@ -6,11 +6,16 @@ from typing import TYPE_CHECKING from textual import work from textual.app import App, ComposeResult -from textual.events import Key +from textual.events import Key, Resize from textual.widgets import DataTable, Footer, Header, ProgressBar, Static from textual.worker import get_current_worker -from .constants import PROGRESS_COLUMN_INDEX, SEEK_SECONDS, TABLE_CSS, TABLE_COLUMNS +from .constants import ( + PROGRESS_COLUMN_INDEX, + SEEK_SECONDS, + TABLE_COLUMN_DEFS, + TABLE_CSS, +) from .downloads import DownloadManager from .library import LibraryClient from .playback import PlaybackController @@ -69,7 +74,6 @@ class Auditui(App): self.title_sort_reverse = False self.progress_sort_reverse = False self.title_column_key: ColumnKey | None = None - self.progress_column_key: ColumnKey | None = None self.progress_column_index = PROGRESS_COLUMN_INDEX def compose(self) -> ComposeResult: @@ -86,10 +90,11 @@ class Auditui(App): def on_mount(self) -> None: """Initialize the table and start fetching library data.""" table = self.query_one(DataTable) - table.add_columns(*TABLE_COLUMNS) + for column_name, _ratio in TABLE_COLUMN_DEFS: + table.add_column(column_name, width=1) + self.call_after_refresh(lambda: self._apply_column_widths(table)) column_keys = list(table.columns.keys()) self.title_column_key = column_keys[0] - self.progress_column_key = column_keys[3] if self.client: self.update_status("Fetching library...") @@ -108,6 +113,15 @@ class Auditui(App): if self.download_manager: self.download_manager.close() + def on_resize(self, event: Resize) -> None: + """Keep table columns responsive to terminal width changes.""" + del event + try: + table = self.query_one(DataTable) + except Exception: + return + self._apply_column_widths(table) + def on_key(self, event: Key) -> None: """Handle key presses.""" if self.playback.is_playing: @@ -149,6 +163,34 @@ class Auditui(App): status = self.query_one("#status", Static) status.update(message) + def _apply_column_widths(self, table: DataTable) -> None: + """Assign proportional column widths based on available space.""" + if not table.columns: + return + + column_keys = list(table.columns.keys()) + ratios = [ratio for _, ratio in TABLE_COLUMN_DEFS] + total_ratio = sum(ratios) or len(column_keys) + available_width = table.size.width - 2 - (len(column_keys) - 1) + if available_width <= 0: + return + + remaining = available_width + widths: list[int] = [] + for ratio in ratios: + width = max(1, (available_width * ratio) // total_ratio) + widths.append(width) + remaining -= width + + if remaining > 0: + widths[0] += remaining + + for column_key, width in zip(column_keys, widths): + column = table.columns[column_key] + column.auto_width = False + column.width = width + table.refresh() + def _thread_status_update(self, message: str) -> None: """Safely update status from worker threads.""" self.call_from_thread(self.update_status, message) @@ -242,10 +284,6 @@ class Auditui(App): else: self.show_all() - def action_show_unfinished(self) -> None: - """Show unfinished books.""" - self.show_unfinished() - def action_play_selected(self) -> None: """Start playing the selected book.""" if not self.download_manager: