diff --git a/src/mail/app.py b/src/mail/app.py index e0bcb44..915dd9a 100644 --- a/src/mail/app.py +++ b/src/mail/app.py @@ -1002,15 +1002,15 @@ class EmailViewerApp(App): config = get_config() - # Add search results header + # Build search header label if results: header_label = f"Search: '{query}' ({len(results)} result{'s' if len(results) != 1 else ''})" else: header_label = f"Search: '{query}' - No results found" - envelopes_list.append(ListItem(GroupHeader(label=header_label))) if not results: # Clear the message viewer when no results + envelopes_list.append(ListItem(GroupHeader(label=header_label))) content_container = self.query_one(ContentContainer) content_container.clear_content() self.message_store.envelopes = [] @@ -1019,14 +1019,64 @@ class EmailViewerApp(App): return # 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.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.metadata_by_id = search_store.metadata_by_id 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": envelopes_list.append(ListItem(GroupHeader(label=item["label"]))) elif item: