Add unread indicator
Co-authored-by: Alexandre Jousset <mid@gtmp.org> Co-authored-by: Aidan Epstein <aidan@jmad.org>
This commit is contained in:
parent
7e3cedaf3f
commit
4cc7e076e6
|
@ -192,6 +192,7 @@ SOURCES
|
||||||
src/ui/conversation_content_view/quote_widget.vala
|
src/ui/conversation_content_view/quote_widget.vala
|
||||||
src/ui/conversation_content_view/reactions_widget.vala
|
src/ui/conversation_content_view/reactions_widget.vala
|
||||||
src/ui/conversation_content_view/subscription_notification.vala
|
src/ui/conversation_content_view/subscription_notification.vala
|
||||||
|
src/ui/conversation_content_view/unread_indicator_populator.vala
|
||||||
|
|
||||||
src/ui/chat_input/chat_input_controller.vala
|
src/ui/chat_input/chat_input_controller.vala
|
||||||
src/ui/chat_input/chat_text_view.vala
|
src/ui/chat_input/chat_text_view.vala
|
||||||
|
|
|
@ -282,6 +282,13 @@ window.dino-main .dino-chatinput-button button:checked:backdrop {
|
||||||
color: alpha(@theme_unfocused_selected_bg_color, 0.8);
|
color: alpha(@theme_unfocused_selected_bg_color, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dino-unread-line label {
|
||||||
|
color: @theme_selected_bg_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dino-unread-line separator {
|
||||||
|
background-color: @theme_selected_bg_color;
|
||||||
|
}
|
||||||
|
|
||||||
.dino-chatinput,
|
.dino-chatinput,
|
||||||
.dino-chatinput textview,
|
.dino-chatinput textview,
|
||||||
|
|
|
@ -53,6 +53,7 @@ sources = files(
|
||||||
'src/ui/conversation_content_view/quote_widget.vala',
|
'src/ui/conversation_content_view/quote_widget.vala',
|
||||||
'src/ui/conversation_content_view/reactions_widget.vala',
|
'src/ui/conversation_content_view/reactions_widget.vala',
|
||||||
'src/ui/conversation_content_view/subscription_notification.vala',
|
'src/ui/conversation_content_view/subscription_notification.vala',
|
||||||
|
'src/ui/conversation_content_view/unread_indicator_populator.vala',
|
||||||
'src/ui/conversation_details.vala',
|
'src/ui/conversation_details.vala',
|
||||||
'src/ui/conversation_list_titlebar.vala',
|
'src/ui/conversation_list_titlebar.vala',
|
||||||
'src/ui/conversation_selector/conversation_selector.vala',
|
'src/ui/conversation_selector/conversation_selector.vala',
|
||||||
|
|
|
@ -87,6 +87,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
|
||||||
Application app = GLib.Application.get_default() as Application;
|
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 ChatStatePopulator(stream_interactor));
|
||||||
app.plugin_registry.register_conversation_addition_populator(new DateSeparatorPopulator(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,
|
// 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.
|
// 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) {
|
foreach (ContentMetaItem item in items) {
|
||||||
do_insert_item(item);
|
do_insert_item(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
Application app = GLib.Application.get_default() as Application;
|
Application app = GLib.Application.get_default() as Application;
|
||||||
foreach (Plugins.NotificationPopulator populator in app.plugin_registry.notification_populators) {
|
foreach (Plugins.NotificationPopulator populator in app.plugin_registry.notification_populators) {
|
||||||
populator.init(conversation, this, Plugins.WidgetType.GTK4);
|
populator.init(conversation, this, Plugins.WidgetType.GTK4);
|
||||||
|
@ -398,6 +400,7 @@ public class ConversationView : Widget, Plugins.ConversationItemCollection, Plug
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_insert_item(item);
|
do_insert_item(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue