Skip to content

Commit fa44df3

Browse files
committed
fix(discord): preserve disabled link buttons
1 parent 2e763e3 commit fa44df3

4 files changed

Lines changed: 60 additions & 6 deletions

File tree

extensions/discord/src/components.builders.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ function createButtonComponent(params: {
6060
class DynamicLinkButton extends LinkButton {
6161
label = params.spec.label;
6262
url = linkUrl;
63+
override disabled = params.spec.disabled ?? false;
6364
}
6465
return { component: new DynamicLinkButton() };
6566
}

extensions/discord/src/components.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MessageFlags } from "discord-api-types/v10";
1+
import { ButtonStyle, MessageFlags } from "discord-api-types/v10";
22
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
33

44
let clearDiscordComponentEntries: typeof import("./components-registry.js").clearDiscordComponentEntries;
@@ -60,6 +60,41 @@ describe("discord components", () => {
6060
expect(result.modals[0]?.allowedUsers).toEqual(["discord:user-1"]);
6161
});
6262

63+
it("serializes disabled link buttons", () => {
64+
const spec = readDiscordComponentSpec({
65+
blocks: [
66+
{
67+
type: "actions",
68+
buttons: [
69+
{
70+
label: "Open docs",
71+
style: "link",
72+
url: "https://example.com/docs",
73+
disabled: true,
74+
},
75+
],
76+
},
77+
],
78+
});
79+
if (!spec) {
80+
throw new Error("Expected component spec to be parsed");
81+
}
82+
83+
const result = buildDiscordComponentMessage({ spec });
84+
const serialized = result.components[0]?.serialize() as
85+
| { components?: Array<{ components?: Array<Record<string, unknown>> }> }
86+
| undefined;
87+
const button = serialized?.components?.[0]?.components?.[0];
88+
89+
expect(button).toMatchObject({
90+
label: "Open docs",
91+
style: ButtonStyle.Link,
92+
url: "https://example.com/docs",
93+
disabled: true,
94+
});
95+
expect(result.entries).toHaveLength(0);
96+
});
97+
6398
it("requires options for modal select fields", () => {
6499
expect(() =>
65100
readDiscordComponentSpec({

extensions/discord/src/outbound-adapter.test.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,10 @@ describe("discordOutbound", () => {
589589
blocks: [
590590
{
591591
type: "buttons",
592-
buttons: [{ label: "Already handled", value: "done", disabled: true }],
592+
buttons: [
593+
{ label: "Already handled", value: "done", disabled: true },
594+
{ label: "Open docs", url: "https://example.com/docs", disabled: true },
595+
],
593596
},
594597
],
595598
},
@@ -611,16 +614,22 @@ describe("discordOutbound", () => {
611614
const discordData = payload.channelData?.discord as
612615
| { presentationComponents?: { blocks?: Array<{ type?: string; buttons?: unknown[] }> } }
613616
| undefined;
614-
const button = discordData?.presentationComponents?.blocks?.find(
617+
const buttons = discordData?.presentationComponents?.blocks?.find(
615618
(block) => block.type === "actions",
616-
)?.buttons?.[0];
619+
)?.buttons;
617620

618-
expect(button).toEqual({
621+
expect(buttons?.[0]).toEqual({
619622
label: "Already handled",
620623
style: "secondary",
621624
callbackData: "done",
622625
disabled: true,
623626
});
627+
expect(buttons?.[1]).toEqual({
628+
label: "Open docs",
629+
style: "link",
630+
url: "https://example.com/docs",
631+
disabled: true,
632+
});
624633
});
625634

626635
it("keeps replyToId on every internal component media send when replyToMode is all", async () => {

extensions/discord/src/shared-interactive.test.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,10 @@ describe("buildDiscordInteractiveComponents", () => {
157157
blocks: [
158158
{
159159
type: "buttons",
160-
buttons: [{ label: "Already handled", value: "done", disabled: true }],
160+
buttons: [
161+
{ label: "Already handled", value: "done", disabled: true },
162+
{ label: "Open docs", url: "https://example.com/docs", disabled: true },
163+
],
161164
},
162165
],
163166
}),
@@ -172,6 +175,12 @@ describe("buildDiscordInteractiveComponents", () => {
172175
callbackData: "done",
173176
disabled: true,
174177
},
178+
{
179+
label: "Open docs",
180+
style: "link",
181+
url: "https://example.com/docs",
182+
disabled: true,
183+
},
175184
],
176185
},
177186
],

0 commit comments

Comments
 (0)