diff --git a/poezio/core/core.py b/poezio/core/core.py index 2ec71cb2..3f435aa3 100644 --- a/poezio/core/core.py +++ b/poezio/core/core.py @@ -1334,10 +1334,10 @@ class Core(object): if tab.name.startswith(room_name): tab.activate(reason=reason) - def on_user_changed_status_in_private(self, jid, msg): + def on_user_changed_status_in_private(self, jid, status): tab = self.get_tab_by_name(jid, tabs.ChatTab) if tab is not None: # display the message in private - tab.add_message(msg, typ=2) + tab.update_status(status) def close_tab(self, tab=None): """ diff --git a/poezio/core/handlers.py b/poezio/core/handlers.py index 3b7d0b46..0427a2d0 100644 --- a/poezio/core/handlers.py +++ b/poezio/core/handlers.py @@ -28,6 +28,7 @@ from poezio import xhtml from poezio import multiuserchat as muc from poezio.common import safeJID from poezio.config import config, CACHE_DIR +from poezio.core.structs import Status from poezio.contact import Resource from poezio.logger import logger from poezio.roster import roster @@ -299,6 +300,9 @@ class HandlerCore: elif not own: remote_nick = conversation.get_nick() + if not own: + conversation.last_remote_message = datetime.now() + self.core.events.trigger('conversation_msg', message, conversation) if not message['body']: return @@ -607,6 +611,7 @@ class HandlerCore: if msg and body: self.core.xmpp.send_message(mto=jid.full, mbody=msg, mtype='chat') return + tab.last_remote_message = datetime.now() self.core.events.trigger('private_msg', message, tab) body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml, tmp_dir=tmp_dir, @@ -830,6 +835,8 @@ class HandlerCore: contact.error = None self.core.events.trigger('normal_presence', presence, contact[jid.full]) tab = self.core.get_conversation_by_jid(jid, create=False) + if tab: + tab.update_status(Status(show=presence['show'], message=presence['status'])) if isinstance(self.core.current_tab(), tabs.RosterInfoTab): self.core.refresh_window() elif self.core.current_tab() == tab: diff --git a/poezio/tabs/__init__.py b/poezio/tabs/__init__.py index 55a74457..e6756088 100644 --- a/poezio/tabs/__init__.py +++ b/poezio/tabs/__init__.py @@ -1,5 +1,5 @@ from poezio.tabs.basetabs import Tab, ChatTab, GapTab, OneToOneTab -from poezio.tabs.basetabs import STATE_PRIORITY +from poezio.tabs.basetabs import STATE_PRIORITY, SHOW_NAME from poezio.tabs.rostertab import RosterInfoTab from poezio.tabs.muctab import MucTab, NS_MUC_USER from poezio.tabs.privatetab import PrivateTab diff --git a/poezio/tabs/basetabs.py b/poezio/tabs/basetabs.py index 5e753643..5dc3eecb 100644 --- a/poezio/tabs/basetabs.py +++ b/poezio/tabs/basetabs.py @@ -18,9 +18,10 @@ log = logging.getLogger(__name__) import string import time +from datetime import datetime from xml.etree import cElementTree as ET -from poezio.core.structs import Command, Completion +from poezio.core.structs import Command, Completion, Status from poezio import timed_events from poezio import windows from poezio import xhtml @@ -77,6 +78,14 @@ STATE_PRIORITY = { 'attention': 3 } +SHOW_NAME = { + 'dnd': 'busy', + 'away': 'away', + 'xa': 'not available', + 'chat': 'chatty', + '': 'available' + } + class Tab(object): plugin_commands = {} plugin_keys = {} @@ -688,6 +697,9 @@ class OneToOneTab(ChatTab): def __init__(self, core, jid=''): ChatTab.__init__(self, core, jid) + self.__status = Status("", "") + self.last_remote_message = datetime.now() + # Set to true once the first disco is done self.__initial_disco = False # change this to True or False when @@ -698,6 +710,33 @@ class OneToOneTab(ChatTab): self.remote_supports_receipts = True self.check_features() + def remote_user_color(self): + return dump_tuple(get_theme().COLOR_REMOTE_USER) + + def update_status(self, status): + old_status = self.__status + if not (old_status.show != status.show or + old_status.message != status.message): + return + self.__status = status + hide_status_change = config.get_by_tabname('hide_status_change', + safeJID(self.name).bare) + now = datetime.now() + dff = now - self.last_remote_message + if hide_status_change > -1 and dff.total_seconds() > hide_status_change: + return + + info_c = dump_tuple(get_theme().COLOR_INFORMATION_TEXT) + nick = self.get_nick() + remote = self.remote_user_color() + msg = '\x19%(color)s}%(nick)s\x19%(info)s} changed: ' + msg %= {'color': remote, 'nick': nick, 'info': info_c} + if status.message != old_status.message and status.message: + msg += 'status: %s, ' % status.message + if status.show in SHOW_NAME: + msg += 'show: %s, ' % SHOW_NAME[status.show] + self.add_message(msg[:-2], typ=2) + @property def remote_wants_chatstates(self): return self._remote_wants_chatstates diff --git a/poezio/tabs/muctab.py b/poezio/tabs/muctab.py index b8865045..f6965a75 100644 --- a/poezio/tabs/muctab.py +++ b/poezio/tabs/muctab.py @@ -17,7 +17,7 @@ import random import re from datetime import datetime -from poezio.tabs import ChatTab, Tab +from poezio.tabs import ChatTab, Tab, SHOW_NAME from poezio import common from poezio import fixes @@ -32,17 +32,9 @@ from poezio.logger import logger from poezio.roster import roster from poezio.theming import get_theme, dump_tuple from poezio.user import User -from poezio.core.structs import Completion +from poezio.core.structs import Completion, Status -SHOW_NAME = { - 'dnd': 'busy', - 'away': 'away', - 'xa': 'not available', - 'chat': 'chatty', - '': 'available' - } - NS_MUC_USER = 'http://jabber.org/protocol/muc#user' @@ -1555,7 +1547,7 @@ class MucTab(ChatTab): self._text_buffer.add_message(msg) self.core.on_user_changed_status_in_private('%s/%s' % (from_room, from_nick), - msg) + Status(show, status)) self.users.remove(user) # finally, effectively change the user status user.update(affiliation, show, status, role) diff --git a/poezio/tabs/privatetab.py b/poezio/tabs/privatetab.py index b110a092..554d4f2c 100644 --- a/poezio/tabs/privatetab.py +++ b/poezio/tabs/privatetab.py @@ -62,6 +62,12 @@ class PrivateTab(OneToOneTab): self.update_commands() self.update_keys() + def remote_user_color(self): + user = self.parent_muc.get_user_by_name(safeJID(self.name).resource) + if user: + return dump_tuple(user.color); + return super().remote_user_color() + @property def general_jid(self): return self.name