Merge branch 'dev'
This commit is contained in:
		| @@ -1,5 +1,29 @@ | |||||||
| mode: ContinuousDelivery | mode: ContinuousDelivery | ||||||
| branches: {} | branches: | ||||||
|  |   main: | ||||||
|  |     regex: ^master$|^main$ | ||||||
|  |     mode: ContinuousDelivery | ||||||
|  |     tag: '' | ||||||
|  |     increment: None | ||||||
|  |     prevent-increment-of-merged-branch-version: true | ||||||
|  |     track-merge-target: false | ||||||
|  |     source-branches: [ 'develop', 'release' ] | ||||||
|  |     tracks-release-branches: false | ||||||
|  |     is-release-branch: true | ||||||
|  |     is-mainline: true | ||||||
|  |     pre-release-weight: 55000 | ||||||
|  |   develop: | ||||||
|  |     regex: ^dev(elop)?(ment)?$ | ||||||
|  |     mode: ContinuousDeployment | ||||||
|  |     tag: pre | ||||||
|  |     increment: None | ||||||
|  |     prevent-increment-of-merged-branch-version: false | ||||||
|  |     track-merge-target: true | ||||||
|  |     source-branches: [] | ||||||
|  |     tracks-release-branches: true | ||||||
|  |     is-release-branch: false | ||||||
|  |     is-mainline: false | ||||||
|  |     pre-release-weight: 0 | ||||||
| ignore: | ignore: | ||||||
|   sha: [] |   sha: [] | ||||||
| merge-message-formats: {} | merge-message-formats: {} | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| { | { | ||||||
|   "TOKEN": "YOUR_BOT_TOKEN", |   "TOKEN": "Bot_Token", | ||||||
|   "LavaLinkPassword": " ", |   "LavaLinkPassword": " ", | ||||||
|   "SpotifyClientId": " ", |   "SpotifyClientId": " ", | ||||||
|   "SpotifyClientSecret": " ", |   "SpotifyClientSecret": " ", | ||||||
|   "YoutubeApiKey": " " |   "YoutubeApiKey": " " | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -213,7 +213,7 @@ namespace TomatenMusic.Commands | |||||||
|                         LavalinkPlaylist playlist = response.Playlist; |                         LavalinkPlaylist playlist = response.Playlist; | ||||||
|                         await player.PlayPlaylistAsync(playlist); |                         await player.PlayPlaylistAsync(playlist); | ||||||
|  |  | ||||||
|                         _ = ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent("Now Playing:").AddEmbed( |                         await ctx.EditResponseAsync(new DiscordWebhookBuilder().WithContent("Now Playing:").AddEmbed( | ||||||
|                         Common.AsEmbed(playlist) |                         Common.AsEmbed(playlist) | ||||||
|                         )); |                         )); | ||||||
|  |  | ||||||
| @@ -231,7 +231,7 @@ namespace TomatenMusic.Commands | |||||||
|                 catch (Exception ex) |                 catch (Exception ex) | ||||||
|                 { |                 { | ||||||
|                     await ctx.EditResponseAsync(new DiscordWebhookBuilder() |                     await ctx.EditResponseAsync(new DiscordWebhookBuilder() | ||||||
|                      .WithContent($"❌ An error occured while playing your Track: ``{ex.Message}``") |                      .WithContent($"❌ An error occured while playing your Track: ``{ex.Message}``, ```{ex.StackTrace}```") | ||||||
|                       ); |                       ); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -40,8 +40,10 @@ namespace TomatenMusic.Music | |||||||
|         { |         { | ||||||
|             return Task.Run(() => |             return Task.Run(() => | ||||||
|             { |             { | ||||||
|                 if (CurrentPlaylist == null) |                 if (CurrentPlaylist == null && Queue.Count == 0) | ||||||
|                     CurrentPlaylist = playlist; |                     CurrentPlaylist = playlist; | ||||||
|  |                 else | ||||||
|  |                     CurrentPlaylist = null; | ||||||
|  |  | ||||||
|                 _logger.LogInformation("Queued Playlist {0}", playlist.Name); |                 _logger.LogInformation("Queued Playlist {0}", playlist.Name); | ||||||
|                 foreach (LavalinkTrack track in playlist.Tracks) |                 foreach (LavalinkTrack track in playlist.Tracks) | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ namespace TomatenMusic.Services | |||||||
|  |  | ||||||
|                     if (track == null) throw new ArgumentException("This Spotify Track was not found on Youtube"); |                     if (track == null) throw new ArgumentException("This Spotify Track was not found on Youtube"); | ||||||
|  |  | ||||||
|                     tracks.Add(await FullTrackContext.PopulateAsync(track, sTrack.Uri)); |                     tracks.Add(await FullTrackContext.PopulateAsync(track, sTrack.Uri.Replace("spotify:track:", ""))); | ||||||
|                 } |                 } | ||||||
|                 Uri uri; |                 Uri uri; | ||||||
|                 Uri.TryCreate(url, UriKind.Absolute, out uri); |                 Uri.TryCreate(url, UriKind.Absolute, out uri); | ||||||
| @@ -98,7 +98,7 @@ namespace TomatenMusic.Services | |||||||
|  |  | ||||||
|                         if (track == null) throw new ArgumentException("This Spotify Track was not found on Youtube"); |                         if (track == null) throw new ArgumentException("This Spotify Track was not found on Youtube"); | ||||||
|  |  | ||||||
|                         tracks.Add(await FullTrackContext.PopulateAsync(track, fullTrack.Uri)); |                         tracks.Add(await FullTrackContext.PopulateAsync(track, fullTrack.Uri.Replace("spotify:track:", ""))); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                 } |                 } | ||||||
| @@ -115,23 +115,35 @@ namespace TomatenMusic.Services | |||||||
|         public async Task<SpotifyPlaylist> PopulateSpotifyPlaylistAsync(SpotifyPlaylist playlist) |         public async Task<SpotifyPlaylist> PopulateSpotifyPlaylistAsync(SpotifyPlaylist playlist) | ||||||
|         { |         { | ||||||
|             var list = await this.Playlists.Get(playlist.Identifier); |             var list = await this.Playlists.Get(playlist.Identifier); | ||||||
|             playlist.Description = list.Description; |             string desc = list.Description; | ||||||
|             playlist.AuthorUri = new Uri(list.Owner.Uri); |  | ||||||
|  |             playlist.Description = desc.Substring(0, Math.Min(desc.Length, 1024)) + (desc.Length > 1020 ? "..." : " "); | ||||||
|  |             if (playlist.Description.Length < 2) | ||||||
|  |                 playlist.Description = "None"; | ||||||
|  |  | ||||||
|  |             playlist.AuthorUri = new Uri($"https://open.spotify.com/user/{list.Owner.Id}"); | ||||||
|             playlist.AuthorName = list.Owner.DisplayName; |             playlist.AuthorName = list.Owner.DisplayName; | ||||||
|             playlist.Followers = list.Followers.Total; |             playlist.Followers = list.Followers.Total; | ||||||
|             playlist.Url = new Uri(list.Uri); |             playlist.Url = new Uri($"https://open.spotify.com/playlist/{playlist.Identifier}"); | ||||||
|  |             try | ||||||
|  |             { | ||||||
|                 playlist.AuthorThumbnail = new Uri(list.Owner.Images.First().Url); |                 playlist.AuthorThumbnail = new Uri(list.Owner.Images.First().Url); | ||||||
|  |             } | ||||||
|  |             catch (Exception ex) { } | ||||||
|  |  | ||||||
|             return playlist; |             return playlist; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public async Task<SpotifyPlaylist> PopulateSpotifyAlbumAsync(SpotifyPlaylist playlist) |         public async Task<SpotifyPlaylist> PopulateSpotifyAlbumAsync(SpotifyPlaylist playlist) | ||||||
|         { |         { | ||||||
|             var list = await this.Albums.Get(playlist.Identifier); |             var list = await this.Albums.Get(playlist.Identifier); | ||||||
|             playlist.Description = list.Label; |             string desc = list.Label; | ||||||
|             playlist.AuthorUri = new Uri(list.Artists.First().Uri); |  | ||||||
|  |             playlist.Description = desc.Substring(0, Math.Min(desc.Length, 1024)) + (desc.Length > 1020 ? "..." : " "); | ||||||
|  |             playlist.AuthorUri = new Uri($"https://open.spotify.com/user/{list.Artists.First().Uri}"); | ||||||
|             playlist.AuthorName = list.Artists.First().Name; |             playlist.AuthorName = list.Artists.First().Name; | ||||||
|             playlist.Followers = list.Popularity; |             playlist.Followers = list.Popularity; | ||||||
|             playlist.Url = new Uri(list.Uri); |             playlist.Url = new Uri($"https://open.spotify.com/album/{playlist.Identifier}"); | ||||||
|  |  | ||||||
|             return playlist; |             return playlist; | ||||||
|         } |         } | ||||||
| @@ -147,7 +159,7 @@ namespace TomatenMusic.Services | |||||||
|             context.SpotifyAlbum = spotifyTrack.Album; |             context.SpotifyAlbum = spotifyTrack.Album; | ||||||
|             context.SpotifyArtists = spotifyTrack.Artists; |             context.SpotifyArtists = spotifyTrack.Artists; | ||||||
|             context.SpotifyPopularity = spotifyTrack.Popularity; |             context.SpotifyPopularity = spotifyTrack.Popularity; | ||||||
|             context.SpotifyUri = new Uri(spotifyTrack.Uri); |             context.SpotifyUri = new Uri($"https://open.spotify.com/track/{context.SpotifyIdentifier}"); | ||||||
|             track.Context = context; |             track.Context = context; | ||||||
|  |  | ||||||
|             return track; |             return track; | ||||||
|   | |||||||
| @@ -41,6 +41,8 @@ namespace TomatenMusic.Music | |||||||
|             else |             else | ||||||
|                 loadResult = await _audioService.LoadTracksAsync(query, SearchMode.YouTube); |                 loadResult = await _audioService.LoadTracksAsync(query, SearchMode.YouTube); | ||||||
| 
 | 
 | ||||||
|  |             if (uri != null && uri.AbsolutePath.Contains(".")) | ||||||
|  |                 return await SearchAsync(uri); | ||||||
| 
 | 
 | ||||||
|             if (loadResult.LoadType == TrackLoadType.LoadFailed) throw new ArgumentException("Track loading failed"); |             if (loadResult.LoadType == TrackLoadType.LoadFailed) throw new ArgumentException("Track loading failed"); | ||||||
| 
 | 
 | ||||||
| @@ -39,7 +39,9 @@ namespace TomatenMusic.Services | |||||||
|                 context.YoutubeAuthorSubs = (ulong) channel.Statistics.SubscriberCount; |                 context.YoutubeAuthorSubs = (ulong) channel.Statistics.SubscriberCount; | ||||||
|             context.YoutubeAuthorThumbnail = new Uri(channel.Snippet.Thumbnails.High.Url); |             context.YoutubeAuthorThumbnail = new Uri(channel.Snippet.Thumbnails.High.Url); | ||||||
|             context.YoutubeAuthorUri = new Uri($"https://www.youtube.com/channel/{channel.Id}"); |             context.YoutubeAuthorUri = new Uri($"https://www.youtube.com/channel/{channel.Id}"); | ||||||
|             context.YoutubeDescription = video.Snippet.Description; |             string desc = video.Snippet.Description; | ||||||
|  |  | ||||||
|  |             context.YoutubeDescription = desc.Substring(0, Math.Min(desc.Length, 1024)) + (desc.Length > 1020 ? "..." : " "); | ||||||
|             if (video.Statistics.LikeCount != null) |             if (video.Statistics.LikeCount != null) | ||||||
|                 context.YoutubeLikes = (ulong) video.Statistics.LikeCount; |                 context.YoutubeLikes = (ulong) video.Statistics.LikeCount; | ||||||
|             context.YoutubeTags = video.Snippet.Tags; |             context.YoutubeTags = video.Snippet.Tags; | ||||||
| @@ -66,7 +68,10 @@ namespace TomatenMusic.Services | |||||||
|  |  | ||||||
|             string desc = list.Snippet.Description; |             string desc = list.Snippet.Description; | ||||||
|  |  | ||||||
|             playlist.Description = desc.Substring(0, Math.Min(desc.Length, 4092)) + (desc.Length > 4092 ? "..." : " "); |             playlist.Description = desc.Substring(0, Math.Min(desc.Length, 1024)) + (desc.Length > 1020 ? "..." : " "); | ||||||
|  |             if (playlist.Description == "") | ||||||
|  |                 playlist.Description = "None"; | ||||||
|  |  | ||||||
|             playlist.Thumbnail = new Uri(list.Snippet.Thumbnails.High.Url); |             playlist.Thumbnail = new Uri(list.Snippet.Thumbnails.High.Url); | ||||||
|             playlist.CreationTime = (DateTime)list.Snippet.PublishedAt; |             playlist.CreationTime = (DateTime)list.Snippet.PublishedAt; | ||||||
|             playlist.YoutubeItem = list; |             playlist.YoutubeItem = list; | ||||||
|   | |||||||
| @@ -4,7 +4,6 @@ using Microsoft.Extensions.Logging; | |||||||
| using DSharpPlus; | using DSharpPlus; | ||||||
| using DSharpPlus.EventArgs; | using DSharpPlus.EventArgs; | ||||||
| using DSharpPlus.Entities; | using DSharpPlus.Entities; | ||||||
| using DSharpPlus.Net; |  | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using DSharpPlus.SlashCommands; | using DSharpPlus.SlashCommands; | ||||||
| using DSharpPlus.SlashCommands.EventArgs; | using DSharpPlus.SlashCommands.EventArgs; | ||||||
| @@ -77,7 +76,6 @@ namespace TomatenMusic | |||||||
|  |  | ||||||
|                     }) |                     }) | ||||||
|  |  | ||||||
|                     // Lavalink |  | ||||||
|                     .AddSingleton<IDiscordClientWrapper, DiscordShardedClientWrapper>() |                     .AddSingleton<IDiscordClientWrapper, DiscordShardedClientWrapper>() | ||||||
|                     .AddSingleton<IAudioService, LavalinkNode>() |                     .AddSingleton<IAudioService, LavalinkNode>() | ||||||
|                     .AddSingleton(new InactivityTrackingOptions |                     .AddSingleton(new InactivityTrackingOptions | ||||||
| @@ -114,7 +112,6 @@ namespace TomatenMusic | |||||||
|         { |         { | ||||||
|             await BuildServiceProvider(); |             await BuildServiceProvider(); | ||||||
|  |  | ||||||
|             //_ = _host.StartAsync(); |  | ||||||
|  |  | ||||||
|             _host.Start(); |             _host.Start(); | ||||||
|             var client = ServiceProvider.GetRequiredService<DiscordShardedClient>(); |             var client = ServiceProvider.GetRequiredService<DiscordShardedClient>(); | ||||||
| @@ -126,15 +123,10 @@ namespace TomatenMusic | |||||||
|             { |             { | ||||||
|                 Services = ServiceProvider |                 Services = ServiceProvider | ||||||
|             }); |             }); | ||||||
|             /* |  | ||||||
|             slash.RegisterCommands<MusicCommands>(888493810554900491); |  | ||||||
|             slash.RegisterCommands<PlayQueueGroup>(888493810554900491); |  | ||||||
|             slash.RegisterCommands<PlayNowGroup>(888493810554900491); |  | ||||||
|              |              | ||||||
|             slash.RegisterCommands<MusicCommands>(835089895092387872); |             //slash.RegisterCommands<MusicCommands>(888493810554900491); | ||||||
|             slash.RegisterCommands<PlayQueueGroup>(835089895092387872); |             //slash.RegisterCommands<PlayQueueGroup>(888493810554900491); | ||||||
|             slash.RegisterCommands<PlayNowGroup>(835089895092387872); |             //slash.RegisterCommands<PlayNowGroup>(888493810554900491); | ||||||
|             */ |  | ||||||
|  |  | ||||||
|             slash.RegisterCommands<MusicCommands>(); |             slash.RegisterCommands<MusicCommands>(); | ||||||
|             slash.RegisterCommands<PlayQueueGroup>(); |             slash.RegisterCommands<PlayQueueGroup>(); | ||||||
| @@ -194,7 +186,7 @@ namespace TomatenMusic | |||||||
|             if (e.Exception is NotFoundException) |             if (e.Exception is NotFoundException) | ||||||
|                 logger.LogDebug($"{ ((NotFoundException)e.Exception).JsonMessage }"); |                 logger.LogDebug($"{ ((NotFoundException)e.Exception).JsonMessage }"); | ||||||
|             if (e.Exception is BadRequestException) |             if (e.Exception is BadRequestException) | ||||||
|                 logger.LogDebug($"{ ((BadRequestException)e.Exception).JsonMessage }"); |                 logger.LogInformation($"{ ((BadRequestException)e.Exception).Errors }"); | ||||||
|             return Task.CompletedTask; |             return Task.CompletedTask; | ||||||
|  |  | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -104,9 +104,9 @@ namespace TomatenMusic.Util | |||||||
|                 .WithAuthor(playlist.AuthorName, playlist.AuthorUri.ToString(), youtubePlaylist.AuthorThumbnail.ToString()) |                 .WithAuthor(playlist.AuthorName, playlist.AuthorUri.ToString(), youtubePlaylist.AuthorThumbnail.ToString()) | ||||||
|                 .WithTitle(playlist.Name) |                 .WithTitle(playlist.Name) | ||||||
|                 .WithUrl(playlist.Url) |                 .WithUrl(playlist.Url) | ||||||
|                 .WithDescription(playlist.Description) |                 .WithDescription(TrackListString(playlist.Tracks)) | ||||||
|                 .WithImageUrl(youtubePlaylist.Thumbnail) |                 .WithImageUrl(youtubePlaylist.Thumbnail) | ||||||
|                 .AddField("Tracks", TrackListString(playlist.Tracks), false) |                 .AddField("Description", playlist.Description, false) | ||||||
|                 .AddField("Track Count", $"{playlist.Tracks.Count()} Tracks", true) |                 .AddField("Track Count", $"{playlist.Tracks.Count()} Tracks", true) | ||||||
|                 .AddField("Length", $"{Common.GetTimestamp(playlist.GetLength())}", true) |                 .AddField("Length", $"{Common.GetTimestamp(playlist.GetLength())}", true) | ||||||
|                 .AddField("Create Date", $"{youtubePlaylist.CreationTime:dd. MMMM, yyyy}", true); |                 .AddField("Create Date", $"{youtubePlaylist.CreationTime:dd. MMMM, yyyy}", true); | ||||||
| @@ -115,17 +115,21 @@ namespace TomatenMusic.Util | |||||||
|             { |             { | ||||||
|                 SpotifyPlaylist spotifyPlaylist = (SpotifyPlaylist)playlist; |                 SpotifyPlaylist spotifyPlaylist = (SpotifyPlaylist)playlist; | ||||||
|                 builder |                 builder | ||||||
|                 .WithAuthor(playlist.AuthorName, playlist.AuthorUri.ToString(), spotifyPlaylist.AuthorThumbnail.ToString()) |  | ||||||
|                 .WithTitle(playlist.Name) |                 .WithTitle(playlist.Name) | ||||||
|                 .WithUrl(playlist.Url) |                 .WithUrl(playlist.Url) | ||||||
|                 .WithDescription(playlist.Description) |                 .WithDescription(TrackListString(playlist.Tracks)) | ||||||
|                 .AddField("Tracks", TrackListString(playlist.Tracks), false) |                 .AddField("Description", playlist.Description, false) | ||||||
|                 .AddField("Track Count", $"{playlist.Tracks.Count()} Tracks", true) |                 .AddField("Track Count", $"{playlist.Tracks.Count()} Tracks", true) | ||||||
|                 .AddField("Length", $"{Common.GetTimestamp(playlist.GetLength())}", true) |                 .AddField("Length", $"{Common.GetTimestamp(playlist.GetLength())}", true) | ||||||
|                 .AddField("Spotify Followers", $"{spotifyPlaylist.Followers:N0}", true); |                 .AddField("Spotify Followers", $"{spotifyPlaylist.Followers:N0}", true); | ||||||
|  |                 if (spotifyPlaylist.AuthorThumbnail != null) | ||||||
|  |                 { | ||||||
|  |                     builder.WithAuthor(playlist.AuthorName, playlist.AuthorUri.ToString(), spotifyPlaylist.AuthorThumbnail.ToString()); | ||||||
|  |                 }else | ||||||
|  |                     builder.WithAuthor(playlist.AuthorName, playlist.AuthorUri.ToString()); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             return builder; |             return builder.Build(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static DiscordEmbed GetQueueEmbed(GuildPlayer player) |         public static DiscordEmbed GetQueueEmbed(GuildPlayer player) | ||||||
| @@ -161,9 +165,9 @@ namespace TomatenMusic.Util | |||||||
|             foreach (LavalinkTrack track in tracks) |             foreach (LavalinkTrack track in tracks) | ||||||
|             { |             { | ||||||
|                 FullTrackContext context = (FullTrackContext)track.Context; |                 FullTrackContext context = (FullTrackContext)track.Context; | ||||||
|                 if (count > 15) |                 if (count > 10) | ||||||
|                 { |                 { | ||||||
|                     builder.Append(String.Format("***And {0} more...***", tracks.Count() - 15)); |                     builder.Append(String.Format("***And {0} more...***", tracks.Count() - 10)); | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -259,16 +263,17 @@ namespace TomatenMusic.Util | |||||||
|  |  | ||||||
|             string progressBar = $"|{ProgressBar((int)player.Position.Position.TotalSeconds, (int)track.Duration.TotalSeconds)}|\n [{Common.GetTimestamp(player.Position.Position)}/{Common.GetTimestamp(track.Duration)}]"; |             string progressBar = $"|{ProgressBar((int)player.Position.Position.TotalSeconds, (int)track.Duration.TotalSeconds)}|\n [{Common.GetTimestamp(player.Position.Position)}/{Common.GetTimestamp(track.Duration)}]"; | ||||||
|              |              | ||||||
|             builder.WithAuthor(track.Author, context.YoutubeAuthorUri.ToString(), context.YoutubeAuthorThumbnail.ToString()); |             builder.WithAuthor(track.Author); | ||||||
|             builder.WithTitle(track.Title); |             builder.WithTitle(track.Title); | ||||||
|             builder.WithUrl(context.YoutubeUri); |             builder.WithUrl(track.Source); | ||||||
|             builder.WithImageUrl(context.YoutubeThumbnail); |  | ||||||
|             builder.WithColor(player.State == PlayerState.Paused ? DiscordColor.Orange : DiscordColor.Green); |             builder.WithColor(player.State == PlayerState.Paused ? DiscordColor.Orange : DiscordColor.Green); | ||||||
|             builder.AddField("Length", Common.GetTimestamp(track.Duration), true); |             builder.AddField("Length", Common.GetTimestamp(track.Duration), true); | ||||||
|             builder.AddField("Loop", player.PlayerQueue.LoopType.ToString(), true); |             builder.AddField("Loop", player.PlayerQueue.LoopType.ToString(), true); | ||||||
|             builder.AddField("Progress", progressBar, true); |             builder.AddField("Progress", progressBar, true); | ||||||
|             if (!context.IsFile) |             if (!context.IsFile) | ||||||
|             { |             { | ||||||
|  |                 builder.WithAuthor(track.Author, context.YoutubeAuthorUri.ToString(), context.YoutubeAuthorThumbnail.ToString()); | ||||||
|  |                 builder.WithImageUrl(context.YoutubeThumbnail); | ||||||
|                 builder.AddField("Views", $"{context.YoutubeViews:N0} Views", true); |                 builder.AddField("Views", $"{context.YoutubeViews:N0} Views", true); | ||||||
|                 builder.AddField("Rating", $"{context.YoutubeLikes:N0} 👍", true); |                 builder.AddField("Rating", $"{context.YoutubeLikes:N0} 👍", true); | ||||||
|                 builder.AddField("Upload Date", $"{context.YoutubeUploadDate.ToString("dd. MMMM, yyyy")}", true); |                 builder.AddField("Upload Date", $"{context.YoutubeUploadDate.ToString("dd. MMMM, yyyy")}", true); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 root
					root