From bb5b610dff541ec67d4b4ca0d4b050f79a5c0f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 13 Aug 2026 13:46:01 -0700 Subject: [PATCH 1/5] ConversationListItem: create menu on bind --- src/ConversationList/ConversationList.vala | 2 +- .../ConversationListItem.vala | 49 +++++++------------ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/ConversationList/ConversationList.vala b/src/ConversationList/ConversationList.vala index 3656d09c1..83a648353 100644 --- a/src/ConversationList/ConversationList.vala +++ b/src/ConversationList/ConversationList.vala @@ -73,7 +73,7 @@ public class Mail.ConversationList : Gtk.Box { }); } - row.assign ((ConversationItemModel)item); + row.bind_model ((ConversationItemModel)item); row.show_all (); return row; }; diff --git a/src/ConversationList/ConversationListItem.vala b/src/ConversationList/ConversationListItem.vala index 3b495dd65..da07ef64e 100644 --- a/src/ConversationList/ConversationListItem.vala +++ b/src/ConversationList/ConversationListItem.vala @@ -33,6 +33,7 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { private Hdy.Carousel carousel; private Gtk.GestureMultiPress gesture_controller; private Gtk.EventControllerKey key_controller; + private Gtk.Menu menu; construct { status_icon = new Gtk.Image.from_icon_name ("mail-unread-symbolic", Gtk.IconSize.MENU); @@ -120,7 +121,7 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { gesture_controller.released.connect ((n_press, x, y) => { select (); - create_context_menu (x, y); + menu.popup_at_pointer (null); }); key_controller = new Gtk.EventControllerKey (this); @@ -130,7 +131,7 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { return; } - create_context_menu (); + menu.popup_at_widget (this, Gdk.Gravity.EAST, Gdk.Gravity.CENTER, null); }); carousel.page_changed.connect ((index) => { @@ -154,27 +155,27 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { }); } - public void assign (ConversationItemModel data) { - carousel.scroll_to_full (grid, 0); + public void bind_model (ConversationItemModel item_model) { + // carousel.scroll_to_full (grid, 0); - date.label = data.formatted_date; - topic.label = data.subject; + date.label = item_model.formatted_date; + topic.label = item_model.subject; var source_label_text = ""; - if (Camel.FolderInfoFlags.TYPE_SENT == (data.folder_info_flags & Camel.FOLDER_TYPE_MASK)) { - source_label_text = data.to; + if (Camel.FolderInfoFlags.TYPE_SENT == (item_model.folder_info_flags & Camel.FOLDER_TYPE_MASK)) { + source_label_text = item_model.to; } else { - source_label_text = data.from; + source_label_text = item_model.from; } source.label = GLib.Markup.escape_text (source_label_text); - tooltip_markup = GLib.Markup.printf_escaped ("%s\n%s", source_label_text, data.subject); + tooltip_markup = GLib.Markup.printf_escaped ("%s\n%s", source_label_text, item_model.subject); - uint num_messages = data.num_messages; + uint num_messages = item_model.num_messages; messages.label = num_messages > 1 ? "%u".printf (num_messages) : null; messages.visible = num_messages > 1; messages.no_show_all = num_messages <= 1; - if (data.unread) { + if (item_model.unread) { grid.get_style_context ().add_class ("unread-message"); status_icon.icon_name = "mail-unread-symbolic"; @@ -189,11 +190,11 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { status_icon.get_style_context ().remove_class (Granite.STYLE_CLASS_ACCENT); source.get_style_context ().remove_class (Granite.STYLE_CLASS_ACCENT); - if (data.replied_all || data.replied) { + if (item_model.replied_all || item_model.replied) { status_icon.icon_name = "mail-replied-symbolic"; status_icon.tooltip_text = _("Replied"); status_revealer.reveal_child = true; - } else if (data.forwarded) { + } else if (item_model.forwarded) { status_icon.icon_name = "mail-forwarded-symbolic"; status_icon.tooltip_text = _("Forwarded"); status_revealer.reveal_child = true; @@ -202,38 +203,26 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { } } - flagged_icon_revealer.reveal_child = data.flagged; - } - - private void create_context_menu (double? x = null, double? y = null) { - var item = (ConversationItemModel)model_item; + flagged_icon_revealer.reveal_child = item_model.flagged; var menu_model = new Menu (); menu_model.append (_("Move To Trash"), MainWindow.ACTION_PREFIX + MainWindow.ACTION_MOVE_TO_TRASH); - if (!item.unread) { + if (!item_model.unread) { menu_model.append (_("Mark As Unread"), MainWindow.ACTION_PREFIX + MainWindow.ACTION_MARK_UNREAD); } else { menu_model.append (_("Mark as Read"), MainWindow.ACTION_PREFIX + MainWindow.ACTION_MARK_READ); } - if (!item.flagged) { + if (!item_model.flagged) { menu_model.append (_("Star"), MainWindow.ACTION_PREFIX + MainWindow.ACTION_MARK_STAR); } else { menu_model.append (_("Unstar"), MainWindow.ACTION_PREFIX + MainWindow.ACTION_MARK_UNSTAR); } - var menu = new Gtk.Menu.from_model (menu_model) { + menu = new Gtk.Menu.from_model (menu_model) { attach_widget = this }; - menu.show_all (); - menu.popup_at_pointer (null); - - if (x == null || y == null) { - menu.popup_at_widget (this, Gdk.Gravity.EAST, Gdk.Gravity.CENTER, null); - } else { - menu.popup_at_pointer (null); - } } private class SwipeAffordance : Gtk.Box { From f1f0fb91eec4e60ee0055e7b962d4e2091e43010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 13 Aug 2026 13:48:21 -0700 Subject: [PATCH 2/5] get rid of extra scroll --- src/ConversationList/ConversationListItem.vala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ConversationList/ConversationListItem.vala b/src/ConversationList/ConversationListItem.vala index da07ef64e..5a863f0c3 100644 --- a/src/ConversationList/ConversationListItem.vala +++ b/src/ConversationList/ConversationListItem.vala @@ -156,8 +156,6 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { } public void bind_model (ConversationItemModel item_model) { - // carousel.scroll_to_full (grid, 0); - date.label = item_model.formatted_date; topic.label = item_model.subject; From 3fea81312d8f21dfce6b276ecc754652da168927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 13 Aug 2026 13:50:44 -0700 Subject: [PATCH 3/5] Use carousel prepend --- src/ConversationList/ConversationListItem.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ConversationList/ConversationListItem.vala b/src/ConversationList/ConversationListItem.vala index 5a863f0c3..0867af35e 100644 --- a/src/ConversationList/ConversationListItem.vala +++ b/src/ConversationList/ConversationListItem.vala @@ -104,8 +104,8 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { carousel = new Hdy.Carousel () { allow_scroll_wheel = false }; - carousel.add (archive_affordance); carousel.add (grid); + carousel.prepend (archive_affordance); carousel.add (trash_affordance); carousel.scroll_to (grid); From abc2941e0d2d4c5e54658616021a86373ed1e4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 13 Aug 2026 13:59:31 -0700 Subject: [PATCH 4/5] use revealer for message count --- src/ConversationList/ConversationListItem.vala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ConversationList/ConversationListItem.vala b/src/ConversationList/ConversationListItem.vala index 0867af35e..5d6ea1db9 100644 --- a/src/ConversationList/ConversationListItem.vala +++ b/src/ConversationList/ConversationListItem.vala @@ -27,6 +27,7 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { private Gtk.Label messages; private Gtk.Label source; private Gtk.Label topic; + private Gtk.Revealer message_count_revealer; private Gtk.Revealer flagged_icon_revealer; private Gtk.Revealer status_revealer; private Gtk.Grid grid; @@ -58,10 +59,12 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { messages = new Gtk.Label (null) { halign = Gtk.Align.END }; + messages.get_style_context ().add_class (Granite.STYLE_CLASS_BADGE); + messages.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT); - weak Gtk.StyleContext messages_style = messages.get_style_context (); - messages_style.add_class (Granite.STYLE_CLASS_BADGE); - messages_style.add_class (Gtk.STYLE_CLASS_FLAT); + message_count_revealer = new Gtk.Revealer () { + child = messages + }; topic = new Gtk.Label (null) { hexpand = true, @@ -89,7 +92,7 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { grid.attach (source, 1, 0, 1, 1); grid.attach (date, 2, 0, 2, 1); grid.attach (topic, 1, 1, 2, 1); - grid.attach (messages, 3, 1, 1, 1); + grid.attach (message_count_revealer, 3, 1); var archive_affordance = new SwipeAffordance ( _("Archive"), "mail-archive-symbolic", END @@ -170,8 +173,7 @@ public class Mail.ConversationListItem : VirtualizingListBoxRow { uint num_messages = item_model.num_messages; messages.label = num_messages > 1 ? "%u".printf (num_messages) : null; - messages.visible = num_messages > 1; - messages.no_show_all = num_messages <= 1; + message_count_revealer.reveal_child = num_messages > 1; if (item_model.unread) { grid.get_style_context ().add_class ("unread-message"); From c8765c31e439e586c63064cc1cc61d073b48c0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Thu, 13 Aug 2026 14:01:21 -0700 Subject: [PATCH 5/5] SPDX header --- .../ConversationListItem.vala | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/ConversationList/ConversationListItem.vala b/src/ConversationList/ConversationListItem.vala index 5d6ea1db9..7ab41ac5c 100644 --- a/src/ConversationList/ConversationListItem.vala +++ b/src/ConversationList/ConversationListItem.vala @@ -1,20 +1,6 @@ -/*- - * Copyright (c) 2017 elementary LLC. (https://elementary.io) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. +/* + * SPDX-License-Identifier: LGPL-3.0-or-later + * SPDX-FileCopyrightText: 2017-2026 elementary, Inc. (https://elementary.io) * * Authored by: Corentin Noël */