From 404450612f50e5d7a932a866be7ef4781b58788b Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Thu, 17 Jul 2025 17:40:15 -0500 Subject: [PATCH] Add List Command and Dependencies --- .../Contracts/IChannelAccessor.cs | 3 +- .../Implementations/ChannelAccessor.cs | 5 +- .../Commands/Application/ListSlashCommands.cs | 442 ++++++++++++++++++ src/CB.Data/CbContext.cs | 42 ++ src/CB.Data/Entities/Channel.cs | 2 + src/CB.Data/Entities/Game.cs | 18 + src/CB.Data/Entities/GameChannel.cs | 10 + src/CB.Data/Entities/Team.cs | 18 + src/CB.Data/Entities/TeamChannel.cs | 10 + src/CB.Shared/Dtos/CbProfile.cs | 4 + src/CB.Shared/Dtos/ChannelDto.cs | 3 + .../Dtos/DiscordLiveConfigurationDto.cs | 5 +- src/CB.Shared/Dtos/GameChannelDto.cs | 10 + src/CB.Shared/Dtos/GameDto.cs | 15 + src/CB.Shared/Dtos/TeamChannelDto.cs | 10 + src/CB.Shared/Dtos/TeamDto.cs | 15 + src/CB.Shared/Models/Bot/ListViewModel.cs | 12 + 17 files changed, 615 insertions(+), 9 deletions(-) create mode 100644 src/CB.Bot/Commands/Application/ListSlashCommands.cs create mode 100644 src/CB.Data/Entities/Game.cs create mode 100644 src/CB.Data/Entities/GameChannel.cs create mode 100644 src/CB.Data/Entities/Team.cs create mode 100644 src/CB.Data/Entities/TeamChannel.cs create mode 100644 src/CB.Shared/Dtos/GameChannelDto.cs create mode 100644 src/CB.Shared/Dtos/GameDto.cs create mode 100644 src/CB.Shared/Dtos/TeamChannelDto.cs create mode 100644 src/CB.Shared/Dtos/TeamDto.cs create mode 100644 src/CB.Shared/Models/Bot/ListViewModel.cs diff --git a/src/CB.Accessors/Contracts/IChannelAccessor.cs b/src/CB.Accessors/Contracts/IChannelAccessor.cs index 44a65ae..58dceca 100644 --- a/src/CB.Accessors/Contracts/IChannelAccessor.cs +++ b/src/CB.Accessors/Contracts/IChannelAccessor.cs @@ -11,8 +11,7 @@ public interface IChannelAccessor Task CreateAsync(Channel entity); - Task UpdateAsync(string id, - Channel entity); + Task UpdateAsync(ChannelDto entity); Task DeleteAsync(string id); } \ No newline at end of file diff --git a/src/CB.Accessors/Implementations/ChannelAccessor.cs b/src/CB.Accessors/Implementations/ChannelAccessor.cs index 40ffbbf..7704e5c 100644 --- a/src/CB.Accessors/Implementations/ChannelAccessor.cs +++ b/src/CB.Accessors/Implementations/ChannelAccessor.cs @@ -37,12 +37,11 @@ await context return mapper.Map(entity); } - public async Task UpdateAsync(string id, - Channel updated) + public async Task UpdateAsync(ChannelDto updated) { var channel = await context .Channels - .FindAsync(id) + .FirstOrDefaultAsync(x => x.Id == updated.Id) .ConfigureAwait(false); if (channel == null) diff --git a/src/CB.Bot/Commands/Application/ListSlashCommands.cs b/src/CB.Bot/Commands/Application/ListSlashCommands.cs new file mode 100644 index 0000000..4a780a5 --- /dev/null +++ b/src/CB.Bot/Commands/Application/ListSlashCommands.cs @@ -0,0 +1,442 @@ +using System.Text; +using CB.Accessors.Contracts; +using CB.Shared.Dtos; +using CB.Shared.Models.Bot; +using Discord; +using Discord.Interactions; +using Discord.WebSocket; +// ReSharper disable UnusedMember.Global +// ReSharper disable UnusedMember.Local + +namespace CB.Bot.Commands.Application; + +/// +/// List Slash Commands +/// +public class ListSlashCommands(DiscordSocketClient discordSocketClient, + IGuildAccessor guildAccessor, + IFilterAccessor filterAccessor, + IChannelAccessor channelAccessor) + : BaseSlashCommands +{ + /// + /// List games slash command + /// + /// + [SlashCommand( + "games", + "List your servers configured games.", + false, + RunMode.Async)] + private async Task ListGamesAsync(int page = 1, + IGuildChannel channel = null) + { + await SocketInteraction.DeferAsync(true); + + if (!await IsUserAdmin()) + { + return; + } + + await ProcessGameList(page, channel?.Id.ToString(), Context.Guild, SocketInteraction); + } + + /// + /// List teams slash command + /// + /// + [SlashCommand( + "teams", + "List your servers configured teams.", + false, + RunMode.Async)] + private async Task ListTeamsAsync(int page = 1, + IGuildChannel channel = null) + { + await SocketInteraction.DeferAsync(true); + + if (!await IsUserAdmin()) + { + return; + } + + await ProcessTeamList(page, channel?.Id.ToString(), Context.Guild, SocketInteraction); + } + + /// + /// Creators slash command + /// + /// + [SlashCommand( + "creators", + "List your servers configured creators.", + false, + RunMode.Async)] + private async Task ListCreatorsAsync(int page = 1, + IGuildChannel channel = null) + { + await SocketInteraction.DeferAsync(true); + + if (!await IsUserAdmin()) + { + return; + } + + await ProcessCreatorList(page, channel?.Id.ToString(), Context.Guild, SocketInteraction); + } + + /// + /// Admins slash command + /// + /// + [SlashCommand( + "filters", + "List your servers configured filters.", + false, + RunMode.Async)] + private async Task ListFiltersAsync(int page = 1) + { + await SocketInteraction.DeferAsync(true); + + if (!await IsUserAdmin()) + { + return; + } + + await ProcessFilterList(page, Context.Guild, SocketInteraction); + } + + private async Task ProcessCreatorList( + long page, + string channelId, + IGuild discordGuild, + SocketInteraction socketInteraction) + { + var guildCreators = await guildAccessor.GetByIdAsync(discordGuild.Id.ToString()); + var creators = new List(); + + if (string.IsNullOrWhiteSpace(channelId)) + { + guildCreators?.Channels.ToList().ForEach(async x => + { + await ValidateChannelDisplayName(socketInteraction, x); + creators.AddRange(x.CreatorChannels.Select(y => y.Creator).Select(creator => new ListViewModel + { + DisplayName = creator.DisplayName, + CreatorChannelId = creator.ChannelId, + PlatformId = creator.PlatformId, + ChannelName = x.DisplayName + })); + }); + } + else + { + guildCreators?.Channels.Where(x => x.Id.Equals(channelId)).ToList().ForEach(x => + { + ValidateChannelDisplayName(socketInteraction, x).GetAwaiter().GetResult(); + creators.AddRange(x.CreatorChannels.Select(y=>y.Creator).Select(creator => new ListViewModel + { + DisplayName = creator.DisplayName, + CreatorChannelId = creator.ChannelId, + PlatformId = creator.PlatformId, + ChannelName = x.DisplayName + })); + }); + } + + var totalCreators = creators.Count; + var pageCount = (creators.Count + 20 - 1) / 20; + + if (page <= 0) + { + page = 1; + } + + if (page > pageCount) + { + page = pageCount; + } + + if (pageCount == 0) + { + pageCount++; + } + + var creatorsToDisplay = page > 1 ? + creators.OrderBy(x => x.DisplayName).ThenBy(x => x.PlatformId).Skip((int)(20 * (page - 1))).Take(20).ToList() : + creators.OrderBy(x => x.DisplayName).ThenBy(x => x.PlatformId).Take(20).ToList(); + + var builder = new EmbedBuilder(); + var authorBuilder = new EmbedAuthorBuilder(); + var footerBuilder = new EmbedFooterBuilder(); + + authorBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + authorBuilder.Name = discordSocketClient.CurrentUser.Username; + authorBuilder.Url = "https://couch.bot"; + + footerBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + footerBuilder.Text = $"Page {page} of {pageCount} • {totalCreators} creators"; + + builder.Author = authorBuilder; + builder.Footer = footerBuilder; + builder.Color = new Color(88, 101, 242); + var strBuilder = new StringBuilder(); + + foreach (var creatorOutput in creatorsToDisplay.Select(creator => creator.PlatformId switch + { + (int)Shared.Enums.Platform.DLive => + $"<:dlive:886103116494299136> [{creator.DisplayName}](https://dlive.tv/{creator.DisplayName}) - #{creator.ChannelName}", + (int)Shared.Enums.Platform.Picarto => + $"<:picarto:844040506056638465> [{creator.DisplayName}](https://picarto.tv/{creator.DisplayName}) - #{creator.ChannelName}", + (int)Shared.Enums.Platform.Piczel => + $"<:piczel:844040506265698304> [{creator.DisplayName}](https://piczel.tv/{creator.DisplayName}) - #{creator.ChannelName}", + (int)Shared.Enums.Platform.Trovo => + $"<:trovo:844040506224803872> [{creator.DisplayName}](https://trovo.live/{creator.DisplayName}) - #{creator.ChannelName}", + (int)Shared.Enums.Platform.Twitch => + $"<:twitch:844040506056376321> [{creator.DisplayName}](https://twitch.tv/{creator.DisplayName}) - #{creator.ChannelName}", + (int)Shared.Enums.Platform.YouTube => + $"<:youtube:844040506321141800> [{creator.DisplayName}](https://youtube.com/channel/{creator.CreatorChannelId}) - #{creator.ChannelName}", + _ => "" + })) + { + strBuilder.AppendLine($"{creatorOutput}"); + } + + builder.Description = creators.Count == 0 ? "It doesn't look like you are announcing any creators." : strBuilder.ToString(); + await socketInteraction.FollowupAsync(embed: builder.Build(), ephemeral: true); + } + + private async Task ProcessFilterList( + long page, + IGuild discordGuild, + SocketInteraction socketInteraction) + { + var guild = await guildAccessor.GetByIdAsync(discordGuild.Id.ToString()); + var filters = await filterAccessor.GetAllAsync(guild.Id); + + var builder = new EmbedBuilder(); + var authorBuilder = new EmbedAuthorBuilder(); + var footerBuilder = new EmbedFooterBuilder(); + + var totalFilters = filters.Count; + var pageCount = (filters.Count + 20 - 1) / 20; + + if (page <= 0) + { + page = 1; + } + + if (page > pageCount) + { + page = pageCount; + } + + if (pageCount == 0) + { + pageCount++; + } + + var filtersToDisplay = page > 1 ? + filters.OrderBy(x => x.PlatformId).ThenBy(x => x.Text).Skip((int)(20 * (page - 1))).Take(20).ToList() : + filters.OrderBy(x => x.PlatformId).ThenBy(x => x.Text).Take(20).ToList(); + + authorBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + authorBuilder.Name = discordSocketClient.CurrentUser.Username; + authorBuilder.Url = "https://couch.bot"; + + footerBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + footerBuilder.Text = $"Page {page} of {pageCount} • {totalFilters} filters"; + + builder.Author = authorBuilder; + builder.Footer = footerBuilder; + builder.Color = new Color(88, 101, 242); + + builder.AddField("Game Filters", + filters.Count(x => x.FilterTypeId == (int)Shared.Enums.FilterType.Game) == 0 ? "None" : + string.Join("\r\n", + filtersToDisplay + .Where(x => x.FilterTypeId == (int)Shared.Enums.FilterType.Game) + .OrderBy(x => x.PlatformId) + .Select(x => $"{Format.Sanitize(x.Text)} ({(Shared.Enums.Platform)x.PlatformId})") + ) + ); + + builder.AddField("Title Filters", + filters.Count(x => x.FilterTypeId == (int)Shared.Enums.FilterType.Title) == 0 ? "None" : + string.Join("\r\n", + filtersToDisplay + .Where(x => x.FilterTypeId == (int)Shared.Enums.FilterType.Title) + .OrderBy(x => x.PlatformId) + .Select(x => $"{Format.Sanitize(x.Text)} ({(Shared.Enums.Platform)x.PlatformId})") + ) + ); + + await socketInteraction.FollowupAsync(embed: builder.Build(), ephemeral: true); + } + + private async Task ProcessGameList( + long page, + string channelId, + IGuild discordGuild, + SocketInteraction socketInteraction) + { + var guildCreators = await guildAccessor.GetByIdAsync(discordGuild.Id.ToString()); + + var builder = new EmbedBuilder(); + var authorBuilder = new EmbedAuthorBuilder(); + var footerBuilder = new EmbedFooterBuilder(); + + var games = new List(); + + if (string.IsNullOrWhiteSpace(channelId)) + { + guildCreators?.Channels.ToList().ForEach(async x => + { + await ValidateChannelDisplayName(socketInteraction, x); + games.AddRange(x.GameChannels.Select(y => y.Game).Select(game => new ListViewModel + { + DisplayName = game.DisplayName, + ChannelName = x.DisplayName + })); + }); + } + else + { + guildCreators?.Channels.Where(x => x.Id.Equals(channelId)).ToList().ForEach(x => + { + ValidateChannelDisplayName(socketInteraction, x).GetAwaiter().GetResult(); + games.AddRange(x.GameChannels.Select(y => y.Game).Select(game => new ListViewModel + { + DisplayName = game.DisplayName, + ChannelName = x.DisplayName + })); + }); + } + + var totalGames = games.Count; + var pageCount = (games.Count + 20 - 1) / 20; + + if (page <= 0) + { + page = 1; + } + + if (page > pageCount) + { + page = pageCount; + } + + if (pageCount == 0) + { + pageCount++; + } + + var gamesToDisplay = page > 1 ? + games.OrderBy(x => x.DisplayName).Skip((int)(20 * (page - 1))).Take(20).ToList() : + games.OrderBy(x => x.DisplayName).Take(20).ToList(); + + authorBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + authorBuilder.Name = discordSocketClient.CurrentUser.Username; + authorBuilder.Url = "https://couch.bot"; + + footerBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + footerBuilder.Text = $"Page {page} of {pageCount} • {totalGames} games"; + + builder.Author = authorBuilder; + builder.Footer = footerBuilder; + builder.Color = new Color(88, 101, 242); + + builder.Description = totalGames == 0 ? "It doesn't look like you are announcing any games." : string.Join("\r\n", gamesToDisplay.Select(x => $"<:twitch:844040506056376321> {x.DisplayName} - #{x.ChannelName}")); + + await socketInteraction.FollowupAsync(embed: builder.Build(), ephemeral: true); + } + + private async Task ValidateChannelDisplayName(SocketInteraction socketInteraction, + ChannelDto x) + { + if (string.IsNullOrEmpty(x.DisplayName)) + { + var guild = discordSocketClient.GetGuild(socketInteraction.GuildId.Value); + var channel = guild.GetChannel(ulong.Parse(x.Id)); + x.DisplayName = channel.Name; + x.ModifiedDate = DateTime.UtcNow; + await channelAccessor.UpdateAsync(x); + } + } + + private async Task ProcessTeamList( + long page, + string channelId, + IGuild discordGuild, + SocketInteraction socketInteraction) + { + var guildCreators = await guildAccessor.GetByIdAsync(discordGuild.Id.ToString()); + + var builder = new EmbedBuilder(); + var authorBuilder = new EmbedAuthorBuilder(); + var footerBuilder = new EmbedFooterBuilder(); + + var teams = new List(); + if (string.IsNullOrWhiteSpace(channelId)) + { + guildCreators?.Channels.ToList().ForEach(async x => + { + await ValidateChannelDisplayName(socketInteraction, x); + teams.AddRange(x.TeamChannels.Select(y => y.Team).Select(team => new ListViewModel + { + DisplayName = team.DisplayName, + ChannelName = x.DisplayName + })); + }); + } + else + { + guildCreators?.Channels.Where(x => x.Id.Equals(channelId)).ToList().ForEach(x => + { + ValidateChannelDisplayName(socketInteraction, x).GetAwaiter().GetResult(); + teams.AddRange(x.TeamChannels.Select(y => y.Team).Select(team => new ListViewModel + { + DisplayName = team.DisplayName, + ChannelName = x.DisplayName + })); + }); + } + + var totalTeams = teams.Count; + var pageCount = (teams.Count + 20 - 1) / 20; + + if (page <= 0) + { + page = 1; + } + + if (page > pageCount) + { + page = pageCount; + } + + if (pageCount == 0) + { + pageCount++; + } + + var teamsToDisplay = page > 1 ? + teams.OrderBy(x => x.DisplayName).Skip((int)(20 * (page - 1))).Take(20).ToList() : + teams.OrderBy(x => x.DisplayName).Take(20).ToList(); + + authorBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + authorBuilder.Name = discordSocketClient.CurrentUser.Username; + authorBuilder.Url = "https://couch.bot"; + + footerBuilder.IconUrl = discordSocketClient.CurrentUser.GetAvatarUrl(); + footerBuilder.Text = $"Page {page} of {pageCount} • {totalTeams} teams"; + + builder.Author = authorBuilder; + builder.Footer = footerBuilder; + builder.Color = new Color(88, 101, 242); + + builder.Description = totalTeams == 0 ? "It doesn't look like you are announcing any teams." : string.Join("\r\n", teamsToDisplay.Select(x => $"<:twitch:844040506056376321> {x.DisplayName} - #{x.ChannelName}")); + + await socketInteraction.FollowupAsync(embed: builder.Build(), ephemeral: true); + } +} \ No newline at end of file diff --git a/src/CB.Data/CbContext.cs b/src/CB.Data/CbContext.cs index 27ab90e..e4d42a4 100644 --- a/src/CB.Data/CbContext.cs +++ b/src/CB.Data/CbContext.cs @@ -14,10 +14,13 @@ public class CbContext(DbContextOptions options) : DbContext(options) public DbSet DiscordLiveConfigurations => Set(); public DbSet DropdownPayloads => Set(); public DbSet Filters => Set(); + public DbSet Games => Set(); + public DbSet GameChannels => Set(); public DbSet Guilds => Set(); public DbSet GuildConfigurations => Set(); public DbSet LiveEmbeds => Set(); public DbSet RoleConfigurations => Set(); + public DbSet TeamChannels => Set(); public DbSet Users => Set(); public DbSet VodEmbeds => Set(); @@ -104,6 +107,31 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasForeignKey(x => x.UserId) .OnDelete(DeleteBehavior.NoAction); + // Configure GameChannels table + modelBuilder.Entity() + .HasKey(cc => new { cc.GameId, cc.ChannelId }); + + modelBuilder.Entity() + .HasOne(cc => cc.Game) + .WithMany(c => c.GameChannels) + .HasForeignKey(cc => cc.GameId); + + modelBuilder.Entity() + .HasOne(cc => cc.Channel) + .WithMany(ch => ch.GameChannels) + .HasForeignKey(cc => cc.ChannelId); + + // Configure Games table + modelBuilder.Entity().ToTable("Games"); + + modelBuilder.Entity() + .Property(x => x.CreatedDate) + .HasColumnType("timestamp without time zone"); + + modelBuilder.Entity() + .Property(x => x.ModifiedDate) + .HasColumnType("timestamp without time zone"); + // Configure Guilds table modelBuilder.Entity().ToTable("Guilds"); @@ -190,6 +218,20 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) // Configure RoleConfiguration table modelBuilder.Entity().ToTable("RoleConfigurations"); + // Configure TeamChannels table + modelBuilder.Entity() + .HasKey(cc => new { cc.TeamId, cc.ChannelId }); + + modelBuilder.Entity() + .HasOne(cc => cc.Team) + .WithMany(c => c.TeamChannels) + .HasForeignKey(cc => cc.TeamId); + + modelBuilder.Entity() + .HasOne(cc => cc.Channel) + .WithMany(ch => ch.TeamChannels) + .HasForeignKey(cc => cc.ChannelId); + // Configure Users table modelBuilder.Entity().ToTable("Users"); diff --git a/src/CB.Data/Entities/Channel.cs b/src/CB.Data/Entities/Channel.cs index f6276a4..7dbe11f 100644 --- a/src/CB.Data/Entities/Channel.cs +++ b/src/CB.Data/Entities/Channel.cs @@ -15,4 +15,6 @@ public class Channel public virtual Guild Guild { get; set; } public virtual ICollection CreatorChannels { get; set; } = new List(); + public virtual ICollection GameChannels { get; set; } = new List(); + public virtual ICollection TeamChannels { get; set; } = new List(); } \ No newline at end of file diff --git a/src/CB.Data/Entities/Game.cs b/src/CB.Data/Entities/Game.cs new file mode 100644 index 0000000..4a4e6d8 --- /dev/null +++ b/src/CB.Data/Entities/Game.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace CB.Data.Entities; + +public class Game +{ + [Key] + public int Id { get; set; } + + public string DisplayName { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime ModifiedDate { get; set; } + public int PlatformId { get; set; } + public Platform Platform { get; set; } + public string GameId { get; set; } + + public virtual ICollection GameChannels { get; set; } +} \ No newline at end of file diff --git a/src/CB.Data/Entities/GameChannel.cs b/src/CB.Data/Entities/GameChannel.cs new file mode 100644 index 0000000..51a533e --- /dev/null +++ b/src/CB.Data/Entities/GameChannel.cs @@ -0,0 +1,10 @@ +namespace CB.Data.Entities; + +public class GameChannel +{ + public int GameId { get; set; } + public string ChannelId { get; set; } + + public Game Game { get; set; } + public Channel Channel { get; set; } +} \ No newline at end of file diff --git a/src/CB.Data/Entities/Team.cs b/src/CB.Data/Entities/Team.cs new file mode 100644 index 0000000..797bca9 --- /dev/null +++ b/src/CB.Data/Entities/Team.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace CB.Data.Entities; + +public class Team +{ + [Key] + public int Id { get; set; } + + public string DisplayName { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime ModifiedDate { get; set; } + public int PlatformId { get; set; } + public Platform Platform { get; set; } + public string TeamId { get; set; } + + public ICollection TeamChannels { get; set; } +} \ No newline at end of file diff --git a/src/CB.Data/Entities/TeamChannel.cs b/src/CB.Data/Entities/TeamChannel.cs new file mode 100644 index 0000000..83d6aa7 --- /dev/null +++ b/src/CB.Data/Entities/TeamChannel.cs @@ -0,0 +1,10 @@ +namespace CB.Data.Entities; + +public class TeamChannel +{ + public int TeamId { get; set; } + public string ChannelId { get; set; } + + public Team Team { get; set; } + public Channel Channel { get; set; } +} \ No newline at end of file diff --git a/src/CB.Shared/Dtos/CbProfile.cs b/src/CB.Shared/Dtos/CbProfile.cs index b2359ef..cbc7319 100644 --- a/src/CB.Shared/Dtos/CbProfile.cs +++ b/src/CB.Shared/Dtos/CbProfile.cs @@ -17,12 +17,16 @@ public CbProfile() CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); } diff --git a/src/CB.Shared/Dtos/ChannelDto.cs b/src/CB.Shared/Dtos/ChannelDto.cs index 13ff205..848b885 100644 --- a/src/CB.Shared/Dtos/ChannelDto.cs +++ b/src/CB.Shared/Dtos/ChannelDto.cs @@ -12,4 +12,7 @@ public class ChannelDto public virtual GuildDto Guild { get; set; } public virtual ICollection CreatorChannels { get; set; } = new List(); + public virtual ICollection GameChannels { get; set; } = new List(); + public virtual ICollection TeamChannels { get; set; } = new List(); + } \ No newline at end of file diff --git a/src/CB.Shared/Dtos/DiscordLiveConfigurationDto.cs b/src/CB.Shared/Dtos/DiscordLiveConfigurationDto.cs index 5e3561a..061b382 100644 --- a/src/CB.Shared/Dtos/DiscordLiveConfigurationDto.cs +++ b/src/CB.Shared/Dtos/DiscordLiveConfigurationDto.cs @@ -1,7 +1,4 @@ -using System.ComponentModel.DataAnnotations; -using CB.Data.Entities; - -namespace CB.Shared.Dtos; +namespace CB.Shared.Dtos; public class DiscordLiveConfigurationDto { diff --git a/src/CB.Shared/Dtos/GameChannelDto.cs b/src/CB.Shared/Dtos/GameChannelDto.cs new file mode 100644 index 0000000..311a5e3 --- /dev/null +++ b/src/CB.Shared/Dtos/GameChannelDto.cs @@ -0,0 +1,10 @@ +namespace CB.Shared.Dtos; + +public class GameChannelDto +{ + public int GameId { get; set; } + public string ChannelId { get; set; } + + public GameDto Game { get; set; } + public ChannelDto Channel { get; set; } +} \ No newline at end of file diff --git a/src/CB.Shared/Dtos/GameDto.cs b/src/CB.Shared/Dtos/GameDto.cs new file mode 100644 index 0000000..566059d --- /dev/null +++ b/src/CB.Shared/Dtos/GameDto.cs @@ -0,0 +1,15 @@ +namespace CB.Shared.Dtos; + +public class GameDto +{ + public int Id { get; set; } + + public string DisplayName { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime ModifiedDate { get; set; } + public int PlatformId { get; set; } +public string GameId { get; set; } + +public virtual PlatformDto Platform { get; set; } + public virtual ICollection GameChannels { get; set; } +} \ No newline at end of file diff --git a/src/CB.Shared/Dtos/TeamChannelDto.cs b/src/CB.Shared/Dtos/TeamChannelDto.cs new file mode 100644 index 0000000..008b3ee --- /dev/null +++ b/src/CB.Shared/Dtos/TeamChannelDto.cs @@ -0,0 +1,10 @@ +namespace CB.Shared.Dtos; + +public class TeamChannelDto +{ + public int TeamId { get; set; } + public string ChannelId { get; set; } + + public TeamDto Team { get; set; } + public ChannelDto Channel { get; set; } +} \ No newline at end of file diff --git a/src/CB.Shared/Dtos/TeamDto.cs b/src/CB.Shared/Dtos/TeamDto.cs new file mode 100644 index 0000000..728e387 --- /dev/null +++ b/src/CB.Shared/Dtos/TeamDto.cs @@ -0,0 +1,15 @@ +namespace CB.Shared.Dtos; + +public class TeamDto +{ + public int Id { get; set; } + + public string DisplayName { get; set; } + public DateTime CreatedDate { get; set; } + public DateTime ModifiedDate { get; set; } + public int PlatformId { get; set; } + public string TeamId { get; set; } + + public virtual PlatformDto Platform { get; set; } + public ICollection TeamChannels { get; set; } +} \ No newline at end of file diff --git a/src/CB.Shared/Models/Bot/ListViewModel.cs b/src/CB.Shared/Models/Bot/ListViewModel.cs new file mode 100644 index 0000000..bad9481 --- /dev/null +++ b/src/CB.Shared/Models/Bot/ListViewModel.cs @@ -0,0 +1,12 @@ +namespace CB.Shared.Models.Bot; + +public class ListViewModel +{ + public string DisplayName { get; set; } + + public string CreatorChannelId { get; set; } + + public int PlatformId { get; set; } + + public string ChannelName { get; set; } +} \ No newline at end of file