Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/CB.Accessors/Contracts/IAllowConfigurationAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@
{
Task<List<AllowConfigurationDto>> GetAllAsync();

Task<AllowConfigurationDto?> GetByIdAsync(string id);

Check warning on line 10 in src/CB.Accessors/Contracts/IAllowConfigurationAccessor.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Task<AllowConfigurationDto> CreateAsync(AllowConfiguration entity);

Task<AllowConfigurationDto?> UpdateAsync(string id,
AllowConfigurationDto entity);
Task<AllowConfigurationDto?> UpdateAsync(AllowConfigurationDto entity);

Task<bool> DeleteAsync(string id);
}
17 changes: 17 additions & 0 deletions src/CB.Accessors/Contracts/IRoleConfigurationAccessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using CB.Data.Entities;
using CB.Shared.Dtos;

namespace CB.Accessors.Contracts;

public interface IRoleConfigurationAccessor
{
Task<List<RoleConfigurationDto>> GetAllAsync();

Task<RoleConfigurationDto?> GetByIdAsync(string id);

Task<RoleConfigurationDto> CreateAsync(RoleConfiguration entity);

Task<RoleConfigurationDto?> UpdateAsync(RoleConfigurationDto entity);

Task<bool> DeleteAsync(string id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@ await context
return mapper.Map<AllowConfigurationDto>(entity);
}

public async Task<AllowConfigurationDto?> UpdateAsync(string id,
AllowConfigurationDto updated)
public async Task<AllowConfigurationDto?> UpdateAsync(AllowConfigurationDto updated)
{
var allowConfiguration = await context
.AllowConfigurations
.FindAsync(id)
.FirstOrDefaultAsync( x => x.GuildId == updated.GuildId)
.ConfigureAwait(false);

if (allowConfiguration == null)
Expand Down
79 changes: 79 additions & 0 deletions src/CB.Accessors/Implementations/RoleConfigurationAccessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using AutoMapper;
using AutoMapper.QueryableExtensions;
using CB.Accessors.Contracts;
using CB.Data;
using CB.Data.Entities;
using CB.Shared.Dtos;
using Microsoft.EntityFrameworkCore;

namespace CB.Accessors.Implementations;

public class RoleConfigurationAccessor(CbContext context,
IMapper mapper)
: IRoleConfigurationAccessor
{
public Task<List<RoleConfigurationDto>> GetAllAsync() => context
.RoleConfigurations
.AsNoTracking()
.ProjectTo<RoleConfigurationDto>(mapper.ConfigurationProvider)
.ToListAsync();

public Task<RoleConfigurationDto?> GetByIdAsync(string id) => context.RoleConfigurations
.AsNoTracking()
.Where(g => g.GuildId == id)
.ProjectTo<RoleConfigurationDto>(mapper.ConfigurationProvider)
.FirstOrDefaultAsync();

public async Task<RoleConfigurationDto> CreateAsync(RoleConfiguration entity)
{
context.RoleConfigurations.Add(entity);
await context
.SaveChangesAsync()
.ConfigureAwait(false);

return mapper.Map<RoleConfigurationDto>(entity);
}

public async Task<RoleConfigurationDto?> UpdateAsync(RoleConfigurationDto updated)
{
var roleConfiguration = await context
.RoleConfigurations
.FirstOrDefaultAsync(x => x.GuildId == updated.GuildId)
.ConfigureAwait(false);

if (roleConfiguration == null)
{
return null;
}

roleConfiguration.DiscoveryRoleId = updated.DiscoveryRoleId;
roleConfiguration.JoinRoleId = updated.JoinRoleId;
roleConfiguration.LiveDiscoveryRoleId = updated.LiveDiscoveryRoleId;

await context
.SaveChangesAsync()
.ConfigureAwait(false);

return mapper.Map<RoleConfigurationDto>(roleConfiguration);
}

public async Task<bool> DeleteAsync(string id)
{
var roleConfiguration = await context
.RoleConfigurations
.FindAsync(id)
.ConfigureAwait(false);

if (roleConfiguration == null)
{
return false;
}

context.RoleConfigurations.Remove(roleConfiguration);
await context
.SaveChangesAsync()
.ConfigureAwait(false);

return true;
}
}
84 changes: 84 additions & 0 deletions src/CB.Bot/Commands/Application/DiscoverySlashCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using CB.Accessors.Contracts;
using Discord;
using Discord.Interactions;

// ReSharper disable UnusedMember.Local
// ReSharper disable UnusedMember.Global

namespace CB.Bot.Commands.Application;

[Group("discovery", "Discovery commands")]
public class DiscoverySlashCommands(IGuildAccessor guildAccessor,
IRoleConfigurationAccessor roleConfigurationAccessor,
IAllowConfigurationAccessor allowConfigurationAccessor) : BaseSlashCommands
{
[SlashCommand(
"enable",
"Configure server 'Discovery' setting",
false,
RunMode.Async)]
private async Task DiscoveryEnableConfigurationAsync(IRole role = null)
{
await DoStuff(true, role);
}

[SlashCommand(
"disable",
"Configure server 'Discovery' setting",
false,
RunMode.Async)]
private async Task DiscoveryDisableConfigurationAsync()
{
await DoStuff(false);
}

private async Task DoStuff(bool isEnabled,
IRole role = null)
{
await SocketInteraction.DeferAsync(true);

if (!await IsUserAdmin())
{
return;
}

var guildChannel = (IGuildChannel)SocketInteraction.Channel;
var guild = await guildAccessor.GetByIdAsync(guildChannel.Guild.Id.ToString());
if (guild == null)
{
await SocketInteraction.FollowupAsync(
"Sorry, unable to configure Discovery for this guild. Contact support.", ephemeral: true);
return;
}

string message;
if (!isEnabled)
{
guild.RoleConfiguration.DiscoveryRoleId = null;
guild.AllowConfiguration.AllowLiveDiscovery = false;
message = "Discovery has been set to `Disabled`.";
}
else
{
if (role != null)
{
guild.RoleConfiguration.DiscoveryRoleId = role.Id.ToString();
guild.AllowConfiguration.AllowLiveDiscovery = true;

message = $"Discovery has been set to role {role.Name}.";
}
else
{
guild.RoleConfiguration.DiscoveryRoleId = null;
guild.AllowConfiguration.AllowLiveDiscovery = true;

message = "Discovery has been set to .. literally everyone!";
}
}

await roleConfigurationAccessor.UpdateAsync(guild.RoleConfiguration);
await allowConfigurationAccessor.UpdateAsync(guild.AllowConfiguration);

await SocketInteraction.FollowupAsync(message, ephemeral: true);
}
}
2 changes: 1 addition & 1 deletion src/CB.Bot/Services/MessageInteractionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ private async Task ProcessAllowDropdownAsync(ISocketMessageChannel channel,
}
}

await _allowConfigurationAccessor.UpdateAsync(guild.Id, guild.AllowConfiguration);
await _allowConfigurationAccessor.UpdateAsync(guild.AllowConfiguration);
await _guildConfigurationAccessor.UpdateAsync(guild.Id, guild.GuildConfiguration);

await message.FollowupAsync(response.ToString(), ephemeral: true);
Expand Down
1 change: 1 addition & 0 deletions src/CB.Data/CbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class CbContext(DbContextOptions<CbContext> options) : DbContext(options)
public DbSet<Guild> Guilds => Set<Guild>();
public DbSet<GuildConfiguration> GuildConfigurations => Set<GuildConfiguration>();
public DbSet<LiveEmbed> LiveEmbeds => Set<LiveEmbed>();
public DbSet<RoleConfiguration> RoleConfigurations => Set<RoleConfiguration>();
public DbSet<User> Users => Set<User>();
public DbSet<VodEmbed> VodEmbeds => Set<VodEmbed>();

Expand Down
Loading