refactor autocompletes
This commit is contained in:
parent
3d5a7b041d
commit
e5b049d0b2
|
@ -2,6 +2,7 @@ import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js
|
||||||
import { weaponAutocomplete, getItem, getItemQuantity, formatItems, formatItem } from '../lib/rpg/items';
|
import { weaponAutocomplete, getItem, getItemQuantity, formatItems, formatItem } from '../lib/rpg/items';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
import { initHealth, dealDamage, BLOOD_ITEM, BLOOD_ID, resetInvincible, INVINCIBLE_TIMER, getInvincibleMs } from '../lib/rpg/pvp';
|
import { initHealth, dealDamage, BLOOD_ITEM, BLOOD_ID, resetInvincible, INVINCIBLE_TIMER, getInvincibleMs } from '../lib/rpg/pvp';
|
||||||
|
import { autocomplete } from '../lib/autocomplete';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -48,5 +49,5 @@ export default {
|
||||||
await interaction.followUp(`You hit ${user} with ${formatItem(weapon)} for ${BLOOD_ITEM.emoji} **${dmg}** damage! They are now at ${formatItems(BLOOD_ITEM, newHealth.quantity)}.\nYou can attack them again <t:${Math.floor((Date.now() + INVINCIBLE_TIMER) / 1000)}:R> (or if they perform an action first).`);
|
await interaction.followUp(`You hit ${user} with ${formatItem(weapon)} for ${BLOOD_ITEM.emoji} **${dmg}** damage! They are now at ${formatItems(BLOOD_ITEM, newHealth.quantity)}.\nYou can attack them again <t:${Math.floor((Date.now() + INVINCIBLE_TIMER) / 1000)}:R> (or if they perform an action first).`);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: weaponAutocomplete,
|
autocomplete: autocomplete(weaponAutocomplete),
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -4,6 +4,7 @@ import { counterAutocomplete, counterConfigs, findCounter, getCounterConfigRaw,
|
||||||
import { outdent } from 'outdent';
|
import { outdent } from 'outdent';
|
||||||
import { formatItem, formatItems, getItem, itemAutocomplete } from '../lib/rpg/items';
|
import { formatItem, formatItems, getItem, itemAutocomplete } from '../lib/rpg/items';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
|
import { autocomplete, set } from '../lib/autocomplete';
|
||||||
|
|
||||||
function extendOption(t: string) {
|
function extendOption(t: string) {
|
||||||
return {name: t, value: t};
|
return {name: t, value: t};
|
||||||
|
@ -442,24 +443,22 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: async (interaction: AutocompleteInteraction) => {{
|
autocomplete: autocomplete(set({
|
||||||
const focused = interaction.options.getFocused(true);
|
type: counterAutocomplete,
|
||||||
|
item: itemAutocomplete,
|
||||||
|
value: async (interaction: AutocompleteInteraction) => {
|
||||||
|
const focused = interaction.options.getFocused();
|
||||||
|
|
||||||
if (focused.name === 'type') {
|
|
||||||
return counterAutocomplete(interaction);
|
|
||||||
} else if (focused.name === 'item') {
|
|
||||||
return itemAutocomplete(interaction);
|
|
||||||
} else if (focused.name === 'value') {
|
|
||||||
const type = interaction.options.getString('type', true);
|
const type = interaction.options.getString('type', true);
|
||||||
const counter = await findCounter(type, interaction.guildId!);
|
const counter = await findCounter(type, interaction.guildId!);
|
||||||
|
|
||||||
const config = await getCounterConfigRaw(counter);
|
const config = await getCounterConfigRaw(counter);
|
||||||
const key = interaction.options.getString('key');
|
const key = interaction.options.getString('key');
|
||||||
|
|
||||||
if (!key) return interaction.respond([]);
|
if (!key) return [];
|
||||||
|
|
||||||
const defaultConfig = counterConfigs.get(key);
|
const defaultConfig = counterConfigs.get(key);
|
||||||
if (!defaultConfig) return interaction.respond([]);
|
if (!defaultConfig) return [];
|
||||||
|
|
||||||
const defaultOptions = getOptions(defaultConfig.type);
|
const defaultOptions = getOptions(defaultConfig.type);
|
||||||
|
|
||||||
|
@ -472,20 +471,20 @@ export default {
|
||||||
value: `${toStringConfig(defaultConfig.default, defaultConfig.type)}`,
|
value: `${toStringConfig(defaultConfig.default, defaultConfig.type)}`,
|
||||||
name: `Default: ${toStringConfig(defaultConfig.default, defaultConfig.type)}`
|
name: `Default: ${toStringConfig(defaultConfig.default, defaultConfig.type)}`
|
||||||
},
|
},
|
||||||
...defaultOptions.filter(s => s.startsWith(focused.value)).map(extendOption)
|
...defaultOptions.filter(s => s.startsWith(focused)).map(extendOption)
|
||||||
];
|
];
|
||||||
|
|
||||||
if (focused.value !== '' && !options.find(opt => opt.value === focused.value)) {
|
if (focused !== '' && !options.find(opt => opt.value === focused)) {
|
||||||
options = [
|
options = [
|
||||||
{
|
{
|
||||||
value: focused.value,
|
value: focused,
|
||||||
name: focused.value
|
name: focused
|
||||||
},
|
},
|
||||||
...options
|
...options
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.respond(options);
|
return options;
|
||||||
}
|
}
|
||||||
}}
|
})),
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -5,6 +5,7 @@ import { formatItem, getItemQuantity, formatItems, getMaxStack, giveItem, format
|
||||||
import { getRecipe, defaultRecipes, formatRecipe, resolveCustomRecipe } from '../lib/rpg/recipes';
|
import { getRecipe, defaultRecipes, formatRecipe, resolveCustomRecipe } from '../lib/rpg/recipes';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
import { initHealth, resetInvincible } from '../lib/rpg/pvp';
|
import { initHealth, resetInvincible } from '../lib/rpg/pvp';
|
||||||
|
import { autocomplete, set } from '../lib/autocomplete';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -102,11 +103,9 @@ export default {
|
||||||
return interaction.followUp(`${station.emoji} ${verb(station)} ${formatItemsArray(outputs)}!${outputs.length === 1 ? `\n_${outputs[0].item.description}_` : ''}${nextUsableAt ? `\n${station.name} usable again <t:${Math.floor(nextUsableAt / 1000)}:R>` : ''}`);
|
return interaction.followUp(`${station.emoji} ${verb(station)} ${formatItemsArray(outputs)}!${outputs.length === 1 ? `\n_${outputs[0].item.description}_` : ''}${nextUsableAt ? `\n${station.name} usable again <t:${Math.floor(nextUsableAt / 1000)}:R>` : ''}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: async (interaction: AutocompleteInteraction) => {
|
autocomplete: autocomplete(set({
|
||||||
const focused = interaction.options.getFocused(true);
|
station: async (interaction: AutocompleteInteraction) =>
|
||||||
|
(await Promise.all(
|
||||||
if (focused.name === 'station') {
|
|
||||||
const found = (await Promise.all(
|
|
||||||
craftingStations
|
craftingStations
|
||||||
.map(async station => [station, await canUseStation(interaction.user.id, station)])
|
.map(async station => [station, await canUseStation(interaction.user.id, station)])
|
||||||
))
|
))
|
||||||
|
@ -114,19 +113,18 @@ export default {
|
||||||
.filter(([_station, usable]) => usable)
|
.filter(([_station, usable]) => usable)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
.map(([station, _]) => station as CraftingStation)
|
.map(([station, _]) => station as CraftingStation)
|
||||||
.filter(station => station.name.toLowerCase().includes(focused.value.toLowerCase()))
|
.filter(station => station.name.toLowerCase().includes(interaction.options.getFocused().toLowerCase()))
|
||||||
.map(station => ({
|
.map(station => ({
|
||||||
name: `${station.emoji} ${station.name}`,
|
name: `${station.emoji} ${station.name}`,
|
||||||
value: station.key
|
value: station.key
|
||||||
}));
|
})),
|
||||||
|
recipe: async (interaction: AutocompleteInteraction) => {
|
||||||
return interaction.respond(found);
|
const focused = interaction.options.getFocused();
|
||||||
} else if (focused.name === 'recipe') {
|
|
||||||
const station = interaction.options.getString('station');
|
const station = interaction.options.getString('station');
|
||||||
|
|
||||||
const foundDefaultRecipes = defaultRecipes
|
const foundDefaultRecipes = defaultRecipes
|
||||||
.filter(recipe => recipe.station === station)
|
.filter(recipe => recipe.station === station)
|
||||||
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.value.toLowerCase())).length > 0);
|
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.toLowerCase())).length > 0);
|
||||||
|
|
||||||
const customRecipes = await db<CustomCraftingRecipe>('customCraftingRecipes')
|
const customRecipes = await db<CustomCraftingRecipe>('customCraftingRecipes')
|
||||||
.where('station', station);
|
.where('station', station);
|
||||||
|
@ -134,17 +132,15 @@ export default {
|
||||||
const resolvedCustomRecipes = await Promise.all(customRecipes.map(resolveCustomRecipe));
|
const resolvedCustomRecipes = await Promise.all(customRecipes.map(resolveCustomRecipe));
|
||||||
|
|
||||||
const foundCustomRecipes = resolvedCustomRecipes
|
const foundCustomRecipes = resolvedCustomRecipes
|
||||||
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.value.toLowerCase())).length > 0);
|
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.toLowerCase())).length > 0);
|
||||||
|
|
||||||
const recipes = [...foundDefaultRecipes, ...foundCustomRecipes];
|
const recipes = [...foundDefaultRecipes, ...foundCustomRecipes];
|
||||||
|
|
||||||
return interaction.respond(
|
return recipes
|
||||||
recipes
|
.map(recipe => ({
|
||||||
.map(recipe => ({
|
name: formatRecipe(recipe, true),
|
||||||
name: formatRecipe(recipe, true),
|
value: recipe.id.toString()
|
||||||
value: recipe.id.toString()
|
}));
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
})),
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -1,6 +1,7 @@
|
||||||
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
||||||
import { changeCounterInteraction, counterAutocomplete } from '../lib/rpg/counter';
|
import { changeCounterInteraction, counterAutocomplete } from '../lib/rpg/counter';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
|
import { autocomplete } from '../lib/autocomplete'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -35,5 +36,5 @@ export default {
|
||||||
changeCounterInteraction(interaction, member, -amount, type);
|
changeCounterInteraction(interaction, member, -amount, type);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: counterAutocomplete
|
autocomplete: autocomplete(counterAutocomplete),
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -1,6 +1,7 @@
|
||||||
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js';
|
||||||
import { changeCounterInteraction, counterAutocomplete } from '../lib/rpg/counter';
|
import { changeCounterInteraction, counterAutocomplete } from '../lib/rpg/counter';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
|
import { autocomplete } from '../lib/autocomplete';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -35,5 +36,5 @@ export default {
|
||||||
changeCounterInteraction(interaction, member, amount, type);
|
changeCounterInteraction(interaction, member, amount, type);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: counterAutocomplete
|
autocomplete: autocomplete(counterAutocomplete)
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -4,6 +4,7 @@ import { customItemAutocomplete, formatItem, formatItems, getCustomItem, getItem
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
import { formatRecipe, getCustomRecipe } from '../lib/rpg/recipes';
|
import { formatRecipe, getCustomRecipe } from '../lib/rpg/recipes';
|
||||||
import { behaviors, formatBehavior, getBehavior } from '../lib/rpg/behaviors';
|
import { behaviors, formatBehavior, getBehavior } from '../lib/rpg/behaviors';
|
||||||
|
import { autocomplete, set } from '../lib/autocomplete';
|
||||||
|
|
||||||
//function extendOption(t: string) {
|
//function extendOption(t: string) {
|
||||||
// return {name: t, value: t};
|
// return {name: t, value: t};
|
||||||
|
@ -321,15 +322,12 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: async (interaction: AutocompleteInteraction) => {
|
autocomplete: autocomplete(set({
|
||||||
const focused = interaction.options.getFocused(true);
|
item: itemAutocomplete,
|
||||||
|
customitem: customItemAutocomplete,
|
||||||
if (focused.name === 'item') {
|
behavior: async (interaction: AutocompleteInteraction) => {
|
||||||
return itemAutocomplete(interaction);
|
const focused = interaction.options.getFocused();
|
||||||
} else if (focused.name === 'customitem') {
|
let foundBehaviors = behaviors.filter(b => b.name.toLowerCase().includes(focused.toLowerCase()));
|
||||||
return customItemAutocomplete(interaction);
|
|
||||||
} else if (focused.name === 'behavior') {
|
|
||||||
let foundBehaviors = behaviors.filter(b => b.name.toLowerCase().includes(focused.value.toLowerCase()));
|
|
||||||
const itemID = interaction.options.getString('customitem');
|
const itemID = interaction.options.getString('customitem');
|
||||||
if (itemID) {
|
if (itemID) {
|
||||||
const item = await getItem(parseInt(itemID));
|
const item = await getItem(parseInt(itemID));
|
||||||
|
@ -338,22 +336,24 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.respond(foundBehaviors.map(b => ({name: `${b.itemType}:${b.name} - ${b.description}`, value: b.name})));
|
return foundBehaviors.map(b => ({name: `${b.itemType}:${b.name} - ${b.description}`, value: b.name}));
|
||||||
} else if (focused.name === 'removebehavior') {
|
},
|
||||||
|
removebehavior: async (interaction: AutocompleteInteraction) => {
|
||||||
|
const focused = interaction.options.getFocused();
|
||||||
const itemID = interaction.options.getString('customitem');
|
const itemID = interaction.options.getString('customitem');
|
||||||
if (!itemID) return await interaction.respond([]);
|
if (!itemID) return [];
|
||||||
const behaviors = await db<ItemBehavior>('itemBehaviors')
|
const behaviors = await db<ItemBehavior>('itemBehaviors')
|
||||||
.where('item', itemID);
|
.where('item', itemID);
|
||||||
|
|
||||||
const foundBehaviors = behaviors
|
const foundBehaviors = behaviors
|
||||||
.map(b => ({ behavior: getBehavior(b.behavior)!, value: b.value }))
|
.map(b => ({ behavior: getBehavior(b.behavior)!, value: b.value }))
|
||||||
.filter(b => b.behavior)
|
.filter(b => b.behavior)
|
||||||
.filter(b => b.behavior.name.toLowerCase().includes(focused.value.toLowerCase()));
|
.filter(b => b.behavior.name.toLowerCase().includes(focused.toLowerCase()));
|
||||||
|
|
||||||
await interaction.respond(foundBehaviors.map(b => ({
|
return foundBehaviors.map(b => ({
|
||||||
name: `${b.behavior.itemType}:${formatBehavior(b.behavior, b.value)} - ${b.behavior.description}`,
|
name: `${b.behavior.itemType}:${formatBehavior(b.behavior, b.value)} - ${b.behavior.description}`,
|
||||||
value: b.behavior.name
|
value: b.behavior.name
|
||||||
})));
|
}));
|
||||||
}
|
},
|
||||||
}
|
})),
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -2,6 +2,7 @@ import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js
|
||||||
import { changeLinkedCounterInteraction, linkedCounterAutocomplete } from '../lib/rpg/counter';
|
import { changeLinkedCounterInteraction, linkedCounterAutocomplete } from '../lib/rpg/counter';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
import { initHealth } from '../lib/rpg/pvp';
|
import { initHealth } from '../lib/rpg/pvp';
|
||||||
|
import { autocomplete } from '../lib/autocomplete';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -38,5 +39,5 @@ export default {
|
||||||
changeLinkedCounterInteraction(interaction, member, amount, type);
|
changeLinkedCounterInteraction(interaction, member, amount, type);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: linkedCounterAutocomplete
|
autocomplete: autocomplete(linkedCounterAutocomplete),
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -1,9 +1,10 @@
|
||||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, ComponentType, Events, ModalBuilder, SlashCommandBuilder, StringSelectMenuBuilder, TextInputBuilder, TextInputStyle } from 'discord.js';
|
import { ActionRowBuilder, AutocompleteInteraction, ButtonBuilder, ButtonStyle, CommandInteraction, ComponentType, Events, ModalBuilder, SlashCommandBuilder, StringSelectMenuBuilder, TextInputBuilder, TextInputStyle } from 'discord.js';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
import { Items, getItem } from '../lib/rpg/items';
|
import { Items, getItem } from '../lib/rpg/items';
|
||||||
import { formatRecipe, getCustomRecipe, resolveCustomRecipe } from '../lib/rpg/recipes';
|
import { formatRecipe, getCustomRecipe, resolveCustomRecipe } from '../lib/rpg/recipes';
|
||||||
import { craftingStations, getStation } from '../lib/rpg/craftingStations';
|
import { craftingStations, getStation } from '../lib/rpg/craftingStations';
|
||||||
import { CustomCraftingRecipe, CustomCraftingRecipeItem, db } from '../lib/db';
|
import { CustomCraftingRecipe, CustomCraftingRecipeItem, db } from '../lib/db';
|
||||||
|
import { autocomplete } from '../lib/autocomplete';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -235,24 +236,20 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: async (interaction) => {
|
autocomplete: autocomplete(async (interaction: AutocompleteInteraction) => {
|
||||||
const focused = interaction.options.getFocused(true);
|
const focused = interaction.options.getFocused();
|
||||||
|
|
||||||
if (focused.name === 'recipe') {
|
const customRecipes = await db<CustomCraftingRecipe>('customCraftingRecipes');
|
||||||
const customRecipes = await db<CustomCraftingRecipe>('customCraftingRecipes');
|
|
||||||
|
|
||||||
const resolvedCustomRecipes = await Promise.all(customRecipes.map(resolveCustomRecipe));
|
const resolvedCustomRecipes = await Promise.all(customRecipes.map(resolveCustomRecipe));
|
||||||
|
|
||||||
const foundCustomRecipes = resolvedCustomRecipes
|
const foundCustomRecipes = resolvedCustomRecipes
|
||||||
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.value.toLowerCase())).length > 0);
|
.filter(recipe => recipe.outputs.filter(n => n.item.name.toLowerCase().includes(focused.toLowerCase())).length > 0);
|
||||||
|
|
||||||
return interaction.respond(
|
return foundCustomRecipes
|
||||||
foundCustomRecipes
|
.map(recipe => ({
|
||||||
.map(recipe => ({
|
name: formatRecipe(recipe, true),
|
||||||
name: formatRecipe(recipe, true),
|
value: recipe.id.toString()
|
||||||
value: recipe.id.toString()
|
}));
|
||||||
}))
|
}),
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -2,6 +2,7 @@ import { GuildMember, CommandInteraction, SlashCommandBuilder } from 'discord.js
|
||||||
import { changeLinkedCounterInteraction, linkedCounterAutocomplete } from '../lib/rpg/counter';
|
import { changeLinkedCounterInteraction, linkedCounterAutocomplete } from '../lib/rpg/counter';
|
||||||
import { initHealth } from '../lib/rpg/pvp';
|
import { initHealth } from '../lib/rpg/pvp';
|
||||||
import { Command } from '../types/index';
|
import { Command } from '../types/index';
|
||||||
|
import { autocomplete } from '../lib/autocomplete';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
|
@ -38,5 +39,5 @@ export default {
|
||||||
changeLinkedCounterInteraction(interaction, member, -amount, type);
|
changeLinkedCounterInteraction(interaction, member, -amount, type);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: linkedCounterAutocomplete
|
autocomplete: autocomplete(linkedCounterAutocomplete)
|
||||||
} satisfies Command;
|
} satisfies Command;
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { AutocompleteInteraction, ApplicationCommandOptionChoiceData } from 'discord.js';
|
||||||
|
import * as log from './log';
|
||||||
|
|
||||||
|
export type Autocomplete = (interaction: AutocompleteInteraction) => Promise<ApplicationCommandOptionChoiceData<string | number>[]>
|
||||||
|
|
||||||
|
export function set(fns: Record<string, Autocomplete>): Autocomplete {
|
||||||
|
return async (interaction: AutocompleteInteraction) => {
|
||||||
|
const focused = interaction.options.getFocused(true);
|
||||||
|
const fn = fns[focused.name];
|
||||||
|
|
||||||
|
if (!fn) return [];
|
||||||
|
|
||||||
|
return fn(interaction);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export function autocomplete(fn: Autocomplete): (interaction: AutocompleteInteraction) => Promise<void> {
|
||||||
|
return async (interaction: AutocompleteInteraction) => {
|
||||||
|
try {
|
||||||
|
const arr = await fn(interaction);
|
||||||
|
if (arr.length > 25) log.warn(`Autocomplete for ${interaction.options.getFocused(true).name} exceeded limit of 25 autocomplete results`);
|
||||||
|
return interaction.respond(arr.slice(0, 25));
|
||||||
|
} catch (err) {
|
||||||
|
log.error(err);
|
||||||
|
return interaction.respond([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import { getSign } from '../util';
|
||||||
import { Counter, CounterConfiguration, CounterUserLink, db } from '../db';
|
import { Counter, CounterConfiguration, CounterUserLink, db } from '../db';
|
||||||
import { formatItems, getItem, getItemQuantity, getMaxStack, giveItem } from './items';
|
import { formatItems, getItem, getItemQuantity, getMaxStack, giveItem } from './items';
|
||||||
import { resetInvincible } from './pvp';
|
import { resetInvincible } from './pvp';
|
||||||
|
import { Autocomplete } from '../autocomplete';
|
||||||
|
|
||||||
export async function getCounter(id: number) {
|
export async function getCounter(id: number) {
|
||||||
const counter = await db<Counter>('counters')
|
const counter = await db<Counter>('counters')
|
||||||
|
@ -378,7 +379,7 @@ function changeCounterInteractionBuilder(linked: boolean) {
|
||||||
export const changeCounterInteraction = changeCounterInteractionBuilder(false);
|
export const changeCounterInteraction = changeCounterInteractionBuilder(false);
|
||||||
export const changeLinkedCounterInteraction = changeCounterInteractionBuilder(true);
|
export const changeLinkedCounterInteraction = changeCounterInteractionBuilder(true);
|
||||||
|
|
||||||
function counterAutocompleteBuilder(linked: boolean) {
|
function counterAutocompleteBuilder(linked: boolean): Autocomplete {
|
||||||
return async (interaction: AutocompleteInteraction) => {
|
return async (interaction: AutocompleteInteraction) => {
|
||||||
const focusedValue = interaction.options.getFocused();
|
const focusedValue = interaction.options.getFocused();
|
||||||
const guild = interaction.guildId;
|
const guild = interaction.guildId;
|
||||||
|
@ -397,9 +398,7 @@ function counterAutocompleteBuilder(linked: boolean) {
|
||||||
|
|
||||||
const foundCounters = await query;
|
const foundCounters = await query;
|
||||||
|
|
||||||
await interaction.respond(
|
return foundCounters.map(choice => ({ name: `${choice.emoji} ${choice.key}`, value: choice.key }));
|
||||||
foundCounters.map(choice => ({ name: `${choice.emoji} ${choice.key}`, value: choice.key }))
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { AutocompleteInteraction } from 'discord.js';
|
import { AutocompleteInteraction } from 'discord.js';
|
||||||
import { CustomItem, ItemBehavior, ItemInventory, db } from '../db';
|
import { CustomItem, ItemBehavior, ItemInventory, db } from '../db';
|
||||||
|
import { Autocomplete } from '../autocomplete';
|
||||||
|
|
||||||
// uses negative IDs
|
// uses negative IDs
|
||||||
export type DefaultItem = Omit<CustomItem, 'guild'> & { behaviors?: Omit<ItemBehavior, 'item'>[] };
|
export type DefaultItem = Omit<CustomItem, 'guild'> & { behaviors?: Omit<ItemBehavior, 'item'>[] };
|
||||||
|
@ -378,7 +379,7 @@ export function formatItemsArray(items: Items[], disableBold = false) {
|
||||||
return items.map(i => formatItems(i.item, i.quantity, disableBold)).join(' ');
|
return items.map(i => formatItems(i.item, i.quantity, disableBold)).join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
function createItemAutocomplete(onlyCustom: boolean, filterType: 'plain' | 'weapon' | 'consumable' | null) {
|
function createItemAutocomplete(onlyCustom: boolean, filterType: 'plain' | 'weapon' | 'consumable' | null): Autocomplete {
|
||||||
return async (interaction: AutocompleteInteraction) => {
|
return async (interaction: AutocompleteInteraction) => {
|
||||||
const focused = interaction.options.getFocused();
|
const focused = interaction.options.getFocused();
|
||||||
|
|
||||||
|
@ -403,9 +404,7 @@ function createItemAutocomplete(onlyCustom: boolean, filterType: 'plain' | 'weap
|
||||||
items = [...foundDefaultItems, ...customItems];
|
items = [...foundDefaultItems, ...customItems];
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.respond(
|
return items.map(choice => ({ name: `${choice.emoji} ${choice.name}`, value: choice.id.toString() }));
|
||||||
items.map(choice => ({ name: `${choice.emoji} ${choice.name}`, value: choice.id.toString() }))
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue