175 lines
No EOL
5.3 KiB
TypeScript
175 lines
No EOL
5.3 KiB
TypeScript
import {ConfigurationHandler, PathConfigurationFrom} from "./ConfigurationHandler";
|
|
import {
|
|
AnyMenuItem,
|
|
CollectionMenuItem,
|
|
FieldMenuItem,
|
|
FieldMenuItemContext,
|
|
FieldMenuItemSaveValue,
|
|
MenuItem,
|
|
MenuItemType,
|
|
PromptMenuItem
|
|
} from "../Menu/MenuRenderer.types";
|
|
import {TraversalPath} from "../Menu/MenuTraversal.types";
|
|
import {
|
|
channelMention,
|
|
ChannelSelectMenuBuilder,
|
|
ChannelType,
|
|
italic,
|
|
StringSelectMenuBuilder,
|
|
TextInputBuilder,
|
|
TextInputStyle
|
|
} from "discord.js";
|
|
import {MessageActionRowComponentBuilder} from "@discordjs/builders";
|
|
import {TransformerType} from "./ConfigurationTransformer";
|
|
|
|
type FieldHandlerMenuItem = MenuItem & (Partial<PromptMenuItem> | Partial<FieldMenuItem>);
|
|
type HandlerMenuItem =
|
|
FieldHandlerMenuItem | CollectionMenuItem<HandlerMenuItem>
|
|
|
|
export class MenuHandler {
|
|
constructor(
|
|
private readonly config: ConfigurationHandler,
|
|
) {
|
|
}
|
|
|
|
public fillMenuItems(
|
|
menuItems: HandlerMenuItem[]
|
|
): AnyMenuItem[] {
|
|
const handler = this;
|
|
|
|
function resolve(path: TraversalPath, menuItem: HandlerMenuItem): AnyMenuItem {
|
|
path = [...path, menuItem.traversalKey];
|
|
|
|
if (menuItem.type === MenuItemType.Collection) {
|
|
menuItem.children = menuItem.children.map((nextMenuItem) => resolve(path, nextMenuItem))
|
|
return <CollectionMenuItem>menuItem;
|
|
}
|
|
|
|
const transformerType = handler.config.transformer.getTransformerType(path.join('.'));
|
|
if (transformerType === undefined || transformerType === null) {
|
|
throw new Error(`Can't resolve type for '${path.join('.')}'`);
|
|
}
|
|
|
|
menuItem.type = handler.findType(transformerType);
|
|
|
|
menuItem.setValue = handler.setValue.bind(handler);
|
|
menuItem.getCurrentValue = handler.findCurrentValueMethod(transformerType);
|
|
menuItem.getActionRowBuilder = handler.findActionRowBuilderMethod(transformerType);
|
|
|
|
return <AnyMenuItem>menuItem;
|
|
}
|
|
|
|
return menuItems.map((menuItem) => resolve([], menuItem))
|
|
}
|
|
|
|
private findType(transformer: TransformerType): MenuItemType.Field | MenuItemType.Prompt
|
|
{
|
|
switch (transformer) {
|
|
case TransformerType.String:
|
|
case TransformerType.Paragraph:
|
|
return MenuItemType.Prompt;
|
|
default:
|
|
return MenuItemType.Field;
|
|
}
|
|
}
|
|
|
|
private findCurrentValueMethod(transformer: TransformerType): (context: FieldMenuItemContext) => string
|
|
{
|
|
switch (transformer) {
|
|
case TransformerType.Channel:
|
|
return this.getChannelValue.bind(this);
|
|
case TransformerType.PermissionBoolean:
|
|
return this.getPermissionBooleanValue.bind(this);
|
|
case TransformerType.String:
|
|
case TransformerType.Paragraph:
|
|
return this.getStringValue.bind(this);
|
|
}
|
|
}
|
|
|
|
private findActionRowBuilderMethod(transformer: TransformerType):
|
|
((context: FieldMenuItemContext) => MessageActionRowComponentBuilder) | ((context: FieldMenuItemContext) => TextInputBuilder)
|
|
{
|
|
switch (transformer) {
|
|
case TransformerType.Channel:
|
|
return this.getChannelMenuBuilder.bind(this);
|
|
case TransformerType.PermissionBoolean:
|
|
return this.getPermissionBooleanBuilder.bind(this);
|
|
case TransformerType.String:
|
|
return this.getStringBuilder.bind(this);
|
|
case TransformerType.Paragraph:
|
|
return this.getTextareaBuilder.bind(this);
|
|
}
|
|
}
|
|
|
|
private getChannelValue(context: FieldMenuItemContext): string {
|
|
const value = this.config.getConfigurationByPath(context.path.join('.'));
|
|
|
|
const isDefault = value.from === PathConfigurationFrom.Default;
|
|
const display = !value ? "None" : channelMention(<string>value.value);
|
|
|
|
if (isDefault) {
|
|
return italic(`Default (${display})`)
|
|
}
|
|
return display;
|
|
}
|
|
|
|
private getChannelMenuBuilder(): MessageActionRowComponentBuilder {
|
|
return new ChannelSelectMenuBuilder()
|
|
.setChannelTypes(ChannelType.GuildText)
|
|
.setPlaceholder("New Value");
|
|
}
|
|
|
|
private getPermissionBooleanValue(context: FieldMenuItemContext) {
|
|
const value = this.config.getConfigurationByPath(context.path.join('.'));
|
|
|
|
const isDefault = value.from === PathConfigurationFrom.Default;
|
|
const display = value.value === null ? "None" : value.value == true ? "Allowed" : "Disallowed";
|
|
|
|
if (isDefault) {
|
|
return italic(`Default (${display})`)
|
|
}
|
|
return display;
|
|
}
|
|
|
|
private getPermissionBooleanBuilder() {
|
|
return new StringSelectMenuBuilder()
|
|
.setOptions(
|
|
[
|
|
{
|
|
label: "Allow",
|
|
value: "1"
|
|
},
|
|
{
|
|
label: "Disallow",
|
|
value: "0"
|
|
}
|
|
]
|
|
)
|
|
}
|
|
|
|
private getStringValue(context: FieldMenuItemContext): string {
|
|
const value = this.config.getConfigurationByPath(context.path.join('.'));
|
|
|
|
return value.value === null ? "" : <string>value.value;
|
|
}
|
|
|
|
private getStringBuilder(): TextInputBuilder {
|
|
return new TextInputBuilder()
|
|
.setStyle(TextInputStyle.Short)
|
|
.setMaxLength(100)
|
|
}
|
|
private getTextareaBuilder(): TextInputBuilder {
|
|
return new TextInputBuilder()
|
|
.setStyle(TextInputStyle.Paragraph)
|
|
.setMaxLength(2048)
|
|
}
|
|
|
|
|
|
private setValue(value: FieldMenuItemSaveValue[]|string, context: FieldMenuItemContext): void {
|
|
const savedValue = typeof value !== 'string' ?
|
|
value.join('; ') :
|
|
value;
|
|
|
|
this.config.save(context.path.join('.'), savedValue);
|
|
}
|
|
} |