PluralKit/PluralKit.Bot/Commands/SystemList.cs

135 lines
5.6 KiB
C#
Raw Normal View History

2020-02-01 12:03:02 +00:00
using System;
2020-02-13 15:35:50 +00:00
using System.Collections.Generic;
2020-02-01 12:03:02 +00:00
using System.Linq;
using System.Threading.Tasks;
2020-02-13 15:35:50 +00:00
using Discord;
2020-02-01 12:03:02 +00:00
using Humanizer;
using PluralKit.Core;
2020-02-01 12:03:02 +00:00
namespace PluralKit.Bot
2020-02-01 12:03:02 +00:00
{
public class SystemList
{
private IDataStore _data;
public SystemList(IDataStore data)
{
_data = data;
}
2020-02-13 15:35:50 +00:00
private async Task RenderMemberList(Context ctx, PKSystem system, bool canShowPrivate, int membersPerPage, string embedTitle, Func<PKMember, bool> filter,
Func<EmbedBuilder, IEnumerable<PKMember>, Task>
renderer)
{
2020-02-01 12:03:02 +00:00
var authCtx = ctx.LookupContextFor(system);
2020-02-13 15:35:50 +00:00
var shouldShowPrivate = authCtx == LookupContext.ByOwner && canShowPrivate;
2020-02-01 12:03:02 +00:00
2020-02-13 15:35:50 +00:00
var membersToShow = await _data.GetSystemMembers(system)
.Where(filter)
.OrderBy(m => m.Name, StringComparer.InvariantCultureIgnoreCase)
.ToListAsync();
2020-02-01 12:03:02 +00:00
2020-02-13 15:35:50 +00:00
var membersToShowWithPrivacy = membersToShow
2020-02-01 12:03:02 +00:00
.Where(m => m.MemberPrivacy == PrivacyLevel.Public || shouldShowPrivate)
2020-02-13 15:35:50 +00:00
.ToList();
var anyMembersHidden = !shouldShowPrivate && membersToShowWithPrivacy.Count != membersToShow.Count;
2020-02-01 12:03:02 +00:00
await ctx.Paginate(
2020-02-13 15:35:50 +00:00
membersToShowWithPrivacy.ToAsyncEnumerable(),
membersToShowWithPrivacy.Count,
membersPerPage,
2020-02-01 12:03:02 +00:00
embedTitle,
(eb, ms) =>
{
2020-02-13 15:35:50 +00:00
var footer = $"{membersToShowWithPrivacy.Count} total.";
2020-02-01 12:03:02 +00:00
if (anyMembersHidden && authCtx == LookupContext.ByOwner)
2020-02-13 15:35:50 +00:00
footer += " Private members have been hidden. Add \"all\" to the command to include them.";
2020-02-01 12:03:02 +00:00
eb.WithFooter(footer);
2020-02-13 15:35:50 +00:00
return renderer(eb, ms);
2020-02-01 12:03:02 +00:00
});
}
2020-02-13 15:35:50 +00:00
private Task ShortRenderer(EmbedBuilder eb, IEnumerable<PKMember> members)
{
eb.Description = string.Join("\n", members.Select((m) =>
{
if (m.HasProxyTags)
{
var proxyTagsString = m.ProxyTagsString().SanitizeMentions();
if (proxyTagsString.Length > 100) // arbitrary threshold for now, tweak?
proxyTagsString = "tags too long, see member card";
return $"[`{m.Hid}`] **{m.Name.SanitizeMentions()}** *({proxyTagsString})*";
}
return $"[`{m.Hid}`] **{m.Name.SanitizeMentions()}**";
}));
2020-02-01 12:03:02 +00:00
2020-02-13 15:35:50 +00:00
return Task.CompletedTask;
}
private Task LongRenderer(EmbedBuilder eb, IEnumerable<PKMember> members)
{
foreach (var m in members)
{
var profile = $"**ID**: {m.Hid}";
if (m.Pronouns != null) profile += $"\n**Pronouns**: {m.Pronouns}";
if (m.Birthday != null) profile += $"\n**Birthdate**: {m.BirthdayString}";
if (m.ProxyTags.Count > 0) profile += $"\n**Proxy tags:** {m.ProxyTagsString()}";
if (m.Description != null) profile += $"\n\n{m.Description}";
if (m.MemberPrivacy == PrivacyLevel.Private)
profile += "\n*(this member is private)*";
eb.AddField(m.Name, profile.Truncate(1024));
}
return Task.CompletedTask;
}
2020-02-01 12:03:02 +00:00
2020-02-13 15:35:50 +00:00
public async Task MemberList(Context ctx, PKSystem system)
{
if (system == null) throw Errors.NoSystemError;
ctx.CheckSystemPrivacy(system, system.MemberListPrivacy);
2020-02-01 12:03:02 +00:00
2020-02-13 15:35:50 +00:00
var embedTitle = system.Name != null
? $"Members of {system.Name.SanitizeMentions()} (`{system.Hid}`)"
: $"Members of `{system.Hid}`";
2020-02-01 12:03:02 +00:00
2020-02-13 15:35:50 +00:00
var shouldShowLongList = ctx.Match("f", "full", "big", "details", "long");
var canShowPrivate = ctx.Match("a", "all", "everyone", "private");
if (shouldShowLongList)
await RenderMemberList(ctx, system, canShowPrivate, 5, embedTitle, _ => true, LongRenderer);
else
await RenderMemberList(ctx, system, canShowPrivate, 25, embedTitle, _ => true, ShortRenderer);
2020-02-01 12:03:02 +00:00
}
2020-02-13 15:49:45 +00:00
public async Task MemberFind(Context ctx, PKSystem system)
{
if (system == null) throw Errors.NoSystemError;
ctx.CheckSystemPrivacy(system, system.MemberListPrivacy);
2020-03-05 18:08:32 +00:00
var shouldShowLongList = ctx.Match("full", "big", "details", "long") || ctx.MatchFlag("f", "full");
var canShowPrivate = ctx.Match("all", "everyone", "private") || ctx.MatchFlag("a", "all");
2020-02-13 15:49:45 +00:00
var searchTerm = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must specify a search term.");
var embedTitle = system.Name != null
2020-02-15 13:14:27 +00:00
? $"Members of {system.Name.SanitizeMentions()} (`{system.Hid}`) matching **{searchTerm.SanitizeMentions()}**"
2020-02-13 15:49:45 +00:00
: $"Members of `{system.Hid}` matching **{searchTerm.SanitizeMentions()}**";
bool Filter(PKMember member) =>
member.Name.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase) ||
(member.DisplayName?.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase) ?? false);
if (shouldShowLongList)
await RenderMemberList(ctx, system, canShowPrivate, 5, embedTitle, Filter, LongRenderer);
else
await RenderMemberList(ctx, system, canShowPrivate, 25, embedTitle, Filter, ShortRenderer);
}
2020-02-01 12:03:02 +00:00
}
}