feat(discord): wizard interaction handlers + DI for StringMenu/Modal (issue #112)

Adds the missing inbound handlers for the Discord wizard that the
previous commit (b81d865) left out. Three thin NetCord module classes
share one WizardInteractionDispatcher:

- DiscordWizardButtonModule
- DiscordWizardStringMenuModule
- DiscordWizardModalModule

Each registers a single [ComponentInteraction("wizard")] method that
hands the args string to the dispatcher. The dispatcher parses the
custom-id tail (btn:choice:<step>:<value>, btn:back, btn:cancel,
btn:create, btn:resume:continue, btn:resume:restart, select:<step>,
modal:<step>), looks up the active draft by (platform="Discord",
ownerId=userId), and routes through the shared
GameCreationWizard.HandleInteractionAsync. The "create" callback
delegates to DiscordWizardSubmitter.SubmitAsync (3-retry finalize).

Program.cs gets 4 new singleton registrations (the dispatcher plus
the three module classes) and 2 new AddComponentInteractions calls
(StringMenu + Modal). The existing Button registration is unchanged.

12 new source-level smoke tests in DiscordWizardInteractionModuleSourceTests
cover the file shape: 3 handler classes, 3 base classes, 3
[ComponentInteraction] registrations, all 5 callback kinds parsed,
GameCreationWizard wired in, submitter invoked on create, Program.cs
registers all 3 AddComponentInteractions and all 4 module classes,
draft lookup by GetActiveAsync("Discord", ...), modal walks
Components[0] -> TextInput -> .Value, string menu reads
SelectedValues[0].

Build green. 190/190 Discord+Wizard tests pass (2 pre-existing
skipped). dotnet format clean.
This commit is contained in:
Coder
2026-06-05 18:31:47 +03:00
parent b81d865832
commit f0952096f3
3 changed files with 695 additions and 0 deletions
+6
View File
@@ -96,6 +96,10 @@ builder.Services.AddSingleton<IWizardContextStore, DiscordWizardContextStore>();
builder.Services.AddSingleton<IWizardMessenger, DiscordWizardMessenger>();
builder.Services.AddSingleton<GmRelay.Shared.Features.Sessions.CreateSession.Wizard.GameCreationWizard>();
builder.Services.AddSingleton<DiscordWizardSubmitter>();
builder.Services.AddSingleton<WizardInteractionDispatcher>();
builder.Services.AddSingleton<DiscordWizardButtonModule>();
builder.Services.AddSingleton<DiscordWizardStringMenuModule>();
builder.Services.AddSingleton<DiscordWizardModalModule>();
builder.Services
.AddDiscordGateway(options =>
@@ -105,6 +109,8 @@ builder.Services
})
.AddApplicationCommands<SlashCommandInteraction, SlashCommandContext>()
.AddComponentInteractions<ButtonInteraction, ButtonInteractionContext>()
.AddComponentInteractions<StringMenuInteraction, StringMenuInteractionContext>()
.AddComponentInteractions<ModalInteraction, ModalInteractionContext>()
.AddGatewayHandlers(typeof(Program).Assembly);
var host = builder.Build();