@kevlid/discordmenus 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/handle/component.js +11 -3
- package/src/menuInstance.js +14 -0
- package/src/render/selectMenu.js +83 -1
package/package.json
CHANGED
package/src/handle/component.js
CHANGED
|
@@ -312,8 +312,8 @@ async function handleComponent(interaction, menu, menu_key, renderMenu) {
|
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
|
|
315
|
+
let category = parseInt(options.get("cat") ?? 0);
|
|
316
|
+
let page = parseInt(options.get("page") ?? 0);
|
|
317
317
|
const action = values[1];
|
|
318
318
|
|
|
319
319
|
let result;
|
|
@@ -362,7 +362,15 @@ async function handleComponent(interaction, menu, menu_key, renderMenu) {
|
|
|
362
362
|
) {
|
|
363
363
|
const optionKey = values[0];
|
|
364
364
|
const selected = Array.isArray(interactionData.values) ? interactionData.values : [];
|
|
365
|
-
|
|
365
|
+
let opt = menu.getOption(category, page, optionKey);
|
|
366
|
+
if (!opt) {
|
|
367
|
+
const found = menu.findOption(optionKey);
|
|
368
|
+
if (found) {
|
|
369
|
+
opt = found.option;
|
|
370
|
+
category = found.category;
|
|
371
|
+
page = found.page;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
366
374
|
const maxSel = Number(opt?.maxValues);
|
|
367
375
|
const multi = Number.isFinite(maxSel) && maxSel > 1;
|
|
368
376
|
let saveValue = multi ? [...selected] : selected[0] ?? null;
|
package/src/menuInstance.js
CHANGED
|
@@ -108,6 +108,20 @@ class MenuInstance {
|
|
|
108
108
|
return page.options.find(o => o.key === optionKey) ?? null;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
findOption(optionKey) {
|
|
112
|
+
for (let cat = 0; cat < this.pages.length; cat++) {
|
|
113
|
+
const categoryPages = this.pages[cat];
|
|
114
|
+
for (let page = 0; page < categoryPages.length; page++) {
|
|
115
|
+
const p = categoryPages[page];
|
|
116
|
+
const opt = p.options?.find(o => o.key === optionKey) ?? null;
|
|
117
|
+
if (opt) {
|
|
118
|
+
return { option: opt, category: cat, page };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
111
125
|
getNavigationTargets(category, index) {
|
|
112
126
|
const categoryPages = this.pages[category];
|
|
113
127
|
const hasPrevCategory = category > 0;
|
package/src/render/selectMenu.js
CHANGED
|
@@ -1 +1,83 @@
|
|
|
1
|
-
const { OptionTypes } = require("../utils/types");
|
|
2
1
|
if (Array.isArray(currentValue)) {
|
|
3
2
|
return currentValue;
|
|
4
3
|
}
|
|
5
4
|
if (currentValue != null) {
|
|
6
5
|
return [currentValue];
|
|
7
6
|
}
|
|
8
7
|
return [];
|
|
9
8
|
const ctx = { userId, category, page };
|
|
10
9
|
const customId = encodeId(menuKey, [opt.key, opt.type], ctx);
|
|
11
10
|
const component = {
|
|
12
11
|
type: opt.selectType,
|
|
13
12
|
custom_id: customId,
|
|
14
13
|
min_values: opt.minValues,
|
|
15
14
|
max_values: opt.maxValues,
|
|
16
15
|
};
|
|
17
16
|
if (opt.placeholder != null) {
|
|
18
17
|
component.placeholder = opt.placeholder;
|
|
19
18
|
}
|
|
20
19
|
if (opt.type === OptionTypes.StringSelect) {
|
|
21
20
|
const selectedValues = toIdArray(currentValue);
|
|
22
21
|
component.options = opt.choices.map(c => ({
|
|
23
22
|
label: c.label,
|
|
24
23
|
value: c.value,
|
|
25
24
|
description: c.description,
|
|
26
25
|
default: selectedValues.includes(c.value),
|
|
27
26
|
}));
|
|
28
27
|
}
|
|
29
28
|
if (opt.type === OptionTypes.UserSelect) {
|
|
30
29
|
const ids = toIdArray(currentValue);
|
|
31
30
|
if (ids.length > 0) {
|
|
32
31
|
component.default_values = ids.map(id => ({ id, type: "user" }));
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
34
|
if (opt.type === OptionTypes.RoleSelect) {
|
|
36
35
|
const ids = toIdArray(currentValue);
|
|
37
36
|
if (ids.length > 0) {
|
|
38
37
|
component.default_values = ids.map(id => ({ id, type: "role" }));
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
if (opt.type === OptionTypes.ChannelSelect) {
|
|
42
41
|
if (opt.channelTypes && opt.channelTypes.length > 0) {
|
|
43
42
|
component.channel_types = opt.channelTypes;
|
|
44
43
|
}
|
|
45
44
|
const ids = toIdArray(currentValue);
|
|
46
45
|
if (ids.length > 0) {
|
|
47
46
|
component.default_values = ids.map(id => ({ id, type: "channel" }));
|
|
48
47
|
}
|
|
49
48
|
}
|
|
50
49
|
return component;
|
|
51
50
|
const lines = [`**${opt.title}**`];
|
|
52
51
|
if (opt.description) {
|
|
53
52
|
lines.push(`-# ${opt.description}`);
|
|
54
53
|
}
|
|
55
54
|
const textDisplay = renderTextDisplay(lines.join("\n"));
|
|
56
55
|
const selectMenu = renderSelectMenuComponent(menuKey, opt, currentValue, userId, category, page);
|
|
57
56
|
const actionRow = renderActionRow(selectMenu);
|
|
58
57
|
return [textDisplay, actionRow, renderSeparator()];
|
|
58
|
+
const { OptionTypes } = require("../utils/types");
|
|
59
|
+
const { renderTextDisplay, renderActionRow, renderSeparator } = require("./utils");
|
|
60
|
+
const { encodeId } = require("../utils/customIds");
|
|
61
|
+
|
|
62
|
+
function toIdArray(currentValue) {
|
|
63
|
+
if (Array.isArray(currentValue)) {
|
|
64
|
+
return currentValue;
|
|
65
|
+
}
|
|
66
|
+
if (currentValue != null) {
|
|
67
|
+
return [currentValue];
|
|
68
|
+
}
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function renderSelectMenuComponent(menuKey, opt, currentValue, userId, category, page) {
|
|
73
|
+
// Stateless: do not depend on current rendered page in the custom id.
|
|
74
|
+
// The handler can locate the option by key in the built menu.
|
|
75
|
+
const ctx = { u: userId };
|
|
76
|
+
const customId = encodeId(menuKey, [opt.key, opt.type], ctx);
|
|
77
|
+
|
|
78
|
+
const component = {
|
|
79
|
+
type: opt.selectType,
|
|
80
|
+
custom_id: customId,
|
|
81
|
+
min_values: opt.minValues,
|
|
82
|
+
max_values: opt.maxValues,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
if (opt.placeholder != null) {
|
|
86
|
+
component.placeholder = opt.placeholder;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (opt.type === OptionTypes.StringSelect) {
|
|
90
|
+
const selectedValues = toIdArray(currentValue);
|
|
91
|
+
component.options = opt.choices.map(c => ({
|
|
92
|
+
label: c.label,
|
|
93
|
+
value: c.value,
|
|
94
|
+
description: c.description,
|
|
95
|
+
default: selectedValues.includes(c.value),
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (opt.type === OptionTypes.UserSelect) {
|
|
100
|
+
const ids = toIdArray(currentValue);
|
|
101
|
+
if (ids.length > 0) {
|
|
102
|
+
component.default_values = ids.map(id => ({ id, type: "user" }));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (opt.type === OptionTypes.RoleSelect) {
|
|
107
|
+
const ids = toIdArray(currentValue);
|
|
108
|
+
if (ids.length > 0) {
|
|
109
|
+
component.default_values = ids.map(id => ({ id, type: "role" }));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (opt.type === OptionTypes.ChannelSelect) {
|
|
114
|
+
if (opt.channelTypes && opt.channelTypes.length > 0) {
|
|
115
|
+
component.channel_types = opt.channelTypes;
|
|
116
|
+
}
|
|
117
|
+
const ids = toIdArray(currentValue);
|
|
118
|
+
if (ids.length > 0) {
|
|
119
|
+
component.default_values = ids.map(id => ({ id, type: "channel" }));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return component;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function renderSelectMenuOption(menuKey, opt, currentValue, userId, category, page) {
|
|
127
|
+
const lines = [`**${opt.title}**`];
|
|
128
|
+
|
|
129
|
+
if (opt.description) {
|
|
130
|
+
lines.push(`-# ${opt.description}`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const textDisplay = renderTextDisplay(lines.join("\n"));
|
|
134
|
+
const selectMenu = renderSelectMenuComponent(menuKey, opt, currentValue, userId, category, page);
|
|
135
|
+
const actionRow = renderActionRow(selectMenu);
|
|
136
|
+
|
|
137
|
+
return [textDisplay, actionRow, renderSeparator()];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = { renderSelectMenuOption };
|