Skip to content

Commit ba66e6f

Browse files
Add badge to display unread count
1 parent adb0023 commit ba66e6f

File tree

4 files changed

+157
-27
lines changed

4 files changed

+157
-27
lines changed

app.py

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@
55
import json
66
import os
77
import requests
8-
import subprocess
98
import sys
109
import traceback
1110
import tempfile
1211
import urwid
1312
from datetime import datetime
14-
from slackclient import SlackClient
1513
from sclack.components import Attachment, Channel, ChannelHeader, ChatBox, Dm
1614
from sclack.components import Indicators, MarkdownText, Message, MessageBox
1715
from sclack.components import NewMessagesDivider, Profile, ProfileSideBar
@@ -36,6 +34,7 @@ def run(self):
3634
def set_exception_handler(self, handler):
3735
self._custom_exception_handler = handler
3836

37+
3938
class App:
4039
message_box = None
4140

@@ -162,22 +161,51 @@ def mount_sidebar(self, executor):
162161
urwid.connect_signal(self.sidebar, 'go_to_channel', self.go_to_channel)
163162
loop.create_task(self.get_channels_info(executor, channels))
164163
loop.create_task(self.get_presences(executor, dms))
164+
loop.create_task(self.get_dms_unread(executor, dms))
165165

166166
@asyncio.coroutine
167167
def get_presences(self, executor, dm_widgets):
168+
"""
169+
Compute and return presence because updating UI from another thread is unsafe
170+
:param executor:
171+
:param dm_widgets:
172+
:return:
173+
"""
168174
def get_presence(dm_widget):
169-
# Compute and return presence because updating UI from another thread is unsafe
170175
presence = self.store.get_presence(dm_widget.user)
171176
return [dm_widget, presence]
172177
presences = yield from asyncio.gather(*[
173178
loop.run_in_executor(executor, get_presence, dm_widget)
174179
for dm_widget in dm_widgets
175180
])
181+
176182
for presence in presences:
177183
[widget, response] = presence
178184
if response['ok']:
179185
widget.set_presence(response['presence'])
180186

187+
@asyncio.coroutine
188+
def get_dms_unread(self, executor, dm_widgets):
189+
"""
190+
Compute and return unread_count_display because updating UI from another thread is unsafe
191+
:param executor:
192+
:param dm_widgets:
193+
:return:
194+
"""
195+
def get_presence(dm_widget):
196+
profile_response = self.store.get_channel_info(dm_widget.id)
197+
return [dm_widget, profile_response]
198+
199+
responses = yield from asyncio.gather(*[
200+
loop.run_in_executor(executor, get_presence, dm_widget)
201+
for dm_widget in dm_widgets
202+
])
203+
204+
for profile_response in responses:
205+
[widget, response] = profile_response
206+
if response is not None:
207+
widget.set_unread(response['unread_count_display'])
208+
181209
@asyncio.coroutine
182210
def get_channels_info(self, executor, channels):
183211
def get_info(channel):
@@ -187,10 +215,20 @@ def get_info(channel):
187215
loop.run_in_executor(executor, get_info, channel)
188216
for channel in channels
189217
])
218+
190219
for channel_info in channels_info:
191220
[widget, response] = channel_info
192221
widget.set_unread(response.get('unread_count_display', 0))
193222

223+
@asyncio.coroutine
224+
def update_chat(self, event):
225+
"""
226+
Update channel/DM message count badge
227+
:param event:
228+
:return:
229+
"""
230+
self.sidebar.update_items(event)
231+
194232
@asyncio.coroutine
195233
def mount_chatbox(self, executor, channel):
196234
yield from asyncio.gather(
@@ -406,7 +444,7 @@ def lazy_load_images(self, files, widget):
406444
if not self.config['features']['pictures']:
407445
return
408446

409-
allowed_file_types = ('bmp', 'gif', 'jpeg', 'jpg', 'png')
447+
allowed_file_types = ('bmp', 'gif', 'jpeg', 'jpg', 'png')
410448

411449
for file in files:
412450
if file.get('filetype') in allowed_file_types:
@@ -417,7 +455,6 @@ def lazy_load_images(self, files, widget):
417455
not file.get('is_external', True)
418456
))
419457

420-
421458
def render_messages(self, messages):
422459
_messages = []
423460
previous_date = self.store.state.last_date
@@ -435,6 +472,7 @@ def render_messages(self, messages):
435472
date_text = 'Today'
436473
else:
437474
date_text = message_date.strftime('%A, %B %d')
475+
438476
# New messages badge
439477
if (message_datetime > last_read_datetime and not self.store.state.did_render_new_messages
440478
and (self.store.state.channel.get('unread_count_display', 0) > 0)):
@@ -527,7 +565,10 @@ def start_real_time(self):
527565
self.store.slack.rtm_connect(auto_reconnect=True)
528566

529567
def stop_typing(*args):
530-
self.chatbox.message_box.typing = None
568+
# Prevent error while switching workspace
569+
if self.chatbox is not None:
570+
self.chatbox.message_box.typing = None
571+
531572
alarm = None
532573
while self.store.slack.server.connected is True:
533574
events = self.store.slack.rtm_read()
@@ -539,9 +580,12 @@ def stop_typing(*args):
539580
for channel in self.sidebar.channels:
540581
if channel.id == event['channel']:
541582
channel.set_unread(unread)
542-
elif event.get('channel') == self.store.state.channel['id']:
543-
if event['type'] == 'message':
544-
# Delete message
583+
elif event['type'] == 'message':
584+
loop.create_task(
585+
self.update_chat(event)
586+
)
587+
588+
if event.get('channel') == self.store.state.channel['id']:
545589
if event.get('subtype') == 'message_deleted':
546590
for widget in self.chatbox.body.body:
547591
if hasattr(widget, 'ts') and getattr(widget, 'ts') == event['deleted_ts']:

0 commit comments

Comments
 (0)