Ejemplo n.º 1
0
    public static async Task RenderMemberList(this Context ctx, LookupContext lookupCtx,
                                              SystemId system, string embedTitle, string color, ListOptions opts)
    {
        // We take an IDatabase instead of a IPKConnection so we don't keep the handle open for the entire runtime
        // We wanna release it as soon as the member list is actually *fetched*, instead of potentially minutes later (paginate timeout)
        var members = (await ctx.Database.Execute(conn => conn.QueryMemberList(system, opts.ToQueryOptions())))
                      .SortByMemberListOptions(opts, lookupCtx)
                      .ToList();

        var itemsPerPage = opts.Type == ListType.Short ? 25 : 5;
        await ctx.Paginate(members.ToAsyncEnumerable(), members.Count, itemsPerPage, embedTitle, color, Renderer);

        // Base renderer, dispatches based on type
        Task Renderer(EmbedBuilder eb, IEnumerable <ListedMember> page)
        {
            // Add a global footer with the filter/sort string + result count
            eb.Footer(new Embed.EmbedFooter($"{opts.CreateFilterString()}. {"result".ToQuantity(members.Count)}."));

            // Then call the specific renderers
            if (opts.Type == ListType.Short)
            {
                ShortRenderer(eb, page);
            }
            else
            {
                LongRenderer(eb, page);
            }

            return(Task.CompletedTask);
        }

        void ShortRenderer(EmbedBuilder eb, IEnumerable <ListedMember> page)
        {
            // We may end up over the description character limit
            // so run it through a helper that "makes it work" :)
            eb.WithSimpleLineContent(page.Select(m =>
            {
                var ret = $"[`{m.Hid}`] **{m.NameFor(ctx)}** ";

                switch (opts.SortProperty)
                {
                case SortProperty.Birthdate:
                    {
                        var birthday = m.BirthdayFor(lookupCtx);
                        if (birthday != null)
                        {
                            ret += $"(birthday: {m.BirthdayString})";
                        }
                        break;
                    }

                case SortProperty.DisplayName:
                    {
                        if (m.DisplayName != null && m.NamePrivacy.CanAccess(lookupCtx))
                        {
                            ret += $"({m.DisplayName})";
                        }
                        break;
                    }

                case SortProperty.MessageCount:
                    {
                        if (m.MessageCountFor(lookupCtx) is { } count)
                        {
                            ret += $"({count} messages)";
                        }
                        break;
                    }

                case SortProperty.LastSwitch:
                    {
                        if (m.MetadataPrivacy.TryGet(lookupCtx, m.LastSwitchTime, out var lastSw))
                        {
                            ret += $"(last switched in: <t:{lastSw.Value.ToUnixTimeSeconds()}>)";
                        }
                        break;
                    }

                // case SortProperty.LastMessage:
                //     {
                //         if (m.MetadataPrivacy.TryGet(lookupCtx, m.LastMessage, out var lastMsg))
                //             ret += $"(last message: <t:{DiscordUtils.SnowflakeToInstant(lastMsg.Value).ToUnixTimeSeconds()}>)";
                //         break;
                //     }
                case SortProperty.CreationDate:
                    {
                        if (m.MetadataPrivacy.TryGet(lookupCtx, m.Created, out var created))
                        {
                            ret += $"(created at <t:{created.ToUnixTimeSeconds()}>)";
                        }
                        break;
                    }

                default:
                    {
                        if (opts.IncludeMessageCount && m.MessageCountFor(lookupCtx) is { } count)
                        {
                            ret += $"({count} messages)";
                        }