Skip to content

Commit 59b9ab9

Browse files
rsashanksrdeotarse
andcommitted
views: Add TopicInfoView to show pop up menu to change topic settings.
Tests added. Co-authored-by: Shivam Deotarse <[email protected]>
1 parent 6b7eb6b commit 59b9ab9

File tree

2 files changed

+109
-2
lines changed

2 files changed

+109
-2
lines changed

tests/ui_tools/test_popups.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pytest_mock import MockerFixture
77
from urwid import Columns, Pile, Text, Widget
88

9-
from zulipterminal.api_types import Message
9+
from zulipterminal.api_types import RESOLVED_TOPIC_PREFIX, Message
1010
from zulipterminal.config.keys import is_command_key, keys_for_command
1111
from zulipterminal.config.ui_mappings import EDIT_MODE_CAPTIONS
1212
from zulipterminal.helper import CustomProfileData, TidiedUserInfo
@@ -26,6 +26,7 @@
2626
PopUpView,
2727
StreamInfoView,
2828
StreamMembersView,
29+
TopicInfoView,
2930
UserInfoView,
3031
)
3132
from zulipterminal.urwid_types import urwid_Size
@@ -1604,6 +1605,52 @@ def test_checkbox_toggle_visual_notification(
16041605
toggle_visual_notify_status.assert_called_once_with(stream_id)
16051606

16061607

1608+
class TestTopicInfoView:
1609+
@pytest.fixture(autouse=True)
1610+
def mock_external_classes(
1611+
self, mocker: MockerFixture, general_stream: Dict[str, Any], topics: List[str]
1612+
) -> None:
1613+
self.controller = mocker.Mock()
1614+
1615+
mocker.patch.object(
1616+
self.controller, "maximum_popup_dimensions", return_value=(64, 64)
1617+
)
1618+
mocker.patch(LISTWALKER, return_value=[])
1619+
self.stream_id = general_stream["stream_id"]
1620+
self.topic = topics[0]
1621+
self.controller.model.stream_dict = {self.stream_id: general_stream}
1622+
1623+
self.topic_info_view = TopicInfoView(
1624+
self.controller, self.stream_id, self.topic
1625+
)
1626+
1627+
@pytest.mark.parametrize(
1628+
"topic_name, expected_topic_button_label",
1629+
[
1630+
("hi!", "Resolve Topic"),
1631+
(f"{RESOLVED_TOPIC_PREFIX}" + "hi!", "Unresolve Topic"),
1632+
],
1633+
)
1634+
def test_topic_button_label(
1635+
self, topic_name: str, expected_topic_button_label: str
1636+
) -> None:
1637+
topic_info_view = TopicInfoView(self.controller, self.stream_id, topic_name)
1638+
assert (
1639+
topic_info_view.resolve_topic_setting_button_label
1640+
== expected_topic_button_label
1641+
)
1642+
1643+
def test_toggle_resolve_status(self) -> None:
1644+
resolve_button = self.topic_info_view.widgets[-1]
1645+
resolve_button._emit("click")
1646+
1647+
self.controller.model.toggle_topic_resolve_status.assert_called_once_with(
1648+
stream_id=self.stream_id, topic_name=self.topic
1649+
)
1650+
1651+
self.controller.exit_popup.assert_called_once()
1652+
1653+
16071654
class TestStreamMembersView:
16081655
@pytest.fixture(autouse=True)
16091656
def mock_external_classes(self, mocker: MockerFixture) -> None:

zulipterminal/ui_tools/views.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import urwid
1111
from typing_extensions import Literal
1212

13-
from zulipterminal.api_types import EditPropagateMode, Message
13+
from zulipterminal.api_types import RESOLVED_TOPIC_PREFIX, EditPropagateMode, Message
1414
from zulipterminal.config.keys import (
1515
HELP_CATEGORIES,
1616
KEY_BINDINGS,
@@ -25,6 +25,7 @@
2525
COLUMN_TITLE_BAR_LINE,
2626
PINNED_STREAMS_DIVIDER,
2727
SECTION_DIVIDER_LINE,
28+
STREAM_TOPIC_SEPARATOR,
2829
)
2930
from zulipterminal.config.ui_mappings import (
3031
BOT_TYPE_BY_ID,
@@ -1569,6 +1570,65 @@ def keypress(self, size: urwid_Size, key: str) -> str:
15691570
return super().keypress(size, key)
15701571

15711572

1573+
class TopicInfoView(PopUpView):
1574+
def __init__(self, controller: Any, stream_id: int, topic: str) -> None:
1575+
self.stream_id = stream_id
1576+
self.controller = controller
1577+
stream = controller.model.stream_dict[stream_id]
1578+
self.topic_name = topic
1579+
stream_name = stream["name"]
1580+
1581+
title = f"{stream_name} {STREAM_TOPIC_SEPARATOR} {self.topic_name}"
1582+
1583+
topic_info_content: PopUpViewTableContent = []
1584+
1585+
popup_width, column_widths = self.calculate_table_widths(
1586+
topic_info_content, len(title)
1587+
)
1588+
1589+
if self.topic_name.startswith(RESOLVED_TOPIC_PREFIX):
1590+
self.resolve_topic_setting_button_label = "Unresolve Topic"
1591+
else:
1592+
self.resolve_topic_setting_button_label = "Resolve Topic"
1593+
resolve_topic_setting = urwid.Button(
1594+
self.resolve_topic_setting_button_label,
1595+
self.toggle_resolve_status,
1596+
)
1597+
1598+
curs_pos = len(self.resolve_topic_setting_button_label) + 1
1599+
# This shifts the cursor present over the first character of
1600+
# resolve_topic_button_setting label to last character + 1 so that it isn't
1601+
# visible
1602+
1603+
resolve_topic_setting._w = urwid.AttrMap(
1604+
urwid.SelectableIcon(
1605+
self.resolve_topic_setting_button_label, cursor_position=curs_pos
1606+
),
1607+
None,
1608+
"selected",
1609+
)
1610+
1611+
# Manual because calculate_table_widths does not support buttons.
1612+
# Add 4 to button label to accommodate the buttons itself.
1613+
popup_width = max(
1614+
popup_width,
1615+
len(resolve_topic_setting.label) + 4,
1616+
)
1617+
1618+
self.widgets = self.make_table_with_categories(
1619+
topic_info_content, column_widths
1620+
)
1621+
1622+
self.widgets.append(resolve_topic_setting)
1623+
super().__init__(controller, self.widgets, "TOPIC_INFO", popup_width, title)
1624+
1625+
def toggle_resolve_status(self, args: Any) -> None:
1626+
self.controller.model.toggle_topic_resolve_status(
1627+
stream_id=self.stream_id, topic_name=self.topic_name
1628+
)
1629+
self.controller.exit_popup()
1630+
1631+
15721632
class MsgInfoView(PopUpView):
15731633
def __init__(
15741634
self,

0 commit comments

Comments
 (0)