diff --git a/nomadnet/Conversation.py b/nomadnet/Conversation.py index 6a117f0..e4c423d 100644 --- a/nomadnet/Conversation.py +++ b/nomadnet/Conversation.py @@ -7,6 +7,7 @@ from nomadnet.Directory import DirectoryEntry class Conversation: cached_conversations = {} + unread_conversations = {} created_callback = None aspect_filter = "lxmf.delivery" @@ -57,6 +58,16 @@ class Conversation: conversation = Conversation.cached_conversations[RNS.hexrep(source_hash, delimit=False)] conversation.scan_storage() + if not source_hash in Conversation.unread_conversations: + Conversation.unread_conversations[source_hash] = True + try: + dirname = RNS.hexrep(source_hash, delimit=False) + open(app.conversationpath + "/" + dirname + "/unread", 'a').close() + except Exception as e: + pass + + Conversation.created_callback() + return ingested_path @staticmethod @@ -70,6 +81,13 @@ class Conversation: app_data = RNS.Identity.recall_app_data(source_hash) display_name = app.directory.display_name(source_hash) + unread = False + if source_hash in Conversation.unread_conversations: + unread = True + elif os.path.isfile(app.conversationpath + "/" + dirname + "/unread"): + Conversation.unread_conversations[source_hash] = True + unread = True + if display_name == None and app_data: display_name = app_data.decode("utf-8") @@ -80,7 +98,7 @@ class Conversation: trust_level = app.directory.trust_level(source_hash, display_name) - entry = (source_hash_text, display_name, trust_level, sort_name) + entry = (source_hash_text, display_name, trust_level, sort_name, unread) conversations.append(entry) except Exception as e: @@ -114,6 +132,7 @@ class Conversation: self.source_known = False self.source_trusted = False self.source_blocked = False + self.unread = False self.__changed_callback = None @@ -143,6 +162,11 @@ class Conversation: message_path = self.messages_path + "/" + filename self.messages.append(ConversationMessage(message_path)) + new_len = len(self.messages) + + if new_len > old_len: + self.unread = True + if self.__changed_callback != None: self.__changed_callback(self) diff --git a/nomadnet/NomadNetworkApp.py b/nomadnet/NomadNetworkApp.py index b07eb4c..4b9dace 100644 --- a/nomadnet/NomadNetworkApp.py +++ b/nomadnet/NomadNetworkApp.py @@ -205,6 +205,18 @@ class NomadNetworkApp: def conversations(self): return nomadnet.Conversation.conversation_list(self) + def conversation_is_unread(self, source_hash): + if bytes.fromhex(source_hash) in nomadnet.Conversation.unread_conversations: + return True + else: + return False + + def mark_conversation_read(self, source_hash): + if bytes.fromhex(source_hash) in nomadnet.Conversation.unread_conversations: + nomadnet.Conversation.unread_conversations.pop(bytes.fromhex(source_hash)) + if os.path.isfile(self.conversationpath + "/" + source_hash + "/unread"): + os.unlink(self.conversationpath + "/" + source_hash + "/unread") + def createDefaultConfig(self): self.config = ConfigObj(__default_nomadnet_config__) self.config.filename = self.configpath diff --git a/nomadnet/ui/TextUI.py b/nomadnet/ui/TextUI.py index 52c3ca2..95040fc 100644 --- a/nomadnet/ui/TextUI.py +++ b/nomadnet/ui/TextUI.py @@ -69,6 +69,7 @@ GLYPHS = { ("arrow_d", "\\/", "\u2193", "\u2193"), ("warning", "!", "\u26a0", "\uf12a"), ("info", "i", "\u2139", "\ufb4d"), + ("unread", "N", "\u2709", "\uf003 "), ("divider1", "-", "\u2504", "\u2504"), ("peer", "P", "\U0001F464", "\uf415"), ("node", "N", "\U0001F5A5", "\uf502"), diff --git a/nomadnet/ui/textui/Conversations.py b/nomadnet/ui/textui/Conversations.py index d804c6e..be01b31 100644 --- a/nomadnet/ui/textui/Conversations.py +++ b/nomadnet/ui/textui/Conversations.py @@ -1,4 +1,5 @@ import RNS +import os import time import nomadnet import LXMF @@ -316,17 +317,43 @@ class ConversationsDisplay(): self.ilb.select_item(ilb_position) nomadnet.NomadNetworkApp.get_shared_instance().ui.loop.draw_screen() + if self.currently_displayed_conversation != None: + if self.app.conversation_is_unread(self.currently_displayed_conversation): + self.app.mark_conversation_read(self.currently_displayed_conversation) + try: + if os.path.isfile(self.app.conversationpath + "/" + self.currently_displayed_conversation + "/unread"): + os.unlink(self.app.conversationpath + "/" + self.currently_displayed_conversation + "/unread") + except Exception as e: + raise e + def display_conversation(self, sender=None, source_hash=None): + if self.currently_displayed_conversation != None: + if self.app.conversation_is_unread(self.currently_displayed_conversation): + self.app.mark_conversation_read(self.currently_displayed_conversation) + self.currently_displayed_conversation = source_hash options = self.widget.options("weight", 1-ConversationsDisplay.list_width) self.widget.contents[1] = (self.make_conversation_widget(source_hash), options) if source_hash == None: self.widget.set_focus_column(0) else: + if self.app.conversation_is_unread(source_hash): + self.app.mark_conversation_read(source_hash) + self.update_conversation_list() + self.widget.set_focus_column(1) + conversation_position = None + index = 0 + for widget in self.list_widgets: + if widget.source_hash == source_hash: + conversation_position = index + index += 1 + + if conversation_position != None: + self.ilb.select_item(conversation_position) def make_conversation_widget(self, source_hash): @@ -364,6 +391,7 @@ class ConversationsDisplay(): trust_level = conversation[2] display_name = conversation[1] source_hash = conversation[0] + unread = conversation[4] g = self.app.ui.glyphs @@ -389,11 +417,17 @@ class ConversationsDisplay(): focus_style = "list_focus_untrusted" display_text = symbol + if display_name != None and display_name != "": display_text += " "+display_name if trust_level != DirectoryEntry.TRUSTED: display_text += " <"+source_hash+">" + else: + if unread: + if source_hash != self.currently_displayed_conversation: + display_text += " "+g["unread"] + widget = ListEntry(display_text) urwid.connect_signal(widget, "click", self.display_conversation, conversation[0])