Compare commits

...

4 Commits

Author SHA1 Message Date
4c27d1864c feat: make the main view truely responsive 2026-02-12 19:03:47 +01:00
81814246d0 fix: redistribute proportions 2026-02-12 19:03:37 +01:00
b71e15d54c chore: update pyproject 2026-02-12 19:03:26 +01:00
181b8314e6 feat: update version 2026-02-12 19:03:21 +01:00
4 changed files with 46 additions and 25 deletions

View File

@@ -1,3 +1,3 @@
"""Auditui package""" """Auditui package"""
__version__ = "0.1.4" __version__ = "0.1.5"

View File

@@ -99,13 +99,15 @@ class Auditui(App):
yield table yield table
yield Static("", id="progress_info") yield Static("", id="progress_info")
with Horizontal(id="progress_bar_container"): with Horizontal(id="progress_bar_container"):
yield ProgressBar(id="progress_bar", show_eta=False, show_percentage=False, total=100) yield ProgressBar(
id="progress_bar", show_eta=False, show_percentage=False, total=100
)
def on_mount(self) -> None: def on_mount(self) -> None:
"""Initialize the table and start fetching library data.""" """Initialize the table and start fetching library data."""
table = self.query_one(DataTable) table = self.query_one(DataTable)
for column_name, _ratio in TABLE_COLUMN_DEFS: for column_name, _ratio in TABLE_COLUMN_DEFS:
table.add_column(column_name, width=1) table.add_column(column_name)
self.call_after_refresh(lambda: self._apply_column_widths(table)) self.call_after_refresh(lambda: self._apply_column_widths(table))
column_keys = list(table.columns.keys()) column_keys = list(table.columns.keys())
self.title_column_key = column_keys[0] self.title_column_key = column_keys[0]
@@ -134,7 +136,7 @@ class Auditui(App):
table = self.query_one(DataTable) table = self.query_one(DataTable)
except Exception: except Exception:
return return
self._apply_column_widths(table) self.call_after_refresh(lambda: self._apply_column_widths(table))
def on_key(self, event: Key) -> None: def on_key(self, event: Key) -> None:
"""Handle key presses.""" """Handle key presses."""
@@ -179,31 +181,44 @@ class Auditui(App):
status.update(message) status.update(message)
def _apply_column_widths(self, table: DataTable) -> None: def _apply_column_widths(self, table: DataTable) -> None:
"""Assign proportional column widths based on available space.""" """Assign proportional column widths based on available space.
Each column's render width = column.width + 2 * cell_padding.
We compute column.width values so columns fill the full table width.
"""
if not table.columns: if not table.columns:
return return
column_keys = list(table.columns.keys()) column_keys = list(table.columns.keys())
num_cols = len(column_keys)
ratios = [ratio for _, ratio in TABLE_COLUMN_DEFS] ratios = [ratio for _, ratio in TABLE_COLUMN_DEFS]
total_ratio = sum(ratios) or len(column_keys) total_ratio = sum(ratios) or num_cols
content_width = table.scrollable_content_region.width content_width = table.scrollable_content_region.width
available_width = content_width if content_width <= 0:
if available_width <= 0: content_width = table.size.width
if content_width <= 0:
return return
padding_total = 2 * table.cell_padding * num_cols
distributable = max(num_cols, content_width - padding_total)
widths: list[int] = [] widths: list[int] = []
for ratio in ratios: for ratio in ratios:
width = max(1, (available_width * ratio) // total_ratio) w = max(1, (distributable * ratio) // total_ratio)
widths.append(width) widths.append(w)
remainder = available_width - sum(widths) remainder = distributable - sum(widths)
if remainder > 0:
indices = sorted(
range(num_cols), key=lambda i: ratios[i], reverse=True)
for i in range(remainder): for i in range(remainder):
widths[i % len(widths)] += 1 widths[indices[i % num_cols]] += 1
for column_key, width in zip(column_keys, widths): for column_key, w in zip(column_keys, widths):
column = table.columns[column_key] col = table.columns[column_key]
column.auto_width = False col.auto_width = False
column.width = width col.width = w
table.refresh() table.refresh()
def _thread_status_update(self, message: str) -> None: def _thread_status_update(self, message: str) -> None:
@@ -250,13 +265,15 @@ class Auditui(App):
for item in items: for item in items:
title, author, runtime, progress, downloaded = format_item_as_row( title, author, runtime, progress, downloaded = format_item_as_row(
item, self.library_client, self.download_manager) item, self.library_client, self.download_manager
)
table.add_row(title, author, runtime, table.add_row(title, author, runtime,
progress, downloaded, key=title) progress, downloaded, key=title)
self.current_items = items self.current_items = items
status = self.query_one("#status", Static) status = self.query_one("#status", Static)
status.display = False status.display = False
self._apply_column_widths(table)
def _refresh_table(self) -> None: def _refresh_table(self) -> None:
"""Refresh the table with current items.""" """Refresh the table with current items."""
@@ -291,7 +308,8 @@ class Auditui(App):
if table.row_count > 0: if table.row_count > 0:
self.progress_sort_reverse = not self.progress_sort_reverse self.progress_sort_reverse = not self.progress_sort_reverse
progress_key, reverse = create_progress_sort_key( progress_key, reverse = create_progress_sort_key(
self.progress_column_index, self.progress_sort_reverse) self.progress_column_index, self.progress_sort_reverse
)
table.sort(key=progress_key, reverse=reverse) table.sort(key=progress_key, reverse=reverse)
def action_show_all(self) -> None: def action_show_all(self) -> None:
@@ -529,13 +547,15 @@ class Auditui(App):
progress_bar_container = self.query_one( progress_bar_container = self.query_one(
"#progress_bar_container", Horizontal) "#progress_bar_container", Horizontal)
progress_percent = min(100.0, max( progress_percent = min(
0.0, (chapter_elapsed / chapter_total) * 100.0)) 100.0, max(0.0, (chapter_elapsed / chapter_total) * 100.0)
)
progress_bar.update(progress=progress_percent) progress_bar.update(progress=progress_percent)
chapter_elapsed_str = LibraryClient.format_time(chapter_elapsed) chapter_elapsed_str = LibraryClient.format_time(chapter_elapsed)
chapter_total_str = LibraryClient.format_time(chapter_total) chapter_total_str = LibraryClient.format_time(chapter_total)
progress_info.update( progress_info.update(
f"{chapter_name} | {chapter_elapsed_str} / {chapter_total_str}") f"{chapter_name} | {chapter_elapsed_str} / {chapter_total_str}"
)
progress_info.display = True progress_info.display = True
progress_bar_container.display = True progress_bar_container.display = True

View File

@@ -11,8 +11,8 @@ MIN_FILE_SIZE = 1024 * 1024
DEFAULT_CHUNK_SIZE = 8192 DEFAULT_CHUNK_SIZE = 8192
TABLE_COLUMN_DEFS = ( TABLE_COLUMN_DEFS = (
("Title", 2), ("Title", 4),
("Author", 2), ("Author", 3),
("Length", 1), ("Length", 1),
("Progress", 1), ("Progress", 1),
("Downloaded", 1), ("Downloaded", 1),
@@ -59,6 +59,7 @@ Screen {
} }
DataTable { DataTable {
width: 100%;
height: 1fr; height: 1fr;
background: #141622; background: #141622;
color: #c7cfe8; color: #c7cfe8;

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "auditui" name = "auditui"
version = "0.1.4" version = "0.1.5"
description = "An Audible TUI client" description = "An Audible TUI client"
readme = "README.md" readme = "README.md"
requires-python = ">=3.10,<3.13" requires-python = ">=3.10,<3.13"