mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	Finished implementing xp shop. It allows users to buy frames and backgrounds if the user enables the feature in data/xp.yml. It can also be available only to patrons
This commit is contained in:
		@@ -1,4 +1,5 @@
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
using NadekoBot.Modules.Xp;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
@@ -193,14 +194,29 @@ public static class MessageChannelExtensions
 | 
			
		||||
    
 | 
			
		||||
    private static readonly IEmote _arrowLeft = Emote.Parse("<:x:969658061805465651>");
 | 
			
		||||
    private static readonly IEmote _arrowRight = Emote.Parse("<:x:969658062220701746>");
 | 
			
		||||
    
 | 
			
		||||
    public static async Task SendPaginatedConfirmAsync(
 | 
			
		||||
 | 
			
		||||
    public static Task SendPaginatedConfirmAsync(
 | 
			
		||||
        this ICommandContext ctx,
 | 
			
		||||
        int currentPage,
 | 
			
		||||
        Func<int, Task<IEmbedBuilder>> pageFunc,
 | 
			
		||||
        int totalElements,
 | 
			
		||||
        int itemsPerPage,
 | 
			
		||||
        bool addPaginatedFooter = true)
 | 
			
		||||
        => ctx.SendPaginatedConfirmAsync(currentPage,
 | 
			
		||||
            pageFunc,
 | 
			
		||||
            default(Func<int, ValueTask<SimpleInteraction<object>?>>),
 | 
			
		||||
            totalElements,
 | 
			
		||||
            itemsPerPage,
 | 
			
		||||
            addPaginatedFooter);
 | 
			
		||||
    
 | 
			
		||||
    public static async Task SendPaginatedConfirmAsync<T>(
 | 
			
		||||
        this ICommandContext ctx,
 | 
			
		||||
        int currentPage,
 | 
			
		||||
        Func<int, Task<IEmbedBuilder>> pageFunc,
 | 
			
		||||
        Func<int, ValueTask<SimpleInteraction<T>?>>? interFactory,
 | 
			
		||||
        int totalElements,
 | 
			
		||||
        int itemsPerPage,
 | 
			
		||||
        bool addPaginatedFooter = true)
 | 
			
		||||
    {
 | 
			
		||||
        var lastPage = (totalElements - 1) / itemsPerPage;
 | 
			
		||||
        
 | 
			
		||||
@@ -209,70 +225,93 @@ public static class MessageChannelExtensions
 | 
			
		||||
        if (addPaginatedFooter)
 | 
			
		||||
            embed.AddPaginatedFooter(currentPage, lastPage);
 | 
			
		||||
 | 
			
		||||
        var component = new ComponentBuilder()
 | 
			
		||||
                        .WithButton(new ButtonBuilder()
 | 
			
		||||
                                    .WithStyle(ButtonStyle.Primary)
 | 
			
		||||
                                    .WithCustomId(BUTTON_LEFT)
 | 
			
		||||
                                    .WithDisabled(lastPage == 0)
 | 
			
		||||
                                    .WithEmote(_arrowLeft))
 | 
			
		||||
                        .WithButton(new ButtonBuilder()
 | 
			
		||||
                                    .WithStyle(ButtonStyle.Primary)
 | 
			
		||||
                                    .WithCustomId(BUTTON_RIGHT)
 | 
			
		||||
                                    .WithDisabled(lastPage == 0)
 | 
			
		||||
                                    .WithEmote(_arrowRight))
 | 
			
		||||
                        .Build();
 | 
			
		||||
        
 | 
			
		||||
        var msg = await ctx.Channel.SendAsync(null, embed: embed.Build(), components: component);
 | 
			
		||||
        
 | 
			
		||||
        Task OnInteractionAsync(SocketInteraction si)
 | 
			
		||||
        SimpleInteraction<T>? maybeInter = null;
 | 
			
		||||
        async Task<ComponentBuilder> GetComponentBuilder()
 | 
			
		||||
        {
 | 
			
		||||
            _ = Task.Run(async () =>
 | 
			
		||||
            var cb = new ComponentBuilder();
 | 
			
		||||
                
 | 
			
		||||
            cb.WithButton(new ButtonBuilder()
 | 
			
		||||
                .WithStyle(ButtonStyle.Primary)
 | 
			
		||||
                .WithCustomId(BUTTON_LEFT)
 | 
			
		||||
                .WithDisabled(lastPage == 0)
 | 
			
		||||
                .WithEmote(_arrowLeft)
 | 
			
		||||
                .WithDisabled(currentPage <= 0));
 | 
			
		||||
 | 
			
		||||
            if (interFactory is not null)
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    if (si is not SocketMessageComponent smc)
 | 
			
		||||
                        return;
 | 
			
		||||
                maybeInter = await interFactory(currentPage);
 | 
			
		||||
 | 
			
		||||
                    if (smc.Message.Id != msg.Id)
 | 
			
		||||
                        return;
 | 
			
		||||
                if (maybeInter is not null)
 | 
			
		||||
                    cb.WithButton(maybeInter.Button);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
                    if (smc.Data.CustomId != BUTTON_LEFT && smc.Data.CustomId != BUTTON_RIGHT)
 | 
			
		||||
                        return;
 | 
			
		||||
            cb.WithButton(new ButtonBuilder()
 | 
			
		||||
                .WithStyle(ButtonStyle.Primary)
 | 
			
		||||
                .WithCustomId(BUTTON_RIGHT)
 | 
			
		||||
                .WithDisabled(lastPage == 0 || currentPage >= lastPage)
 | 
			
		||||
                .WithEmote(_arrowRight));
 | 
			
		||||
 | 
			
		||||
                    await si.DeferAsync();
 | 
			
		||||
                    if (smc.User.Id != ctx.User.Id)
 | 
			
		||||
                        return;
 | 
			
		||||
            return cb;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                    if (smc.Data.CustomId == BUTTON_LEFT)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (currentPage == 0)
 | 
			
		||||
                            return;
 | 
			
		||||
        async Task UpdatePageAsync(SocketMessageComponent smc)
 | 
			
		||||
        {
 | 
			
		||||
            var toSend = await pageFunc(currentPage);
 | 
			
		||||
            if (addPaginatedFooter)
 | 
			
		||||
                toSend.AddPaginatedFooter(currentPage, lastPage);
 | 
			
		||||
            
 | 
			
		||||
            var component = (await GetComponentBuilder()).Build();
 | 
			
		||||
 | 
			
		||||
                        var toSend = await pageFunc(--currentPage);
 | 
			
		||||
                        if (addPaginatedFooter)
 | 
			
		||||
                            toSend.AddPaginatedFooter(currentPage, lastPage);
 | 
			
		||||
 | 
			
		||||
                        await smc.ModifyOriginalResponseAsync(x => x.Embed = toSend.Build());
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (smc.Data.CustomId == BUTTON_RIGHT)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (lastPage > currentPage)
 | 
			
		||||
                        {
 | 
			
		||||
                            var toSend = await pageFunc(++currentPage);
 | 
			
		||||
                            if (addPaginatedFooter)
 | 
			
		||||
                                toSend.AddPaginatedFooter(currentPage, lastPage);
 | 
			
		||||
 | 
			
		||||
                            await smc.ModifyOriginalResponseAsync(x => x.Embed = toSend.Build());
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    Log.Error(ex, "Error in pagination: {ErrorMessage}", ex.Message);
 | 
			
		||||
                }
 | 
			
		||||
            await smc.ModifyOriginalResponseAsync(x =>
 | 
			
		||||
            {
 | 
			
		||||
                x.Embed = toSend.Build();
 | 
			
		||||
                x.Components = component;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        var component = (await GetComponentBuilder()).Build();
 | 
			
		||||
        var msg = await ctx.Channel.SendAsync(null, embed: embed.Build(), components: component);
 | 
			
		||||
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        async Task OnInteractionAsync(SocketInteraction si)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if (si is not SocketMessageComponent smc)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                if (smc.Message.Id != msg.Id)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                await si.DeferAsync();
 | 
			
		||||
                if (smc.User.Id != ctx.User.Id)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                if (smc.Data.CustomId == BUTTON_LEFT)
 | 
			
		||||
                {
 | 
			
		||||
                    if (currentPage == 0)
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
                    --currentPage;
 | 
			
		||||
                    _ = UpdatePageAsync(smc);
 | 
			
		||||
                }
 | 
			
		||||
                else if (smc.Data.CustomId == BUTTON_RIGHT)
 | 
			
		||||
                {
 | 
			
		||||
                    if (currentPage >= lastPage)
 | 
			
		||||
                        return;
 | 
			
		||||
                    
 | 
			
		||||
                    ++currentPage;
 | 
			
		||||
                    _ = UpdatePageAsync(smc);
 | 
			
		||||
                }
 | 
			
		||||
                else if (maybeInter is { } inter && inter.Button.CustomId == smc.Data.CustomId)
 | 
			
		||||
                {
 | 
			
		||||
                    await inter.TriggerAsync(smc);
 | 
			
		||||
                    _ = UpdatePageAsync(smc);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                Log.Error(ex, "Error in pagination: {ErrorMessage}", ex.Message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (lastPage == 0)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user