@open-discord-bots/framework 0.3.7 → 0.3.9

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.
@@ -5,6 +5,7 @@ import { ODId, ODValidId, ODSystemError, ODManagerData, ODNoGeneric, ODManager,
5
5
  import * as discord from "discord.js"
6
6
  import { ODWorkerManager, ODWorkerCallback, ODWorker } from "./worker.js"
7
7
  import { ODDebugger } from "./console.js"
8
+ import { ODMessage, ODMessageInstance } from "./builder.js"
8
9
 
9
10
  /**## ODComponentFactoryInstance `class`
10
11
  * An Open Discord component factory instance.
@@ -49,6 +50,14 @@ export class ODComponentFactory<Component extends ODComponent<object,any>,Origin
49
50
  if (!rootComponent) throw new ODSystemError("ODComponentFactory.build() --> Failed to build component! (id: "+this.id.value+")")
50
51
  return rootComponent.build()
51
52
  }
53
+ /**Duplicate this component factory. Warning: If workers access external variables (outside parameters), the clone will still use those variables. This might result in unexpected behaviour! */
54
+ duplicate(newId?:ODValidId): ODComponentFactory<Component,Origin,Params,WorkerIds> {
55
+ const newMessage = new ODComponentFactory<Component,Origin,Params,WorkerIds>(newId ?? this.id.value)
56
+ for (const worker of this.workers.getAll()){
57
+ newMessage.workers.add(worker.duplicate())
58
+ }
59
+ return newMessage
60
+ }
52
61
  }
53
62
 
54
63
  /**## ODComponentManagerIdConstraint `type`
@@ -88,6 +97,46 @@ export class ODBaseComponentManager<IdList extends ODComponentManagerIdConstrain
88
97
  }
89
98
  }
90
99
 
100
+
101
+ /**## ODComponentModifierManagerIdConstraint `type`
102
+ * The constraint/layout for id mappings/interfaces of the `ODComponentModifierManager` class.
103
+ */
104
+ export type ODComponentModifierManagerIdConstraint = Record<string,ODMessageComponentModifier<string,{}>>
105
+
106
+ /**## ODComponentModifierManager `class`
107
+ * An Open Discord component modifier manager.
108
+ *
109
+ * It contains a collection of all `ODMessageComponentModifier`'s. You can:
110
+ * - Patch, modify, expand or update existing messages
111
+ * - It Does not affect the original message (cloned)
112
+ */
113
+ export class ODComponentModifierManager<IdList extends ODComponentModifierManagerIdConstraint = ODComponentModifierManagerIdConstraint> extends ODManager<ODMessageComponentModifier<string,{}>> {
114
+ constructor(debug:ODDebugger){
115
+ super(debug,"component modifier")
116
+ }
117
+
118
+ get<ModifierId extends keyof ODNoGeneric<IdList>>(id:ModifierId): IdList[ModifierId]
119
+ get(id:ODValidId): ODMessageComponentModifier<string,{}>|null
120
+
121
+ get(id:ODValidId): ODMessageComponentModifier<string,{}>|null {
122
+ return super.get(id)
123
+ }
124
+
125
+ remove<ModifierId extends keyof ODNoGeneric<IdList>>(id:ModifierId): IdList[ModifierId]
126
+ remove(id:ODValidId): ODMessageComponentModifier<string,{}>|null
127
+
128
+ remove(id:ODValidId): ODMessageComponentModifier<string,{}>|null {
129
+ return super.remove(id)
130
+ }
131
+
132
+ exists(id:keyof ODNoGeneric<IdList>): boolean
133
+ exists(id:ODValidId): boolean
134
+
135
+ exists(id:ODValidId): boolean {
136
+ return super.exists(id)
137
+ }
138
+ }
139
+
91
140
  /**## ODSharedComponentManager `class
92
141
  * A special class with types for shared message/modal `ODComponent`'s.
93
142
  * Create button, dropdown or any other layout component template to use them in messages & modals.
@@ -135,7 +184,8 @@ export class ODModalComponentManager<IdList extends ODComponentManagerIdConstrai
135
184
  export class ODComponentManager<
136
185
  SharedIdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint,
137
186
  MessageIdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint,
138
- ModalIdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint
187
+ ModalIdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint,
188
+ ModifierIdList extends ODComponentModifierManagerIdConstraint = ODComponentModifierManagerIdConstraint
139
189
  > {
140
190
  /**The manager for all shared components. */
141
191
  shared: ODSharedComponentManager<SharedIdList>
@@ -143,11 +193,14 @@ export class ODComponentManager<
143
193
  messages: ODMessageComponentManager<MessageIdList>
144
194
  /**The manager for all modals components. */
145
195
  modals: ODModalComponentManager<ModalIdList>
196
+ /**The collection of all component modifiers. */
197
+ modifiers: ODComponentModifierManager<ModifierIdList>
146
198
 
147
199
  constructor(debug:ODDebugger){
148
200
  this.shared = new ODSharedComponentManager(debug)
149
201
  this.messages = new ODMessageComponentManager(debug)
150
202
  this.modals = new ODModalComponentManager(debug)
203
+ this.modifiers = new ODComponentModifierManager(debug)
151
204
  }
152
205
  }
153
206
 
@@ -160,21 +213,58 @@ export class ODComponentManager<
160
213
  */
161
214
  export type ODComponentInferBuildResult<Component> = Component extends ODComponent<object,infer BuildResult> ? BuildResult : never
162
215
 
216
+ /**## ODComponentType `type`
217
+ * The type of an `ODComponent`.
218
+ */
219
+ export type ODComponentType = "message"|"simple-message"|"modal"|"action-row"|"container"|"section"|"label"|"separator"|"text"|"file"|"gallery"|"thumbnail"|"simple-content"|"simple-embed"|"simple-poll"|"button"|"short-input"|"paragraph-input"|"dropdown"|"radio-group"|"checkbox-group"|"checkbox"|"file-upload"
220
+
221
+ /**## ODComponentType `type`
222
+ * Get the `ODComponent` class for a specific `ODComponentType`.
223
+ */
224
+ export interface ODComponentForType {
225
+ "message":ODMessageComponent,
226
+ "simple-message":ODSimpleMessageComponent,
227
+ "modal":ODModalComponent,
228
+ "action-row":ODActionRowComponent,
229
+ "container":ODContainerComponent,
230
+ "section":ODSectionComponent,
231
+ "label":ODLabelComponent,
232
+ "separator":ODSeparatorComponent,
233
+ "text":ODTextComponent,
234
+ "file":ODFileComponent,
235
+ "gallery":ODGalleryComponent,
236
+ "thumbnail":ODThumbnailComponent,
237
+ "simple-content":ODContentComponent,
238
+ "simple-embed":ODEmbedComponent,
239
+ "simple-poll":ODPollComponent,
240
+ "button":ODButtonComponent,
241
+ "short-input":ODShortInputComponent,
242
+ "paragraph-input":ODParagraphInputComponent,
243
+ "dropdown":ODDropdownComponent,
244
+ "radio-group":ODRadioGroupComponent,
245
+ "checkbox-group":ODCheckboxGroupComponent,
246
+ "checkbox":ODCheckboxComponent,
247
+ "file-upload":ODFileUploadComponent,
248
+ }
249
+
163
250
  /**## ODComponent `class`
164
251
  * An Open Discord message/modal component.
165
252
  *
166
253
  * This class itself doesn't do anything, but is a blueprint for other
167
254
  * `ODComponent` classes which represent the new Discord message/modal components.
168
255
  */
169
- export abstract class ODComponent<Data extends object,BuildResult> {
256
+ export abstract class ODComponent<Data extends object,BuildResult,Type extends ODComponentType = ODComponentType> {
170
257
  /**The id of this message/modal component. */
171
258
  id: ODId
172
259
  /**The data or configuration of this message/modal component. */
173
260
  readonly data: Data
261
+ /**The type of this component. */
262
+ readonly type: Type
174
263
 
175
- constructor(id:ODValidId,data:Data){
264
+ constructor(id:ODValidId,type:Type,data:Data){
176
265
  this.id = new ODId(id)
177
266
  this.data = data
267
+ this.type = type
178
268
  }
179
269
 
180
270
  /**Build this component. Returns `null` when invalid. */
@@ -189,7 +279,7 @@ export abstract class ODComponent<Data extends object,BuildResult> {
189
279
  */
190
280
  export abstract class ODGroupComponent<Data extends object,ChildComponent extends ODComponent<object,any>,BuildResult> extends ODComponent<Data,BuildResult> {
191
281
  /**The collection of child components. */
192
- readonly children: ChildComponent[] = []
282
+ children: ChildComponent[] = []
193
283
 
194
284
  /**Add a new component to this group. There are multiple modes available:
195
285
  * - `start`: insert at the start of the list.
@@ -223,15 +313,55 @@ export abstract class ODGroupComponent<Data extends object,ChildComponent extend
223
313
  }
224
314
  }
225
315
  }
226
- /**Get a component with a certain ID in this group. Returns `null` if non-existent. */
227
- getComponent(id:ODValidId){
316
+ /**Get a component with a certain ID in this group. Returns `null` if non-existent. Also able to search for components recursively. */
317
+ getComponent(id:ODValidId): ChildComponent|null
318
+ getComponent(id:ODValidId,recursive:true,recursiveLimit?:number): ODComponent<any,any,ODComponentType>|null
319
+ getComponent(id:ODValidId,recursive?:boolean,recursiveLimit:number=15){
228
320
  const component = this.children.find((c) => c.id.value === new ODId(id).value)
229
- return component ?? null
321
+ if (component) return component
322
+ else if (recursive && (recursiveLimit > 0)){
323
+ for (const child of this.children){
324
+ if (child instanceof ODGroupComponent){
325
+ const finalComponent = child.getComponent(id,recursive,recursiveLimit-1) as ODComponent<any,any,ODComponentType>
326
+ if (finalComponent) return finalComponent
327
+ }else if (child instanceof ODParentComponent){
328
+ const finalComponent = child.child as ODComponent<any,any,ODComponentType>
329
+ if (finalComponent.id.value === new ODId(id).value) return finalComponent
330
+ }
331
+ }
332
+ return null
333
+ }else return null
334
+ }
335
+ /**Get all components of a certain type in this group. Also able to search for components recursively. */
336
+ getComponentsOfType<Type extends ODComponentType>(type:Type): ODComponentForType[Type][]
337
+ getComponentsOfType<Type extends ODComponentType>(type:Type,recursive:true,recursiveLimit?:number): ODComponentForType[Type][]
338
+ getComponentsOfType(type:ODComponentType,recursive?:boolean,recursiveLimit:number=15){
339
+ if (recursive && (recursiveLimit > 0)){
340
+ const finalComponents: ODComponent<any,any,ODComponentType>[] = [...this.children.filter((c) => c.type === type)]
341
+
342
+ for (const child of this.children){
343
+ if (child instanceof ODGroupComponent){
344
+ finalComponents.push(...(child.getComponentsOfType(type,recursive,recursiveLimit-1) as ODComponent<any,any,ODComponentType>[]))
345
+
346
+ }else if (child instanceof ODParentComponent){
347
+ const finalComponent = child.child as ODComponent<any,any,ODComponentType>
348
+ if (finalComponent.type === type) finalComponents.push(finalComponent)
349
+ }
350
+ }
351
+ return finalComponents
352
+ }else{
353
+ const finalComponents: ChildComponent[] = [...this.children.filter((c) => c.type === type)]
354
+ return finalComponents
355
+ }
230
356
  }
231
357
  /**Get the position of a component with a certain ID in this group. Returns `-1` if non-existent. */
232
358
  getComponentPosition(id:ODValidId){
233
359
  return this.children.findIndex((c) => c.id.value === new ODId(id).value)
234
360
  }
361
+ /**List all child components of this group. */
362
+ listComponent(){
363
+ return this.children
364
+ }
235
365
  /**Returns if a component with a certain ID exists in this group. */
236
366
  existsComponent(id:ODValidId){
237
367
  const component = this.children.find((c) => c.id.value === new ODId(id).value)
@@ -243,6 +373,12 @@ export abstract class ODGroupComponent<Data extends object,ChildComponent extend
243
373
  if (index < 0) return null
244
374
  else return this.children.splice(index,1)[0]
245
375
  }
376
+ /**Remove all child components from this group. Returns the removed components. */
377
+ clearComponents(){
378
+ const removedChildren = this.children
379
+ this.children = []
380
+ return removedChildren
381
+ }
246
382
  /**Moves an existing component to a new location in this group. There are multiple modes available:
247
383
  * - `start`: move to the start of the list.
248
384
  * - `end`: move to the end of the list.
@@ -284,6 +420,36 @@ export abstract class ODParentComponent<Data extends object,ChildComponent exten
284
420
  }
285
421
  }
286
422
 
423
+ /////////////////////////////
424
+ // COMPONENT MODIFIERS //
425
+ /////////////////////////////
426
+
427
+ /**## ODMessageComponentModifier `class`
428
+ * This is an Open Discord message component modifier.
429
+ *
430
+ * It contains a worker which is can be added to a message.
431
+ *
432
+ * The original message is preserved and a duplicate of `ODMessage` or `ODComponentFactory` is returned.
433
+ *
434
+ * Warning: If workers access external variables (outside parameters), the clone will still use those variables. This might result in unexpected behaviour!
435
+ */
436
+ export class ODMessageComponentModifier<Origin extends string,Params> extends ODManagerData {
437
+ /**The worker which will modify the message. */
438
+ worker: ODWorker<ODMessageInstance|ODComponentFactoryInstance<ODMessageComponent>,Origin,Params>
439
+
440
+ constructor(id:ODValidId,worker:ODWorker<ODMessageInstance|ODComponentFactoryInstance<ODMessageComponent>,Origin,Params>){
441
+ super(id)
442
+ this.worker = worker
443
+ }
444
+
445
+ /**Modify an `ODMessage` or `ODComponentFactory` with the worker. A copy will be returned and the original is preserved. */
446
+ modify<Message extends ODMessage<any,any,any>|ODComponentFactory<ODMessageComponent,any,any,any>>(message:Message): Message {
447
+ const newMsg = message.duplicate(message.id.value+"-VERIFYBAR") as Message
448
+ newMsg.workers.add(this.worker.duplicate())
449
+ return newMsg
450
+ }
451
+ }
452
+
287
453
  //////////////////////////////////////
288
454
  // GLOBAL COMPONENT DEFINITIONS //
289
455
  //////////////////////////////////////
@@ -307,7 +473,7 @@ export interface ODMessageComponentData {
307
473
  /**## ODValidMessageComponents `type`
308
474
  * A collection of all valid top-level components that can be sent in a message.
309
475
  */
310
- export type ODValidMessageComponents = ODTextComponent|ODFileComponent|ODGalleryComponent
476
+ export type ODValidMessageComponents = ODTextComponent|ODFileComponent|ODGalleryComponent|ODActionRowComponent|ODContainerComponent|ODSectionComponent|ODSeparatorComponent
311
477
 
312
478
  /**## ODMessageComponentBuildResult `type`
313
479
  * The constructed message from an `ODMessageComponent`.
@@ -336,7 +502,7 @@ export interface ODMessageComponentBuildResult {
336
502
  export class ODMessageComponent extends ODGroupComponent<ODMessageComponentData,ODValidMessageComponents,ODMessageComponentBuildResult> {
337
503
  constructor(id:ODValidId,data?:Partial<ODMessageComponentData>){
338
504
  const initData: ODMessageComponentData = {...data}
339
- super(id,initData)
505
+ super(id,"message",initData)
340
506
  }
341
507
 
342
508
  async build(){
@@ -357,6 +523,11 @@ export class ODMessageComponent extends ODGroupComponent<ODMessageComponentData,
357
523
  const res = await component.build()
358
524
  if (res) components.push(res.gallery)
359
525
  if (res?.attachments) attachments.push(...res.attachments)
526
+ }else if (component instanceof ODContainerComponent){
527
+ //ODContainerComponent (special)
528
+ const res = await component.build()
529
+ if (res) components.push(res.container)
530
+ if (res?.attachments) attachments.push(...res.attachments)
360
531
  }else{
361
532
  //general ODComponent's
362
533
  const res = await component.build()
@@ -429,7 +600,7 @@ export type ODValidSimpleMessageComponents = ODContentComponent|ODEmbedComponent
429
600
  export class ODSimpleMessageComponent extends ODGroupComponent<ODSimpleMessageComponentData,ODValidSimpleMessageComponents,ODMessageComponentBuildResult> {
430
601
  constructor(id:ODValidId,data?:Partial<ODMessageComponentData>){
431
602
  const initData: ODMessageComponentData = {...data}
432
- super(id,initData)
603
+ super(id,"simple-message",initData)
433
604
  }
434
605
 
435
606
  async build(){
@@ -521,7 +692,7 @@ export type ODValidModalComponents = ODLabelComponent|ODTextComponent
521
692
  export class ODModalComponent extends ODGroupComponent<ODModalComponentData,ODValidModalComponents,discord.ModalBuilder> {
522
693
  constructor(id:ODValidId,data?:Partial<ODModalComponentData>){
523
694
  const initData: ODModalComponentData = {title:"<empty>",...data}
524
- super(id,initData)
695
+ super(id,"modal",initData)
525
696
  }
526
697
 
527
698
  async build(){
@@ -584,7 +755,7 @@ export type ODValidActionRowComponents = ODButtonComponent|ODDropdownComponent
584
755
  export class ODActionRowComponent extends ODGroupComponent<ODActionRowComponentData,ODValidActionRowComponents,discord.ActionRowBuilder<discord.MessageActionRowComponentBuilder>> {
585
756
  constructor(id:ODValidId,data?:Partial<ODActionRowComponentData>){
586
757
  const initData: ODActionRowComponentData = {...data}
587
- super(id,initData)
758
+ super(id,"action-row",initData)
588
759
  }
589
760
 
590
761
  async build(){
@@ -624,7 +795,7 @@ export type ODValidContainerComponents = ODActionRowComponent|ODTextComponent|OD
624
795
  export class ODContainerComponent extends ODGroupComponent<ODContainerComponentData,ODValidContainerComponents,{container:discord.ContainerBuilder,attachments:discord.AttachmentBuilder[]}> {
625
796
  constructor(id:ODValidId,data?:Partial<ODContainerComponentData>){
626
797
  const initData: ODContainerComponentData = {spoiler:false,...data}
627
- super(id,initData)
798
+ super(id,"container",initData)
628
799
  }
629
800
 
630
801
  async build(){
@@ -689,7 +860,7 @@ export interface ODSectionComponentData {
689
860
  export class ODSectionComponent extends ODGroupComponent<ODSectionComponentData,ODTextComponent,discord.SectionBuilder> {
690
861
  constructor(id:ODValidId,data?:Partial<ODSectionComponentData>){
691
862
  const initData: ODSectionComponentData = {...data}
692
- super(id,initData)
863
+ super(id,"section",initData)
693
864
  }
694
865
 
695
866
  async build(){
@@ -741,7 +912,7 @@ export type ODValidLabelComponents = ODShortInputComponent|ODParagraphInputCompo
741
912
  export class ODLabelComponent extends ODParentComponent<ODLabelComponentData,ODValidLabelComponents,discord.LabelBuilder> {
742
913
  constructor(id:ODValidId,data:Partial<ODLabelComponentData>){
743
914
  const initData: ODLabelComponentData = {title:"<empty>",...data}
744
- super(id,initData)
915
+ super(id,"label",initData)
745
916
  }
746
917
 
747
918
  async build(){
@@ -785,7 +956,7 @@ export interface ODSeparatorComponentData {
785
956
  export class ODSeparatorComponent extends ODComponent<ODSeparatorComponentData,discord.SeparatorBuilder> {
786
957
  constructor(id:ODValidId,data:Partial<ODSeparatorComponentData>){
787
958
  const initData: ODSeparatorComponentData = {divider:true,spacing:"small",...data}
788
- super(id,initData)
959
+ super(id,"separator",initData)
789
960
  }
790
961
 
791
962
  async build(){
@@ -823,7 +994,7 @@ export interface ODTextComponentData {
823
994
  export class ODTextComponent extends ODComponent<ODTextComponentData,discord.TextDisplayBuilder> {
824
995
  constructor(id:ODValidId,data:Partial<ODTextComponentData>){
825
996
  const initData: ODTextComponentData = {content:"",...data}
826
- super(id,initData)
997
+ super(id,"text",initData)
827
998
  }
828
999
 
829
1000
  async build(){
@@ -861,7 +1032,7 @@ export interface ODFileComponentData {
861
1032
  export class ODFileComponent extends ODComponent<ODFileComponentData,{file:discord.FileBuilder,attachment:discord.AttachmentBuilder|null}> {
862
1033
  constructor(id:ODValidId,data:Partial<ODFileComponentData>){
863
1034
  const initData: ODFileComponentData = {name:"file.txt",...data}
864
- super(id,initData)
1035
+ super(id,"file",initData)
865
1036
  }
866
1037
 
867
1038
  async build(){
@@ -919,7 +1090,7 @@ export interface ODGalleryComponentData {
919
1090
  export class ODGalleryComponent extends ODGroupComponent<ODGalleryComponentData,ODFileComponent,{gallery:discord.MediaGalleryBuilder,attachments:discord.AttachmentBuilder[]}> {
920
1091
  constructor(id:ODValidId,data?:Partial<ODGalleryComponentData>){
921
1092
  const initData: ODGalleryComponentData = {...data}
922
- super(id,initData)
1093
+ super(id,"gallery",initData)
923
1094
  }
924
1095
 
925
1096
  async build(){
@@ -966,7 +1137,7 @@ export interface ODThumbnailComponentData {
966
1137
  export class ODThumbnailComponent extends ODComponent<ODThumbnailComponentData,discord.ThumbnailBuilder> {
967
1138
  constructor(id:ODValidId,data:Partial<ODThumbnailComponentData>){
968
1139
  const initData: ODThumbnailComponentData = {url:"",...data}
969
- super(id,initData)
1140
+ super(id,"thumbnail",initData)
970
1141
  }
971
1142
 
972
1143
  async build(){
@@ -1007,7 +1178,7 @@ export interface ODContentComponentData {
1007
1178
  export class ODContentComponent extends ODComponent<ODContentComponentData,{content:string}> {
1008
1179
  constructor(id:ODValidId,data:Partial<ODContentComponentData>){
1009
1180
  const initData: ODContentComponentData = {content:"",...data}
1010
- super(id,initData)
1181
+ super(id,"simple-content",initData)
1011
1182
  }
1012
1183
 
1013
1184
  async build(){
@@ -1062,7 +1233,7 @@ export interface ODEmbedComponentData {
1062
1233
  export class ODEmbedComponent extends ODComponent<ODEmbedComponentData,discord.EmbedBuilder> {
1063
1234
  constructor(id:ODValidId,data:Partial<ODEmbedComponentData>){
1064
1235
  const initData: ODEmbedComponentData = {...data}
1065
- super(id,initData)
1236
+ super(id,"simple-embed",initData)
1066
1237
  }
1067
1238
 
1068
1239
  async build(){
@@ -1195,7 +1366,7 @@ export interface ODPollComponentData {
1195
1366
  export class ODPollComponent extends ODComponent<ODPollComponentData,discord.PollData> {
1196
1367
  constructor(id:ODValidId,data:Partial<ODPollComponentData>){
1197
1368
  const initData: ODPollComponentData = {question:"<empty>",durationHours:1,allowMultiSelect:false,answers:[],...data}
1198
- super(id,initData)
1369
+ super(id,"simple-poll",initData)
1199
1370
  }
1200
1371
 
1201
1372
  async build(){
@@ -1262,7 +1433,7 @@ export interface ODButtonComponentData {
1262
1433
  export class ODButtonComponent extends ODComponent<ODButtonComponentData,discord.ButtonBuilder> {
1263
1434
  constructor(id:ODValidId,data:Partial<ODButtonComponentData>){
1264
1435
  const initData: ODButtonComponentData = {color:"gray",disabled:false,...data}
1265
- super(id,initData)
1436
+ super(id,"button",initData)
1266
1437
  }
1267
1438
 
1268
1439
  async build(){
@@ -1346,7 +1517,7 @@ export interface ODShortInputComponentData {
1346
1517
  export class ODShortInputComponent extends ODComponent<ODShortInputComponentData,discord.TextInputBuilder> {
1347
1518
  constructor(id:ODValidId,data:Partial<ODShortInputComponentData>){
1348
1519
  const initData: ODShortInputComponentData = {required:false,...data}
1349
- super(id,initData)
1520
+ super(id,"short-input",initData)
1350
1521
  }
1351
1522
 
1352
1523
  async build(){
@@ -1418,7 +1589,7 @@ export interface ODParagraphInputComponentData {
1418
1589
  export class ODParagraphInputComponent extends ODComponent<ODParagraphInputComponentData,discord.TextInputBuilder> {
1419
1590
  constructor(id:ODValidId,data:Partial<ODParagraphInputComponentData>){
1420
1591
  const initData: ODParagraphInputComponentData = {required:false,...data}
1421
- super(id,initData)
1592
+ super(id,"paragraph-input",initData)
1422
1593
  }
1423
1594
 
1424
1595
  async build(){
@@ -1504,7 +1675,7 @@ export interface ODDropdownComponentData {
1504
1675
  export class ODDropdownComponent extends ODComponent<ODDropdownComponentData,discord.BaseSelectMenuBuilder<discord.APISelectMenuComponent>> {
1505
1676
  constructor(id:ODValidId,data:Partial<ODDropdownComponentData>){
1506
1677
  const initData: ODDropdownComponentData = {type:"string",...data}
1507
- super(id,initData)
1678
+ super(id,"dropdown",initData)
1508
1679
  }
1509
1680
 
1510
1681
  async build(){
@@ -1631,7 +1802,7 @@ export interface ODRadioGroupComponentData {
1631
1802
  export class ODRadioGroupComponent extends ODComponent<ODRadioGroupComponentData,discord.RadioGroupBuilder> {
1632
1803
  constructor(id:ODValidId,data:Partial<ODRadioGroupComponentData>){
1633
1804
  const initData: ODRadioGroupComponentData = {required:false,options:[],...data}
1634
- super(id,initData)
1805
+ super(id,"radio-group",initData)
1635
1806
  }
1636
1807
 
1637
1808
  async build(){
@@ -1684,7 +1855,7 @@ export interface ODCheckboxGroupComponentData {
1684
1855
  export class ODCheckboxGroupComponent extends ODComponent<ODCheckboxGroupComponentData,discord.CheckboxGroupBuilder> {
1685
1856
  constructor(id:ODValidId,data:Partial<ODCheckboxGroupComponentData>){
1686
1857
  const initData: ODCheckboxGroupComponentData = {required:false,options:[],...data}
1687
- super(id,initData)
1858
+ super(id,"checkbox-group",initData)
1688
1859
  }
1689
1860
 
1690
1861
  async build(){
@@ -1744,7 +1915,7 @@ export interface ODCheckboxComponentData {
1744
1915
  export class ODCheckboxComponent extends ODComponent<ODCheckboxComponentData,discord.CheckboxBuilder> {
1745
1916
  constructor(id:ODValidId,data:Partial<ODCheckboxComponentData>){
1746
1917
  const initData: ODCheckboxComponentData = {default:false,...data}
1747
- super(id,initData)
1918
+ super(id,"checkbox",initData)
1748
1919
  }
1749
1920
 
1750
1921
  async build(){
@@ -1788,7 +1959,7 @@ export interface ODFileUploadComponentData {
1788
1959
  export class ODFileUploadComponent extends ODComponent<ODFileUploadComponentData,discord.FileUploadBuilder> {
1789
1960
  constructor(id:ODValidId,data:Partial<ODFileUploadComponentData>){
1790
1961
  const initData: ODFileUploadComponentData = {required:false,...data}
1791
- super(id,initData)
1962
+ super(id,"file-upload",initData)
1792
1963
  }
1793
1964
 
1794
1965
  async build(){
@@ -185,6 +185,8 @@ export interface ODSharedFuseList {
185
185
  messageComponentsLoading:boolean,
186
186
  /**Load the default Open Discord modal components. */
187
187
  modalComponentsLoading:boolean,
188
+ /**Load the default Open Discord component modifiers. */
189
+ componentModifiersLoading:boolean,
188
190
 
189
191
  /**Load the default Open Discord command responders. */
190
192
  commandRespondersLoading:boolean,
@@ -323,6 +325,7 @@ export class ODSharedFuseManager extends ODFuseManager<ODSharedFuseList> {
323
325
  sharedComponentsLoading:true,
324
326
  messageComponentsLoading:true,
325
327
  modalComponentsLoading:true,
328
+ componentModifiersLoading:true,
326
329
 
327
330
  commandRespondersLoading:true,
328
331
  buttonRespondersLoading:true,
@@ -2,79 +2,60 @@
2
2
  //VERIFYBAR MODULE
3
3
  ///////////////////////////////////////
4
4
  import { ODId, ODManager, ODManagerData, ODNoGeneric, ODValidId } from "./base.js"
5
- import { ODMessage } from "./builder.js"
6
5
  import { ODDebugger } from "./console.js"
7
6
  import { ODButtonResponderInstance } from "./responder.js"
8
- import * as discord from "discord.js"
9
7
  import { ODWorkerManager } from "./worker.js"
8
+ import * as discord from "discord.js"
10
9
 
11
10
  /**## ODVerifyBar `class`
12
- * This is an Open Discord verifybar.
11
+ * This is an Open Discord verifybar responder.
13
12
  *
14
- * It is contains 2 sets of workers and a lot of utilities for the (✅ ❌) verifybars in the bot.
13
+ * It contain `ODWorkerManager`'s that will be fired when the continue/stop (✅ ❌) buttons are pressed.
15
14
  *
16
- * It doesn't contain the code which activates or spawns the verifybars!
15
+ * Verifybars don't automatically trigger these workers. The button responders of the verifybars should implement it manually.
17
16
  */
18
- export class ODVerifyBar<SuccessWorkerIds extends string = string,FailureWorkerIds extends string = string,> extends ODManagerData {
19
- /**All workers that will run when the verifybar is accepted. */
20
- success: ODWorkerManager<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null},SuccessWorkerIds>
21
- /**All workers that will run when the verifybar is stopped. */
22
- failure: ODWorkerManager<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null},FailureWorkerIds>
23
- /**The message that will be built wen activating this verifybar. */
24
- message: ODMessage<"verifybar",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>}>
25
- /**When disabled, it will skip the verifybar and instantly fire the `success` workers. */
26
- enabled: boolean
27
-
28
- constructor(id:ODValidId, message:ODMessage<"verifybar",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>}>, enabled?:boolean){
17
+ export class ODVerifyBar<ButtonIds extends string,WorkerIds extends string = string> extends ODManagerData {
18
+ /**All workers that will run when a button in the verifybar is pressed. */
19
+ workers: ODWorkerManager<ODButtonResponderInstance,"verifybar",{selectedButtonId:ButtonIds},WorkerIds>
20
+
21
+ constructor(id:ODValidId){
29
22
  super(id)
30
- this.success = new ODWorkerManager("descending")
31
- this.failure = new ODWorkerManager("descending")
32
- this.message = message
33
- this.enabled = enabled ?? true
23
+ this.workers = new ODWorkerManager("descending")
34
24
  }
35
25
 
36
- /**Build the message and reply to a button with this verifybar. */
37
- async activate(responder:ODButtonResponderInstance){
38
- if (this.enabled){
39
- //show verifybar
40
- const {guild,channel,user,message} = responder
41
- await responder.update(await this.message.build("verifybar",{guild,channel,user,verifybar:this,originalMessage:message}))
42
- }else{
43
- //instant success
44
- if (this.success) await this.success.executeWorkers(responder,"verifybar",{data:null,verifybarMessage:null})
45
- }
26
+ /**Activate the verifybar response to this button. */
27
+ async activate(responder:ODButtonResponderInstance,selectedButtonId:ButtonIds){
28
+ await this.workers.executeWorkers(responder,"verifybar",{selectedButtonId})
46
29
  }
47
30
  }
48
31
 
49
32
  /**## ODVerifyBarManagerIdConstraint `type`
50
33
  * The constraint/layout for id mappings/interfaces of the `ODVerifyBarManager` class.
51
34
  */
52
- export type ODVerifyBarManagerIdConstraint = Record<string,{successWorkerIds:string,failureWorkerIds:string}>
35
+ export type ODVerifyBarManagerIdConstraint = Record<string,ODVerifyBar<string>>
53
36
 
54
37
  /**## ODVerifyBarManager `class`
55
- * This is an Open Discord verifybar manager.
56
- *
57
- * It contains all (✅ ❌) verifybars in the bot.
38
+ * The Open Discord verifybar manager manages all responders for (✅ ❌) verifybars in the bot.
58
39
  * The `ODVerifyBar` classes contain `ODWorkerManager`'s that will be fired when the continue/stop buttons are pressed.
59
40
  *
60
- * It doesn't contain the code which activates the verifybars! This should be implemented by your own.
41
+ * Verifybars don't automatically trigger these workers. The button responders of the verifybars should implement it manually.
61
42
  */
62
- export class ODVerifyBarManager<IdList extends ODVerifyBarManagerIdConstraint = ODVerifyBarManagerIdConstraint> extends ODManager<ODVerifyBar> {
43
+ export class ODVerifyBarManager<IdList extends ODVerifyBarManagerIdConstraint = ODVerifyBarManagerIdConstraint> extends ODManager<ODVerifyBar<string>> {
63
44
  constructor(debug:ODDebugger){
64
45
  super(debug,"verifybar")
65
46
  }
66
47
 
67
- get<VerifyBarId extends keyof ODNoGeneric<IdList>>(id:VerifyBarId): ODVerifyBar<IdList[VerifyBarId]["successWorkerIds"],IdList[VerifyBarId]["failureWorkerIds"]>
68
- get(id:ODValidId): ODVerifyBar|null
48
+ get<VerifyBarId extends keyof ODNoGeneric<IdList>>(id:VerifyBarId): IdList[VerifyBarId]
49
+ get(id:ODValidId): ODVerifyBar<string>|null
69
50
 
70
- get(id:ODValidId): ODVerifyBar|null {
51
+ get(id:ODValidId): ODVerifyBar<string>|null {
71
52
  return super.get(id)
72
53
  }
73
54
 
74
- remove<VerifyBarId extends keyof ODNoGeneric<IdList>>(id:VerifyBarId): ODVerifyBar<IdList[VerifyBarId]["successWorkerIds"],IdList[VerifyBarId]["failureWorkerIds"]>
75
- remove(id:ODValidId): ODVerifyBar|null
55
+ remove<VerifyBarId extends keyof ODNoGeneric<IdList>>(id:VerifyBarId): IdList[VerifyBarId]
56
+ remove(id:ODValidId): ODVerifyBar<string>|null
76
57
 
77
- remove(id:ODValidId): ODVerifyBar|null {
58
+ remove(id:ODValidId): ODVerifyBar<string>|null {
78
59
  return super.remove(id)
79
60
  }
80
61
 
@@ -29,6 +29,11 @@ export class ODWorker<Instance, Origin extends string, Params> extends ODManager
29
29
  this.priority = priority
30
30
  this.callback = callback
31
31
  }
32
+
33
+ /**Duplicate this worker. Warning: If the callback accesses external variables (outside parameters), the clone will still use those variables. This might result in unexpected behaviour! */
34
+ duplicate(newId?:ODValidId): ODWorker<Instance,Origin,Params> {
35
+ return new ODWorker<Instance,Origin,Params>(newId ?? this.id.value,this.priority,this.callback)
36
+ }
32
37
  }
33
38
 
34
39
  /**## ODWorker `class`