Fix search stability and improve Escape key behavior
- Add bounds check in _mark_message_as_read to prevent IndexError - Clear metadata_by_id when search returns no results - Escape now focuses search input when in search mode instead of exiting - Add focus_input() method to SearchPanel
This commit is contained in:
@@ -273,6 +273,12 @@ class EmailViewerApp(App):
|
|||||||
|
|
||||||
async def _mark_message_as_read(self, message_id: int, index: int) -> None:
|
async def _mark_message_as_read(self, message_id: int, index: int) -> None:
|
||||||
"""Mark a message as read and update the UI."""
|
"""Mark a message as read and update the UI."""
|
||||||
|
# Skip if message_id is invalid or index is out of bounds
|
||||||
|
if message_id <= 0:
|
||||||
|
return
|
||||||
|
if index < 0 or index >= len(self.message_store.envelopes):
|
||||||
|
return
|
||||||
|
|
||||||
# Check if already read
|
# Check if already read
|
||||||
envelope_data = self.message_store.envelopes[index]
|
envelope_data = self.message_store.envelopes[index]
|
||||||
if envelope_data and envelope_data.get("type") != "header":
|
if envelope_data and envelope_data.get("type") != "header":
|
||||||
@@ -885,32 +891,18 @@ class EmailViewerApp(App):
|
|||||||
self._update_list_view_subtitle()
|
self._update_list_view_subtitle()
|
||||||
|
|
||||||
def action_clear_selection(self) -> None:
|
def action_clear_selection(self) -> None:
|
||||||
"""Clear all selected messages and exit search mode."""
|
"""Clear all selected messages or focus search input if in search mode."""
|
||||||
|
# If in search mode, focus the search input instead of exiting
|
||||||
|
if self.search_mode:
|
||||||
|
search_panel = self.query_one("#search_panel", SearchPanel)
|
||||||
|
search_panel.focus_input()
|
||||||
|
return
|
||||||
|
|
||||||
if self.selected_messages:
|
if self.selected_messages:
|
||||||
self.selected_messages.clear()
|
self.selected_messages.clear()
|
||||||
self.refresh_list_view_items() # Refresh all items to uncheck checkboxes
|
self.refresh_list_view_items() # Refresh all items to uncheck checkboxes
|
||||||
self._update_list_view_subtitle()
|
self._update_list_view_subtitle()
|
||||||
|
|
||||||
# Exit search mode if active
|
|
||||||
if self.search_mode:
|
|
||||||
search_panel = self.query_one("#search_panel", SearchPanel)
|
|
||||||
search_panel.hide()
|
|
||||||
self.search_mode = False
|
|
||||||
self.search_query = ""
|
|
||||||
|
|
||||||
# Restore cached envelopes
|
|
||||||
if self._cached_envelopes:
|
|
||||||
self.message_store.envelopes = self._cached_envelopes
|
|
||||||
self._cached_envelopes = []
|
|
||||||
self._populate_list_view()
|
|
||||||
|
|
||||||
# Restore envelope list title
|
|
||||||
sort_indicator = "↑" if self.sort_order_ascending else "↓"
|
|
||||||
self.query_one(
|
|
||||||
"#envelopes_list"
|
|
||||||
).border_title = f"1️⃣ Emails {sort_indicator}"
|
|
||||||
self._update_list_view_subtitle()
|
|
||||||
|
|
||||||
def action_oldest(self) -> None:
|
def action_oldest(self) -> None:
|
||||||
self.fetch_envelopes() if self.reload_needed else None
|
self.fetch_envelopes() if self.reload_needed else None
|
||||||
self.show_message(self.message_store.get_oldest_id())
|
self.show_message(self.message_store.get_oldest_id())
|
||||||
@@ -1017,6 +1009,7 @@ class EmailViewerApp(App):
|
|||||||
content_container = self.query_one(ContentContainer)
|
content_container = self.query_one(ContentContainer)
|
||||||
content_container.clear_content()
|
content_container.clear_content()
|
||||||
self.message_store.envelopes = []
|
self.message_store.envelopes = []
|
||||||
|
self.message_store.metadata_by_id = {}
|
||||||
self.total_messages = 0
|
self.total_messages = 0
|
||||||
self.current_message_id = 0
|
self.current_message_id = 0
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -216,6 +216,11 @@ class SearchPanel(Widget):
|
|||||||
self._cancel_debounce()
|
self._cancel_debounce()
|
||||||
self.result_count = -1
|
self.result_count = -1
|
||||||
|
|
||||||
|
def focus_input(self) -> None:
|
||||||
|
"""Focus the search input field."""
|
||||||
|
input_widget = self.query_one("#search-input", Input)
|
||||||
|
input_widget.focus()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_visible(self) -> bool:
|
def is_visible(self) -> bool:
|
||||||
"""Check if the panel is visible."""
|
"""Check if the panel is visible."""
|
||||||
|
|||||||
Reference in New Issue
Block a user