Skip to content

Commit dcfdfea

Browse files
committed
Removeuser (resolve #3065), silent adding/removing (#3054)
1 parent adac1de commit dcfdfea

File tree

3 files changed

+117
-25
lines changed

3 files changed

+117
-25
lines changed

Diff for: CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ however, insignificant breaking changes do not guarantee a major version bump, s
88

99
# v3.10.0-dev4
1010

11+
v3.10 adds group conversations while resolving othre bugs and QOL changes. It is potentially breaking to some plugins that adds functionality to threads.
12+
13+
## Breaking
14+
15+
- `Thread.recipient` (`str`) is now `Thread.recipients` (`List[str]`).
16+
1117
## Added
1218

1319
- Ability to have group conversations. ([GH #143](https://github.com/kyb3r/modmail/issues/143))

Diff for: cogs/modmail.py

+80-19
Original file line numberDiff line numberDiff line change
@@ -675,8 +675,11 @@ async def title(self, ctx, *, name: str):
675675
@checks.has_permissions(PermissionLevel.SUPPORTER)
676676
@checks.thread_only()
677677
@commands.cooldown(1, 600, BucketType.channel)
678-
async def adduser(self, ctx, *, user: discord.Member):
679-
"""Adds a user to a modmail thread"""
678+
async def adduser(self, ctx, user: discord.Member, *, options: str.lower = ""):
679+
"""Adds a user to a modmail thread
680+
681+
`options` can be `silent` or `silently`.
682+
"""
680683

681684
curr_thread = await self.bot.threads.find(recipient=user)
682685
if curr_thread:
@@ -686,30 +689,88 @@ async def adduser(self, ctx, *, user: discord.Member):
686689
color=self.bot.error_color,
687690
)
688691
await ctx.send(embed=em)
692+
ctx.command.reset_cooldown(ctx)
689693
else:
694+
if 'silent' not in options and 'silently' not in options:
695+
em = discord.Embed(
696+
title="New Thread (Group)",
697+
description=f"{ctx.author.name} has added you to a Modmail thread.",
698+
color=self.bot.main_color,
699+
)
700+
if self.bot.config["show_timestamp"]:
701+
em.timestamp = datetime.utcnow()
702+
em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url)
703+
await user.send(embed=em)
704+
705+
em = discord.Embed(
706+
title="New User",
707+
description=f"{ctx.author.name} has added {user.name} to the Modmail thread.",
708+
color=self.bot.main_color,
709+
)
710+
if self.bot.config["show_timestamp"]:
711+
em.timestamp = datetime.utcnow()
712+
em.set_footer(text=f"{user}", icon_url=user.avatar_url)
713+
714+
for i in ctx.thread.recipients:
715+
if i != user:
716+
await i.send(embed=em)
717+
718+
await ctx.thread.add_user(user)
719+
sent_emoji, _ = await self.bot.retrieve_emoji()
720+
await self.bot.add_reaction(ctx.message, sent_emoji)
721+
722+
@commands.command(cooldown_after_parsing=True)
723+
@checks.has_permissions(PermissionLevel.SUPPORTER)
724+
@checks.thread_only()
725+
@commands.cooldown(1, 600, BucketType.channel)
726+
async def removeuser(self, ctx, user: discord.Member, *, options: str.lower = ""):
727+
"""Removes a user from a modmail thread
728+
729+
`options` can be `silent` or `silently`.
730+
"""
731+
732+
curr_thread = await self.bot.threads.find(recipient=user)
733+
if ctx.thread != curr_thread:
690734
em = discord.Embed(
691-
title="New Thread (Group)",
692-
description=f"{ctx.author.name} has added you to a Modmail thread.",
693-
color=self.bot.main_color,
735+
title="Error",
736+
description="User is not in this thread.",
737+
color=self.bot.error_color,
694738
)
695-
if self.bot.config["show_timestamp"]:
696-
em.timestamp = datetime.utcnow()
697-
em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url)
698-
await user.send(embed=em)
699-
739+
await ctx.send(embed=em)
740+
ctx.command.reset_cooldown(ctx)
741+
elif ctx.thread.recipient == user:
700742
em = discord.Embed(
701-
title="New User",
702-
description=f"{ctx.author.name} has added {user.name} to the Modmail thread.",
703-
color=self.bot.main_color,
743+
title="Error",
744+
description="User is the main recipient of the thread and cannot be removed.",
745+
color=self.bot.error_color,
704746
)
705-
if self.bot.config["show_timestamp"]:
706-
em.timestamp = datetime.utcnow()
707-
em.set_footer(text=f"{user}", icon_url=user.avatar_url)
747+
await ctx.send(embed=em)
748+
ctx.command.reset_cooldown(ctx)
749+
else:
750+
if 'silent' not in options and 'silently' not in options:
751+
em = discord.Embed(
752+
title="Removed From Thread (Group)",
753+
description=f"{ctx.author.name} has been removed from the Modmail thread.",
754+
color=self.bot.main_color,
755+
)
756+
if self.bot.config["show_timestamp"]:
757+
em.timestamp = datetime.utcnow()
758+
em.set_footer(text=f"{ctx.author}", icon_url=ctx.author.avatar_url)
759+
await user.send(embed=em)
708760

709-
for i in ctx.thread.recipients:
710-
await i.send(embed=em)
761+
em = discord.Embed(
762+
title="User Removed",
763+
description=f"{ctx.author.name} has removed {user.name} from the Modmail thread.",
764+
color=self.bot.main_color,
765+
)
766+
if self.bot.config["show_timestamp"]:
767+
em.timestamp = datetime.utcnow()
768+
em.set_footer(text=f"{user}", icon_url=user.avatar_url)
711769

712-
await ctx.thread.add_user(user)
770+
for i in ctx.thread.recipients:
771+
await i.send(embed=em)
772+
773+
await ctx.thread.remove_user(user)
713774
sent_emoji, _ = await self.bot.retrieve_emoji()
714775
await self.bot.add_reaction(ctx.message, sent_emoji)
715776

Diff for: core/thread.py

+31-6
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ def __init__(
5757
self._cancelled = False
5858

5959
def __repr__(self):
60-
return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipienets={len(self._other_recipients)})'
60+
return f'Thread(recipient="{self.recipient or self.id}", channel={self.channel.id}, other_recipients={len(self._other_recipients)})'
61+
62+
def __eq__(self, other):
63+
return self.id == other.id
6164

6265
async def wait_until_ready(self) -> None:
6366
"""Blocks execution until the thread is fully set up."""
@@ -115,13 +118,19 @@ async def from_channel(cls, manager: "ThreadManager", channel: discord.TextChann
115118
recipient_id = match_user_id(
116119
channel.topic
117120
) # there is a chance it grabs from another recipient's main thread
118-
recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id)
119121

120-
other_recipients = match_other_recipients(channel.topic)
121-
for n, uid in enumerate(other_recipients):
122-
other_recipients[n] = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid)
122+
if recipient_id in manager.cache:
123+
thread = manager.cache[recipient_id]
124+
else:
125+
recipient = manager.bot.get_user(recipient_id) or await manager.bot.fetch_user(recipient_id)
123126

124-
return cls(manager, recipient or recipient_id, channel, other_recipients)
127+
other_recipients = match_other_recipients(channel.topic)
128+
for n, uid in enumerate(other_recipients):
129+
other_recipients[n] = manager.bot.get_user(uid) or await manager.bot.fetch_user(uid)
130+
131+
thread = cls(manager, recipient or recipient_id, channel, other_recipients)
132+
133+
return thread
125134

126135
async def setup(self, *, creator=None, category=None, initial_message=None):
127136
"""Create the thread channel and other io related initialisation tasks"""
@@ -1088,6 +1097,16 @@ async def add_user(self, user: typing.Union[discord.Member, discord.User]) -> No
10881097
ids = ",".join(str(i.id) for i in self._other_recipients)
10891098
await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}")
10901099

1100+
async def remove_user(self, user: typing.Union[discord.Member, discord.User]) -> None:
1101+
title = match_title(self.channel.topic)
1102+
user_id = match_user_id(self.channel.topic)
1103+
self._other_recipients.remove(user)
1104+
1105+
ids = ",".join(str(i.id) for i in self._other_recipients)
1106+
await self.channel.edit(topic=f"Title: {title}\nUser ID: {user_id}\nOther Recipients: {ids}")
1107+
# if user.id in self.manager.cache:
1108+
# self.manager.cache.pop(self.id)
1109+
10911110

10921111
class ThreadManager:
10931112
"""Class that handles storing, finding and creating Modmail threads."""
@@ -1146,6 +1165,7 @@ async def find(
11461165
await thread.close(closer=self.bot.user, silent=True, delete_channel=False)
11471166
thread = None
11481167
else:
1168+
print('in here')
11491169
channel = discord.utils.find(
11501170
lambda x: str(recipient_id) in x.topic if x.topic else False,
11511171
self.bot.modmail_guild.text_channels,
@@ -1157,6 +1177,11 @@ async def find(
11571177
# only save if data is valid
11581178
self.cache[recipient_id] = thread
11591179
thread.ready = True
1180+
1181+
if thread and recipient_id not in [x.id for x in thread.recipients]:
1182+
self.cache.pop(recipient_id)
1183+
thread = None
1184+
11601185
return thread
11611186

11621187
async def _find_from_channel(self, channel):

0 commit comments

Comments
 (0)