diff --git a/src/tabs/muctab.py b/src/tabs/muctab.py index bb0f51d9..6c961874 100644 --- a/src/tabs/muctab.py +++ b/src/tabs/muctab.py @@ -10,12 +10,12 @@ user list, and updates private tabs when necessary. import logging log = logging.getLogger(__name__) +import bisect import curses import os import random import re from datetime import datetime -from functools import reduce from . import ChatTab, Tab @@ -1089,7 +1089,7 @@ class MucTab(ChatTab): and typ != "unavailable"): new_user = User(from_nick, affiliation, show, status, role, jid, deterministic, color) - self.users.append(new_user) + bisect.insort_left(self.users, new_user) self.core.events.trigger('muc_join', presence, self) if '110' in status_codes or self.own_nick == from_nick: # second part of the condition is a workaround for old @@ -1200,7 +1200,7 @@ class MucTab(ChatTab): affiliation, role, show, status) if self.core.current_tab() is self: self.text_win.refresh() - self.user_win.refresh(self.users) + self.user_win.refresh_if_changed(self.users) self.info_header.refresh(self, self.text_win) self.input.refresh() self.core.doupdate() @@ -1230,7 +1230,7 @@ class MucTab(ChatTab): deterministic = config.get_by_tabname('deterministic_nick_colors', self.name) user = User(from_nick, affiliation, show, status, role, jid, deterministic, color) - self.users.append(user) + bisect.insort_left(self.users, user) hide_exit_join = config.get_by_tabname('hide_exit_join', self.general_jid) if hide_exit_join != 0: @@ -1277,6 +1277,8 @@ class MucTab(ChatTab): self.name) user.change_color(color, deterministic) user.change_nick(new_nick) + self.users.remove(user) + bisect.insort_left(self.users, user) if config.get_by_tabname('display_user_color_in_join_part', self.general_jid): @@ -1698,8 +1700,7 @@ class MucTab(ChatTab): return color nick_color_aliases = config.get_by_tabname('nick_color_aliases', self.name) if nick_color_aliases: - nick_alias = re.sub('^_*', '', nick) - nick_alias = re.sub('_*$', '', nick_alias) + nick_alias = re.sub('^_*(.*?)_*$', '\\1', nick) color = config.get_by_tabname(nick_alias, 'muc_colors') return color diff --git a/src/windows/muc.py b/src/windows/muc.py index c4e8df6e..84775787 100644 --- a/src/windows/muc.py +++ b/src/windows/muc.py @@ -13,10 +13,17 @@ import poopt from config import config from theming import to_curses_attr, get_theme +def userlist_to_cache(userlist): + result = [] + for user in userlist: + result.append((user.nick, user.status, user.chatstate, user.affiliation, user.role)) + return result + class UserList(Win): def __init__(self): Win.__init__(self) self.pos = 0 + self.cache = [] def scroll_up(self): self.pos += self.height-1 @@ -32,25 +39,36 @@ class UserList(Win): def draw_plus(self, y): self.addstr(y, self.width-2, '++', to_curses_attr(get_theme().COLOR_MORE_INDICATOR)) + + def refresh_if_changed(self, users): + old = self.cache + new = userlist_to_cache(users[self.pos:self.pos+self.height]) + if len(old) != len(new): + self.cache = new + self.refresh(users) + return + for i in range(len(old)): + if old[i] != new[i]: + self.cache = new + self.refresh(users) + def refresh(self, users): log.debug('Refresh: %s', self.__class__.__name__) if config.get('hide_user_list'): return # do not refresh if this win is hidden. + if len(users) < self.height: + self.pos = 0 + elif self.pos >= len(users) - self.height and self.pos != 0: + self.pos = len(users) - self.height self._win.erase() asc_sort = (config.get('user_list_sort').lower() == 'asc') if asc_sort: y, x = self._win.getmaxyx() y -= 1 - users = sorted(users) else: y = 0 - users = sorted(users) - if len(users) < self.height: - self.pos = 0 - elif self.pos >= len(users) - self.height and self.pos != 0: - self.pos = len(users) - self.height - for user in users[self.pos:]: + for user in users[self.pos:self.pos+self.height]: self.draw_role_affiliation(y, user) self.draw_status_chatstate(y, user) self.addstr(y, 2,