diff options
-rw-r--r-- | data/default_config.cfg | 10 | ||||
-rw-r--r-- | data/themes/dark.py | 2 | ||||
-rw-r--r-- | doc/source/configuration.rst | 16 | ||||
-rw-r--r-- | src/core/core.py | 7 | ||||
-rw-r--r-- | src/core/handlers.py | 35 | ||||
-rw-r--r-- | src/tabs/basetabs.py | 18 | ||||
-rw-r--r-- | src/theming.py | 2 |
7 files changed, 89 insertions, 1 deletions
diff --git a/data/default_config.cfg b/data/default_config.cfg index 0e5ecf4f..10ed9ddb 100644 --- a/data/default_config.cfg +++ b/data/default_config.cfg @@ -250,6 +250,16 @@ plugins_conf_dir = # with no activity, set to true. Else, set to false show_inactive_tabs = true +# If you want to highlight tabs where the contact is typing +# possible values: +# - direct: one-to-one chats +# - private: private chats in chatrooms +# - conversation: chats with contacts or other JIDs +# - muc: chatrooms +# - true: all chat tabs +# - false or anything else: no highlighting +show_composing_tabs = direct + # If you want to show the tab names in the bottom tab bar, set this to true show_tab_names = false diff --git a/data/themes/dark.py b/data/themes/dark.py index ba7208a4..33fc5f37 100644 --- a/data/themes/dark.py +++ b/data/themes/dark.py @@ -17,6 +17,7 @@ class DarkTheme(theming.Theme): COLOR_TAB_NORMAL = (-1, 236) COLOR_TAB_NONEMPTY = (-1, 236) COLOR_TAB_CURRENT = (-1, 16) + COLOR_TAB_COMPOSING = (3, 236) COLOR_TAB_NEW_MESSAGE = (3, 236) COLOR_TAB_HIGHLIGHT = (1, 236) COLOR_TAB_ATTENTION = (6, 236) @@ -36,6 +37,7 @@ class DarkTheme(theming.Theme): COLOR_VERTICAL_TAB_NORMAL = (240, -1) COLOR_VERTICAL_TAB_CURRENT = (-1, 236) COLOR_VERTICAL_TAB_NEW_MESSAGE = (3, -1) + COLOR_VERTICAL_TAB_COMPOSING = (3, -1) COLOR_VERTICAL_TAB_HIGHLIGHT = (1, -1) COLOR_VERTICAL_TAB_PRIVATE = (2, -1) COLOR_VERTICAL_TAB_ATTENTION = (6, -1) diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index 9a642883..4d490665 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -439,6 +439,22 @@ or the way messages are displayed. This directory will be created at startup if it doesn't exist + show_composing_tabs + + **Default value:** ``direct`` + + Highlight tabs where the last activity was a "composing" chat state, + which means the contact is currently typing. + + Possible values are: + + - ``direct``: highlight only in one-to-one chats (equiv. of private & conversation) + - ``private``: highlight only in private chats inside chatrooms + - ``conversation``: highlight only in chats with contacts or direct JIDs + - ``muc``: highlight only in chatrooms + - ``true``: highlight all possible tabs (equiv. of muc & private & conversation) + - ``false`` or any other value: don’t highlight anything + user_list_sort **Default value:** ``desc`` diff --git a/src/core/core.py b/src/core/core.py index b41bb1a4..00d7b9a6 100644 --- a/src/core/core.py +++ b/src/core/core.py @@ -1228,6 +1228,13 @@ class Core(object): Refresh the window containing the tab list """ self.current_tab().refresh_tab_win() + self.refresh_input() + self.doupdate() + + def refresh_input(self): + """ + Refresh the input if it exists + """ if self.current_tab().input: self.current_tab().input.refresh() self.doupdate() diff --git a/src/core/handlers.py b/src/core/handlers.py index b0256246..bc43cc28 100644 --- a/src/core/handlers.py +++ b/src/core/handlers.py @@ -565,6 +565,9 @@ def on_chatstate_normal_conversation(self, message, state): if tab == self.current_tab(): tab.refresh_info_header() self.doupdate() + else: + composing_tab_state(tab, state) + self.refresh_tab_win() return True def on_chatstate_private_conversation(self, message, state): @@ -580,6 +583,9 @@ def on_chatstate_private_conversation(self, message, state): if tab == self.current_tab(): tab.refresh_info_header() self.doupdate() + else: + composing_tab_state(tab, state) + self.refresh_tab_win() return True def on_chatstate_groupchat_conversation(self, message, state): @@ -596,6 +602,9 @@ def on_chatstate_groupchat_conversation(self, message, state): tab.user_win.refresh(tab.users) tab.input.refresh() self.doupdate() + else: + composing_tab_state(tab, state) + self.refresh_tab_win() ### subscription-related handlers ### @@ -1052,3 +1061,29 @@ def validate_ssl(self, pem): self.information(_('Unable to write in the config file'), 'Error') +def composing_tab_state(tab, state): + """ + Set a tab state to or from the "composing" state + according to the config and the current tab state + """ + if isinstance(tab, tabs.MucTab): + values = ('true', 'muc') + elif isinstance(tab, tabs.PrivateTab): + values = ('true', 'direct', 'private') + elif isinstance(tab, tabs.ConversationTab): + values = ('true', 'direct', 'conversation') + else: + return # should not happen + + show = config.get('show_composing_tabs', 'direct') + show = show in values + + if tab.state != 'composing' and state == 'composing': + if show: + if tabs.STATE_PRIORITY[tab.state] > tabs.STATE_PRIORITY[state]: + return + tab.save_state() + tab.state = 'composing' + elif tab.state == 'composing' and state != 'composing': + tab.restore_state() + diff --git a/src/tabs/basetabs.py b/src/tabs/basetabs.py index d4704b79..94b38062 100644 --- a/src/tabs/basetabs.py +++ b/src/tabs/basetabs.py @@ -47,6 +47,7 @@ STATE_COLORS = { 'nonempty': lambda: get_theme().COLOR_TAB_NONEMPTY, 'joined': lambda: get_theme().COLOR_TAB_JOINED, 'message': lambda: get_theme().COLOR_TAB_NEW_MESSAGE, + 'composing': lambda: get_theme().COLOR_TAB_COMPOSING, 'highlight': lambda: get_theme().COLOR_TAB_HIGHLIGHT, 'private': lambda: get_theme().COLOR_TAB_PRIVATE, 'normal': lambda: get_theme().COLOR_TAB_NORMAL, @@ -59,6 +60,7 @@ VERTICAL_STATE_COLORS = { 'nonempty': lambda: get_theme().COLOR_VERTICAL_TAB_NONEMPTY, 'joined': lambda: get_theme().COLOR_VERTICAL_TAB_JOINED, 'message': lambda: get_theme().COLOR_VERTICAL_TAB_NEW_MESSAGE, + 'composing': lambda: get_theme().COLOR_VERTICAL_TAB_COMPOSING, 'highlight': lambda: get_theme().COLOR_VERTICAL_TAB_HIGHLIGHT, 'private': lambda: get_theme().COLOR_VERTICAL_TAB_PRIVATE, 'normal': lambda: get_theme().COLOR_VERTICAL_TAB_NORMAL, @@ -75,6 +77,7 @@ STATE_PRIORITY = { 'disconnected': 0, 'nonempty': 0.1, 'scrolled': 0.5, + 'composing': 0.9, 'message': 1, 'joined': 1, 'highlight': 2, @@ -90,9 +93,9 @@ class Tab(object): def __init__(self): self.input = None self._state = 'normal' + self._prev_state = None self.need_resize = False - self.need_resize = False self.key_func = {} # each tab should add their keys in there # and use them in on_input self.commands = {} # and their own commands @@ -161,6 +164,19 @@ class Tab(object): log.debug('Did not set state because disconnected tabs remain visible') else: self._state = value + if self._state == 'current': + self._prev_state = None + + def save_state(self): + if self._state != 'composing': + self._prev_state = self._state + + def restore_state(self): + if self.state == 'composing' and self._prev_state: + self._state = self._prev_state + self._prev_state = None + elif not self._prev_state: + self._state = 'normal' @staticmethod def resize(scr): diff --git a/src/theming.py b/src/theming.py index 8576a2a0..10844956 100644 --- a/src/theming.py +++ b/src/theming.py @@ -205,6 +205,7 @@ class Theme(object): COLOR_TAB_SCROLLED = (5, 4) COLOR_TAB_JOINED = (82, 4) COLOR_TAB_CURRENT = (7, 6) + COLOR_TAB_COMPOSING = (7, 5) COLOR_TAB_NEW_MESSAGE = (7, 5) COLOR_TAB_HIGHLIGHT = (7, 3) COLOR_TAB_PRIVATE = (7, 2) @@ -217,6 +218,7 @@ class Theme(object): COLOR_VERTICAL_TAB_SCROLLED = (66, -1) COLOR_VERTICAL_TAB_CURRENT = (7, 4) COLOR_VERTICAL_TAB_NEW_MESSAGE = (5, -1) + COLOR_VERTICAL_TAB_COMPOSING = (5, -1) COLOR_VERTICAL_TAB_HIGHLIGHT = (3, -1) COLOR_VERTICAL_TAB_PRIVATE = (2, -1) COLOR_VERTICAL_TAB_ATTENTION = (1, -1) |