From 1287135ebbe8420de44ab73ce6a553b17067dfdb Mon Sep 17 00:00:00 2001 From: fiaxh Date: Sat, 14 Sep 2019 16:08:08 +0200 Subject: [PATCH] Improve conversation unread status detection --- libdino/src/service/chat_interaction.vala | 37 +++++++++++++++++++ .../counterpart_interaction_manager.vala | 2 + .../conversation_selector_row.vala | 9 ++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/libdino/src/service/chat_interaction.vala b/libdino/src/service/chat_interaction.vala index de352e95..b200916a 100644 --- a/libdino/src/service/chat_interaction.vala +++ b/libdino/src/service/chat_interaction.vala @@ -31,6 +31,43 @@ public class ChatInteraction : StreamInteractionModule, Object { stream_interactor.get_module(MessageProcessor.IDENTITY).message_sent.connect(on_message_sent); } + public bool has_unread(Conversation conversation) { + ContentItem? last_content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_latest(conversation); + if (last_content_item == null) return false; + + MessageItem? message_item = last_content_item as MessageItem; + if (message_item != null) { + Message last_message = message_item.message; + + // We are the message sender + if (last_message.from.equals_bare(conversation.account.bare_jid)) return false; + // We read up to the message + if (conversation.read_up_to != null && last_message.equals(conversation.read_up_to)) return false; + + return true; + } + + FileItem? file_item = last_content_item as FileItem; + if (file_item != null) { + FileTransfer file_transfer = file_item.file_transfer; + + // We are the file sender + if (file_transfer.from.equals_bare(conversation.account.bare_jid)) return false; + + if (file_transfer.provider == 0) { + // HTTP file transfer: Check if the associated message is the last one + Message? message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_id(int.parse(file_transfer.info), conversation); + if (message == null) return false; + if (message.equals(conversation.read_up_to)) return false; + } + if (file_transfer.provider == 1) { + if (file_transfer.state == FileTransfer.State.COMPLETE) return false; + } + return true; + } + return false; + } + public bool is_active_focus(Conversation? conversation = null) { if (conversation != null) { return focus_in && conversation.equals(this.selected_conversation); diff --git a/libdino/src/service/counterpart_interaction_manager.vala b/libdino/src/service/counterpart_interaction_manager.vala index 7da65650..5ff74eb7 100644 --- a/libdino/src/service/counterpart_interaction_manager.vala +++ b/libdino/src/service/counterpart_interaction_manager.vala @@ -89,6 +89,8 @@ public class CounterpartInteractionManager : StreamInteractionModule, Object { if (conversation == null) return; Entities.Message? message = stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(stanza_id, conversation); if (message == null) return; + // Don't move read marker backwards because we get old info from another client + if (conversation.read_up_to.local_time.compare(message.local_time) > 0) return; conversation.read_up_to = message; } else { // We received a marker from someone else. Search the respective message and mark it. diff --git a/main/src/ui/conversation_selector/conversation_selector_row.vala b/main/src/ui/conversation_selector/conversation_selector_row.vala index 8d601309..3696f6da 100644 --- a/main/src/ui/conversation_selector/conversation_selector_row.vala +++ b/main/src/ui/conversation_selector/conversation_selector_row.vala @@ -166,13 +166,10 @@ public class ConversationSelectorRow : ListBoxRow { } protected void update_read() { - MessageItem? message_item = last_content_item as MessageItem; - if (message_item == null) return; - Message last_message = message_item.message; + bool current_read_status = !stream_interactor.get_module(ChatInteraction.IDENTITY).has_unread(conversation); + if (read == current_read_status) return; + read = current_read_status; - bool read_was = read; - read = last_message == null || (conversation.read_up_to != null && last_message.equals(conversation.read_up_to)); - if (read == read_was) return; if (read) { name_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD))); time_label.attributes.filter((attr) => attr.equal(attr_weight_new(Weight.BOLD)));