Lexi Winter: 1 Status bar improvements 4 files changed, 54 insertions(+), 17 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~ihabunek/toot-discuss/patches/48479/mbox | git am -3Learn more about email & git
Move the status bar to MainScreen, which is a more appropriate place for it than TimelineTab. Add a new ShowStatusMessage message which can be used to display a status message. Use ShowStatusMessage to display messages and errors when fetching the timeline in TimelineTab. --- tooi/messages.py | 5 +++++ tooi/screens/main.py | 34 ++++++++++++++++++++++++++++------ tooi/tabs/timeline.py | 28 +++++++++++++++++++--------- tooi/widgets/status_bar.py | 4 ++-- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/tooi/messages.py b/tooi/messages.py index 2b15fc9..8e2750c 100644 --- a/tooi/messages.py +++ b/tooi/messages.py @@ -81,3 +81,8 @@ class ShowStatusMenu(StatusMessage): class StatusReply(StatusMessage): pass + +class ShowStatusMessage(Message): + def __init__(self, text: str | None = None): + super().__init__() + self.text = text diff --git a/tooi/screens/main.py b/tooi/screens/main.py index 21b4bb1..d7b7202 100644 --- a/tooi/screens/main.py +++ b/tooi/screens/main.py @@ -1,13 +1,16 @@ from textual.app import ComposeResult from textual.binding import Binding +from textual.containers import Vertical from textual.screen import Screen from textual.widgets import TabPane, TabbedContent, Footer from tooi.api.timeline import HomeTimeline, Timeline from tooi.data.instance import InstanceInfo +from tooi.messages import ShowStatusMessage from tooi.tabs.search import SearchTab from tooi.tabs.timeline import TimelineTab from tooi.widgets.header import Header +from tooi.widgets.status_bar import StatusBar class MainScreen(Screen[None]): @@ -32,6 +35,11 @@ class MainScreen(Screen[None]): TabPane { padding: 0; } + + #footer { + height: 2; + dock: bottom; + } """ BINDINGS = [ @@ -51,15 +59,21 @@ class MainScreen(Screen[None]): ] def __init__(self, instance: InstanceInfo): - self.instance = instance super().__init__() + self.instance = instance def compose(self) -> ComposeResult: - yield Header("toot") - # Start with the home timeline - with TabbedContent(): - yield TimelineTab(self.instance, HomeTimeline(self.instance)) - yield Footer() + with Vertical(): + yield Header("toot") + # Start with the home timeline + with TabbedContent(): + yield TimelineTab(self.instance, HomeTimeline(self.instance)) + with Vertical(id="footer"): + # Footer() needs to be in its own container, because it forcibly docks itself to the + # bottom, which would cause it to overlap the status bar. + with Vertical(): + yield Footer() + yield StatusBar() async def open_timeline_tab(self, timeline: Timeline, initial_focus: str | None = None): tab = TimelineTab(self.instance, timeline, initial_focus=initial_focus) @@ -67,6 +81,14 @@ class MainScreen(Screen[None]): await tc.add_pane(tab) tc.active = tab.id + def on_show_status_message(self, message: ShowStatusMessage): + status_bar = self.query_one(StatusBar) + + if message.text is None: + status_bar.clear() + else: + status_bar.update(message.text) + def action_select_tab(self, tabnr: int): tc = self.query_one(TabbedContent) tabs = tc.query(TabPane) diff --git a/tooi/tabs/timeline.py b/tooi/tabs/timeline.py index 5cc56c4..83f090a 100644 --- a/tooi/tabs/timeline.py +++ b/tooi/tabs/timeline.py @@ -9,8 +9,7 @@ from tooi.api.timeline import Timeline from tooi.context import get_context from tooi.data.instance import InstanceInfo from tooi.messages import ShowAccount, ShowSource, ShowStatusMenu, ShowThread -from tooi.messages import EventHighlighted, EventSelected, StatusReply -from tooi.widgets.status_bar import StatusBar +from tooi.messages import EventHighlighted, EventSelected, StatusReply, ShowStatusMessage from tooi.widgets.status_detail import StatusDetail from tooi.widgets.event_detail import make_event_detail, EventDetailPlaceholder from tooi.widgets.event_list import EventList @@ -58,7 +57,6 @@ class TimelineTab(TabPane): # Start with an empty status list while we wait to load statuses. self.event_list = EventList([]) self.event_detail = EventDetailPlaceholder() - self.status_bar = StatusBar() def on_show(self, message): self.event_list.focus() @@ -75,7 +73,6 @@ class TimelineTab(TabPane): self.event_detail, id="main_window" ) - yield self.status_bar def make_event_detail(self, event: Event): return make_event_detail(event) @@ -88,16 +85,29 @@ class TimelineTab(TabPane): newevents = [] - async for eventslist in self.timeline.update(): - newevents += eventslist + self.post_message(ShowStatusMessage(f"[green]Updating timeline...[/]")) + + try: + async for eventslist in self.timeline.update(): + newevents += eventslist + except Exception as exc: + self.post_message(ShowStatusMessage(f"[red]Could not load timeline: {str(exc)}[/]")) + return # The updates are returned in inverse chronological order, so reverse them before adding. newevents.reverse() self.event_list.prepend_events(newevents) + self.post_message(ShowStatusMessage()) async def fetch_timeline(self): self.generator = self.timeline.fetch() - events = await anext(self.generator) + + try: + events = await anext(self.generator) + except Exception as exc: + self.post_message(ShowStatusMessage(f"[red]Could not load timeline: {str(exc)}[/]")) + return + self.event_list.replace(events) self.query_one("#main_window").mount(self.event_detail) @@ -162,14 +172,14 @@ class TimelineTab(TabPane): async def maybe_fetch_next_batch(self): if self.generator and self.should_fetch(): self.fetching = True - self.status_bar.update("[green]Loading statuses...[/]") + self.post_message(ShowStatusMessage("[green]Loading statuses...[/]")) # TODO: handle exceptions try: next_events = await anext(self.generator) self.event_list.append_events(next_events) finally: + self.post_message(ShowStatusMessage()) self.fetching = False - self.status_bar.update() def should_fetch(self): if not self.fetching and self.event_list.index is not None: diff --git a/tooi/widgets/status_bar.py b/tooi/widgets/status_bar.py index 511cb8b..90c5483 100644 --- a/tooi/widgets/status_bar.py +++ b/tooi/widgets/status_bar.py @@ -1,8 +1,8 @@ from textual.timer import Timer -from textual.widgets import Static +from textual.widgets import Label -class StatusBar(Static): +class StatusBar(Label): timer: Timer # TODO: support multiple messages -- 2.43.0