aboutsummaryrefslogtreecommitdiffstats
path: root/slack
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2023-08-26 21:00:07 +0200
committerTrygve Aaberge <trygveaa@gmail.com>2024-02-18 11:32:54 +0100
commit4b68e8721d18f83c58fea5109da95346363bb9e8 (patch)
tree540d5bbe9995dd114f0d05d0a024197e9d1e34a1 /slack
parent6722517e91c19cc7c1d39335a1b64020ac7c0b9b (diff)
downloadwee-slack-4b68e8721d18f83c58fea5109da95346363bb9e8.tar.gz
Support showing thread replies in the channel
Diffstat (limited to 'slack')
-rw-r--r--slack/config.py7
-rw-r--r--slack/slack_conversation.py31
-rw-r--r--slack/slack_message.py34
3 files changed, 65 insertions, 7 deletions
diff --git a/slack/config.py b/slack/config.py
index 4503709..9cca910 100644
--- a/slack/config.py
+++ b/slack/config.py
@@ -156,6 +156,13 @@ class SlackConfigSectionLook:
False,
)
+ self.display_thread_replies_in_channel = WeeChatOption(
+ self._section,
+ "display_thread_replies_in_channel",
+ "display thread replies in the parent channel; can be overridden per buffer with the buffer localvar display_thread_replies_in_channel; note that it only takes effect for new messages; note that due to limitations in the Slack API, on load only thread messages for parents that are in the buffer and thread messages in subscribed threads will be displayed (but all thread messages received while connected will be displayed)",
+ False,
+ )
+
self.external_user_suffix = WeeChatOption(
self._section,
"external_user_suffix",
diff --git a/slack/slack_conversation.py b/slack/slack_conversation.py
index 1d89eae..982f06a 100644
--- a/slack/slack_conversation.py
+++ b/slack/slack_conversation.py
@@ -199,6 +199,8 @@ class SlackConversationMessageHashes(Dict[SlackTs, str]):
other_message = self._conversation.get_message(ts_with_same_hash)
if other_message:
run_async(self._conversation.rerender_message(other_message))
+ for reply in other_message.replies:
+ run_async(self._conversation.rerender_message(reply))
self._setitem(key, short_hash)
self._inverse_map[short_hash] = key
@@ -392,6 +394,8 @@ class SlackConversation:
for message in messages:
self._messages[message.ts] = message
+ # TODO: Account for reply messages
+
sender_user_ids = [m.sender_user_id for m in messages if m.sender_user_id]
self.workspace.users.initialize_items(sender_user_ids)
@@ -421,17 +425,32 @@ class SlackConversation:
self.buffer_pointer, "", user.nick(), color, "", "", 1
)
+ def display_thread_replies(self) -> bool:
+ buffer_value = weechat.buffer_get_string(
+ self.buffer_pointer, "localvar_display_thread_replies_in_channel"
+ )
+ if buffer_value:
+ return bool(weechat.config_string_to_boolean(buffer_value))
+ return shared.config.look.display_thread_replies_in_channel.value
+
async def add_new_message(self, message: SlackMessage):
# TODO: Remove old messages
self._messages[message.ts] = message
- if self.history_filled:
- await self.print_message(message)
- else:
- weechat.buffer_set(
- self.buffer_pointer, "hotlist", str(message.priority.value)
- )
+
+ if not message.is_reply or self.display_thread_replies():
+ if self.history_filled:
+ await self.print_message(message)
+ else:
+ weechat.buffer_set(
+ self.buffer_pointer, "hotlist", str(message.priority.value)
+ )
+
+ parent_message = message.parent_message
+ if parent_message:
+ parent_message.replies.append(message)
if message.sender_user_id:
+ # TODO: thread buffers
user = await self.workspace.users[message.sender_user_id]
weechat.hook_signal_send(
"typing_set_nick",
diff --git a/slack/slack_message.py b/slack/slack_message.py
index 3537e1d..1d61950 100644
--- a/slack/slack_message.py
+++ b/slack/slack_message.py
@@ -107,6 +107,7 @@ class SlackMessage:
self._rendered_message = None
self.conversation = conversation
self.ts = SlackTs(message_json["ts"])
+ self.replies: List[SlackMessage] = []
self._deleted = False
@property
@@ -118,6 +119,28 @@ class SlackMessage:
return self.conversation.message_hashes[self.ts]
@property
+ def thread_ts(self) -> Optional[SlackTs]:
+ return (
+ SlackTs(self._message_json["thread_ts"])
+ if "thread_ts" in self._message_json
+ else None
+ )
+
+ @property
+ def is_thread_parent(self) -> bool:
+ return self.thread_ts == self.ts
+
+ @property
+ def is_reply(self) -> bool:
+ return self.thread_ts is not None and not self.is_thread_parent
+
+ @property
+ def parent_message(self) -> Optional[SlackMessage]:
+ if not self.is_reply or self.thread_ts is None:
+ return None
+ return self.conversation.get_message(self.thread_ts)
+
+ @property
def is_bot_message(self) -> bool:
return (
"subtype" in self._message_json
@@ -341,6 +364,7 @@ class SlackMessage:
if self._deleted:
return with_color(shared.config.color.deleted_message.value, "(deleted)")
else:
+ thread_prefix = self._create_thread_prefix()
text = await self._render_message_text()
text_edited = (
f" {with_color(shared.config.color.edited_message_suffix.value, '(edited)')}"
@@ -349,7 +373,7 @@ class SlackMessage:
)
reactions = await self._create_reactions_string()
thread = self._create_thread_string()
- return text + text_edited + reactions + thread
+ return thread_prefix + text + text_edited + reactions + thread
async def render_message(self, rerender: bool = False) -> str:
if self._rendered_message is not None and not rerender:
@@ -517,6 +541,14 @@ class SlackMessage:
else:
return ""
+ def _create_thread_prefix(self) -> str:
+ parent_message = self.parent_message
+ if not parent_message:
+ return ""
+
+ text = f"[{parent_message.hash}]"
+ return with_color(nick_color(str(parent_message.hash)), text) + " "
+
def _create_thread_string(self) -> str:
if "reply_count" not in self._message_json:
return ""