Add project files.
This commit is contained in:
		
							
								
								
									
										41
									
								
								TomatenMusicCore/Prompt/Model/ButtonPrompt.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								TomatenMusicCore/Prompt/Model/ButtonPrompt.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| using DSharpPlus.Entities; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using TomatenMusic.Prompt.Option; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace TomatenMusic.Prompt.Model | ||||
| { | ||||
|     class ButtonPrompt : DiscordPromptBase | ||||
|     { | ||||
|         public string Content { get; protected set; } = ""; | ||||
|         public List<DiscordEmbed> Embeds { get; protected set; } = new List<DiscordEmbed>(); | ||||
|  | ||||
|         public ButtonPrompt(DiscordPromptBase lastPrompt = null, string content = " ", List<DiscordEmbed> embeds = null) : base(lastPrompt) | ||||
|         { | ||||
|             this.Content = content; | ||||
|             this.Embeds = embeds == null ? new List<DiscordEmbed>() : embeds; | ||||
|         } | ||||
|  | ||||
|         protected override Task<DiscordComponent> GetComponentAsync(IPromptOption option) | ||||
|         { | ||||
|             var myOption = (ButtonPromptOption)option; | ||||
|             DiscordComponent component; | ||||
|  | ||||
|             if (myOption.Link != null) | ||||
|                 component = new DiscordLinkButtonComponent(myOption.Link, myOption.Content, myOption.Disabled, myOption.Emoji); | ||||
|             else | ||||
|                 component = new DiscordButtonComponent(myOption.Style, myOption.CustomID, myOption.Content, myOption.Disabled, myOption.Emoji); | ||||
|             return Task.FromResult<DiscordComponent>(component); | ||||
|         } | ||||
|  | ||||
|         protected override Task<DiscordMessageBuilder> GetMessageAsync() | ||||
|         { | ||||
|             return Task.FromResult<DiscordMessageBuilder>(new DiscordMessageBuilder() | ||||
|             .WithContent(Content) | ||||
|             .AddEmbeds(Embeds)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										62
									
								
								TomatenMusicCore/Prompt/Model/CombinedPrompt.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								TomatenMusicCore/Prompt/Model/CombinedPrompt.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| using DSharpPlus.Entities; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using TomatenMusic.Prompt.Option; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using TomatenMusic.Util; | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
|  | ||||
| namespace TomatenMusic.Prompt.Model | ||||
| { | ||||
|     class CombinedPrompt : DiscordPromptBase | ||||
|     { | ||||
|         public string Content { get; protected set; } = ""; | ||||
|         public List<DiscordEmbed> Embeds { get; protected set; } = new List<DiscordEmbed>(); | ||||
|  | ||||
|         public CombinedPrompt(DiscordPromptBase lastPrompt = null, string content = "Example Content", List<DiscordEmbed> embeds = null) : base(lastPrompt) | ||||
|         { | ||||
|             this.LastPrompt = lastPrompt; | ||||
|  | ||||
|             this.Content = content; | ||||
|             this.Embeds = embeds == null ? new List<DiscordEmbed>() : embeds; | ||||
|         } | ||||
|  | ||||
|         protected async override Task<DiscordComponent> GetComponentAsync(IPromptOption option) | ||||
|         { | ||||
|             if (option is SelectMenuPromptOption) | ||||
|             { | ||||
|                 SelectMenuPromptOption selectOption = (SelectMenuPromptOption)option; | ||||
|                 List<DiscordSelectComponentOption> options = new List<DiscordSelectComponentOption>(); | ||||
|                 foreach (var item in selectOption.Options) | ||||
|                 { | ||||
|                     options.Add(new DiscordSelectComponentOption(item.Label, item.CustomID, item.Description, item.Default, item.Emoji)); | ||||
|                 } | ||||
|  | ||||
|                 return new DiscordSelectComponent(selectOption.CustomID, selectOption.Content, options, selectOption.Disabled, selectOption.MinValues, selectOption.MaxValues); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 var myOption = (ButtonPromptOption)option; | ||||
|                 DiscordComponent component; | ||||
|  | ||||
|                 if (myOption.Link != null) | ||||
|                     component = new DiscordLinkButtonComponent(myOption.Link, myOption.Content, myOption.Disabled, myOption.Emoji); | ||||
|                 else | ||||
|                     component = new DiscordButtonComponent(myOption.Style, myOption.CustomID, myOption.Content, myOption.Disabled, myOption.Emoji); | ||||
|                 return component; | ||||
|             } | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|         protected async override Task<DiscordMessageBuilder> GetMessageAsync() | ||||
|         { | ||||
|             return new DiscordMessageBuilder() | ||||
|             .WithContent(Content) | ||||
|             .AddEmbeds(Embeds); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										471
									
								
								TomatenMusicCore/Prompt/Model/DiscordPromptBase.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										471
									
								
								TomatenMusicCore/Prompt/Model/DiscordPromptBase.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,471 @@ | ||||
| using DSharpPlus.Entities; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using System.Linq; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using TomatenMusic.Prompt.Option; | ||||
| using TomatenMusic.Util; | ||||
| using DSharpPlus.Exceptions; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using DSharpPlus; | ||||
|  | ||||
| namespace TomatenMusic.Prompt.Model | ||||
| { | ||||
|     abstract class DiscordPromptBase | ||||
|     { | ||||
|         public static List<DiscordPromptBase> ActivePrompts { get; } = new List<DiscordPromptBase>(); | ||||
|  | ||||
|         public PromptState State { get; protected set; } | ||||
|         public DiscordMessage Message { get; private set; } | ||||
|         public DiscordInteraction Interaction { get; private set; } | ||||
|         public List<IPromptOption> Options { get; protected set; } = new List<IPromptOption>(); | ||||
|         public DiscordClient _client { get; set; } | ||||
|         public DiscordPromptBase LastPrompt { get; protected set; } | ||||
|  | ||||
|         protected ILogger<DiscordPromptBase> _logger { get; set; } | ||||
|  | ||||
|         protected EventId eventId = new EventId(16, "Prompts"); | ||||
|  | ||||
|         protected DiscordPromptBase(DiscordPromptBase lastPrompt) | ||||
|         { | ||||
|             LastPrompt = lastPrompt; | ||||
|             Options = new List<IPromptOption>(); | ||||
|             IServiceProvider serviceProvider = TomatenMusicBot.ServiceProvider; | ||||
|  | ||||
|             _logger = serviceProvider.GetRequiredService<ILogger<DiscordPromptBase>>(); | ||||
|   | ||||
|  | ||||
|             if (lastPrompt != null) | ||||
|             { | ||||
|                 Options.Add(new ButtonPromptOption | ||||
|                 { | ||||
|                     Style = DSharpPlus.ButtonStyle.Danger, | ||||
|                     Row = 5, | ||||
|                     Emoji = new DiscordComponentEmoji("↩️"), | ||||
|                     Run = async (args, sender, option) => | ||||
|                     { | ||||
|                         _ = BackAsync(); | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             Options.Add(new ButtonPromptOption | ||||
|             { | ||||
|                 Style = DSharpPlus.ButtonStyle.Danger, | ||||
|                 Row = 5, | ||||
|                 Emoji = new DiscordComponentEmoji("❌"), | ||||
|                 Run = async (args, sender, option) => | ||||
|                 { | ||||
|                     _ = InvalidateAsync(); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public async Task InvalidateAsync(bool withEdit = true, bool destroyHistory = false) | ||||
|         { | ||||
|             foreach (var option in Options) | ||||
|                 option.UpdateMethod = (prompt) => | ||||
|                 { | ||||
|                     prompt.Disabled = true; | ||||
|                     return Task.FromResult<IPromptOption>(prompt); | ||||
|                 }; | ||||
|  | ||||
|             if (withEdit) | ||||
|                 await EditMessageAsync(new DiscordWebhookBuilder().WithContent("This Prompt is invalid!")); | ||||
|             ActivePrompts.Remove(this); | ||||
|             if (destroyHistory) | ||||
|             { | ||||
|                 if (LastPrompt != null) | ||||
|                     await LastPrompt.InvalidateAsync(false); | ||||
|                 await EditMessageAsync(new DiscordWebhookBuilder().WithContent("This Prompt is invalid!")); | ||||
|             } | ||||
|  | ||||
|             if (State == PromptState.INVALID) | ||||
|                 return; | ||||
|             State = PromptState.INVALID; | ||||
|              | ||||
|  | ||||
|             _client.ComponentInteractionCreated -= Discord_ComponentInteractionCreated; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public async Task SendAsync(DiscordChannel channel) | ||||
|         { | ||||
|             if (State == PromptState.INVALID) | ||||
|                 return; | ||||
|  | ||||
|             IServiceProvider serviceProvider = TomatenMusicBot.ServiceProvider; | ||||
|             var client = serviceProvider.GetRequiredService<DiscordShardedClient>(); | ||||
|             _client = client.GetShard( (ulong) channel.GuildId); | ||||
|  | ||||
|             _client.ComponentInteractionCreated += Discord_ComponentInteractionCreated; | ||||
|             ActivePrompts.Add(this); | ||||
|             AddGuids(); | ||||
|             DiscordMessageBuilder builder = await GetMessageAsync(); | ||||
|             builder = await AddComponentsAsync(builder); | ||||
|  | ||||
|  | ||||
|             Message = await builder.SendAsync(channel); | ||||
|             State = PromptState.OPEN; | ||||
|         } | ||||
|  | ||||
|         public async Task SendAsync(DiscordInteraction interaction, bool ephemeral = false) | ||||
|         { | ||||
|             if (State == PromptState.INVALID) | ||||
|                 return; | ||||
|  | ||||
|             IServiceProvider serviceProvider = TomatenMusicBot.ServiceProvider; | ||||
|             var client = serviceProvider.GetRequiredService<DiscordShardedClient>(); | ||||
|             _client = client.GetShard((ulong)interaction.GuildId); | ||||
|  | ||||
|             _client.ComponentInteractionCreated += Discord_ComponentInteractionCreated; | ||||
|             ActivePrompts.Add(this); | ||||
|  | ||||
|             AddGuids(); | ||||
|             DiscordFollowupMessageBuilder builder = await GetFollowupMessageAsync(); | ||||
|             builder = await AddComponentsAsync(builder); | ||||
|             builder.AsEphemeral(ephemeral); | ||||
|  | ||||
|             Interaction = interaction; | ||||
|             Message = await interaction.CreateFollowupMessageAsync(builder); | ||||
|             State = PromptState.OPEN; | ||||
|         } | ||||
|  | ||||
|         public async Task UseAsync(DiscordMessage message) | ||||
|         { | ||||
|             if (State == PromptState.INVALID) | ||||
|                 return; | ||||
|  | ||||
|             IServiceProvider serviceProvider = TomatenMusicBot.ServiceProvider; | ||||
|             var client = serviceProvider.GetRequiredService<DiscordShardedClient>(); | ||||
|             _client = client.GetShard((ulong)message.Channel.GuildId); | ||||
|  | ||||
|             _client.ComponentInteractionCreated += Discord_ComponentInteractionCreated; | ||||
|             ActivePrompts.Add(this); | ||||
|  | ||||
|             AddGuids(); | ||||
|             DiscordWebhookBuilder builder = await GetWebhookMessageAsync(); | ||||
|  | ||||
|             await EditMessageAsync(builder); | ||||
|             State = PromptState.OPEN; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public async Task UseAsync(DiscordInteraction interaction, DiscordMessage message) | ||||
|         { | ||||
|             if (State == PromptState.INVALID) | ||||
|                 return; | ||||
|  | ||||
|             IServiceProvider serviceProvider = TomatenMusicBot.ServiceProvider; | ||||
|             var client = serviceProvider.GetRequiredService<DiscordShardedClient>(); | ||||
|             _client = client.GetShard((ulong)interaction.GuildId); | ||||
|  | ||||
|             _client.ComponentInteractionCreated += Discord_ComponentInteractionCreated; | ||||
|             ActivePrompts.Add(this); | ||||
|             AddGuids(); | ||||
|             DiscordWebhookBuilder builder = await GetWebhookMessageAsync(); | ||||
|             Interaction = interaction; | ||||
|             Message = message; | ||||
|             await EditMessageAsync(builder); | ||||
|             State = PromptState.OPEN; | ||||
|         } | ||||
|  | ||||
|         private void AddGuids() | ||||
|         { | ||||
|             foreach (var item in Options) | ||||
|             { | ||||
|                 item.CustomID = RandomUtil.GenerateGuid(); | ||||
|                 if (item is SelectMenuPromptOption) | ||||
|                 { | ||||
|                     SelectMenuPromptOption menuItem = (SelectMenuPromptOption)item; | ||||
|                     foreach (var option in menuItem.Options) | ||||
|                     { | ||||
|                         option.CustomID = RandomUtil.GenerateGuid(); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|             //this.Options = options; | ||||
|         } | ||||
|  | ||||
|         protected abstract Task<DiscordComponent> GetComponentAsync(IPromptOption option); | ||||
|  | ||||
|         protected abstract Task<DiscordMessageBuilder> GetMessageAsync(); | ||||
|  | ||||
|         private async Task<DiscordFollowupMessageBuilder> GetFollowupMessageAsync() | ||||
|         { | ||||
|             DiscordMessageBuilder oldBuilder = await GetMessageAsync(); | ||||
|  | ||||
|             return new DiscordFollowupMessageBuilder() | ||||
|                 .WithContent(oldBuilder.Content) | ||||
|                 .AddEmbeds(oldBuilder.Embeds); | ||||
|                  | ||||
|         } | ||||
|         private async Task<DiscordWebhookBuilder> GetWebhookMessageAsync() | ||||
|         { | ||||
|             DiscordMessageBuilder oldBuilder = await GetMessageAsync(); | ||||
|  | ||||
|             return new DiscordWebhookBuilder() | ||||
|                 .WithContent(oldBuilder.Content) | ||||
|                 .AddEmbeds(oldBuilder.Embeds); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public async Task UpdateAsync() | ||||
|         { | ||||
|            if (State == PromptState.INVALID) | ||||
|                 return; | ||||
|            await EditMessageAsync(await GetWebhookMessageAsync()); | ||||
|             | ||||
|         } | ||||
|  | ||||
|         private async Task UpdateOptionsAsync() | ||||
|         { | ||||
|             List<IPromptOption> options = new List<IPromptOption>(); | ||||
|             foreach (var option in this.Options) | ||||
|                 options.Add(await option.UpdateMethod.Invoke(option)); | ||||
|             this.Options = options; | ||||
|         } | ||||
|  | ||||
|         protected async Task Discord_ComponentInteractionCreated(DSharpPlus.DiscordClient sender, DSharpPlus.EventArgs.ComponentInteractionCreateEventArgs e) | ||||
|         { | ||||
|             if (State == PromptState.INVALID) | ||||
|                 return; | ||||
|  | ||||
|             foreach (var option in Options) | ||||
|             { | ||||
|                 if (option.CustomID == e.Id) | ||||
|                 { | ||||
|  | ||||
|                     await e.Interaction.CreateResponseAsync(DSharpPlus.InteractionResponseType.DeferredMessageUpdate); | ||||
|                     _ = option.Run.Invoke(e, sender, option); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public async Task EditMessageAsync(DiscordWebhookBuilder builder) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 if (Interaction != null) | ||||
|                 { | ||||
|                     await AddComponentsAsync(builder); | ||||
|                     try | ||||
|                     { | ||||
|                         Message = await Interaction.EditFollowupMessageAsync(Message.Id, builder); | ||||
|                     }catch (Exception e) | ||||
|                     { | ||||
|                         Message = await Interaction.EditOriginalResponseAsync(builder); | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     DiscordMessageBuilder msgbuilder = new DiscordMessageBuilder() | ||||
|                         .AddEmbeds(builder.Embeds) | ||||
|                         .WithContent(builder.Content); | ||||
|                     await AddComponentsAsync(msgbuilder); | ||||
|                     Message = await Message.ModifyAsync(msgbuilder); | ||||
|                 } | ||||
|             }catch (BadRequestException e) | ||||
|             { | ||||
|                 _logger.LogError(e.Errors); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         protected async Task<DiscordMessageBuilder> AddComponentsAsync(DiscordMessageBuilder builder) | ||||
|         { | ||||
|             await UpdateOptionsAsync(); | ||||
|             builder.ClearComponents(); | ||||
|  | ||||
|             List<DiscordComponent> row1 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row2 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row3 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row4 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row5 = new List<DiscordComponent>(5); | ||||
|  | ||||
|             foreach (var option in Options) | ||||
|             { | ||||
|                 switch (option.Row) | ||||
|                 { | ||||
|                     case 1: | ||||
|                         row1.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 2: | ||||
|                         row2.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 3: | ||||
|                         row3.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 4: | ||||
|                         row4.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 5: | ||||
|                         row5.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     default: | ||||
|                         throw new ArgumentException("Invalid Row! Must be between 1 and 5", "Row"); | ||||
|                 } | ||||
|             } | ||||
|             if (row1.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row1); | ||||
|             } | ||||
|             if (row2.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row2); | ||||
|             } | ||||
|             if (row3.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row3); | ||||
|             } | ||||
|             if (row4.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row4); | ||||
|             } | ||||
|             if (row5.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row5); | ||||
|             } | ||||
|             return builder; | ||||
|         } | ||||
|  | ||||
|         protected async Task<DiscordFollowupMessageBuilder> AddComponentsAsync(DiscordFollowupMessageBuilder builder) | ||||
|         { | ||||
|             await UpdateOptionsAsync(); | ||||
|             builder.ClearComponents(); | ||||
|  | ||||
|             List<DiscordComponent> row1 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row2 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row3 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row4 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row5 = new List<DiscordComponent>(5); | ||||
|  | ||||
|             foreach (var option in Options) | ||||
|             { | ||||
|                 switch (option.Row) | ||||
|                 { | ||||
|                     case 1: | ||||
|                         row1.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 2: | ||||
|                         row2.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 3: | ||||
|                         row3.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 4: | ||||
|                         row4.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 5: | ||||
|                         row5.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     default: | ||||
|                         throw new ArgumentException("Invalid Row! Must be between 1 and 5", "Row"); | ||||
|                 } | ||||
|             } | ||||
|             if (row1.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row1); | ||||
|             } | ||||
|             if (row2.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row2); | ||||
|             } | ||||
|             if (row3.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row3); | ||||
|             } | ||||
|             if (row4.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row4); | ||||
|             } | ||||
|             if (row5.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row5); | ||||
|             } | ||||
|             return builder; | ||||
|         } | ||||
|  | ||||
|         protected async Task<DiscordWebhookBuilder> AddComponentsAsync(DiscordWebhookBuilder builder) | ||||
|         { | ||||
|             await UpdateOptionsAsync(); | ||||
|             builder.ClearComponents(); | ||||
|  | ||||
|             List<DiscordComponent> row1 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row2 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row3 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row4 = new List<DiscordComponent>(5); | ||||
|             List<DiscordComponent> row5 = new List<DiscordComponent>(5); | ||||
|  | ||||
|             foreach (var option in Options) | ||||
|             { | ||||
|                 switch (option.Row) | ||||
|                 { | ||||
|                     case 1: | ||||
|                         row1.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 2: | ||||
|                         row2.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 3: | ||||
|                         row3.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 4: | ||||
|                         row4.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     case 5: | ||||
|                         row5.Add(await GetComponentAsync(option)); | ||||
|                         break; | ||||
|                     default: | ||||
|                         throw new ArgumentException("Invalid Row! Must be between 1 and 5", "Row"); | ||||
|                 } | ||||
|             } | ||||
|             if (row1.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row1); | ||||
|             } | ||||
|             if (row2.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row2); | ||||
|             } | ||||
|             if (row3.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row3); | ||||
|             } | ||||
|             if (row4.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row4); | ||||
|             } | ||||
|             if (row5.Count != 0) | ||||
|             { | ||||
|                 builder.AddComponents(row5); | ||||
|             } | ||||
|             return builder; | ||||
|         } | ||||
|  | ||||
|         public async Task BackAsync() | ||||
|         { | ||||
|  | ||||
|             if (LastPrompt == null) | ||||
|                 return; | ||||
|             _client.ComponentInteractionCreated -= LastPrompt.Discord_ComponentInteractionCreated; | ||||
|  | ||||
|             await InvalidateAsync(false); | ||||
|             if (Interaction == null) | ||||
|                 await LastPrompt.UseAsync(Message); | ||||
|             else | ||||
|                 await LastPrompt.UseAsync(Interaction, Message); | ||||
|         } | ||||
|  | ||||
|         public void AddOption(IPromptOption option) | ||||
|         { | ||||
|             Options.Add(option); | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										138
									
								
								TomatenMusicCore/Prompt/Model/PaginatedButtonPrompt.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								TomatenMusicCore/Prompt/Model/PaginatedButtonPrompt.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| using DSharpPlus.Entities; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using TomatenMusic.Util; | ||||
| using DSharpPlus; | ||||
| using DSharpPlus.EventArgs; | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
|  | ||||
|  | ||||
| namespace TomatenMusic.Prompt.Model | ||||
| { | ||||
|     abstract class PaginatedButtonPrompt<T> : ButtonPrompt | ||||
|     { | ||||
|         protected PageManager<T> PageManager { get; set; } | ||||
|         protected int CurrentPage { get; set; } = 1; | ||||
|         public string Title { get; set; } | ||||
|  | ||||
|         public PaginatedButtonPrompt(string title, List<T> items, DiscordPromptBase lastPrompt = null) : base(lastPrompt) | ||||
|         { | ||||
|             PageManager = new PageManager<T>(items, 9); | ||||
|             Title = title; | ||||
|  | ||||
|             for (int i = 0; i < 9; i++) | ||||
|             { | ||||
|                 int currentNumber = i + 1; | ||||
|                 ButtonPromptOption option = new ButtonPromptOption() | ||||
|                 { | ||||
|                     Style = DSharpPlus.ButtonStyle.Primary, | ||||
|                     Row = i < 5 ? 1 : 2, | ||||
|                     UpdateMethod = async (option) => | ||||
|                     { | ||||
|                         option.Disabled = PageManager.GetPage(CurrentPage).Count < currentNumber; | ||||
|                         return option; | ||||
|                     }, | ||||
|                     Run = async (args, sender, prompt) => | ||||
|                     { | ||||
|                         List<T> items = PageManager.GetPage(CurrentPage); | ||||
|                         await OnSelect(items[currentNumber-1], args, sender); | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 switch (i) | ||||
|                 { | ||||
|                     case 0: | ||||
|                         option.Emoji = new DiscordComponentEmoji("1️⃣"); | ||||
|                         break; | ||||
|                     case 1: | ||||
|                         option.Emoji = new DiscordComponentEmoji("2️⃣"); | ||||
|                         break; | ||||
|                     case 2: | ||||
|                         option.Emoji = new DiscordComponentEmoji("3️⃣"); | ||||
|                         break; | ||||
|                     case 3: | ||||
|                         option.Emoji = new DiscordComponentEmoji("4️⃣"); | ||||
|                         break; | ||||
|                     case 4: | ||||
|                         option.Emoji = new DiscordComponentEmoji("5️⃣"); | ||||
|                         break; | ||||
|                     case 5: | ||||
|                         option.Emoji = new DiscordComponentEmoji("6️⃣"); | ||||
|                         break; | ||||
|                     case 6: | ||||
|                         option.Emoji = new DiscordComponentEmoji("7️⃣"); | ||||
|                         break; | ||||
|                     case 7: | ||||
|                         option.Emoji = new DiscordComponentEmoji("8️⃣"); | ||||
|                         break; | ||||
|                     case 8: | ||||
|                         option.Emoji = new DiscordComponentEmoji("9️⃣"); | ||||
|                         break; | ||||
|                 } | ||||
|  | ||||
|                 AddOption(option); | ||||
|             } | ||||
|  | ||||
|             AddOption(new ButtonPromptOption | ||||
|             { | ||||
|                 Style = ButtonStyle.Secondary, | ||||
|                 Emoji= new DiscordComponentEmoji("⬅️"), | ||||
|                 Row = 3, | ||||
|                 UpdateMethod = async (prompt) => | ||||
|                 { | ||||
|                     prompt.Disabled = CurrentPage - 1 == 0; | ||||
|                     return prompt; | ||||
|                 }, | ||||
|                 Run = async (args, sender, prompt) => | ||||
|                 { | ||||
|                     CurrentPage--; | ||||
|                     await UpdateAsync(); | ||||
|  | ||||
|                 } | ||||
|             }); | ||||
|             AddOption(new ButtonPromptOption | ||||
|             { | ||||
|                 Style = ButtonStyle.Secondary, | ||||
|                 Emoji = new DiscordComponentEmoji("➡️"), | ||||
|                 Row = 3, | ||||
|                 UpdateMethod = async (prompt) => | ||||
|                 { | ||||
|                     prompt.Disabled = PageManager.GetTotalPages() == CurrentPage; | ||||
|                     return prompt; | ||||
|                 }, | ||||
|                 Run = async (args, sender, prompt) => | ||||
|                 { | ||||
|                     CurrentPage++; | ||||
|                     await UpdateAsync(); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public abstract Task OnSelect(T item, ComponentInteractionCreateEventArgs args, DiscordClient sender); | ||||
|  | ||||
|         protected int GetTotalPages() | ||||
|         { | ||||
|             return PageManager.GetTotalPages(); | ||||
|         } | ||||
|  | ||||
|         protected async override Task<DiscordMessageBuilder> GetMessageAsync() | ||||
|         { | ||||
|             DiscordEmbedBuilder builder = new DiscordEmbedBuilder() | ||||
|                 .WithTitle(Title) | ||||
|                 .WithFooter($"Page {CurrentPage} of {GetTotalPages()}") | ||||
|                 .WithDescription("Select your desired Tracks"); | ||||
|  | ||||
|             return PopulateMessage(builder); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         protected abstract DiscordMessageBuilder PopulateMessage(DiscordEmbedBuilder builder); | ||||
|  | ||||
|  | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										160
									
								
								TomatenMusicCore/Prompt/Model/PaginatedSelectPrompt.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								TomatenMusicCore/Prompt/Model/PaginatedSelectPrompt.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,160 @@ | ||||
| using DSharpPlus.Entities; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using TomatenMusic.Util; | ||||
| using DSharpPlus; | ||||
| using DSharpPlus.EventArgs; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using TomatenMusic.Prompt.Option; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace TomatenMusic.Prompt.Model | ||||
| { | ||||
|     abstract class PaginatedSelectPrompt<T> : CombinedPrompt | ||||
|     { | ||||
|         protected PageManager<T> PageManager { get; set; } | ||||
|         protected int CurrentPage { get; set; } = 1; | ||||
|  | ||||
|         public string Title { get; set; } | ||||
|         public List<T> SelectedItems { get; set; } = new List<T>(); | ||||
|  | ||||
|  | ||||
|         public PaginatedSelectPrompt(string title, List<T> items, DiscordPromptBase lastPrompt = null, List<DiscordEmbed> embeds = null) : base(lastPrompt) | ||||
|         { | ||||
|             Embeds = embeds; | ||||
|             PageManager = new PageManager<T>(items, 25); | ||||
|             Title = title; | ||||
|             AddOption(new SelectMenuPromptOption | ||||
|             { | ||||
|                 Row = 1, | ||||
|                 MinValues = 1, | ||||
|                 MaxValues = PageManager.GetPage(CurrentPage).Count, | ||||
|                 Content = "Select a Value", | ||||
|                 UpdateMethod = async (option) => | ||||
|                 { | ||||
|                     SelectMenuPromptOption _option = (SelectMenuPromptOption)option; | ||||
|                      | ||||
|                     _option.MaxValues = PageManager.GetPage(CurrentPage).Count; | ||||
|                     _option.Options.Clear(); | ||||
|                     foreach (var item in PageManager.GetPage(CurrentPage)) | ||||
|                     { | ||||
|                         _option.Options.Add(await GetOption(item)); | ||||
|                     } | ||||
|                     foreach (var item in _option.Options) | ||||
|                     { | ||||
|                         foreach (var sOption in SelectedItems) | ||||
|                         { | ||||
|                             PaginatedSelectMenuOption<T> _item = (PaginatedSelectMenuOption<T>)item; | ||||
|                             if (_item.Item.Equals(sOption)) | ||||
|                             { | ||||
|                                 _option.CurrentValues.Add(_item.CustomID); | ||||
|                             } | ||||
|                         } | ||||
|                          | ||||
|                     } | ||||
|  | ||||
|                     return _option; | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|  | ||||
|             AddOption(new ButtonPromptOption | ||||
|             { | ||||
|                 Style = ButtonStyle.Secondary, | ||||
|                 Emoji = new DiscordComponentEmoji("⬅️"), | ||||
|                 Row = 2, | ||||
|                 UpdateMethod = async (prompt) => | ||||
|                 { | ||||
|                     prompt.Disabled = CurrentPage - 1 == 0; | ||||
|                     return prompt; | ||||
|                 }, | ||||
|                 Run = async (args, sender, prompt) => | ||||
|                 { | ||||
|                     CurrentPage--; | ||||
|                     await UpdateAsync(); | ||||
|  | ||||
|                 } | ||||
|             }); | ||||
|             AddOption(new ButtonPromptOption | ||||
|             { | ||||
|                 Style = ButtonStyle.Secondary, | ||||
|                 Emoji = new DiscordComponentEmoji("➡️"), | ||||
|                 Row = 2, | ||||
|                 UpdateMethod = async (prompt) => | ||||
|                 { | ||||
|                     prompt.Disabled = PageManager.GetTotalPages() == CurrentPage; | ||||
|                     return prompt; | ||||
|                 }, | ||||
|                 Run = async (args, sender, prompt) => | ||||
|                 { | ||||
|                     CurrentPage++; | ||||
|                     await UpdateAsync(); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         private async Task<PaginatedSelectMenuOption<T>> GetOption(T item) | ||||
|         { | ||||
|             var option = await ConvertToOption(item); | ||||
|             option.Item = item; | ||||
|             option.CustomID = RandomUtil.GenerateGuid(); | ||||
|             option.Default = SelectedItems.Contains(item); | ||||
|             option.OnSelected = async (args, sender, option) => | ||||
|             { | ||||
|                 PaginatedSelectMenuOption<T> _option = (PaginatedSelectMenuOption<T>)option; | ||||
|                 if (!SelectedItems.Contains(_option.Item)) | ||||
|                     SelectedItems.Add(_option.Item); | ||||
|                 await OnSelect(_option.Item, args, sender); | ||||
|                  | ||||
|             }; | ||||
|             option.OnUnselected = async (args, sender, option) => | ||||
|             { | ||||
|                 PaginatedSelectMenuOption<T> _option = (PaginatedSelectMenuOption<T>)option; | ||||
|                 SelectedItems.Remove(_option.Item); | ||||
|                 await OnUnselect(_option.Item, args, sender); | ||||
|             }; | ||||
|  | ||||
|  | ||||
|             return option; | ||||
|         } | ||||
|         public abstract Task<PaginatedSelectMenuOption<T>> ConvertToOption(T item); | ||||
|  | ||||
|         public abstract Task OnSelect(T item, ComponentInteractionCreateEventArgs args, DiscordClient sender); | ||||
|  | ||||
|         public abstract Task OnUnselect(T item, ComponentInteractionCreateEventArgs args, DiscordClient sender); | ||||
|  | ||||
|         protected int GetTotalPages() | ||||
|         { | ||||
|             return PageManager.GetTotalPages(); | ||||
|         } | ||||
|  | ||||
|         protected async override Task<DiscordMessageBuilder> GetMessageAsync() | ||||
|         { | ||||
|             DiscordEmbedBuilder builder; | ||||
|             if (Embeds != null) | ||||
|             { | ||||
|                 builder = new DiscordEmbedBuilder(Embeds[0]); | ||||
|             }else | ||||
|             { | ||||
|                 builder = new DiscordEmbedBuilder(); | ||||
|             } | ||||
|  | ||||
|             builder | ||||
|                 .WithTitle(Title) | ||||
|                 .WithFooter($"Page {CurrentPage} of {GetTotalPages()}"); | ||||
|  | ||||
|             return PopulateMessage(builder); | ||||
|  | ||||
|         } | ||||
|  | ||||
|         protected abstract DiscordMessageBuilder PopulateMessage(DiscordEmbedBuilder builder); | ||||
|  | ||||
|         public class PaginatedSelectMenuOption<I> : SelectMenuOption | ||||
|         { | ||||
|             public I Item { get; set; } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										15
									
								
								TomatenMusicCore/Prompt/Model/PromptState.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								TomatenMusicCore/Prompt/Model/PromptState.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
|  | ||||
| namespace TomatenMusic.Prompt.Model | ||||
| { | ||||
|     enum PromptState | ||||
|     { | ||||
|  | ||||
|         PREPARED, | ||||
|         OPEN, | ||||
|         INVALID, | ||||
|         RESPONDED | ||||
|     } | ||||
| } | ||||
							
								
								
									
										48
									
								
								TomatenMusicCore/Prompt/Model/SelectPrompt.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								TomatenMusicCore/Prompt/Model/SelectPrompt.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| using DSharpPlus.Entities; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| using TomatenMusic.Prompt.Option; | ||||
| using System.Linq; | ||||
| using DSharpPlus; | ||||
| using DSharpPlus.EventArgs; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using TomatenMusic.Util; | ||||
|  | ||||
|  | ||||
| namespace TomatenMusic.Prompt.Model | ||||
| { | ||||
|     class SelectPrompt : DiscordPromptBase | ||||
|     { | ||||
|         public List<DiscordEmbed> Embeds { get; protected set; } = new List<DiscordEmbed>(); | ||||
|         public string Content { get; protected set; } = ""; | ||||
|         public SelectPrompt(DiscordPromptBase lastPrompt = null, string content = " Example", List<DiscordEmbed> embeds = null) : base(lastPrompt) | ||||
|         { | ||||
|  | ||||
|             this.Content = content; | ||||
|             this.Embeds = embeds == null ? new List<DiscordEmbed>() : embeds; | ||||
|         } | ||||
|  | ||||
|         protected async override Task<DiscordComponent> GetComponentAsync(IPromptOption option) | ||||
|         { | ||||
|  | ||||
|             SelectMenuPromptOption selectOption = (SelectMenuPromptOption)option; | ||||
|             List<DiscordSelectComponentOption> options = new List<DiscordSelectComponentOption>(); | ||||
|             foreach ( var item in selectOption.Options) | ||||
|             { | ||||
|                 options.Add(new DiscordSelectComponentOption(item.Label, item.CustomID, item.Description, item.Default, item.Emoji)); | ||||
|             } | ||||
|  | ||||
|                 return new DiscordSelectComponent(selectOption.CustomID, selectOption.Content, options, selectOption.Disabled, selectOption.MinValues, selectOption.MaxValues); | ||||
|         } | ||||
|  | ||||
|         protected async override Task<DiscordMessageBuilder> GetMessageAsync() | ||||
|         { | ||||
|             return new DiscordMessageBuilder() | ||||
|                 .WithContent(Content) | ||||
|                 .AddEmbeds(Embeds); | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Tim Müller
					Tim Müller