diff --git a/app.py b/app.py index 494cbac..b4f7640 100755 --- a/app.py +++ b/app.py @@ -106,6 +106,10 @@ def switch_to_workspace(self, workspace_number): loop.create_task(self.animate_loading()) loop.create_task(self.component_did_mount()) + @property + def is_chatbox_rendered(self): + return not self._loading and self.chatbox and type(self.chatbox) is ChatBox + @property def sidebar(self): return self.columns.contents[0][0].original_widget @@ -578,13 +582,13 @@ def scroll_messages(self, *args): @asyncio.coroutine def mark_read_slack(self, index): - if not self.chatbox.body or not self.chatbox.body.body: + if not self.is_chatbox_rendered: return if index is None or index == -1: index = len(self.chatbox.body.body) - 1 - if self.chatbox.body.body and self.chatbox.body.body and len(self.chatbox.body.body) > index: + if len(self.chatbox.body.body) > index: message = self.chatbox.body.body[index] # Only apply for message @@ -616,11 +620,12 @@ def _go_to_channel(self, channel_id): messages = self.render_messages(self.store.state.messages, channel_id=channel_id) header = self.render_chatbox_header() - self.chatbox.body.body[:] = messages - self.chatbox.header = header - self.chatbox.message_box.is_read_only = self.store.state.channel.get('is_read_only', False) - self.sidebar.select_channel(channel_id) - self.urwid_loop.set_alarm_in(0, self.scroll_messages) + if self.is_chatbox_rendered: + self.chatbox.body.body[:] = messages + self.chatbox.header = header + self.chatbox.message_box.is_read_only = self.store.state.channel.get('is_read_only', False) + self.sidebar.select_channel(channel_id) + self.urwid_loop.set_alarm_in(0, self.scroll_messages) if len(self.store.state.messages) == 0: self.go_to_sidebar() @@ -694,7 +699,7 @@ def start_real_time(self): def stop_typing(*args): # Prevent error while switching workspace - if self.chatbox is not None: + if self.is_chatbox_rendered: self.chatbox.message_box.typing = None alarm = None @@ -725,6 +730,9 @@ def stop_typing(*args): ) if event.get('channel') == self.store.state.channel['id']: + if not self.is_chatbox_rendered: + return + if event.get('subtype') == 'message_deleted': for widget in self.chatbox.body.body: if hasattr(widget, 'ts') and getattr(widget, 'ts') == event['deleted_ts']: @@ -741,6 +749,9 @@ def stop_typing(*args): else: pass elif event['type'] == 'user_typing': + if not self.is_chatbox_rendered: + return + if event.get('channel') == self.store.state.channel['id']: user = self.store.find_user_by_id(event['user']) name = user.get('display_name') or user.get('real_name') or user['name'] @@ -755,6 +766,9 @@ def stop_typing(*args): self.store.is_snoozed = event['dnd_status']['snooze_enabled'] self.sidebar.profile.set_snooze(self.store.is_snoozed) elif event.get('ok', False): + if not self.is_chatbox_rendered: + return + # Message was sent, Slack confirmed it. self.chatbox.body.body.extend(self.render_messages([{ 'text': event['text'], @@ -841,11 +855,18 @@ def unhandled_input(self, key): elif key == keymap['open_quick_switcher']: return self.open_quick_switcher() elif key in ('1', '2', '3', '4', '5', '6', '7', '8', '9') and len(self.workspaces) >= int(key): - if self.workspaces_line is not None: - self.workspaces_line.select(int(key)) - # Stop rtm to switch workspace - self.real_time_task.cancel() - return self.switch_to_workspace(int(key)) + # Loading or only 1 workspace + if self._loading or self.workspaces_line is None: + return + + # Workspace is selected + if selected_workspace - 1 == self.workspaces_line.selected: + return + + self.workspaces_line.select(selected_workspace) + # Stop rtm to switch workspace + self.real_time_task.cancel() + return self.switch_to_workspace(selected_workspace) elif key == keymap['set_snooze']: return self.open_set_snooze() diff --git a/sclack/components.py b/sclack/components.py index 8f6e461..15b8afd 100644 --- a/sclack/components.py +++ b/sclack/components.py @@ -1053,6 +1053,7 @@ def __init__(self, workspaces): workspace = Workspace(index + 1, name) urwid.connect_signal(workspace, 'select_workspace', self.switch_workspace) body.append(('pack', workspace)) + self.selected = 0 self.body = body self.body[0][1].select() super(Workspaces, self).__init__(urwid.Columns(body), 'workspace_line') @@ -1060,10 +1061,16 @@ def __init__(self, workspaces): def select(self, number): for workspace in self.body: workspace[1].deselect() + if number > 1: self.body[number - 2][1].select_as_previous() + self.body[number - 1][1].select() + new_selected = number - 1 + + self.selected = new_selected def switch_workspace(self, number): - self.select(number) - urwid.emit_signal(self, 'switch_workspace', number) + if number - 1 != self.selected: + self.select(number) + urwid.emit_signal(self, 'switch_workspace', number) diff --git a/sclack/loading.py b/sclack/loading.py index d90b517..3e752e2 100644 --- a/sclack/loading.py +++ b/sclack/loading.py @@ -60,6 +60,7 @@ def status_message(self): def status_message(self, value): self._status_message.set_text(value) + class LoadingSideBar(urwid.Frame): def __init__(self): header = TextDivider(placeholder(size=12)) @@ -71,6 +72,19 @@ def __init__(self): for size in [5, 7, 19, 8, 0, 3, 22, 14, 11, 13]]) super(LoadingSideBar, self).__init__(body, header=header, footer=divider) + def update_items(self, event): + pass + + def get_all_channels(self): + return [] + + def get_all_groups(self): + return [] + + def get_all_dms(self): + return [] + + class SlackBot(urwid.Pile): _matrix = [ [(' \uE0BA', 'white', 'h69'), (' ', 'white', 'white'), ('\uE0B8 ', 'white', 'h200')],