Skip to content

Commit

Permalink
🔀 Merge pull request #121 from davep/better-raindrops-messaging
Browse files Browse the repository at this point in the history
Tidy up the way the highlighted raindrop is handled
  • Loading branch information
davep authored Jan 24, 2025
2 parents 8a3c29a + eac4447 commit 65192f7
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 26 deletions.
24 changes: 16 additions & 8 deletions src/braindrop/app/screens/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ class Main(Screen[None]):
active_collection: var[Raindrops] = var(Raindrops, always_update=True)
"""The currently-active collection."""

highlighted_raindrop: var[Raindrop | None] = var(None)
"""The currently-highlighted raindrop."""

def __init__(self, api: API) -> None:
"""Initialise the main screen.
Expand Down Expand Up @@ -205,7 +208,9 @@ def compose(self) -> ComposeResult:
yield RaindropsView(classes="focus").data_bind(
raindrops=Main.active_collection
)
yield RaindropDetails(classes="focus")
yield RaindropDetails(classes="focus").data_bind(
raindrop=Main.highlighted_raindrop
)
yield Footer()

@work
Expand Down Expand Up @@ -367,12 +372,15 @@ def command_show_tagged(self, command: ShowTagged) -> None:
"""
self.active_collection = self.active_collection.tagged(command.tag)

@on(RaindropsView.OptionHighlighted)
def update_details(self) -> None:
"""Update the details panel to show the current raindrop."""
self.query_one(RaindropDetails).raindrop = self.query_one(
RaindropsView
).highlighted_raindrop
@on(RaindropsView.Empty)
def deselect_raindrop(self) -> None:
"""Handle that there is no selected Raindrop."""
self.highlighted_raindrop = None

@on(RaindropsView.Highlighted)
def highlight_raindrop(self, message: RaindropsView.Highlighted) -> None:
"""Handle the highlighted raindrop changing."""
self.highlighted_raindrop = message.raindrop

@on(Redownload)
def action_redownload_command(self) -> None:
Expand Down Expand Up @@ -502,7 +510,7 @@ def _current_raindrop(self, action: str) -> Raindrop | None:
Returns:
The highlighted raindrop, or `None`.
"""
if (raindrop := self.query_one(RaindropsView).highlighted_raindrop) is None:
if (raindrop := self.highlighted_raindrop) is None:
self.notify(
f"No Raindrop is highlighted, there is nothing to {action}!",
title="No Raindrop",
Expand Down
43 changes: 25 additions & 18 deletions src/braindrop/app/widgets/raindrops_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

##############################################################################
# Python imports.
from dataclasses import dataclass
from typing import Final, cast

##############################################################################
Expand All @@ -17,7 +18,9 @@

##############################################################################
# Textual imports.
from textual import on
from textual.binding import Binding
from textual.message import Message
from textual.reactive import var
from textual.widgets.option_list import Option, OptionDoesNotExist

Expand Down Expand Up @@ -140,6 +143,9 @@ class RaindropsView(OptionListEx):
compact: var[bool] = var(False)
"""Toggle to say if we should use a compact view or not."""

class Empty(Message):
"""A message sent if the view becomes empty."""

def _add_raindrops(self) -> None:
"""Add the current raindrops to the display."""
with self.preserved_highlight:
Expand All @@ -149,6 +155,8 @@ def _add_raindrops(self) -> None:
for raindrop in self.raindrops
]
)
if not self.option_count:
self.post_message(self.Empty())

def watch_data(self) -> None:
"""React to the data being changed."""
Expand All @@ -162,24 +170,23 @@ def watch_compact(self) -> None:
"""React to the compact setting being toggled."""
self._add_raindrops()

@property
def highlighted_raindrop(self) -> Raindrop | None:
"""The currently-highlighted Raindrop, if there is one, or `None`."""
if self.highlighted is not None:
return cast(
RaindropView, self.get_option_at_index(self.highlighted)
).raindrop
return None

@highlighted_raindrop.setter
def highlighted_raindrop(self, raindrop: Raindrop | None) -> None:
if raindrop is None:
self.highlighted = None
else:
try:
self.highlighted = self.get_option_index(RaindropView.id_of(raindrop))
except OptionDoesNotExist:
pass
@dataclass
class Highlighted(Message):
"""Message sent when a new Raindrop is highlighted."""

raindrop: Raindrop
"""The raindrop that was highlighted."""

@on(OptionListEx.OptionHighlighted)
def raindrop_highlighted(self, message: OptionListEx.OptionHighlighted) -> None:
"""Handle a raindrop being highlighted.
Args:
message: The message to handle.
"""
message.stop()
assert isinstance(message.option, RaindropView)
self.post_message(self.Highlighted(message.option.raindrop))

def action_visit(self) -> None:
"""Action that visits the currently-selected raindrop link, if there is one."""
Expand Down

0 comments on commit 65192f7

Please sign in to comment.