Example #1
0
 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)
Example #2
0
 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()
Example #3
0
 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()
Example #4
0
 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()
Example #5
0
 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)
Example #6
0
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)
Example #7
0
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
Example #8
0
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
Example #9
0
 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)
Example #10
0
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