Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Braindrop ChangeLog

## Unreleased

**Released: WiP**

- Added `JumpToNavigation`, `JumpToRaindrops` and `JumpToDetails` commands
for quickly jumping between the 3 main panels.
([#201](https://github.com/davep/braindrop/pull/201))

## v1.0.0

**Released: 2025-12-16**
Expand Down
6 changes: 6 additions & 0 deletions src/braindrop/app/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
CompactMode,
Details,
Escape,
JumpToDetails,
JumpToNavigation,
JumpToRaindrops,
Logout,
Redownload,
TagOrder,
Expand All @@ -48,6 +51,9 @@
"Details",
"EditRaindrop",
"Escape",
"JumpToDetails",
"JumpToNavigation",
"JumpToRaindrops",
"Logout",
"Redownload",
"Search",
Expand Down
21 changes: 21 additions & 0 deletions src/braindrop/app/commands/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,25 @@ class VisitRaindrop(Command):
SHOW_IN_FOOTER = True


##############################################################################
class JumpToNavigation(Command):
"Move focus to the navigation pane"

BINDING_KEY = "1"


##############################################################################
class JumpToRaindrops(Command):
"Move focus to the raindrops pane"

BINDING_KEY = "2"


##############################################################################
class JumpToDetails(Command):
"Move focus to the details pane"

BINDING_KEY = "3"


### main.py ends here
6 changes: 6 additions & 0 deletions src/braindrop/app/providers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
Details,
EditRaindrop,
Escape,
JumpToDetails,
JumpToNavigation,
JumpToRaindrops,
Logout,
Redownload,
Search,
Expand Down Expand Up @@ -74,6 +77,9 @@ def commands(self) -> CommandHits:
yield TagOrder()
yield VisitLink()
yield VisitRaindrop()
yield from self.maybe(JumpToDetails)
yield from self.maybe(JumpToNavigation)
yield from self.maybe(JumpToRaindrops)


### main.py ends here
40 changes: 40 additions & 0 deletions src/braindrop/app/screens/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
Details,
EditRaindrop,
Escape,
JumpToDetails,
JumpToNavigation,
JumpToRaindrops,
Logout,
Redownload,
Search,
Expand Down Expand Up @@ -161,6 +164,9 @@ class Main(EnhancedScreen[None]):
ShowUnsorted,
ShowUntagged,
VisitLink,
JumpToDetails,
JumpToNavigation,
JumpToRaindrops,
)

BINDINGS = Command.bindings(*COMMAND_MESSAGES)
Expand Down Expand Up @@ -304,6 +310,27 @@ def populate_display(self) -> None:
self.active_collection = self._data.all
self.query_one(Navigation).highlight_collection(SpecialCollection.ALL())

def check_action(self, action: str, parameters: tuple[object, ...]) -> bool | None:
"""Check if an action is possible to perform right now.

Args:
action: The action to perform.
parameters: The parameters of the action.

Returns:
`True` if it can perform, `False` or `None` if not.
"""
if not self.is_mounted:
# Surprisingly it seems that Textual's "dynamic bindings" can
# cause this method to be called before the DOM is up and
# running. This breaks the rule of least astonishment, I'd say,
# but okay let's be defensive... (when I can come up with a nice
# little MRE I'll report it).
return True
if action == JumpToDetails.action_name():
return not self.has_class("details-hidden")
return True

@on(ShowCollection)
def command_show_collection(self, command: ShowCollection) -> None:
"""Handle the command that requests we show a collection.
Expand Down Expand Up @@ -715,5 +742,18 @@ async def action_delete_raindrop_command(self) -> None:
timeout=8,
)

def action_jump_to_navigation_command(self) -> None:
"""Jump to the navigation pane."""
self.set_focus(self.query_one(Navigation))

def action_jump_to_raindrops_command(self) -> None:
"""Jump to the raindrops pane."""
self.set_focus(self.query_one(RaindropsView))

def action_jump_to_details_command(self) -> None:
"""Jump to the details pane."""
if not self.has_class("details-hidden"):
self.set_focus(self.query_one(RaindropDetails))


### main.py ends here
Loading
Loading