def __init__(self, width: int, view: Any) -> None: self.width = width self.view = view self.user_search = PanelSearchBox(self, 'SEARCH_PEOPLE', self.update_user_list) self.view.user_search = self.user_search search_box = urwid.LineBox( self.user_search, tlcorner='─', tline='', lline='', trcorner='─', blcorner='─', rline='', bline='─', brcorner='─' ) self.allow_update_user_list = True self.search_lock = threading.Lock() super().__init__(self.users_view(), header=search_box)
def __init__(self, streams_btn_list: List[Any], view: Any) -> None: self.view = view self.log = urwid.SimpleFocusListWalker(streams_btn_list) self.streams_btn_list = streams_btn_list self.focus_index_before_search = 0 list_box = urwid.ListBox(self.log) self.stream_search_box = PanelSearchBox(self, 'SEARCH_STREAMS', self.update_streams) super().__init__(list_box, header=urwid.LineBox( self.stream_search_box, tlcorner='─', tline='', lline='', trcorner='─', blcorner='─', rline='', bline='─', brcorner='─' )) self.search_lock = threading.Lock()
def __init__(self, topics_btn_list: List[Any], view: Any, stream_button: Any) -> None: self.view = view self.log = urwid.SimpleFocusListWalker(topics_btn_list) self.topics_btn_list = topics_btn_list self.stream_button = stream_button self.focus_index_before_search = 0 self.list_box = urwid.ListBox(self.log) self.topic_search_box = PanelSearchBox(self, 'SEARCH_TOPICS', self.update_topics) self.header_list = urwid.Pile([self.stream_button, urwid.Divider('─'), self.topic_search_box]) super().__init__(self.list_box, header=urwid.LineBox( self.header_list, tlcorner='─', tline='', lline='', trcorner='─', blcorner='─', rline='', bline='─', brcorner='─' )) self.search_lock = threading.Lock()
def __init__(self, streams_btn_list: List[Any], view: Any) -> None: self.view = view self.log = urwid.SimpleFocusListWalker(streams_btn_list) self.streams_btn_list = streams_btn_list list_box = urwid.ListBox(self.log) self.stream_search_box = PanelSearchBox(self, 'SEARCH_STREAMS') urwid.connect_signal(self.stream_search_box, 'change', self.update_streams) super(StreamsView, self).__init__(list_box, header=urwid.LineBox( self.stream_search_box, tlcorner=u'─', tline=u'', lline=u'', trcorner=u'─', blcorner=u'─', rline=u'', bline=u'─', brcorner=u'─' )) self.search_lock = threading.Lock()
def __init__(self, width: int, view: Any) -> None: self.width = width self.view = view self.user_search = PanelSearchBox(self, 'SEARCH_PEOPLE') urwid.connect_signal(self.user_search, 'change', self.update_user_list) self.view.user_search = self.user_search search_box = urwid.LineBox( self.user_search, tlcorner=u'─', tline=u'', lline=u'', trcorner=u'─', blcorner=u'─', rline=u'', bline=u'─', brcorner=u'─' ) self.allow_update_user_list = True self.search_lock = threading.Lock() super(RightColumnView, self).__init__(self.users_view(), header=search_box)
class RightColumnView(urwid.Frame): """ Displays the users list on the right side of the app. """ def __init__(self, width: int, view: Any) -> None: self.width = width self.view = view self.user_search = PanelSearchBox(self, 'SEARCH_PEOPLE', self.update_user_list) self.view.user_search = self.user_search search_box = urwid.LineBox(self.user_search, tlcorner='─', tline='', lline='', trcorner='─', blcorner='─', rline='', bline='─', brcorner='─') self.allow_update_user_list = True self.search_lock = threading.Lock() super().__init__(self.users_view(), header=search_box) @asynch def update_user_list(self, search_box: Any = None, new_text: str = "", user_list: Any = None) -> None: assert ((user_list is None and search_box is not None) or (user_list is not None and search_box is None and new_text == "")) if not self.view.controller.editor_mode and not user_list: return if not self.allow_update_user_list and new_text == "": return # wait for any previously started search to finish to avoid # displaying wrong user list. with self.search_lock: if user_list: self.view.users = user_list users = self.view.users.copy() if new_text: users_display = [ user for user in users if match_user(user, new_text) ] else: users_display = users self.body = self.users_view(users_display) self.set_body(self.body) self.view.controller.update_screen() def users_view(self, users: Any = None) -> Any: reset_default_view_users = False if users is None: users = self.view.users.copy() reset_default_view_users = True users_btn_list = list() for user in users: # Only include `inactive` users in search result. if (user['status'] == 'inactive' and not self.view.controller.editor_mode): continue unread_count = (self.view.model.unread_counts['unread_pms'].get( user['user_id'], 0)) users_btn_list.append( UserButton(user, controller=self.view.controller, view=self.view, width=self.width, color='user_' + user['status'], count=unread_count)) user_w = UsersView(users_btn_list) # Donot reset them while searching. if reset_default_view_users: self.users_btn_list = users_btn_list self.view.user_w = user_w return user_w def keypress(self, size: urwid_Size, key: str) -> Optional[str]: if is_command_key('SEARCH_PEOPLE', key): self.allow_update_user_list = False self.set_focus('header') return key elif is_command_key('GO_BACK', key): self.user_search.reset_search_text() self.allow_update_user_list = True self.body = UsersView(self.users_btn_list) self.set_body(self.body) self.set_focus('body') self.view.controller.update_screen() return key elif is_command_key('GO_LEFT', key): self.view.show_right_panel(visible=False) return super().keypress(size, key)
class TopicsView(urwid.Frame): def __init__(self, topics_btn_list: List[Any], view: Any, stream_button: Any) -> None: self.view = view self.log = urwid.SimpleFocusListWalker(topics_btn_list) self.topics_btn_list = topics_btn_list self.stream_button = stream_button self.focus_index_before_search = 0 self.list_box = urwid.ListBox(self.log) self.topic_search_box = PanelSearchBox(self, 'SEARCH_TOPICS', self.update_topics) self.header_list = urwid.Pile( [self.stream_button, urwid.Divider('─'), self.topic_search_box]) super().__init__(self.list_box, header=urwid.LineBox(self.header_list, tlcorner='─', tline='', lline='', trcorner='─', blcorner='─', rline='', bline='─', brcorner='─')) self.search_lock = threading.Lock() @asynch def update_topics(self, search_box: Any, new_text: str) -> None: if not self.view.controller.editor_mode: return # wait for any previously started search to finish to avoid # displaying wrong topics list. with self.search_lock: new_text = new_text.lower() topics_to_display = [ topic for topic in self.topics_btn_list.copy() if new_text in topic.topic_name.lower() ] self.log.clear() self.log.extend(topics_to_display) self.view.controller.update_screen() def update_topics_list(self, stream_id: int, topic_name: str, sender_id: int) -> None: # More recent topics are found towards the beginning # of the list. for topic_iterator, topic_button in enumerate(self.log): if topic_button.topic_name == topic_name: self.log.insert(0, self.log.pop(topic_iterator)) self.list_box.set_focus_valign('bottom') if sender_id == self.view.model.user_id: self.list_box.set_focus(0) return # No previous topics with same topic names are found # hence we create a new topic button for it. new_topic_button = TopicButton(stream_id, topic_name, self.view.controller, self.view.LEFT_WIDTH, 0) self.log.insert(0, new_topic_button) self.list_box.set_focus_valign('bottom') if sender_id == self.view.model.user_id: self.list_box.set_focus(0) def mouse_event(self, size: urwid_Size, event: str, button: int, col: int, row: int, focus: bool) -> bool: if event == 'mouse press': if button == 4: self.keypress(size, 'up') return True elif button == 5: self.keypress(size, 'down') return True return super().mouse_event(size, event, button, col, row, focus) def keypress(self, size: urwid_Size, key: str) -> Optional[str]: if is_command_key('TOGGLE_TOPIC', key): # Exit topic view self.view.left_panel.contents[1] = (self.view.left_panel.stream_v, self.view.left_panel.options( height_type="weight")) self.view.left_panel.is_in_topic_view = False elif is_command_key('GO_RIGHT', key): self.view.show_left_panel(visible=False) self.view.body.focus_col = 1 if is_command_key('SEARCH_TOPICS', key): self.set_focus('header') self.header_list.set_focus(2) return key elif is_command_key('GO_BACK', key): self.topic_search_box.reset_search_text() self.log.clear() self.log.extend(self.topics_btn_list) self.set_focus('body') self.log.set_focus(self.focus_index_before_search) self.view.controller.update_screen() return key return_value = super().keypress(size, key) _, self.focus_index_before_search = self.log.get_focus() return return_value
class StreamsView(urwid.Frame): def __init__(self, streams_btn_list: List[Any], view: Any) -> None: self.view = view self.log = urwid.SimpleFocusListWalker(streams_btn_list) self.streams_btn_list = streams_btn_list self.focus_index_before_search = 0 list_box = urwid.ListBox(self.log) self.stream_search_box = PanelSearchBox(self, 'SEARCH_STREAMS', self.update_streams) super().__init__(list_box, header=urwid.LineBox(self.stream_search_box, tlcorner='─', tline='', lline='', trcorner='─', blcorner='─', rline='', bline='─', brcorner='─')) self.search_lock = threading.Lock() @asynch def update_streams(self, search_box: Any, new_text: str) -> None: if not self.view.controller.editor_mode: return # wait for any previously started search to finish to avoid # displaying wrong stream list. with self.search_lock: new_text = new_text.lower() streams_display = [ stream for stream in self.streams_btn_list.copy() if new_text in stream.stream_name.lower() ] self.log.clear() self.log.extend(streams_display) self.view.controller.update_screen() def mouse_event(self, size: urwid_Size, event: str, button: int, col: int, row: int, focus: bool) -> bool: if event == 'mouse press': if button == 4: self.keypress(size, 'up') return True elif button == 5: self.keypress(size, 'down') return True return super().mouse_event(size, event, button, col, row, focus) def keypress(self, size: urwid_Size, key: str) -> Optional[str]: if is_command_key('SEARCH_STREAMS', key): self.set_focus('header') return key elif is_command_key('GO_BACK', key): self.stream_search_box.reset_search_text() self.log.clear() self.log.extend(self.streams_btn_list) self.set_focus('body') self.log.set_focus(self.focus_index_before_search) self.view.controller.update_screen() return key return_value = super().keypress(size, key) _, self.focus_index_before_search = self.log.get_focus() return return_value
def panel_search_box(self, mocker): # X is the return from keys_for_command("UNTESTED_TOKEN") mocker.patch(BOXES + ".keys_for_command", return_value="X") panel_view = mocker.Mock() update_func = mocker.Mock() return PanelSearchBox(panel_view, "UNTESTED_TOKEN", update_func)
class StreamsView(urwid.Frame): def __init__(self, streams_btn_list: List[Any], view: Any) -> None: self.view = view self.log = urwid.SimpleFocusListWalker(streams_btn_list) self.streams_btn_list = streams_btn_list self.focus_index_before_search = 0 list_box = urwid.ListBox(self.log) self.stream_search_box = PanelSearchBox(self, 'SEARCH_STREAMS', self.update_streams) super().__init__(list_box, header=urwid.LineBox( self.stream_search_box, tlcorner='─', tline='', lline='', trcorner='─', blcorner='─', rline='', bline='─', brcorner='─' )) self.search_lock = threading.Lock() @asynch def update_streams(self, search_box: Any, new_text: str) -> None: if not self.view.controller.is_in_editor_mode(): return # wait for any previously started search to finish to avoid # displaying wrong stream list. with self.search_lock: stream_buttons = [ (stream, stream.stream_name) for stream in self.streams_btn_list.copy() ] streams_display = match_stream(stream_buttons, new_text, self.view.pinned_streams)[0] # Add a divider to separate pinned streams from the rest. pinned_stream_names = [ stream[0] for stream in self.view.pinned_streams ] first_unpinned_index = len(streams_display) for index, stream in enumerate(streams_display): if stream.stream_name not in pinned_stream_names: first_unpinned_index = index break if first_unpinned_index not in [0, len(streams_display)]: # Do not add a divider when it is already present. This can # happen when new_text=''. if not isinstance(streams_display[first_unpinned_index], StreamsViewDivider): streams_display.insert(first_unpinned_index, StreamsViewDivider()) self.log.clear() self.log.extend(streams_display) self.view.controller.update_screen() def mouse_event(self, size: urwid_Size, event: str, button: int, col: int, row: int, focus: bool) -> bool: if event == 'mouse press': if button == 4: self.keypress(size, 'up') return True elif button == 5: self.keypress(size, 'down') return True return super().mouse_event(size, event, button, col, row, focus) def keypress(self, size: urwid_Size, key: str) -> Optional[str]: if is_command_key('SEARCH_STREAMS', key): self.set_focus('header') return key elif is_command_key('GO_BACK', key): self.stream_search_box.reset_search_text() self.log.clear() self.log.extend(self.streams_btn_list) self.set_focus('body') self.log.set_focus(self.focus_index_before_search) self.view.controller.update_screen() return key return_value = super().keypress(size, key) _, self.focus_index_before_search = self.log.get_focus() return return_value