Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions tests/ui/test_ui_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
from zulipterminal.ui_tools.views import (
AboutView, HelpView, LeftColumnView, MessageView, MiddleColumnView,
ModListWalker, MsgInfoView, PopUpConfirmationView, PopUpView,
RightColumnView, StreamInfoView, StreamsView, TopicsView, UsersView,
RightColumnView, StreamInfoView, StreamsView, StreamsViewDivider,
TopicsView, UsersView,
)
from zulipterminal.version import MINIMUM_SUPPORTED_SERVER_VERSION, ZT_VERSION

Expand Down Expand Up @@ -392,6 +393,15 @@ def test_read_message_last_unread_message_focused(self, mocker,
[message_fixture['id']])


class TestStreamsViewDivider:
def test_init(self):
streams_view_divider = StreamsViewDivider()

assert isinstance(streams_view_divider, Divider)
assert streams_view_divider.stream_id == -1
assert streams_view_divider.stream_name == ''


class TestStreamsView:

@pytest.fixture
Expand All @@ -412,6 +422,7 @@ def test_init(self, mocker, stream_view):
stream_view, 'SEARCH_STREAMS', stream_view.update_streams)

@pytest.mark.parametrize('new_text, expected_log, to_pin', [
# NOTE: '' represents StreamsViewDivider's stream name.
('f', ['fan', 'FOO', 'foo', 'FOOBAR'], []),
('bar', ['bar'], []),
('foo', ['FOO', 'foo', 'FOOBAR'], []),
Expand All @@ -420,8 +431,10 @@ def test_init(self, mocker, stream_view):
('here', ['test here'], []),
('test here', ['test here'], []),
# With 'foo' pinned.
('f', ['foo', 'fan', 'FOO', 'FOOBAR'], [['foo'], ]),
('FOO', ['foo', 'FOO', 'FOOBAR'], [['foo'], ]),
('f', ['foo', '', 'fan', 'FOO', 'FOOBAR'], [['foo'], ]),
('FOO', ['foo', '', 'FOO', 'FOOBAR'], [['foo'], ]),
# With 'bar' pinned.
('bar', ['bar'], [['bar'], ]),
])
def test_update_streams(self, mocker, stream_view, new_text, expected_log,
to_pin):
Expand Down Expand Up @@ -1107,13 +1120,13 @@ def test_streams_view(self, mocker, streams, pinned, width=40):
stream_button = mocker.patch(VIEWS + '.StreamButton')
stream_view = mocker.patch(VIEWS + '.StreamsView')
line_box = mocker.patch(VIEWS + '.urwid.LineBox')
divider = mocker.patch(VIEWS + '.urwid.Divider')
divider = mocker.patch(VIEWS + '.StreamsViewDivider')
mocker.patch(STREAMBUTTON + ".mark_muted")

left_col_view = LeftColumnView(width, self.view)

if pinned:
divider.assert_called_once_with('-')
assert divider.called
else:
divider.assert_not_called()

Expand Down
40 changes: 32 additions & 8 deletions zulipterminal/ui_tools/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,18 @@ def read_message(self, index: int=-1) -> None:
self.model.mark_message_ids_as_read(read_msg_ids)


class StreamsViewDivider(urwid.Divider):
"""
A custom urwid.Divider to visually separate pinned and unpinned streams.
"""
def __init__(self) -> None:
# FIXME: Necessary since the divider is treated as a StreamButton.
# NOTE: This is specifically for stream search to work correctly.
self.stream_id = -1
self.stream_name = ''
super().__init__(div_char='-')


class StreamsView(urwid.Frame):
def __init__(self, streams_btn_list: List[Any], view: Any) -> None:
self.view = view
Expand Down Expand Up @@ -275,6 +287,25 @@ def update_streams(self, search_box: Any, new_text: str) -> None:
]
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()
Expand Down Expand Up @@ -696,14 +727,7 @@ def streams_view(self) -> Any:
) for stream in self.view.pinned_streams]

if len(streams_btn_list):
unpinned_divider = urwid.Divider("-")

# FIXME Necessary since the divider is treated as a StreamButton
# NOTE: This is specifically for stream search to work correctly
unpinned_divider.stream_id = -1
unpinned_divider.stream_name = ''

streams_btn_list += [unpinned_divider]
streams_btn_list += [StreamsViewDivider()]

streams_btn_list += [
StreamButton(
Expand Down