Skip to content

Commit 2637561

Browse files
committed
ui: Make side panels to overlay the center panel in autohide layout.
This commit makes the side panels to overlay the body which avoids squashing and stretching of the message view which improves UX in autohide mode. To do this the `show_panel` functions have been updated to use Overlay. The focus setting in the `show_panel` functions which could be avoided at a later point needed a reordering in the SEARCH keypress which actually makes it the correct order, i.e., * first handle autohide * then handle search Tests updated.
1 parent 17bca83 commit 2637561

File tree

2 files changed

+76
-46
lines changed

2 files changed

+76
-46
lines changed

tests/ui/test_ui.py

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -230,56 +230,60 @@ def just_set_message_view(self: Any) -> None:
230230
show_left_panel.assert_called_once_with(visible=True)
231231

232232
@pytest.mark.parametrize("autohide", [True, False])
233-
@pytest.mark.parametrize("visible, width", [(True, LEFT_WIDTH), (False, TAB_WIDTH)])
234-
def test_show_left_panel(
233+
@pytest.mark.parametrize("visible", [True, False])
234+
@pytest.mark.parametrize("test_method", ["left_panel", "right_panel"])
235+
def test_show_panel_methods(
235236
self,
236237
mocker: MockerFixture,
237238
view: View,
238239
visible: bool,
239-
width: int,
240240
autohide: bool,
241+
test_method: str,
241242
) -> None:
242-
view.body = mocker.Mock()
243-
view.body.contents = [view.left_panel, mocker.Mock(), mocker.Mock()]
243+
view.frame.body = view.body
244244
view.controller.autohide = autohide
245+
expected_overlay_options = [
246+
"",
247+
None,
248+
"given",
249+
0,
250+
None,
251+
0,
252+
0,
253+
"top",
254+
None,
255+
"relative",
256+
100,
257+
None,
258+
0,
259+
0,
260+
]
261+
if test_method == "left_panel":
262+
expected_overlay_options[0] = "left"
263+
expected_overlay_options[3] = LEFT_WIDTH + 1
264+
expected_tab = view.left_tab
265+
expected_panel = view.left_panel
245266

246-
view.show_left_panel(visible=visible)
247-
248-
if autohide:
249-
if visible:
250-
assert view.body.contents[0][0] == view.left_panel
251-
else:
252-
assert view.body.contents[0][0] == view.left_tab
253-
view.body.options.assert_called_once_with("given", width)
267+
view.show_left_panel(visible=visible)
254268
else:
255-
view.body.options.assert_not_called()
269+
expected_overlay_options[0] = "right"
270+
expected_overlay_options[3] = RIGHT_WIDTH + 1
271+
expected_tab = view.right_tab
272+
expected_panel = view.right_panel
256273

257-
@pytest.mark.parametrize("autohide", [True, False])
258-
@pytest.mark.parametrize(
259-
"visible, width", [(True, RIGHT_WIDTH), (False, TAB_WIDTH)]
260-
)
261-
def test_show_right_panel(
262-
self,
263-
mocker: MockerFixture,
264-
view: View,
265-
visible: bool,
266-
width: int,
267-
autohide: bool,
268-
) -> None:
269-
view.body = mocker.Mock()
270-
view.body.contents = [mocker.Mock(), mocker.Mock(), view.right_panel]
271-
view.controller.autohide = autohide
272-
273-
view.show_right_panel(visible=visible)
274+
view.show_right_panel(visible=visible)
274275

275276
if autohide:
276277
if visible:
277-
assert view.body.contents[2][0] == view.right_panel
278+
assert (expected_panel, mocker.ANY) in view.frame.body.top_w.contents
279+
assert view.frame.body.bottom_w == view.body
280+
assert view.frame.body.contents[1][1] == tuple(expected_overlay_options)
278281
else:
279-
assert view.body.contents[2][0] == view.right_tab
280-
view.body.options.assert_called_once_with("given", width)
282+
assert view.frame.body.contents[0][0] == expected_tab
283+
assert view.body.focus_position == 1
281284
else:
282-
view.body.options.assert_not_called()
285+
# No change
286+
assert view.frame.body.contents[0][0] == expected_tab
283287

284288
def test_keypress_normal_mode_navigation(
285289
self,
@@ -359,7 +363,7 @@ def test_keypress_autohide_users(
359363
view.right_panel = mocker.Mock()
360364
size = widget_size(view)
361365
view.controller.is_in_editor_mode = lambda: False
362-
view.body.focus_position = None
366+
view.body.focus_position = 1
363367

364368
view.keypress(size, key)
365369

zulipterminal/ui.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,43 @@ def show_left_panel(self, *, visible: bool) -> None:
190190
if not self.controller.autohide:
191191
return
192192

193-
width = LEFT_WIDTH if visible else TAB_WIDTH
194-
widget = self.left_panel if visible else self.left_tab
195-
self.body.contents[0] = (widget, self.body.options("given", width))
193+
if visible:
194+
self.frame.body = urwid.Overlay(
195+
urwid.Columns(
196+
[(LEFT_WIDTH, self.left_panel), (1, urwid.SolidFill("▏"))]
197+
),
198+
self.body,
199+
align="left",
200+
width=LEFT_WIDTH + 1,
201+
valign="top",
202+
height=("relative", 100),
203+
)
204+
else:
205+
self.frame.body = self.body
206+
# FIXME: This can be avoided after fixing the "sacrificing 1st
207+
# unread msg" issue and setting focus_column=1 when initializing.
208+
self.body.focus_position = 1
196209

197210
def show_right_panel(self, *, visible: bool) -> None:
198211
if not self.controller.autohide:
199212
return
200213

201-
width = RIGHT_WIDTH if visible else TAB_WIDTH
202-
widget = self.right_panel if visible else self.right_tab
203-
self.body.contents[2] = (widget, self.body.options("given", width))
214+
if visible:
215+
self.frame.body = urwid.Overlay(
216+
urwid.Columns(
217+
[(1, urwid.SolidFill("▕")), (RIGHT_WIDTH, self.right_panel)]
218+
),
219+
self.body,
220+
align="right",
221+
width=RIGHT_WIDTH + 1,
222+
valign="top",
223+
height=("relative", 100),
224+
)
225+
else:
226+
self.frame.body = self.body
227+
# FIXME: This can be avoided after fixing the "sacrificing 1st
228+
# unread msg" issue and setting focus_column=1 when initializing.
229+
self.body.focus_position = 1
204230

205231
def keypress(self, size: urwid_Box, key: str) -> Optional[str]:
206232
self.model.new_user_input = True
@@ -228,19 +254,19 @@ def keypress(self, size: urwid_Box, key: str) -> Optional[str]:
228254
self.body.focus_col = 1
229255
elif is_command_key("SEARCH_PEOPLE", key):
230256
# Start User Search if not in editor_mode
231-
self.body.focus_position = 2
232-
self.users_view.keypress(size, key)
233257
self.show_left_panel(visible=False)
234258
self.show_right_panel(visible=True)
259+
self.body.focus_position = 2
260+
self.users_view.keypress(size, key)
235261
return key
236262
elif is_command_key("SEARCH_STREAMS", key) or is_command_key(
237263
"SEARCH_TOPICS", key
238264
):
239265
# jump stream search
240-
self.body.focus_position = 0
241-
self.left_panel.keypress(size, key)
242266
self.show_right_panel(visible=False)
243267
self.show_left_panel(visible=True)
268+
self.body.focus_position = 0
269+
self.left_panel.keypress(size, key)
244270
return key
245271
elif is_command_key("OPEN_DRAFT", key):
246272
saved_draft = self.model.session_draft_message()

0 commit comments

Comments
 (0)