Skip to content

Commit 9f3d500

Browse files
HandyS11claude
andcommitted
feat(workspace): render disconnect + remove-server buttons (EN/FR)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 0555754 commit 9f3d500

5 files changed

Lines changed: 58 additions & 3 deletions

File tree

src/RustPlusBot.Features.Workspace/Localization/LocalizationCatalog.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ internal sealed class LocalizationCatalog
2525
["setup.body"] =
2626
"Click **Connect account** below and paste your Rust+ FCM credentials. Then pair a server in-game and its channels appear automatically.",
2727
["setup.connect.button"] = "Connect account",
28+
["setup.disconnect.button"] = "Disconnect account",
29+
["server.info.remove.button"] = "Remove server",
2830
["settings.title"] = "Settings",
2931
["settings.body"] = "Configure the bot for this server.",
3032
["settings.language.label"] = "Language",
@@ -54,6 +56,8 @@ internal sealed class LocalizationCatalog
5456
["setup.body"] =
5557
"Cliquez sur **Connecter le compte** ci-dessous et collez vos identifiants FCM Rust+. Appairez ensuite un serveur en jeu et ses salons apparaitront automatiquement.",
5658
["setup.connect.button"] = "Connecter le compte",
59+
["setup.disconnect.button"] = "Déconnecter le compte",
60+
["server.info.remove.button"] = "Supprimer le serveur",
5761
["settings.title"] = "Parametres",
5862
["settings.body"] = "Configurez le bot pour ce serveur.",
5963
["settings.language.label"] = "Langue",

src/RustPlusBot.Features.Workspace/Messages/ServerInfoMessageRenderer.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public async ValueTask<MessagePayload> RenderAsync(MessageRenderContext context,
6565
.Where(c => c.Status != CredentialStatus.Invalid)
6666
.Take(SelectMenuBuilder.MaxOptionCount) // Discord hard-limits a select menu to 25 options.
6767
.ToList();
68-
MessageComponent? components = null;
68+
var builder = new ComponentBuilder();
6969
if (eligible.Count > 0)
7070
{
7171
var select = new SelectMenuBuilder()
@@ -77,10 +77,15 @@ public async ValueTask<MessagePayload> RenderAsync(MessageRenderContext context,
7777
select.AddOption(label, credential.Id.ToString(), isDefault: credential.Id == active?.Id);
7878
}
7979

80-
components = new ComponentBuilder().WithSelectMenu(select).Build();
80+
builder.WithSelectMenu(select);
8181
}
8282

83-
return new MessagePayload(null, embed.Build(), components);
83+
builder.WithButton(
84+
localizer.Get("server.info.remove.button", context.Culture),
85+
$"{WorkspaceComponentIds.ServerInfoRemovePrefix}{serverId}",
86+
ButtonStyle.Danger);
87+
88+
return new MessagePayload(null, embed.Build(), builder.Build());
8489
}
8590

8691
private static string Glyph(ConnectionStatus status) => status switch

src/RustPlusBot.Features.Workspace/Messages/SetupMessageRenderer.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ public ValueTask<MessagePayload> RenderAsync(MessageRenderContext context, Cance
2626
localizer.Get("setup.connect.button", context.Culture),
2727
WorkspaceComponentIds.ConnectAccount,
2828
ButtonStyle.Primary)
29+
.WithButton(
30+
localizer.Get("setup.disconnect.button", context.Culture),
31+
WorkspaceComponentIds.DisconnectAccount,
32+
ButtonStyle.Danger)
2933
.Build();
3034
return ValueTask.FromResult(new MessagePayload(null, embed, components));
3135
}

src/RustPlusBot.Features.Workspace/WorkspaceComponentIds.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@ public static class WorkspaceComponentIds
1111

1212
/// <summary>Prefix for the #info "swap active player" select; the server id is appended. Handled by Connections.</summary>
1313
public const string ServerInfoSwapPrefix = "workspace:info:swap:";
14+
15+
/// <summary>The #setup "Disconnect account" button; handled by the Pairing feature.</summary>
16+
public const string DisconnectAccount = "workspace:setup:disconnect";
17+
18+
/// <summary>Prefix for the #info "remove server" button; the server id is appended. Handled by Connections.</summary>
19+
public const string ServerInfoRemovePrefix = "workspace:info:remove:";
1420
}

tests/RustPlusBot.Features.Workspace.Tests/Messages/RendererTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,40 @@ public async Task Setup_HasConnectAccountButton()
182182
.SelectMany(r => r.Components).OfType<ButtonComponent>();
183183
Assert.Contains(buttons, b => b.CustomId == "workspace:setup:connect");
184184
}
185+
186+
[Fact]
187+
public async Task Setup_HasDisconnectAccountButton()
188+
{
189+
var renderer = new SetupMessageRenderer(Loc);
190+
191+
var payload = await renderer.RenderAsync(Global, default);
192+
193+
var buttons = payload.Components!.Components.OfType<ActionRowComponent>()
194+
.SelectMany(r => r.Components).OfType<ButtonComponent>();
195+
Assert.Contains(buttons, b => b.CustomId == "workspace:setup:disconnect");
196+
}
197+
198+
[Fact]
199+
public async Task ServerInfo_HasRemoveServerButton()
200+
{
201+
var serverId = Guid.NewGuid();
202+
var servers = Substitute.For<IServerService>();
203+
servers.GetAsync(1, serverId, Arg.Any<CancellationToken>())
204+
.Returns(new RustServer { Id = serverId, GuildId = 1, Name = "S", Ip = "1.2.3.4", Port = 28015 });
205+
var connections = Substitute.For<IConnectionStore>();
206+
connections.GetStateAsync(1, serverId, Arg.Any<CancellationToken>())
207+
.Returns(new DomainConnectionState
208+
{
209+
RustServerId = serverId, GuildId = 1, Status = ConnectionStatus.NoCredentials
210+
});
211+
connections.ListPoolAsync(1, serverId, Arg.Any<CancellationToken>())
212+
.Returns(new List<PlayerCredential>());
213+
var renderer = new ServerInfoMessageRenderer(servers, connections, Loc);
214+
215+
var payload = await renderer.RenderAsync(new MessageRenderContext(1, serverId, "en"), default);
216+
217+
var buttons = payload.Components!.Components.OfType<ActionRowComponent>()
218+
.SelectMany(r => r.Components).OfType<ButtonComponent>();
219+
Assert.Contains(buttons, b => b.CustomId == $"workspace:info:remove:{serverId}");
220+
}
185221
}

0 commit comments

Comments
 (0)