Skip to content

Commit 8db0ba9

Browse files
committed
model/views: Add method to regularly update state markers in messages.
This commit: * introduces asynch method `update_msg_box_presence_markers` in middle column view class. It would be responsible for rendering the status icons (if present) in message boxes. * adds presence renderer function to the handler `start_presence_updates`. This way, the method `update_msg_box_presence_markers` is called every minute. The function `update_msg_box_presence_markers` uses existing model method `_update_rendered_view` to update the message box (if required). Tests added and amended. Fixes zulip#896.
1 parent b06bcbe commit 8db0ba9

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

tests/ui/test_ui_tools.py

+43-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pytz
66
from bs4 import BeautifulSoup
77
from pytest import param as case
8-
from urwid import Columns, Divider, Padding, Text
8+
from urwid import AttrMap, Columns, Divider, Padding, Text
99

1010
from zulipterminal.config.keys import keys_for_command
1111
from zulipterminal.config.symbols import (
@@ -814,7 +814,7 @@ class TestMiddleColumnView:
814814
@pytest.fixture(autouse=True)
815815
def mock_external_classes(self, mocker):
816816
mocker.patch(VIEWS + ".MessageView", return_value="MSG_LIST")
817-
self.model = mocker.Mock()
817+
self.model = mocker.MagicMock()
818818
self.view = mocker.Mock()
819819
self.write_box = mocker.Mock()
820820
self.search_box = mocker.Mock()
@@ -887,6 +887,47 @@ def test_get_next_unread_pm_no_unread(self, mid_col_view):
887887
assert return_value is None
888888
assert mid_col_view.last_unread_pm is None
889889

890+
@pytest.mark.parametrize('message', [
891+
{
892+
'id': 4,
893+
'type': 'stream',
894+
'display_recipient': 'Verona',
895+
'stream_id': 5,
896+
'subject': 'Test topic',
897+
'is_me_message': True,
898+
'flags': [],
899+
'content': '',
900+
'reactions': [],
901+
'sender_full_name': 'Human 1', # this message name
902+
'timestamp': 1532103879,
903+
}
904+
])
905+
@pytest.mark.parametrize('differences, header_needed, update_required', [
906+
({'subject': 'Test topic 2'}, True, True),
907+
({}, False, False),
908+
({'sender_full_name': 'Human 2'}, False, True),
909+
({'timestamp': 1532103869}, False, False),
910+
], ids=[
911+
'recipient_header_present',
912+
'recipient_header_not_present',
913+
'content_header_present',
914+
'content_header_not_present',
915+
])
916+
def test_update_msg_box_presence_markers(self, mid_col_view, message,
917+
update_required, mocker,
918+
differences, header_needed):
919+
last_msg = dict(message, **differences)
920+
921+
msg_box = MessageBox(message, mid_col_view.model, last_msg)
922+
923+
mid_col_view.body = mocker.Mock()
924+
mocker.patch.object(mid_col_view.body, 'log',
925+
[AttrMap(msg_box, None)])
926+
927+
mid_col_view.update_msg_box_presence_markers()
928+
929+
assert self.model._update_rendered_view.called == update_required
930+
890931
@pytest.mark.parametrize('key', keys_for_command('GO_BACK'))
891932
def test_keypress_GO_BACK(self, mid_col_view, mocker, key, widget_size):
892933
size = widget_size(mid_col_view)

zulipterminal/model.py

+2
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ def _start_presence_updates(self) -> None:
345345
if hasattr(self.controller, 'view'):
346346
self.controller.view.users_view.update_user_list(
347347
user_list=self.users)
348+
(self.controller.view.middle_column
349+
.update_msg_box_presence_markers())
348350
time.sleep(60)
349351

350352
@asynch

zulipterminal/ui_tools/views.py

+19
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,25 @@ def get_next_unread_pm(self) -> Optional[int]:
530530
return pm
531531
return None
532532

533+
@asynch
534+
def update_msg_box_presence_markers(self) -> None:
535+
for msg_btn in self.body.log:
536+
msg_box = msg_btn.original_widget
537+
538+
if msg_box.need_recipient_header():
539+
is_sender_header = (msg_box[1][1].text != ' ')
540+
541+
# Content header is not None
542+
elif isinstance(msg_box[0][1], urwid.Text):
543+
is_sender_header = (msg_box[0][1].text != ' ')
544+
545+
# Content header is None
546+
else:
547+
is_sender_header = False
548+
549+
if is_sender_header:
550+
self.model._update_rendered_view(msg_box.message['id'])
551+
533552
def keypress(self, size: urwid_Size, key: str) -> Optional[str]:
534553
if is_command_key('GO_BACK', key):
535554
self.header.keypress(size, 'esc')

0 commit comments

Comments
 (0)