2021-11-26 22:02:58 -05:00
using System.Text ;
2022-01-23 01:47:55 -05:00
using Humanizer ;
2021-11-26 22:02:58 -05:00
using Myriad.Builders ;
using PluralKit.Core ;
namespace PluralKit.Bot ;
public class GroupMember
{
public async Task AddRemoveGroups ( Context ctx , PKMember target , Groups . AddRemoveOperation op )
{
ctx . CheckSystem ( ) . CheckOwnMember ( target ) ;
var groups = ( await ctx . ParseGroupList ( ctx . System . Id ) )
. Select ( g = > g . Id )
. Distinct ( )
. ToList ( ) ;
2022-01-22 03:05:01 -05:00
var existingGroups = ( await ctx . Repository . GetMemberGroups ( target . Id ) . ToListAsync ( ) )
2021-11-26 22:02:58 -05:00
. Select ( g = > g . Id )
. Distinct ( )
. ToList ( ) ;
List < GroupId > toAction ;
if ( op = = Groups . AddRemoveOperation . Add )
{
toAction = groups
. Where ( group = > ! existingGroups . Contains ( group ) )
. ToList ( ) ;
2022-01-22 03:05:01 -05:00
await ctx . Repository . AddGroupsToMember ( target . Id , toAction ) ;
2021-11-26 22:02:58 -05:00
}
else if ( op = = Groups . AddRemoveOperation . Remove )
{
toAction = groups
. Where ( group = > existingGroups . Contains ( group ) )
. ToList ( ) ;
2022-01-22 03:05:01 -05:00
await ctx . Repository . RemoveGroupsFromMember ( target . Id , toAction ) ;
2021-11-26 22:02:58 -05:00
}
else
{
return ; // otherwise toAction "may be unassigned"
}
await ctx . Reply ( GroupMemberUtils . GenerateResponse ( op , 1 , groups . Count , toAction . Count ,
groups . Count - toAction . Count ) ) ;
}
public async Task ListMemberGroups ( Context ctx , PKMember target )
{
2024-10-01 08:56:38 -04:00
var targetSystem = await ctx . Repository . GetSystem ( target . System ) ;
2024-10-04 10:49:10 -06:00
var opts = ctx . ParseListOptions ( ctx . DirectLookupContextFor ( target . System ) , ctx . LookupContextFor ( target . System ) ) ;
2024-10-01 08:56:38 -04:00
opts . MemberFilter = target . Id ;
2021-11-26 22:02:58 -05:00
2025-09-20 02:46:29 +02:00
var title = new StringBuilder ( $"Groups containing {target.NameFor(ctx)} (`{target.DisplayHid(ctx.Config)}`) in " ) ;
2024-10-01 08:56:38 -04:00
if ( ctx . Guild ! = null )
{
var guildSettings = await ctx . Repository . GetSystemGuild ( ctx . Guild . Id , targetSystem . Id ) ;
if ( guildSettings . DisplayName ! = null )
title . Append ( $"{guildSettings.DisplayName} (`{targetSystem.DisplayHid(ctx.Config)}`)" ) ;
else if ( targetSystem . NameFor ( ctx ) ! = null )
title . Append ( $"{targetSystem.NameFor(ctx)} (`{targetSystem.DisplayHid(ctx.Config)}`)" ) ;
else
title . Append ( $"`{targetSystem.DisplayHid(ctx.Config)}`" ) ;
}
2021-11-26 22:02:58 -05:00
else
{
2024-10-01 08:56:38 -04:00
if ( targetSystem . NameFor ( ctx ) ! = null )
title . Append ( $"{targetSystem.NameFor(ctx)} (`{targetSystem.DisplayHid(ctx.Config)}`)" ) ;
else
title . Append ( $"`{targetSystem.DisplayHid(ctx.Config)}`" ) ;
2021-11-26 22:02:58 -05:00
}
2024-10-01 08:56:38 -04:00
if ( opts . Search ! = null )
title . Append ( $" matching **{opts.Search.Truncate(100)}**" ) ;
2021-11-26 22:02:58 -05:00
2024-10-01 08:56:38 -04:00
await ctx . RenderGroupList ( ctx . LookupContextFor ( target . System ) , target . System , title . ToString ( ) ,
target . Color , opts ) ;
2021-11-26 22:02:58 -05:00
}
public async Task AddRemoveMembers ( Context ctx , PKGroup target , Groups . AddRemoveOperation op )
{
ctx . CheckOwnGroup ( target ) ;
2024-10-03 02:30:39 -06:00
List < MemberId > members ;
if ( ctx . MatchFlag ( "all" , "a" ) )
{
members = ( await ctx . Database . Execute ( conn = > conn . QueryMemberList ( target . System ,
new DatabaseViewsExt . ListQueryOptions { } ) ) )
. Select ( m = > m . Id )
. Distinct ( )
. ToList ( ) ;
}
else
{
members = ( await ctx . ParseMemberList ( ctx . System . Id ) )
2021-11-26 22:02:58 -05:00
. Select ( m = > m . Id )
. Distinct ( )
. ToList ( ) ;
2024-10-03 02:30:39 -06:00
}
2021-11-26 22:02:58 -05:00
2022-01-22 03:05:01 -05:00
var existingMembersInGroup = ( await ctx . Database . Execute ( conn = > conn . QueryMemberList ( target . System ,
2022-01-14 22:30:02 -05:00
new DatabaseViewsExt . ListQueryOptions { GroupFilter = target . Id } ) ) )
2021-11-26 22:02:58 -05:00
. Select ( m = > m . Id . Value )
. Distinct ( )
. ToHashSet ( ) ;
List < MemberId > toAction ;
if ( op = = Groups . AddRemoveOperation . Add )
{
toAction = members
. Where ( m = > ! existingMembersInGroup . Contains ( m . Value ) )
. ToList ( ) ;
2022-01-22 03:05:01 -05:00
await ctx . Repository . AddMembersToGroup ( target . Id , toAction ) ;
2021-11-26 22:02:58 -05:00
}
else if ( op = = Groups . AddRemoveOperation . Remove )
{
toAction = members
. Where ( m = > existingMembersInGroup . Contains ( m . Value ) )
. ToList ( ) ;
2024-11-07 19:01:37 -07:00
if ( ctx . MatchFlag ( "all" , "a" ) & & ! await ctx . PromptYesNo ( $"Are you sure you want to remove all members from group {target.Reference(ctx)}?" , "Empty Group" ) ) throw Errors . GenericCancelled ( ) ;
2022-01-22 03:05:01 -05:00
await ctx . Repository . RemoveMembersFromGroup ( target . Id , toAction ) ;
2021-11-26 22:02:58 -05:00
}
else
{
return ; // otherwise toAction "may be undefined"
}
await ctx . Reply ( GroupMemberUtils . GenerateResponse ( op , members . Count , 1 , toAction . Count ,
members . Count - toAction . Count ) ) ;
}
public async Task ListGroupMembers ( Context ctx , PKGroup target )
{
2021-12-07 01:32:29 -05:00
// see global system list for explanation of how privacy settings are used here
2021-11-26 22:02:58 -05:00
var targetSystem = await GetGroupSystem ( ctx , target ) ;
2021-12-07 01:32:29 -05:00
ctx . CheckSystemPrivacy ( targetSystem . Id , target . ListPrivacy ) ;
2021-11-26 22:02:58 -05:00
2024-10-04 10:49:10 -06:00
var opts = ctx . ParseListOptions ( ctx . DirectLookupContextFor ( target . System ) , ctx . LookupContextFor ( target . System ) ) ;
2021-11-26 22:02:58 -05:00
opts . GroupFilter = target . Id ;
2024-04-28 15:46:06 +12:00
var title = new StringBuilder ( $"Members of {target.DisplayName ?? target.Name} (`{target.DisplayHid(ctx.Config)}`) in " ) ;
2023-07-19 12:48:04 +12:00
if ( ctx . Guild ! = null )
{
var guildSettings = await ctx . Repository . GetSystemGuild ( ctx . Guild . Id , targetSystem . Id ) ;
if ( guildSettings . DisplayName ! = null )
2024-04-28 15:46:06 +12:00
title . Append ( $"{guildSettings.DisplayName} (`{targetSystem.DisplayHid(ctx.Config)}`)" ) ;
2023-07-19 12:48:04 +12:00
else if ( targetSystem . NameFor ( ctx ) ! = null )
2024-04-28 15:46:06 +12:00
title . Append ( $"{targetSystem.NameFor(ctx)} (`{targetSystem.DisplayHid(ctx.Config)}`)" ) ;
2023-07-19 12:48:04 +12:00
else
2024-04-28 15:46:06 +12:00
title . Append ( $"`{targetSystem.DisplayHid(ctx.Config)}`" ) ;
2023-07-19 12:48:04 +12:00
}
2021-11-26 22:02:58 -05:00
else
2023-07-19 12:48:04 +12:00
{
if ( targetSystem . NameFor ( ctx ) ! = null )
2024-04-28 15:46:06 +12:00
title . Append ( $"{targetSystem.NameFor(ctx)} (`{targetSystem.DisplayHid(ctx.Config)}`)" ) ;
2023-07-19 12:48:04 +12:00
else
2024-04-28 15:46:06 +12:00
title . Append ( $"`{targetSystem.DisplayHid(ctx.Config)}`" ) ;
2023-07-19 12:48:04 +12:00
}
2021-11-26 22:02:58 -05:00
if ( opts . Search ! = null )
2022-01-23 01:47:55 -05:00
title . Append ( $" matching **{opts.Search.Truncate(100)}**" ) ;
2021-11-26 22:02:58 -05:00
await ctx . RenderMemberList ( ctx . LookupContextFor ( target . System ) , target . System , title . ToString ( ) ,
target . Color , opts ) ;
}
private async Task < PKSystem > GetGroupSystem ( Context ctx , PKGroup target )
{
var system = ctx . System ;
if ( system ? . Id = = target . System )
return system ;
2022-01-22 03:05:01 -05:00
return await ctx . Repository . GetSystem ( target . System ) ! ;
2021-11-26 22:02:58 -05:00
}
}