Skip to content

Commit c734d2a

Browse files
committed
core/views: Stack inner popups, add support for exiting all popups.
Support 2 functions. - Exiting the current popup - goes back to the previous popup. - Exiting all popups - clears all popups. Why stack popups? Currently, we create a new popup even when closing the uppermost popups. With stacking, we can re-use the popups. This allows us to not pass the entire data for creating the inner popups to the outer popups. Currently, the only popup that opens other popups is the MsgInfoView. Affected widgets: EditHistoryView, FullRenderedMsgView, FullRawMsgView. Updated them to use the newly added functions to exit popups. Hotkey behavior (from the widget): - Press Esc or respective command -> go to MsgInfoView popup - Press i from the widget -> close all popups (EXIT_POPUP command) By adding new keypress handling to their parent PopupView, we can pass their respective commands without having to implement custom keypress handlers. Tests updated. Renamed tests: - test_keypress_show_msg_info -> test_keypress_exit_to_msg_info. - test_keypress_exit_popup -> test_keypress_exit_all_popups.
1 parent 15a7c86 commit c734d2a

File tree

3 files changed

+34
-65
lines changed

3 files changed

+34
-65
lines changed

tests/ui_tools/test_popups.py

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -520,14 +520,14 @@ def test_init(self, msg_box: MessageBox) -> None:
520520
assert self.full_rendered_message.footer.widget_list == msg_box.footer
521521

522522
@pytest.mark.parametrize("key", keys_for_command("MSG_INFO"))
523-
def test_keypress_exit_popup(
523+
def test_keypress_exit_all_popups(
524524
self, key: str, widget_size: Callable[[Widget], urwid_Size]
525525
) -> None:
526526
size = widget_size(self.full_rendered_message)
527527

528528
self.full_rendered_message.keypress(size, key)
529529

530-
assert self.controller.exit_popup.called
530+
assert self.controller.exit_all_popups.called
531531

532532
def test_keypress_exit_popup_invalid_key(
533533
self, widget_size: Callable[[Widget], urwid_Size]
@@ -546,19 +546,14 @@ def test_keypress_exit_popup_invalid_key(
546546
*keys_for_command("EXIT_POPUP"),
547547
},
548548
)
549-
def test_keypress_show_msg_info(
549+
def test_keypress_exit_to_msg_info(
550550
self, key: str, widget_size: Callable[[Widget], urwid_Size]
551551
) -> None:
552552
size = widget_size(self.full_rendered_message)
553553

554554
self.full_rendered_message.keypress(size, key)
555555

556-
self.controller.show_msg_info.assert_called_once_with(
557-
msg=self.message,
558-
topic_links=OrderedDict(),
559-
message_links=OrderedDict(),
560-
time_mentions=list(),
561-
)
556+
assert self.controller.exit_popup.called
562557

563558

564559
class TestFullRawMsgView:
@@ -596,14 +591,14 @@ def test_init(self, msg_box: MessageBox) -> None:
596591
assert self.full_raw_message.footer.widget_list == msg_box.footer
597592

598593
@pytest.mark.parametrize("key", keys_for_command("MSG_INFO"))
599-
def test_keypress_exit_popup(
594+
def test_keypress_exit_all_popups(
600595
self, key: str, widget_size: Callable[[Widget], urwid_Size]
601596
) -> None:
602597
size = widget_size(self.full_raw_message)
603598

604599
self.full_raw_message.keypress(size, key)
605600

606-
assert self.controller.exit_popup.called
601+
assert self.controller.exit_all_popups.called
607602

608603
def test_keypress_exit_popup_invalid_key(
609604
self, widget_size: Callable[[Widget], urwid_Size]
@@ -622,19 +617,14 @@ def test_keypress_exit_popup_invalid_key(
622617
*keys_for_command("EXIT_POPUP"),
623618
},
624619
)
625-
def test_keypress_show_msg_info(
620+
def test_keypress_exit_to_msg_info(
626621
self, key: str, widget_size: Callable[[Widget], urwid_Size]
627622
) -> None:
628623
size = widget_size(self.full_raw_message)
629624

630625
self.full_raw_message.keypress(size, key)
631626

632-
self.controller.show_msg_info.assert_called_once_with(
633-
msg=self.message,
634-
topic_links=OrderedDict(),
635-
message_links=OrderedDict(),
636-
time_mentions=list(),
637-
)
627+
assert self.controller.exit_popup.called
638628

639629

640630
class TestEditHistoryView:
@@ -671,14 +661,14 @@ def test_init(self) -> None:
671661
)
672662

673663
@pytest.mark.parametrize("key", keys_for_command("MSG_INFO"))
674-
def test_keypress_exit_popup(
664+
def test_keypress_exit_all_popups(
675665
self, key: str, widget_size: Callable[[Widget], urwid_Size]
676666
) -> None:
677667
size = widget_size(self.edit_history_view)
678668

679669
self.edit_history_view.keypress(size, key)
680670

681-
assert self.controller.exit_popup.called
671+
assert self.controller.exit_all_popups.called
682672

683673
def test_keypress_exit_popup_invalid_key(
684674
self, widget_size: Callable[[Widget], urwid_Size]
@@ -700,12 +690,7 @@ def test_keypress_show_msg_info(
700690

701691
self.edit_history_view.keypress(size, key)
702692

703-
self.controller.show_msg_info.assert_called_once_with(
704-
msg=self.message,
705-
topic_links=OrderedDict(),
706-
message_links=OrderedDict(),
707-
time_mentions=list(),
708-
)
693+
assert self.controller.exit_popup.called
709694

710695
@pytest.mark.parametrize(
711696
"snapshot",

zulipterminal/core.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def __init__(
8686
self.notify_enabled = notify
8787
self.maximum_footlinks = maximum_footlinks
8888
self.editor_command = editor_command
89+
self.popup_stack: List[urwid.Widget] = []
8990

9091
self.debug_path = debug_path
9192

@@ -226,6 +227,8 @@ def clamp(n: int, minn: int, maxn: int) -> int:
226227
return max_popup_cols, max_popup_rows
227228

228229
def show_pop_up(self, to_show: Any, style: str) -> None:
230+
self.popup_stack.append(self.loop.widget)
231+
229232
text = urwid.Text(to_show.title, align="center")
230233
title_map = urwid.AttrMap(urwid.Filler(text), style)
231234
title_box_adapter = urwid.BoxAdapter(title_map, height=1)
@@ -249,6 +252,10 @@ def is_any_popup_open(self) -> bool:
249252
return isinstance(self.loop.widget, urwid.Overlay)
250253

251254
def exit_popup(self) -> None:
255+
self.loop.widget = self.popup_stack.pop()
256+
257+
def exit_all_popups(self) -> None:
258+
self.popup_stack.clear()
252259
self.loop.widget = self.view
253260

254261
def show_help(self) -> None:

zulipterminal/ui_tools/views.py

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -959,12 +959,14 @@ def __init__(
959959
title: str,
960960
header: Optional[Any] = None,
961961
footer: Optional[Any] = None,
962+
command_full_exit: Optional[str] = None,
962963
) -> None:
963964
self.controller = controller
964965
self.command = command
965966
self.title = title
966967
self.log = urwid.SimpleFocusListWalker(body)
967968
self.body = urwid.ListBox(self.log)
969+
self.command_full_exit = command_full_exit
968970

969971
max_cols, max_rows = controller.maximum_popup_dimensions()
970972

@@ -1060,7 +1062,8 @@ def make_table_with_categories(
10601062
def keypress(self, size: urwid_Size, key: str) -> str:
10611063
if is_command_key("EXIT_POPUP", key) or is_command_key(self.command, key):
10621064
self.controller.exit_popup()
1063-
1065+
elif self.command_full_exit and is_command_key(self.command_full_exit, key):
1066+
self.controller.exit_all_popups()
10641067
return super().keypress(size, key)
10651068

10661069

@@ -1831,7 +1834,14 @@ def __init__(
18311834
]
18321835
widgets.append(urwid.Text(feedback, align="center"))
18331836

1834-
super().__init__(controller, widgets, "MSG_INFO", width, title)
1837+
super().__init__(
1838+
controller,
1839+
widgets,
1840+
"EDIT_HISTORY",
1841+
width,
1842+
title,
1843+
command_full_exit="MSG_INFO",
1844+
)
18351845

18361846
def _make_edit_block(self, snapshot: Dict[str, Any], tag: EditHistoryTag) -> Any:
18371847
content = snapshot["content"]
@@ -1896,17 +1906,6 @@ def _get_author_prefix(snapshot: Dict[str, Any], tag: EditHistoryTag) -> str:
18961906

18971907
return author_prefix
18981908

1899-
def keypress(self, size: urwid_Size, key: str) -> str:
1900-
if is_command_key("EXIT_POPUP", key) or is_command_key("EDIT_HISTORY", key):
1901-
self.controller.show_msg_info(
1902-
msg=self.message,
1903-
topic_links=self.topic_links,
1904-
message_links=self.message_links,
1905-
time_mentions=self.time_mentions,
1906-
)
1907-
return key
1908-
return super().keypress(size, key)
1909-
19101909

19111910
class FullRenderedMsgView(PopUpView):
19121911
def __init__(
@@ -1931,26 +1930,14 @@ def __init__(
19311930
super().__init__(
19321931
controller,
19331932
[msg_box.content],
1934-
"MSG_INFO",
1933+
"FULL_RENDERED_MESSAGE",
19351934
max_cols,
19361935
title,
19371936
urwid.Pile(msg_box.header),
19381937
urwid.Pile(msg_box.footer),
1938+
command_full_exit="MSG_INFO",
19391939
)
19401940

1941-
def keypress(self, size: urwid_Size, key: str) -> str:
1942-
if is_command_key("EXIT_POPUP", key) or is_command_key(
1943-
"FULL_RENDERED_MESSAGE", key
1944-
):
1945-
self.controller.show_msg_info(
1946-
msg=self.message,
1947-
topic_links=self.topic_links,
1948-
message_links=self.message_links,
1949-
time_mentions=self.time_mentions,
1950-
)
1951-
return key
1952-
return super().keypress(size, key)
1953-
19541941

19551942
class FullRawMsgView(PopUpView):
19561943
def __init__(
@@ -1983,24 +1970,14 @@ def __init__(
19831970
super().__init__(
19841971
controller,
19851972
body_list,
1986-
"MSG_INFO",
1973+
"FULL_RAW_MESSAGE",
19871974
max_cols,
19881975
title,
19891976
urwid.Pile(msg_box.header),
19901977
urwid.Pile(msg_box.footer),
1978+
command_full_exit="MSG_INFO",
19911979
)
19921980

1993-
def keypress(self, size: urwid_Size, key: str) -> str:
1994-
if is_command_key("EXIT_POPUP", key) or is_command_key("FULL_RAW_MESSAGE", key):
1995-
self.controller.show_msg_info(
1996-
msg=self.message,
1997-
topic_links=self.topic_links,
1998-
message_links=self.message_links,
1999-
time_mentions=self.time_mentions,
2000-
)
2001-
return key
2002-
return super().keypress(size, key)
2003-
20041981

20051982
class EmojiPickerView(PopUpView):
20061983
"""

0 commit comments

Comments
 (0)