INIT
This commit is contained in:
59
TomatenMusicCore/Prompt/Buttons/AddToQueueButton.cs
Normal file
59
TomatenMusicCore/Prompt/Buttons/AddToQueueButton.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using DSharpPlus.Entities;
|
||||
using Lavalink4NET;
|
||||
using Lavalink4NET.Player;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic.Music;
|
||||
using TomatenMusic.Music.Entitites;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TomatenMusicCore.Music;
|
||||
using TomatenMusicCore.Music.Entities;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
|
||||
namespace TomatenMusic.Prompt.Buttons
|
||||
{
|
||||
class AddToQueueButton : ButtonPromptOption
|
||||
{
|
||||
public TrackList Tracks { get; set; }
|
||||
|
||||
public AddToQueueButton(TrackList tracks, int row, DiscordMember requestMember)
|
||||
{
|
||||
Tracks = tracks;
|
||||
Emoji = new DiscordComponentEmoji("▶️");
|
||||
Row = row;
|
||||
Style = DSharpPlus.ButtonStyle.Secondary;
|
||||
UpdateMethod = (prompt) =>
|
||||
{
|
||||
if (requestMember.VoiceState == null || requestMember.VoiceState.Channel == null)
|
||||
prompt.Disabled = true;
|
||||
|
||||
return Task.FromResult(prompt);
|
||||
};
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
IAudioService audioService = TomatenMusicBot.ServiceProvider.GetRequiredService<IAudioService>();
|
||||
GuildPlayer player;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
player = await audioService.JoinAsync<GuildPlayer>(args.Guild.Id, ((DiscordMember)args.User).VoiceState.Channel.Id, true);
|
||||
|
||||
}catch (Exception ex)
|
||||
{
|
||||
player = audioService.GetPlayer<GuildPlayer>(args.Guild.Id);
|
||||
}
|
||||
await player.PlayItemAsync(Tracks);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
60
TomatenMusicCore/Prompt/Buttons/PlayNowButton.cs
Normal file
60
TomatenMusicCore/Prompt/Buttons/PlayNowButton.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using DSharpPlus.Entities;
|
||||
using Lavalink4NET;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic;
|
||||
using TomatenMusic.Music;
|
||||
using TomatenMusic.Prompt;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
using TomatenMusicCore.Music.Entities;
|
||||
|
||||
namespace TomatenMusicCore.Prompt.Buttons
|
||||
{
|
||||
class PlayNowButton : ButtonPromptOption
|
||||
{
|
||||
public TrackList Tracks { get; set; }
|
||||
|
||||
public PlayNowButton(TrackList tracks, int row, DiscordMember requestMember)
|
||||
{
|
||||
Tracks = tracks;
|
||||
Emoji = new DiscordComponentEmoji("▶");
|
||||
Content = "Now";
|
||||
Row = row;
|
||||
Style = DSharpPlus.ButtonStyle.Secondary;
|
||||
UpdateMethod = (prompt) =>
|
||||
{
|
||||
if (requestMember.VoiceState == null || requestMember.VoiceState.Channel == null)
|
||||
prompt.Disabled = true;
|
||||
|
||||
return Task.FromResult(prompt);
|
||||
};
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
IAudioService audioService = TomatenMusicBot.ServiceProvider.GetRequiredService<IAudioService>();
|
||||
GuildPlayer player;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
player = await audioService.JoinAsync<GuildPlayer>(args.Guild.Id, ((DiscordMember)args.User).VoiceState.Channel.Id, true);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
player = audioService.GetPlayer<GuildPlayer>(args.Guild.Id);
|
||||
}
|
||||
await player.PlayNowAsync(Tracks);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,105 @@
|
||||
using DSharpPlus;
|
||||
using DSharpPlus.Entities;
|
||||
using DSharpPlus.EventArgs;
|
||||
using Lavalink4NET.Player;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic.Music.Entitites;
|
||||
using TomatenMusic.Prompt;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
using TomatenMusic.Util;
|
||||
using TomatenMusicCore.Music;
|
||||
using TomatenMusicCore.Music.Entities;
|
||||
|
||||
namespace TomatenMusicCore.Prompt.Implementation
|
||||
{
|
||||
class PlaylistSongSelectorPrompt : PaginatedSelectPrompt<TomatenMusicTrack>
|
||||
{
|
||||
public bool IsConfirmed { get; set; }
|
||||
public Func<TrackList, Task> ConfirmCallback { get; set; } = (tracks) =>
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
public ILavalinkPlaylist Playlist { get; private set; }
|
||||
|
||||
public PlaylistSongSelectorPrompt(ILavalinkPlaylist playlist, DiscordPromptBase lastPrompt = null, List<DiscordEmbed> embeds = null) : base(playlist.Title, playlist.Tracks.ToList(), lastPrompt, embeds)
|
||||
{
|
||||
Playlist = playlist;
|
||||
AddOption(new ButtonPromptOption
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("✔️"),
|
||||
Row = 3,
|
||||
Style = ButtonStyle.Success,
|
||||
Run = async (args, client, option) =>
|
||||
{
|
||||
if (SelectedItems.Count == 0)
|
||||
{
|
||||
await args.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder().WithContent("Please Select a Song!").AsEphemeral(true));
|
||||
return;
|
||||
}
|
||||
IsConfirmed = true;
|
||||
_ = ConfirmCallback.Invoke(new TrackList(SelectedItems));
|
||||
}
|
||||
});
|
||||
}
|
||||
public override Task<PaginatedSelectMenuOption<TomatenMusicTrack>> ConvertToOption(TomatenMusicTrack item)
|
||||
{
|
||||
return Task.FromResult<PaginatedSelectMenuOption<TomatenMusicTrack>>(new PaginatedSelectMenuOption<TomatenMusicTrack>
|
||||
{
|
||||
Label = item.Title,
|
||||
Description = item.Author
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public override Task OnSelect(TomatenMusicTrack item, ComponentInteractionCreateEventArgs args, DiscordClient sender)
|
||||
{
|
||||
_logger.LogDebug($"Added {item.Title}, {SelectedItems}");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task OnUnselect(TomatenMusicTrack item, ComponentInteractionCreateEventArgs args, DiscordClient sender)
|
||||
{
|
||||
_logger.LogDebug($"Removed {item.Title}");
|
||||
return Task.CompletedTask;
|
||||
|
||||
}
|
||||
|
||||
public async Task<TrackList> AwaitSelectionAsync()
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
while (!IsConfirmed)
|
||||
{
|
||||
if (State == PromptState.INVALID)
|
||||
throw new InvalidOperationException("Prompt has been Invalidated");
|
||||
}
|
||||
IsConfirmed = false;
|
||||
return new TrackList(SelectedItems);
|
||||
});
|
||||
}
|
||||
|
||||
protected override DiscordMessageBuilder PopulateMessage(DiscordEmbedBuilder builder)
|
||||
{
|
||||
|
||||
builder.WithTitle(Title);
|
||||
builder.WithDescription(Common.TrackListString(PageManager.GetPage(CurrentPage), 4000));
|
||||
builder.WithUrl(Playlist.Url);
|
||||
builder.WithAuthor(Playlist.AuthorName, Playlist.AuthorUri.ToString(), Playlist.AuthorThumbnail.ToString());
|
||||
|
||||
List<DiscordEmbed> embeds = new List<DiscordEmbed>();
|
||||
embeds.Add(builder.Build());
|
||||
|
||||
if (Embeds != null)
|
||||
embeds.AddRange(Embeds);
|
||||
|
||||
return new DiscordMessageBuilder().AddEmbeds(embeds);
|
||||
}
|
||||
}
|
||||
}
|
278
TomatenMusicCore/Prompt/Implementation/QueuePrompt.cs
Normal file
278
TomatenMusicCore/Prompt/Implementation/QueuePrompt.cs
Normal file
@@ -0,0 +1,278 @@
|
||||
using DSharpPlus.Entities;
|
||||
using Lavalink4NET.Player;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using TomatenMusic.Music;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
using TomatenMusic.Util;
|
||||
|
||||
namespace TomatenMusic.Prompt.Implementation
|
||||
{
|
||||
class QueuePrompt : ButtonPrompt
|
||||
{
|
||||
|
||||
public static void InvalidateFor(ulong guildId)
|
||||
{
|
||||
foreach (var prompt in ActivePrompts)
|
||||
{
|
||||
if (prompt.State != PromptState.OPEN)
|
||||
continue;
|
||||
if (!(prompt is QueuePrompt))
|
||||
continue;
|
||||
if (((QueuePrompt)prompt).Player.GuildId != guildId)
|
||||
continue;
|
||||
_ = prompt.InvalidateAsync();
|
||||
|
||||
}
|
||||
}
|
||||
public static void UpdateFor(ulong guildId)
|
||||
{
|
||||
_ = Task.Delay(400).ContinueWith(async (task) =>
|
||||
{
|
||||
foreach (var prompt in ActivePrompts)
|
||||
{
|
||||
if (prompt.State != PromptState.OPEN)
|
||||
continue;
|
||||
if (!(prompt is QueuePrompt))
|
||||
continue;
|
||||
if (((QueuePrompt)prompt).Player.GuildId != guildId)
|
||||
continue;
|
||||
_ = prompt.UpdateAsync();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public GuildPlayer Player { get; private set; }
|
||||
|
||||
public QueuePrompt(GuildPlayer player, DiscordPromptBase lastPrompt = null, List<DiscordEmbed> embeds = null) : base(lastPrompt, embeds: embeds)
|
||||
{
|
||||
Player = player;
|
||||
|
||||
AddOption(
|
||||
new ButtonPromptOption()
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("⏯️"),
|
||||
Row = 1,
|
||||
UpdateMethod = (option) =>
|
||||
{
|
||||
ButtonPromptOption button = (ButtonPromptOption)option;
|
||||
if (player.State == PlayerState.Paused)
|
||||
button.Style = DSharpPlus.ButtonStyle.Danger;
|
||||
else
|
||||
button.Style = DSharpPlus.ButtonStyle.Success;
|
||||
|
||||
return Task.FromResult((IPromptOption) button);
|
||||
},
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
|
||||
await Player.TogglePauseAsync();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
AddOption(new ButtonPromptOption()
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("⏮️"),
|
||||
Row = 1,
|
||||
Style = DSharpPlus.ButtonStyle.Secondary,
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
await Player.RewindAsync();
|
||||
}catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
AddOption(new ButtonPromptOption()
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("⏹️"),
|
||||
Row = 1,
|
||||
Style = DSharpPlus.ButtonStyle.Secondary,
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
|
||||
await Player.DisconnectAsync();
|
||||
}
|
||||
});
|
||||
AddOption(new ButtonPromptOption()
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("⏭️"),
|
||||
Row = 1,
|
||||
Style = DSharpPlus.ButtonStyle.Secondary,
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
|
||||
await Player.SkipAsync();
|
||||
|
||||
System.Timers.Timer timer = new System.Timers.Timer(800);
|
||||
timer.Elapsed += (s, args) =>
|
||||
{
|
||||
_ = UpdateAsync();
|
||||
timer.Stop();
|
||||
};
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
AddOption(
|
||||
new ButtonPromptOption()
|
||||
{
|
||||
Row = 1,
|
||||
UpdateMethod = (option) =>
|
||||
{
|
||||
ButtonPromptOption button = (ButtonPromptOption)option;
|
||||
|
||||
if (player.PlayerQueue.LoopType == LoopType.TRACK)
|
||||
{
|
||||
button.Style = DSharpPlus.ButtonStyle.Success;
|
||||
button.Emoji = new DiscordComponentEmoji("🔂");
|
||||
}
|
||||
else if (player.PlayerQueue.LoopType == LoopType.QUEUE)
|
||||
{
|
||||
button.Style = DSharpPlus.ButtonStyle.Success;
|
||||
button.Emoji = new DiscordComponentEmoji("🔁");
|
||||
}
|
||||
else
|
||||
{
|
||||
button.Style = DSharpPlus.ButtonStyle.Danger;
|
||||
button.Emoji = null;
|
||||
button.Content = "Loop";
|
||||
}
|
||||
|
||||
|
||||
return Task.FromResult((IPromptOption)button);
|
||||
},
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (player.PlayerQueue.LoopType)
|
||||
{
|
||||
case LoopType.NONE:
|
||||
_ = Player.SetLoopAsync(LoopType.QUEUE);
|
||||
break;
|
||||
case LoopType.QUEUE:
|
||||
_ = Player.SetLoopAsync(LoopType.TRACK);
|
||||
break;
|
||||
case LoopType.TRACK:
|
||||
_ = Player.SetLoopAsync(LoopType.NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
AddOption(new ButtonPromptOption()
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("🔀"),
|
||||
Row = 2,
|
||||
Style = DSharpPlus.ButtonStyle.Secondary,
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
|
||||
await Player.ShuffleAsync();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
AddOption(new ButtonPromptOption()
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("🚫"),
|
||||
Row = 2,
|
||||
Style = DSharpPlus.ButtonStyle.Secondary,
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
|
||||
Player.PlayerQueue.Queue.Clear();
|
||||
|
||||
_ = UpdateAsync();
|
||||
}
|
||||
});
|
||||
|
||||
AddOption(
|
||||
new ButtonPromptOption()
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("➡️"),
|
||||
Content = "AutoPlay",
|
||||
Row = 2,
|
||||
UpdateMethod = (option) =>
|
||||
{
|
||||
ButtonPromptOption button = (ButtonPromptOption)option;
|
||||
if (player.Autoplay)
|
||||
button.Style = DSharpPlus.ButtonStyle.Success;
|
||||
else
|
||||
button.Style = DSharpPlus.ButtonStyle.Danger;
|
||||
|
||||
return Task.FromResult((IPromptOption)button);
|
||||
},
|
||||
Run = async (args, sender, option) =>
|
||||
{
|
||||
if (!await Player.AreActionsAllowedAsync((DiscordMember)args.User))
|
||||
{
|
||||
_ = args.Interaction.EditOriginalResponseAsync(new DiscordWebhookBuilder().WithContent("Please connect to the bots Channel to use this Interaction"));
|
||||
return;
|
||||
}
|
||||
|
||||
Player.Autoplay = !Player.Autoplay;
|
||||
|
||||
_ = UpdateAsync();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
protected async override Task<DiscordMessageBuilder> GetMessageAsync()
|
||||
{
|
||||
return new DiscordMessageBuilder()
|
||||
.AddEmbed(Common.GetQueueEmbed(Player))
|
||||
.AddEmbed(await Common.CurrentSongEmbedAsync(Player))
|
||||
.AddEmbeds(Embeds);
|
||||
}
|
||||
}
|
||||
}
|
35
TomatenMusicCore/Prompt/Implementation/SongActionPrompt.cs
Normal file
35
TomatenMusicCore/Prompt/Implementation/SongActionPrompt.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using DSharpPlus.Entities;
|
||||
using Lavalink4NET.Player;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic.Music.Entitites;
|
||||
using TomatenMusic.Prompt.Buttons;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using TomatenMusic.Util;
|
||||
using TomatenMusicCore.Music;
|
||||
using TomatenMusicCore.Music.Entities;
|
||||
using TomatenMusicCore.Prompt.Buttons;
|
||||
|
||||
namespace TomatenMusic.Prompt.Implementation
|
||||
{
|
||||
class SongActionPrompt : ButtonPrompt
|
||||
{
|
||||
public LavalinkTrack Track { get; set; }
|
||||
public SongActionPrompt(TomatenMusicTrack track, DiscordMember requestMember, List<DiscordEmbed> embeds = null)
|
||||
{
|
||||
Embeds = embeds == null ? new List<DiscordEmbed>() : embeds;
|
||||
Track = track;
|
||||
|
||||
AddOption(new AddToQueueButton(new TrackList() { track }, 1, requestMember));
|
||||
AddOption(new PlayNowButton(new TrackList() { track }, 1, requestMember));
|
||||
|
||||
}
|
||||
|
||||
protected async override Task<DiscordMessageBuilder> GetMessageAsync()
|
||||
{
|
||||
return new DiscordMessageBuilder().AddEmbed(Common.AsEmbed(Track)).AddEmbeds(Embeds);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
using DSharpPlus.Entities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic.Music.Entitites;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using System.Linq;
|
||||
using TomatenMusic.Util;
|
||||
using TomatenMusic.Music;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TomatenMusic.Prompt.Buttons;
|
||||
using Lavalink4NET.Player;
|
||||
using TomatenMusicCore.Music;
|
||||
using TomatenMusicCore.Music.Entities;
|
||||
using TomatenMusicCore.Prompt.Buttons;
|
||||
|
||||
namespace TomatenMusic.Prompt.Implementation
|
||||
{
|
||||
class SongListActionPrompt : ButtonPrompt
|
||||
{
|
||||
//TODO
|
||||
public TrackList Tracks { get; private set; }
|
||||
|
||||
public SongListActionPrompt(TrackList tracks, DiscordMember requestMember, DiscordPromptBase lastPrompt = null) : base(lastPrompt)
|
||||
{
|
||||
Tracks = tracks;
|
||||
|
||||
AddOption(new AddToQueueButton(tracks, 1, requestMember));
|
||||
AddOption(new PlayNowButton(tracks, 1, requestMember));
|
||||
|
||||
}
|
||||
|
||||
protected override Task<DiscordMessageBuilder> GetMessageAsync()
|
||||
{
|
||||
|
||||
DiscordEmbedBuilder builder = new DiscordEmbedBuilder()
|
||||
.WithTitle("What do you want to do with these Tracks?");
|
||||
|
||||
builder.WithDescription(Common.TrackListString(Tracks, 1000));
|
||||
|
||||
return Task.FromResult(new DiscordMessageBuilder().WithEmbed(builder.Build()));
|
||||
}
|
||||
}
|
||||
}
|
103
TomatenMusicCore/Prompt/Implementation/SongSelectorPrompt.cs
Normal file
103
TomatenMusicCore/Prompt/Implementation/SongSelectorPrompt.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using DSharpPlus;
|
||||
using System.Threading.Tasks;
|
||||
using DSharpPlus.EventArgs;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DSharpPlus.Entities;
|
||||
using TomatenMusic.Util;
|
||||
using TomatenMusic.Music.Entitites;
|
||||
using TomatenMusic.Music;
|
||||
using System.Linq;
|
||||
using Lavalink4NET.Player;
|
||||
using TomatenMusicCore.Music;
|
||||
using TomatenMusicCore.Music.Entities;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
|
||||
namespace TomatenMusic.Prompt.Implementation
|
||||
{
|
||||
sealed class SongSelectorPrompt : PaginatedSelectPrompt<LavalinkTrack>
|
||||
{
|
||||
public bool IsConfirmed { get; set; }
|
||||
public Func<TrackList, Task> ConfirmCallback { get; set; } = (tracks) =>
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
public IEnumerable<LavalinkTrack> Tracks { get; private set; }
|
||||
|
||||
public SongSelectorPrompt(string title, IEnumerable<LavalinkTrack> tracks, DiscordPromptBase lastPrompt = null, List<DiscordEmbed> embeds = null) : base(title, tracks.ToList(), lastPrompt, embeds)
|
||||
{
|
||||
Title = title;
|
||||
Tracks = tracks;
|
||||
AddOption(new ButtonPromptOption
|
||||
{
|
||||
Emoji = new DiscordComponentEmoji("✔️"),
|
||||
Row = 3,
|
||||
Style = ButtonStyle.Success,
|
||||
Run = async (args, client, option) =>
|
||||
{
|
||||
if (SelectedItems.Count == 0)
|
||||
{
|
||||
await args.Interaction.CreateFollowupMessageAsync(new DiscordFollowupMessageBuilder().WithContent("Please Select a Song!").AsEphemeral(true));
|
||||
return;
|
||||
}
|
||||
IsConfirmed = true;
|
||||
_ = ConfirmCallback.Invoke(new TrackList(SelectedItems));
|
||||
}
|
||||
});
|
||||
}
|
||||
public override Task<PaginatedSelectMenuOption<LavalinkTrack>> ConvertToOption(LavalinkTrack item)
|
||||
{
|
||||
return Task.FromResult<PaginatedSelectMenuOption<LavalinkTrack>>(new PaginatedSelectMenuOption<LavalinkTrack>
|
||||
{
|
||||
Label = item.Title,
|
||||
Description = item.Author
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public override Task OnSelect(LavalinkTrack item, ComponentInteractionCreateEventArgs args, DiscordClient sender)
|
||||
{
|
||||
_logger.LogDebug($"Added {item.Title}, {SelectedItems}");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override Task OnUnselect(LavalinkTrack item, ComponentInteractionCreateEventArgs args, DiscordClient sender)
|
||||
{
|
||||
_logger.LogDebug($"Removed {item.Title}");
|
||||
return Task.CompletedTask;
|
||||
|
||||
}
|
||||
|
||||
public async Task<List<LavalinkTrack>> AwaitSelectionAsync()
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
while (!IsConfirmed)
|
||||
{
|
||||
if (State == PromptState.INVALID)
|
||||
throw new InvalidOperationException("Prompt has been Invalidated");
|
||||
}
|
||||
IsConfirmed = false;
|
||||
return SelectedItems;
|
||||
});
|
||||
}
|
||||
|
||||
protected override DiscordMessageBuilder PopulateMessage(DiscordEmbedBuilder builder)
|
||||
{
|
||||
|
||||
builder.WithTitle(Title);
|
||||
builder.WithDescription(Common.TrackListString(PageManager.GetPage(CurrentPage), 4000));
|
||||
List<DiscordEmbed> embeds = new List<DiscordEmbed>();
|
||||
embeds.Add(builder.Build());
|
||||
|
||||
if (Embeds != null)
|
||||
embeds.AddRange(Embeds);
|
||||
|
||||
return new DiscordMessageBuilder().AddEmbeds(embeds);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using DSharpPlus;
|
||||
using System.Threading.Tasks;
|
||||
using DSharpPlus.EventArgs;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DSharpPlus.Entities;
|
||||
|
||||
namespace TomatenMusic.Prompt.Implementation
|
||||
{
|
||||
class StringSelectorPrompt : PaginatedSelectPrompt<string>
|
||||
{
|
||||
public StringSelectorPrompt(string title, List<string> strings, DiscordPromptBase lastPrompt = null) : base(title, strings, lastPrompt)
|
||||
{
|
||||
}
|
||||
public async override Task<PaginatedSelectMenuOption<string>> ConvertToOption(string item)
|
||||
{
|
||||
return new PaginatedSelectMenuOption<string>
|
||||
{
|
||||
Label = item
|
||||
};
|
||||
}
|
||||
|
||||
public async override Task OnSelect(string item, ComponentInteractionCreateEventArgs args, DiscordClient sender)
|
||||
{
|
||||
}
|
||||
|
||||
public async override Task OnUnselect(string item, ComponentInteractionCreateEventArgs args, DiscordClient sender)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override DiscordMessageBuilder PopulateMessage(DiscordEmbedBuilder builder)
|
||||
{
|
||||
foreach (var item in PageManager.GetPage(CurrentPage))
|
||||
{
|
||||
builder.AddField(item, item);
|
||||
}
|
||||
|
||||
return new DiscordMessageBuilder().WithEmbed(builder);
|
||||
}
|
||||
}
|
||||
}
|
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);
|
||||
}
|
||||
}
|
||||
}
|
499
TomatenMusicCore/Prompt/Model/DiscordPromptBase.cs
Normal file
499
TomatenMusicCore/Prompt/Model/DiscordPromptBase.cs
Normal file
@@ -0,0 +1,499 @@
|
||||
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; }
|
||||
public System.Timers.Timer TimeoutTimer { get; 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;
|
||||
|
||||
long timeoutTime = (Interaction.CreationTimestamp.ToUnixTimeMilliseconds() + 900000) - DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||
|
||||
if (TimeoutTimer != null)
|
||||
TimeoutTimer.Close();
|
||||
|
||||
TimeoutTimer = new System.Timers.Timer(timeoutTime);
|
||||
TimeoutTimer.Elapsed += OnTimeout;
|
||||
TimeoutTimer.AutoReset = false;
|
||||
TimeoutTimer.Start();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
long timeoutTime = (Interaction.CreationTimestamp.ToUnixTimeMilliseconds() + 900000) - DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||
|
||||
if (TimeoutTimer != null)
|
||||
TimeoutTimer.Close();
|
||||
|
||||
TimeoutTimer = new System.Timers.Timer(timeoutTime);
|
||||
TimeoutTimer.Elapsed += OnTimeout;
|
||||
TimeoutTimer.AutoReset = false;
|
||||
TimeoutTimer.Start();
|
||||
|
||||
}
|
||||
|
||||
private void OnTimeout(object? sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
_ = InvalidateAsync();
|
||||
}
|
||||
|
||||
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;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
|
||||
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, 10);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
32
TomatenMusicCore/Prompt/Option/ButtonPromptOption.cs
Normal file
32
TomatenMusicCore/Prompt/Option/ButtonPromptOption.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DSharpPlus;
|
||||
using DSharpPlus.Entities;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
|
||||
|
||||
namespace TomatenMusic.Prompt.Option
|
||||
{
|
||||
class ButtonPromptOption : IPromptOption
|
||||
{
|
||||
|
||||
public ButtonStyle Style { get; set; } = ButtonStyle.Primary;
|
||||
public string Content { get; set; } = " ";
|
||||
public DiscordComponentEmoji Emoji { get; set; }
|
||||
public bool Disabled { get; set; } = false;
|
||||
public string CustomID { get; set; }
|
||||
public string Link { get; set; }
|
||||
public int Row { get; set; }
|
||||
public Func<Option.IPromptOption, Task<Option.IPromptOption>> UpdateMethod { get; set; } = async prompt =>
|
||||
{
|
||||
return prompt;
|
||||
};
|
||||
public Func<DSharpPlus.EventArgs.ComponentInteractionCreateEventArgs, DiscordClient, IPromptOption, Task> Run { get; set; } = async (args, sender, prompt) =>
|
||||
{
|
||||
|
||||
};
|
||||
}
|
||||
}
|
23
TomatenMusicCore/Prompt/Option/IPromptOption.cs
Normal file
23
TomatenMusicCore/Prompt/Option/IPromptOption.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DSharpPlus;
|
||||
using DSharpPlus.Entities;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic.Prompt.Option;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
|
||||
|
||||
namespace TomatenMusic.Prompt.Option
|
||||
{
|
||||
interface IPromptOption
|
||||
{
|
||||
public string Content { get; set; }
|
||||
public string CustomID { get; set; }
|
||||
public int Row { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public Func<IPromptOption, Task<IPromptOption>> UpdateMethod { get; set; }
|
||||
public Func<DSharpPlus.EventArgs.ComponentInteractionCreateEventArgs, DiscordClient, IPromptOption, Task> Run { get; set; }
|
||||
|
||||
}
|
||||
}
|
23
TomatenMusicCore/Prompt/Option/SelectMenuOption.cs
Normal file
23
TomatenMusicCore/Prompt/Option/SelectMenuOption.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using DSharpPlus;
|
||||
using DSharpPlus.EventArgs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using DSharpPlus.Entities;
|
||||
|
||||
namespace TomatenMusic.Prompt.Option
|
||||
{
|
||||
class SelectMenuOption
|
||||
{
|
||||
public string Label { get; set; }
|
||||
public string CustomID { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool Default { get; set; }
|
||||
public DiscordComponentEmoji Emoji { get; set; }
|
||||
public Func<ComponentInteractionCreateEventArgs, DiscordClient, SelectMenuOption, Task> OnSelected { get; set; }
|
||||
public Func<ComponentInteractionCreateEventArgs, DiscordClient, SelectMenuOption, Task> OnUnselected { get; set; }
|
||||
|
||||
}
|
||||
}
|
50
TomatenMusicCore/Prompt/Option/SelectMenuPromptOption.cs
Normal file
50
TomatenMusicCore/Prompt/Option/SelectMenuPromptOption.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using DSharpPlus;
|
||||
using DSharpPlus.Entities;
|
||||
using DSharpPlus.EventArgs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TomatenMusic.Prompt.Model;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace TomatenMusic.Prompt.Option
|
||||
{
|
||||
class SelectMenuPromptOption : IPromptOption
|
||||
{
|
||||
public string Content { get; set; } = " ";
|
||||
public string CustomID { get; set; }
|
||||
public int Row { get; set; } = 1;
|
||||
public bool Disabled { get; set; } = false;
|
||||
public List<SelectMenuOption> Options { get; set; } = new List<SelectMenuOption>();
|
||||
public int MinValues { get; set; } = 1;
|
||||
public int MaxValues { get; set; } = 1;
|
||||
public List<string> CurrentValues { get; set; } = new List<string>();
|
||||
|
||||
|
||||
public Func<IPromptOption, Task<IPromptOption>> UpdateMethod { get; set; } = async (prompt) =>
|
||||
{
|
||||
return prompt;
|
||||
};
|
||||
public Func<ComponentInteractionCreateEventArgs, DiscordClient, IPromptOption, Task> Run { get; set; } = async (args, sender, option) =>
|
||||
{
|
||||
SelectMenuPromptOption _option = (SelectMenuPromptOption)option;
|
||||
foreach (var item in _option.Options)
|
||||
{
|
||||
if (_option.CurrentValues.Contains(item.CustomID) && !args.Values.Contains(item.CustomID))
|
||||
{
|
||||
await item.OnUnselected.Invoke(args, sender, item);
|
||||
}
|
||||
if (!_option.CurrentValues.Contains(item.CustomID) && args.Values.Contains(item.CustomID))
|
||||
{
|
||||
await item.OnSelected.Invoke(args, sender, item);
|
||||
}
|
||||
}
|
||||
_option.CurrentValues = new List<string>(args.Values);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user