aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--slack/config.py30
-rw-r--r--slack/register.py2
-rw-r--r--slack/slack_conversation.py47
-rw-r--r--slack/slack_user.py7
-rw-r--r--slack/weechat_config.py66
5 files changed, 125 insertions, 27 deletions
diff --git a/slack/config.py b/slack/config.py
index 8b60ac1..e7dbbaf 100644
--- a/slack/config.py
+++ b/slack/config.py
@@ -6,6 +6,7 @@ import weechat
from slack.log import print_error
from slack.shared import shared
+from slack.slack_conversation import invalidate_nicklists
from slack.slack_workspace import SlackWorkspace
from slack.util import get_callback_name
from slack.weechat_config import (
@@ -76,6 +77,15 @@ class SlackConfigSectionLook:
" :]",
)
+ self.color_nicks_in_nicklist = WeeChatOption(
+ self._section,
+ "color_nicks_in_nicklist",
+ "use nick color in nicklist",
+ False,
+ parent_option="irc.look.color_nicks_in_nicklist",
+ callback_change=self.config_change_color_nicks_in_nicklist_cb,
+ )
+
self.external_user_suffix = WeeChatOption(
self._section,
"external_user_suffix",
@@ -83,6 +93,26 @@ class SlackConfigSectionLook:
"*",
)
+ weechat.hook_config(
+ "weechat.look.nick_color_*",
+ get_callback_name(self.config_change_nick_colors_cb),
+ "",
+ )
+ weechat.hook_config(
+ "weechat.color.chat_nick_colors",
+ get_callback_name(self.config_change_nick_colors_cb),
+ "",
+ )
+
+ def config_change_color_nicks_in_nicklist_cb(
+ self, option: WeeChatOption[WeeChatOptionType], parent_changed: bool
+ ):
+ invalidate_nicklists()
+
+ def config_change_nick_colors_cb(self, data: str, option: str, value: str):
+ invalidate_nicklists()
+ return weechat.WEECHAT_RC_OK
+
class SlackConfigSectionWorkspace:
def __init__(
diff --git a/slack/register.py b/slack/register.py
index 5e40c6a..e7628e0 100644
--- a/slack/register.py
+++ b/slack/register.py
@@ -22,7 +22,7 @@ def shutdown_cb():
def signal_buffer_switch_cb(data: str, signal: str, buffer_pointer: str) -> int:
conversation = get_conversation_from_buffer_pointer(buffer_pointer)
if conversation:
- run_async(conversation.fill_history())
+ run_async(conversation.buffer_switched_to())
return weechat.WEECHAT_RC_OK
diff --git a/slack/slack_conversation.py b/slack/slack_conversation.py
index 00052af..fc53979 100644
--- a/slack/slack_conversation.py
+++ b/slack/slack_conversation.py
@@ -30,6 +30,12 @@ def get_conversation_from_buffer_pointer(
return None
+def invalidate_nicklists():
+ for workspace in shared.workspaces.values():
+ for conversation in workspace.open_conversations.values():
+ conversation.nicklist_needs_refresh = True
+
+
class SlackConversation:
def __init__(
self,
@@ -45,6 +51,7 @@ class SlackConversation:
self.is_loading = False
self.history_filled = False
self.history_pending = False
+ self.nicklist_needs_refresh = True
self.completion_context: Literal[
"NO_COMPLETION",
@@ -84,12 +91,9 @@ class SlackConversation:
im_user = await self.workspace.users[self._info["user"]]
return im_user.nick()
elif self._info["is_mpim"] is True:
- if self._members is None:
- members_response = await self._api.fetch_conversations_members(self)
- self._members = members_response["members"]
- await self.workspace.users.initialize_items(self._members)
+ members = await self.load_members(load_all=True)
member_users = await gather(
- *(self.workspace.users[user_id] for user_id in self._members)
+ *(self.workspace.users[user_id] for user_id in members)
)
return ",".join([user.nick() for user in member_users])
else:
@@ -147,6 +151,8 @@ class SlackConversation:
"short_name": short_name,
"title": "topic",
"input_multiline": "1",
+ "nicklist": "0" if self.type == "im" else "1",
+ "nicklist_display_groups": "0",
"localvar_set_type": (
"private" if self.type in ("im", "mpim") else "channel"
),
@@ -178,6 +184,18 @@ class SlackConversation:
self.workspace.open_conversations[self.id] = self
+ async def buffer_switched_to(self):
+ await gather(self.nicklist_update(), self.fill_history())
+
+ async def load_members(self, load_all: bool = False):
+ if self._members is None:
+ members_response = await self._api.fetch_conversations_members(
+ self, pages=-1 if load_all else 1
+ )
+ self._members = members_response["members"]
+ await self.workspace.users.initialize_items(self._members)
+ return self._members
+
async def fill_history(self):
if self.history_filled or self.history_pending:
return
@@ -204,6 +222,25 @@ class SlackConversation:
self.history_filled = True
self.history_pending = False
+ async def nicklist_update(self):
+ if self.nicklist_needs_refresh:
+ self.nicklist_needs_refresh = False
+ members = await self.load_members()
+ weechat.nicklist_remove_all(self.buffer_pointer)
+ await gather(*(self.nicklist_add_user(user_id) for user_id in members))
+
+ async def nicklist_add_user(self, user_id: str):
+ user = await self.workspace.users[user_id]
+ # TODO: weechat.color.nicklist_away
+ color = (
+ user.nick_color()
+ if shared.config.look.color_nicks_in_nicklist.value
+ else ""
+ )
+ weechat.nicklist_add_nick(
+ self.buffer_pointer, "", user.nick(), color, "", "", 1
+ )
+
async def add_message(self, message: SlackMessage):
self._messages[message.ts] = message
if self.history_filled:
diff --git a/slack/slack_user.py b/slack/slack_user.py
index 2356eaf..9a5989d 100644
--- a/slack/slack_user.py
+++ b/slack/slack_user.py
@@ -58,7 +58,7 @@ class SlackUser:
nick = self._name_without_spaces()
if colorize:
- nick = with_color(self._nick_color(), nick)
+ nick = with_color(self.nick_color(), nick)
if self._info["profile"]["team"] != self.workspace.id:
nick += shared.config.look.external_user_suffix.value
@@ -68,7 +68,7 @@ class SlackUser:
def _name_without_spaces(self) -> str:
return name_from_user_info_without_spaces(self.workspace, self._info)
- def _nick_color(self) -> str:
+ def nick_color(self) -> str:
if self._info["id"] == self.workspace.my_user._info["id"]:
return weechat.config_string(
weechat.config_get("weechat.color.chat_nick_self")
@@ -90,6 +90,9 @@ class SlackBot:
def nick(self, colorize: bool = False) -> str:
return format_bot_nick(self._info["name"], colorize)
+ def nick_color(self):
+ return nick_color(self._info["name"].replace(" ", ""))
+
class SlackUsergroup:
def __init__(self, workspace: SlackWorkspace, info: SlackUsergroupInfo):
diff --git a/slack/weechat_config.py b/slack/weechat_config.py
index 7fc2742..c2f5b16 100644
--- a/slack/weechat_config.py
+++ b/slack/weechat_config.py
@@ -1,11 +1,12 @@
from __future__ import annotations
from dataclasses import dataclass
-from typing import Generic, Optional, TypeVar, Union, cast
+from typing import Callable, Generic, Optional, TypeVar, Union, cast
import weechat
from slack.shared import shared
+from slack.util import get_callback_name
class WeeChatColor(str):
@@ -52,6 +53,19 @@ WeeChatOptionTypes = Union[int, str]
WeeChatOptionType = TypeVar("WeeChatOptionType", bound=WeeChatOptionTypes)
+def option_get_value(
+ option_pointer: str, option_type: WeeChatOptionType
+) -> WeeChatOptionType:
+ if isinstance(option_type, bool):
+ return cast(WeeChatOptionType, weechat.config_boolean(option_pointer) == 1)
+ if isinstance(option_type, int):
+ return cast(WeeChatOptionType, weechat.config_integer(option_pointer))
+ if isinstance(option_type, WeeChatColor):
+ color = weechat.config_color(option_pointer)
+ return cast(WeeChatOptionType, WeeChatColor(color))
+ return cast(WeeChatOptionType, weechat.config_string(option_pointer))
+
+
@dataclass
class WeeChatOption(Generic[WeeChatOptionType]):
section: WeeChatSection
@@ -61,7 +75,10 @@ class WeeChatOption(Generic[WeeChatOptionType]):
min_value: Optional[int] = None
max_value: Optional[int] = None
string_values: Optional[str] = None
- parent_option: Optional[WeeChatOption[WeeChatOptionType]] = None
+ parent_option: Union[WeeChatOption[WeeChatOptionType], str, None] = None
+ callback_change: Optional[
+ Callable[[WeeChatOption[WeeChatOptionType], bool], None]
+ ] = None
def __post_init__(self):
self._pointer = self._create_weechat_option()
@@ -69,18 +86,13 @@ class WeeChatOption(Generic[WeeChatOptionType]):
@property
def value(self) -> WeeChatOptionType:
if weechat.config_option_is_null(self._pointer):
- if self.parent_option:
+ if isinstance(self.parent_option, str):
+ parent_option_pointer = weechat.config_get(self.parent_option)
+ return option_get_value(parent_option_pointer, self.default_value)
+ elif self.parent_option:
return self.parent_option.value
return self.default_value
-
- if isinstance(self.default_value, bool):
- return cast(WeeChatOptionType, weechat.config_boolean(self._pointer) == 1)
- if isinstance(self.default_value, int):
- return cast(WeeChatOptionType, weechat.config_integer(self._pointer))
- if isinstance(self.default_value, WeeChatColor):
- color = weechat.config_color(self._pointer)
- return cast(WeeChatOptionType, WeeChatColor(color))
- return cast(WeeChatOptionType, weechat.config_string(self._pointer))
+ return option_get_value(self._pointer, self.default_value)
@value.setter
def value(self, value: WeeChatOptionType):
@@ -110,16 +122,32 @@ class WeeChatOption(Generic[WeeChatOptionType]):
return "color"
return "string"
+ def _changed_cb(self, data: str, option: str, value: Optional[str] = None):
+ if self.callback_change:
+ parent_changed = data == "parent_changed"
+ if not parent_changed or weechat.config_option_is_null(self._pointer):
+ self.callback_change(self, parent_changed)
+ return weechat.WEECHAT_RC_OK
+
def _create_weechat_option(self) -> str:
if self.parent_option:
- parent_option_name = (
- f"{self.parent_option.section.weechat_config.name}"
- f".{self.parent_option.section.name}"
- f".{self.parent_option.name}"
- )
- name = f"{self.name} << {parent_option_name}"
+ if isinstance(self.parent_option, str):
+ parent_option_name = self.parent_option
+ name = f"{self.name} << {parent_option_name}"
+ else:
+ parent_option_name = (
+ f"{self.parent_option.section.weechat_config.name}"
+ f".{self.parent_option.section.name}"
+ f".{self.parent_option.name}"
+ )
+ name = f"{self.name} << {parent_option_name}"
default_value = None
null_value_allowed = True
+ weechat.hook_config(
+ parent_option_name,
+ get_callback_name(self._changed_cb),
+ "parent_changed",
+ )
else:
name = self.name
default_value = str(self.default_value)
@@ -145,7 +173,7 @@ class WeeChatOption(Generic[WeeChatOptionType]):
null_value_allowed,
"",
"",
- "",
+ get_callback_name(self._changed_cb),
"",
"",
"",