diff options
Diffstat (limited to 'main/src/ui')
-rw-r--r-- | main/src/ui/conversation_content_view/conversation_view.vala | 3 | ||||
-rw-r--r-- | main/src/ui/conversation_content_view/unread_indicator_populator.vala | 88 |
2 files changed, 91 insertions, 0 deletions
diff --git a/main/src/ui/conversation_content_view/conversation_view.vala b/main/src/ui/conversation_content_view/conversation_view.vala index 33cb3b22..519aa01f 100644 --- a/main/src/ui/conversation_content_view/conversation_view.vala +++ b/main/src/ui/conversation_content_view/conversation_view.vala @@ -87,6 +87,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug Application app = GLib.Application.get_default() as Application; app.plugin_registry.register_conversation_addition_populator(new ChatStatePopulator(stream_interactor)); app.plugin_registry.register_conversation_addition_populator(new DateSeparatorPopulator(stream_interactor)); + app.plugin_registry.register_conversation_addition_populator(new UnreadIndicatorPopulator(stream_interactor)); // Rather than connecting to the leave event of the main_event_box directly, // we connect to the parent event box that also wraps the overlaying message_menu_box. @@ -382,6 +383,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug foreach (ContentMetaItem item in items) { do_insert_item(item); } + Application app = GLib.Application.get_default() as Application; foreach (Plugins.NotificationPopulator populator in app.plugin_registry.notification_populators) { populator.init(conversation, this, Plugins.WidgetType.GTK4); @@ -398,6 +400,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug return; } } + do_insert_item(item); } diff --git a/main/src/ui/conversation_content_view/unread_indicator_populator.vala b/main/src/ui/conversation_content_view/unread_indicator_populator.vala new file mode 100644 index 00000000..79aa7576 --- /dev/null +++ b/main/src/ui/conversation_content_view/unread_indicator_populator.vala @@ -0,0 +1,88 @@ +using Gee; +using Gtk; + +using Dino.Entities; +using Xmpp; + +namespace Dino.Ui.ConversationSummary { + + class UnreadIndicatorPopulator : Plugins.ConversationItemPopulator, Plugins.ConversationAdditionPopulator, Object { + + public string id { get { return "unread_indicator"; } } + + private StreamInteractor stream_interactor; + private Conversation? current_conversation; + private UnreadIndicatorItem? unread_indicator = null; + Plugins.ConversationItemCollection item_collection = null; + + public UnreadIndicatorPopulator(StreamInteractor stream_interactor) { + this.stream_interactor = stream_interactor; + + stream_interactor.get_module(ChatInteraction.IDENTITY).focused_out.connect(() => { + update_unread_indicator(); + }); + + stream_interactor.get_module(ContentItemStore.IDENTITY).new_item.connect(() => { + if (!stream_interactor.get_module(ChatInteraction.IDENTITY).is_active_focus(current_conversation)) { + update_unread_indicator(); + } + }); + } + + private void update_unread_indicator() { + if (current_conversation == null) return; + + ContentItem? read_up_to_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item_by_id(current_conversation, current_conversation.read_up_to_item); + int current_num_unread = stream_interactor.get_module(ChatInteraction.IDENTITY).get_num_unread(current_conversation); + if (current_num_unread == 0 && unread_indicator != null) { + item_collection.remove_item(unread_indicator); + unread_indicator = null; + } + + if (read_up_to_item != null && current_num_unread > 0) { + if (unread_indicator != null) { + item_collection.remove_item(unread_indicator); + } + + unread_indicator = new UnreadIndicatorItem(read_up_to_item); + item_collection.insert_item(unread_indicator); + } + } + + public void init(Conversation conversation, Plugins.ConversationItemCollection item_collection, Plugins.WidgetType type) { + current_conversation = conversation; + this.item_collection = item_collection; + update_unread_indicator(); + } + + public void close(Conversation conversation) { } + + public void populate_timespan(Conversation conversation, DateTime after, DateTime before) { } + } + + private class UnreadIndicatorItem : Plugins.MetaConversationItem { + public UnreadIndicatorItem(ContentItem after_item) { + this.time = after_item.time; + this.secondary_sort_indicator = int.MAX; + } + + public override Object? get_widget(Plugins.ConversationItemWidgetInterface outer, Plugins.WidgetType type) { + Box box = new Box(Orientation.HORIZONTAL, 10) { hexpand=true }; + box.get_style_context().add_class("dino-unread-line"); + + Separator sep = new Separator(Orientation.HORIZONTAL) { valign=Align.CENTER, hexpand=true }; + box.append(sep); + + Label label = new Label(_("New")) { halign=Align.END, hexpand=false }; + label.attributes = new Pango.AttrList(); + label.attributes.insert(Pango.attr_weight_new(Pango.Weight.BOLD)); + box.append(label); + + return box; + } + + public override Gee.List<Plugins.MessageAction>? get_item_actions(Plugins.WidgetType type) { + return null; + } + } +} |