Fix IndexError when selecting search results
The search header was being added to ListView but not to message_store.envelopes, causing an index mismatch when marking messages as read. Now the search header is included in the envelopes list and metadata_by_id is properly updated so indices align between ListView and the message store.
This commit is contained in:
@@ -1002,15 +1002,15 @@ class EmailViewerApp(App):
|
|||||||
|
|
||||||
config = get_config()
|
config = get_config()
|
||||||
|
|
||||||
# Add search results header
|
# Build search header label
|
||||||
if results:
|
if results:
|
||||||
header_label = f"Search: '{query}' ({len(results)} result{'s' if len(results) != 1 else ''})"
|
header_label = f"Search: '{query}' ({len(results)} result{'s' if len(results) != 1 else ''})"
|
||||||
else:
|
else:
|
||||||
header_label = f"Search: '{query}' - No results found"
|
header_label = f"Search: '{query}' - No results found"
|
||||||
envelopes_list.append(ListItem(GroupHeader(label=header_label)))
|
|
||||||
|
|
||||||
if not results:
|
if not results:
|
||||||
# Clear the message viewer when no results
|
# Clear the message viewer when no results
|
||||||
|
envelopes_list.append(ListItem(GroupHeader(label=header_label)))
|
||||||
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 = []
|
||||||
@@ -1019,14 +1019,64 @@ class EmailViewerApp(App):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Create a temporary message store for search results
|
# Create a temporary message store for search results
|
||||||
|
# We need to include the search header in the envelopes so indices match
|
||||||
search_store = MessageStore()
|
search_store = MessageStore()
|
||||||
search_store.load(results, self.sort_order_ascending)
|
|
||||||
|
|
||||||
# Store for navigation (replace main store temporarily)
|
# Manually build envelopes list with search header first
|
||||||
|
# so that ListView indices match message_store.envelopes indices
|
||||||
|
grouped_envelopes = [{"type": "header", "label": header_label}]
|
||||||
|
|
||||||
|
# Sort results by date
|
||||||
|
sorted_results = sorted(
|
||||||
|
results,
|
||||||
|
key=lambda x: x.get("date", ""),
|
||||||
|
reverse=not self.sort_order_ascending,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Group by month and build metadata
|
||||||
|
months: Dict[str, bool] = {}
|
||||||
|
for envelope in sorted_results:
|
||||||
|
if "id" not in envelope:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Extract date and determine month group
|
||||||
|
date_str = envelope.get("date", "")
|
||||||
|
try:
|
||||||
|
date = datetime.fromisoformat(date_str.replace("Z", "+00:00"))
|
||||||
|
month_key = date.strftime("%B %Y")
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
month_key = "Unknown Date"
|
||||||
|
|
||||||
|
# Add month header if this is a new month
|
||||||
|
if month_key not in months:
|
||||||
|
months[month_key] = True
|
||||||
|
grouped_envelopes.append({"type": "header", "label": month_key})
|
||||||
|
|
||||||
|
# Add the envelope
|
||||||
|
grouped_envelopes.append(envelope)
|
||||||
|
|
||||||
|
# Store metadata for quick access (index matches grouped_envelopes)
|
||||||
|
envelope_id = int(envelope["id"])
|
||||||
|
search_store.metadata_by_id[envelope_id] = {
|
||||||
|
"id": envelope_id,
|
||||||
|
"subject": envelope.get("subject", ""),
|
||||||
|
"from": envelope.get("from", {}),
|
||||||
|
"to": envelope.get("to", {}),
|
||||||
|
"cc": envelope.get("cc", {}),
|
||||||
|
"date": date_str,
|
||||||
|
"index": len(grouped_envelopes) - 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
search_store.envelopes = grouped_envelopes
|
||||||
|
search_store.total_messages = len(search_store.metadata_by_id)
|
||||||
|
|
||||||
|
# Store for navigation (replace main store)
|
||||||
self.message_store.envelopes = search_store.envelopes
|
self.message_store.envelopes = search_store.envelopes
|
||||||
|
self.message_store.metadata_by_id = search_store.metadata_by_id
|
||||||
self.total_messages = len(results)
|
self.total_messages = len(results)
|
||||||
|
|
||||||
for item in search_store.envelopes:
|
# Build ListView to match envelopes list exactly
|
||||||
|
for item in self.message_store.envelopes:
|
||||||
if item and item.get("type") == "header":
|
if item and item.get("type") == "header":
|
||||||
envelopes_list.append(ListItem(GroupHeader(label=item["label"])))
|
envelopes_list.append(ListItem(GroupHeader(label=item["label"])))
|
||||||
elif item:
|
elif item:
|
||||||
|
|||||||
Reference in New Issue
Block a user