[Activity] Add due time
This commit is contained in:
159
Cocotte/Migrations/20230325234255_AddActivityDueTime.Designer.cs
generated
Normal file
159
Cocotte/Migrations/20230325234255_AddActivityDueTime.Designer.cs
generated
Normal file
@@ -0,0 +1,159 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Cocotte.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Cocotte.Migrations
|
||||
{
|
||||
[DbContext(typeof(CocotteDbContext))]
|
||||
[Migration("20230325234255_AddActivityDueTime")]
|
||||
partial class AddActivityDueTime
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "7.0.4");
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b =>
|
||||
{
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("ChannelId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("MessageId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("AreRolesEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreationDate")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CreatorDisplayName")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("CreatorUserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<TimeOnly?>("DueTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MaxPlayers")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Name")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("ThreadId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("GuildId", "ChannelId", "MessageId");
|
||||
|
||||
b.HasIndex("ThreadId");
|
||||
|
||||
b.ToTable("Activities");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("Activity");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityPlayer", b =>
|
||||
{
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("ChannelId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("MessageId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Discriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("GuildId", "ChannelId", "MessageId", "UserId");
|
||||
|
||||
b.ToTable("ActivityPlayers");
|
||||
|
||||
b.HasDiscriminator<string>("Discriminator").HasValue("ActivityPlayer");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activities.Models.InterstellarActivity", b =>
|
||||
{
|
||||
b.HasBaseType("Cocotte.Modules.Activities.Models.Activity");
|
||||
|
||||
b.Property<int>("Color")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasDiscriminator().HasValue("InterstellarActivity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activities.Models.StagedActivity", b =>
|
||||
{
|
||||
b.HasBaseType("Cocotte.Modules.Activities.Models.Activity");
|
||||
|
||||
b.Property<uint>("Stage")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasDiscriminator().HasValue("StagedActivity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityRolePlayer", b =>
|
||||
{
|
||||
b.HasBaseType("Cocotte.Modules.Activities.Models.ActivityPlayer");
|
||||
|
||||
b.Property<byte>("Roles")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasDiscriminator().HasValue("ActivityRolePlayer");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activities.Models.ActivityPlayer", b =>
|
||||
{
|
||||
b.HasOne("Cocotte.Modules.Activities.Models.Activity", "Activity")
|
||||
.WithMany("ActivityPlayers")
|
||||
.HasForeignKey("GuildId", "ChannelId", "MessageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Activity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Cocotte.Modules.Activities.Models.Activity", b =>
|
||||
{
|
||||
b.Navigation("ActivityPlayers");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
29
Cocotte/Migrations/20230325234255_AddActivityDueTime.cs
Normal file
29
Cocotte/Migrations/20230325234255_AddActivityDueTime.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Cocotte.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddActivityDueTime : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<TimeOnly>(
|
||||
name: "DueTime",
|
||||
table: "Activities",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DueTime",
|
||||
table: "Activities");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,9 @@ namespace Cocotte.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<TimeOnly?>("DueTime")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<uint>("MaxPlayers")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
|
||||
@@ -66,13 +66,27 @@ public class ActivityFormatter
|
||||
$"{FormatActivityName(activity.Name)} ({players.Count}/{activity.MaxPlayers})"
|
||||
};
|
||||
|
||||
// Build description
|
||||
var descriptionBuilder = new StringBuilder();
|
||||
|
||||
// Add time if specified
|
||||
if (activity.DueTime is { } time)
|
||||
{
|
||||
descriptionBuilder.AppendLine($"**:clock2: {TimestampTag.FormatFromDateTime(DateTime.Today.WithTimeOnly(time), TimestampTagStyles.ShortTime)}**");
|
||||
}
|
||||
else
|
||||
{
|
||||
descriptionBuilder.AppendLine($"**:clock2: Maintenant**");
|
||||
}
|
||||
|
||||
// Add generic message or specified activity description
|
||||
descriptionBuilder.AppendLine(
|
||||
string.IsNullOrWhiteSpace(activity.Description)
|
||||
? $"Rejoignez l'activité de {MentionUtils.MentionUser(activity.CreatorUserId)}"
|
||||
: activity.Description
|
||||
);
|
||||
|
||||
// Add thread link
|
||||
descriptionBuilder.AppendLine();
|
||||
descriptionBuilder.Append($"**[Fil associé]({ChannelUtils.GetChannelLink(activity.GuildId, activity.ThreadId)})**");
|
||||
|
||||
|
||||
@@ -53,91 +53,108 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
||||
|
||||
[SlashCommand("abime-néant", "Créer un groupe pour l'Abîme du Néant")]
|
||||
[Alias("abime", "abyss")]
|
||||
public async Task ActivityVoidAbyss([Summary("étage", "A quel étage vous êtes")] [MinValue(1), MaxValue(6)] uint stage, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityVoidAbyss([Summary("étage", "A quel étage vous êtes")] [MinValue(1), MaxValue(6)] uint stage, [Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.Abyss, description, stage: stage);
|
||||
await CreateActivity(ActivityName.Abyss, timeInput, description, stage: stage);
|
||||
}
|
||||
|
||||
[SlashCommand("origine-guerre", "Créer un groupe pour l'Origine de la guerre")]
|
||||
[Alias("origine", "OOW")]
|
||||
public async Task ActivityOrigins([Summary("étage", "A quel étage vous êtes")] [MinValue(1), MaxValue(25)] uint stage, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityOrigins([Summary("étage", "A quel étage vous êtes")] [MinValue(1), MaxValue(25)] uint stage, [Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.OriginsOfWar, description, stage: stage);
|
||||
await CreateActivity(ActivityName.OriginsOfWar, timeInput, description, stage: stage);
|
||||
}
|
||||
|
||||
[SlashCommand("raids", "Créer un groupe pour les Raids")]
|
||||
public async Task ActivityRaids([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityRaids([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.Raids, description);
|
||||
await CreateActivity(ActivityName.Raids, timeInput, description);
|
||||
}
|
||||
|
||||
[SlashCommand("conflit-frontalier", "Créer un groupe pour Conflit frontalier")]
|
||||
[Alias("conflit", "FC")]
|
||||
public async Task ActivityFrontierClash([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityFrontierClash([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.FrontierClash, description);
|
||||
await CreateActivity(ActivityName.FrontierClash, timeInput, description);
|
||||
}
|
||||
|
||||
[SlashCommand("failles-neant", "Créer un groupe pour les Failles du néant")]
|
||||
[Alias("failles", "rift")]
|
||||
public async Task ActivityVoidRift([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityVoidRift([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.VoidRift, description);
|
||||
await CreateActivity(ActivityName.VoidRift, timeInput, description);
|
||||
}
|
||||
|
||||
[SlashCommand("operations-conjointes", "Créer un groupe pour les Opérations conjointes")]
|
||||
[Alias("operations", "JO")]
|
||||
public async Task ActivityJointOperation([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityJointOperation([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.JointOperation, description);
|
||||
await CreateActivity(ActivityName.JointOperation, timeInput, description);
|
||||
}
|
||||
|
||||
[SlashCommand("portes-interstellaires", "Créer un groupe pour les Portes interstellaires")]
|
||||
[Alias("portes")]
|
||||
public async Task ActivityInterstellarExploration([Summary("couleur", "De quel couleur de matériaux s'agît-il")] InterstellarColor color, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityInterstellarExploration([Summary("couleur", "De quel couleur de matériaux s'agît-il")] InterstellarColor color, [Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.InterstellarExploration, description, areRolesEnabled: false, interstellarColor: color);
|
||||
await CreateActivity(ActivityName.InterstellarExploration, timeInput, description, areRolesEnabled: false, interstellarColor: color);
|
||||
}
|
||||
|
||||
[SlashCommand("3v3", "Créer un groupe pour le 3v3 (Échapper au destin)")]
|
||||
[Alias("BR")]
|
||||
public async Task ActivityBreakFromDestiny([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityBreakFromDestiny([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.BreakFromDestiny, description, areRolesEnabled: false);
|
||||
await CreateActivity(ActivityName.BreakFromDestiny, timeInput, description, areRolesEnabled: false);
|
||||
}
|
||||
|
||||
[SlashCommand("8v8", "Créer un groupe pour le 8v8 (Abîme critique)")]
|
||||
[Alias("critical")]
|
||||
public async Task ActivityCriticalAbyss([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityCriticalAbyss([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.CriticalAbyss, description);
|
||||
await CreateActivity(ActivityName.CriticalAbyss, timeInput, description);
|
||||
}
|
||||
|
||||
[SlashCommand("evenement", "Créer un groupe pour les évènements")]
|
||||
[Alias("event")]
|
||||
public async Task ActivityEvent([Summary("joueurs", "Nombre de joueurs maximum pour cette activité")] [MinValue(2), MaxValue(16)] uint maxPlayers = 8, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityEvent([Summary("joueurs", "Nombre de joueurs maximum pour cette activité")] [MinValue(2), MaxValue(16)] uint maxPlayers = 8, [Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.Event, description, areRolesEnabled: false, maxPlayers: maxPlayers);
|
||||
await CreateActivity(ActivityName.Event, timeInput, description, areRolesEnabled: false, maxPlayers: maxPlayers);
|
||||
}
|
||||
|
||||
[SlashCommand("peche", "Créer un groupe pour de la pêche")]
|
||||
[Alias("fishing")]
|
||||
public async Task ActivityFishing([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityFishing([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.Fishing, description, areRolesEnabled: false);
|
||||
await CreateActivity(ActivityName.Fishing, timeInput, description, areRolesEnabled: false);
|
||||
}
|
||||
|
||||
[SlashCommand("course", "Créer un groupe pour les courses de Mirroria")]
|
||||
[Alias("BR")]
|
||||
public async Task ActivityMirroriaRace([Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
public async Task ActivityMirroriaRace([Summary("heure", "Heure à laquelle l'activité est prévue")] string? timeInput = null, [Summary("description", "Message accompagnant la demande de groupe")] string description = "")
|
||||
{
|
||||
await CreateActivity(ActivityName.MirroriaRace, description, areRolesEnabled: false);
|
||||
await CreateActivity(ActivityName.MirroriaRace, timeInput, description, areRolesEnabled: false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private async Task CreateActivity(ActivityName activityName, string description, bool areRolesEnabled = true, uint? maxPlayers = null, uint? stage = null, InterstellarColor? interstellarColor = null)
|
||||
private async Task CreateActivity(ActivityName activityName, string? timeInput, string description, bool areRolesEnabled = true, uint? maxPlayers = null, uint? stage = null, InterstellarColor? interstellarColor = null)
|
||||
{
|
||||
// Check time if it's specified
|
||||
TimeOnly? time = null;
|
||||
if (timeInput is not null)
|
||||
{
|
||||
if (!TimeOnly.TryParse(timeInput, out var parsedTime))
|
||||
{
|
||||
await RespondAsync(
|
||||
ephemeral: true,
|
||||
embed: EmbedUtils.ErrorEmbed("**Heure invalide**, essayez avec le **format** `heure:minutes`\nPar exemple: `15:30`").Build()
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
time = parsedTime;
|
||||
}
|
||||
|
||||
_logger.LogTrace("{User} is creating activity {Activity}", User.DisplayName, activityName);
|
||||
|
||||
// Activities are identified using their original message id
|
||||
@@ -163,6 +180,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
||||
CreatorUserId = Context.User.Id,
|
||||
CreatorDisplayName = ((SocketGuildUser) Context.User).DisplayName,
|
||||
Description = description,
|
||||
DueTime = time,
|
||||
Type = activityType,
|
||||
Name = activityName,
|
||||
AreRolesEnabled = areRolesEnabled,
|
||||
@@ -181,6 +199,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
||||
CreatorUserId = Context.User.Id,
|
||||
CreatorDisplayName = ((SocketGuildUser) Context.User).DisplayName,
|
||||
Description = description,
|
||||
DueTime = time,
|
||||
Type = activityType,
|
||||
Name = activityName,
|
||||
AreRolesEnabled = false,
|
||||
@@ -199,6 +218,7 @@ public partial class ActivityModule : InteractionModuleBase<SocketInteractionCon
|
||||
CreatorUserId = Context.User.Id,
|
||||
CreatorDisplayName = ((SocketGuildUser) Context.User).DisplayName,
|
||||
Description = description,
|
||||
DueTime = time,
|
||||
Type = activityType,
|
||||
Name = activityName,
|
||||
AreRolesEnabled = areRolesEnabled,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
using Cocotte.Modules.Activities.Models;
|
||||
using Cocotte.Utils;
|
||||
using Discord;
|
||||
|
||||
@@ -17,6 +17,7 @@ public class Activity
|
||||
public required ulong ThreadId { get; init; }
|
||||
public required ulong CreatorUserId { get; init; }
|
||||
public required string CreatorDisplayName { get; init; }
|
||||
public TimeOnly? DueTime { get; init; }
|
||||
public string? Description { get; set; }
|
||||
public required ActivityType Type { get; init; }
|
||||
public required ActivityName Name { get; init; }
|
||||
|
||||
@@ -13,4 +13,11 @@ public static class DateTimeUtils
|
||||
int offset = (7 - c + d) % 7;
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static DateTime WithTimeOnly(this DateTime dateTime, TimeOnly timeOnly)
|
||||
{
|
||||
return new DateTime(
|
||||
dateTime.Year, dateTime.Month, dateTime.Day, timeOnly.Hour, timeOnly.Minute, timeOnly.Second
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user