Skip to content

Commit

Permalink
feat: add switching locale & fix locale
Browse files Browse the repository at this point in the history
  • Loading branch information
Mara-Li committed Aug 24, 2024
1 parent e6058dc commit 4a81dd9
Show file tree
Hide file tree
Showing 27 changed files with 1,398 additions and 1,229 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"restart": "pm2 restart dicelette",
"delete": "pm2 delete dicelette",
"dev": "tsx watch src/index.ts",
"lint:fix": "pnpm biome check --write src/",
"lint": "pnpm biome format --write src/",
"db": "tsx db-management.ts",
"release": "commit-and-tag-version",
"test": "vitest run",
Expand Down
62 changes: 60 additions & 2 deletions src/commands/admin/configuration.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
import type { Translation } from "@interface";
import { type Translation } from "@interface";
import { cmdLn, ln } from "@localization";
import type { EClient } from "@main";
import { reply } from "@utils";
import * as Djs from "discord.js";
import i18next from "i18next";
import { dedent } from "ts-dedent";
import { LocalePrimary, localeList } from "@localization/init";

const t = i18next.getFixedT("en");
const findLocale = function (locale?: Djs.Locale) {
if (locale === Djs.Locale.EnglishUS || locale === Djs.Locale.EnglishGB) return "English";
if (!locale) return undefined;
const localeName = Object.entries(Djs.Locale).find(([name, abbr]) => {
return name === locale || abbr === locale;
});
const name= localeName?.[0];
if (name) return LocalePrimary[name as keyof typeof LocalePrimary];
return undefined;
}
export const configuration = {
data: new Djs.SlashCommandBuilder()
.setName(t("config.name"))
.setNameLocalizations(cmdLn("config.name"))
.setDefaultMemberPermissions(Djs.PermissionFlagsBits.ManageRoles)
.setDescription(t("config.description"))
.setDescriptionLocalizations(cmdLn("config.description"))
/* CHANGE LANG*/
.addSubcommand((subcommand) =>
subcommand
.setName(t("config.lang.name"))
.setNameLocalizations(cmdLn("config.lang.name"))
.setDescription(t("config.lang.description"))
.setDescriptionLocalizations(cmdLn("config.lang.description"))
.addStringOption((option) =>
option
.setName(t("config.lang.options.name"))
.setNameLocalizations(cmdLn("config.lang.options.name"))
.setDescription(t("config.lang.options.desc"))
.setDescriptionLocalizations(cmdLn("config.lang.options.desc"))
.setRequired(true)
.addChoices(...localeList)
)
)

/* LOGS */
.addSubcommand((subcommand) =>
subcommand
Expand Down Expand Up @@ -221,7 +250,10 @@ export const configuration = {
),
async execute(interaction: Djs.CommandInteraction, client: EClient) {
if (!interaction.guild) return;
const ul = ln(interaction.locale);
const lang =
client.settings.get(interaction.guild.id, "lang") ??
interaction.guild.preferredLocale;
const ul = ln(lang);
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const subcommand = options.getSubcommand(true);
const subcommandGroup = options.getSubcommandGroup();
Expand Down Expand Up @@ -249,10 +281,27 @@ export const configuration = {
return await linkToLog(interaction, client, ul);
case t("hidden.title"):
return await hiddenRoll(interaction, client, ul, options);
case t("config.lang.name"):
return changeLanguage(options, client, interaction);
}
},
};

function changeLanguage(
options: Djs.CommandInteractionOptionResolver,
client: EClient,
interaction: Djs.CommandInteraction
) {
const lang = options.getString(t("config.lang.options.name"), true) as Djs.Locale;
client.settings.set(interaction.guild!.id, lang, "lang");
const ul = ln(lang);
const nameOfLang = findLocale(lang);
return reply(interaction, {
content: ul("config.lang.set", { lang: nameOfLang }),
ephemeral: true,
});
}

function stats(
options: Djs.CommandInteractionOptionResolver,
client: EClient,
Expand Down Expand Up @@ -459,11 +508,20 @@ async function display(
return `<#${settings}>`;
};




const userLocale = findLocale(guildSettings.lang) ?? findLocale(interaction.guild!.preferredLocale) ?? "English";
const baseEmbed = new Djs.EmbedBuilder()
.setTitle(ul("config.title", { guild: interaction.guild!.name }))
.setThumbnail(interaction.guild!.iconURL() ?? "")
.setColor("Random")
.addFields(
{
name: ul("config.lang.options.name").capitalize(),
value: userLocale.capitalize(),
inline: true
},
{
name: ul("config.logs"),
value: dedent(`
Expand Down
6 changes: 4 additions & 2 deletions src/commands/admin/delete_char.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export const deleteChar = {
const guildData = client.settings.get(interaction.guildId as string);
if (!guildData) return;
const choices: string[] = [];
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData.lang ?? interaction.locale;
const ul = ln(lang);
let user = options.get(t("display.userLowercase"))?.value;
if (typeof user !== "string") user = interaction.user.id;
if (fixed.name === t("common.character")) {
Expand All @@ -66,7 +67,8 @@ export const deleteChar = {
async execute(interaction: Djs.CommandInteraction, client: EClient): Promise<void> {
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const guildData = client.settings.get(interaction.guildId as string);
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData?.lang ?? interaction.locale;
const ul = ln(lang);
if (!guildData) {
await reply(interaction, { embeds: [embedError(ul("error.noTemplate"), ul)] });
return;
Expand Down
10 changes: 8 additions & 2 deletions src/commands/admin/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ export const exportData = {
if (!interaction.guild) return;
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const isPrivate = options.getBoolean(t("export.options.name")) ?? undefined;
const allUser = client.settings.get(interaction.guild!.id, "user");
const guildData = client.settings.get(interaction.guild.id);
if (!guildData) {
await interaction.reply(t("export.error.noData"));
return;
}
const allUser = guildData.user;
await interaction.deferReply();
if (!allUser) {
await interaction.reply(t("export.error.noData"));
return;
}
const ul = ln(interaction.locale);
const lang = guildData.lang ?? interaction.locale;
const ul = ln(lang);
const csv: CSVRow[] = [];
const statsName = client.settings.get(interaction.guild.id, "templateID.statsName");
const isPrivateAllowed = client.settings.get(interaction.guild.id, "privateChannel");
Expand Down
28 changes: 20 additions & 8 deletions src/commands/admin/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ export const bulkAdd = {
async execute(interaction: Djs.CommandInteraction, client: EClient) {
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const csvFile = options.getAttachment(t("import.options.name"), true);
const ul = ln(interaction.guild?.preferredLocale ?? interaction.locale);
const langToUse =
client.settings.get(interaction.guild!.id, "lang") ??
interaction.guild?.preferredLocale ??
interaction.locale;
const ul = ln(langToUse);
await interaction.deferReply({ ephemeral: true });
const ext = csvFile.name.split(".").pop()?.toLowerCase() ?? "";
if (!ext || ext !== "csv") {
Expand All @@ -71,7 +75,8 @@ export const bulkAdd = {
csvFile.url,
guildTemplate,
interaction,
client.settings.has(interaction.guild!.id, "privateChannel")
client.settings.has(interaction.guild!.id, "privateChannel"),
langToUse
);
const defaultChannel = client.settings.get(interaction.guild!.id, "managerId");
const privateChannel = client.settings.get(interaction.guild!.id, "privateChannel");
Expand Down Expand Up @@ -194,7 +199,11 @@ export const bulkAddTemplate = {
.setDescriptionLocalizations(cmdLn("csv_generation.description")),
async execute(interaction: Djs.CommandInteraction, client: EClient) {
if (!interaction.guild) return;
const ul = ln(interaction.locale);
const lang =
client.settings.get(interaction.guild.id, "lang") ??
interaction.guild.preferredLocale ??
interaction.locale;
const ul = ln(lang);
const guildTemplate = await getTemplateWithDB(interaction, client.settings);
if (!guildTemplate) {
return reply(interaction, { content: ul("error.noTemplate") });
Expand Down Expand Up @@ -226,14 +235,16 @@ export async function parseCSV(
url: string,
guildTemplate: StatisticalTemplate,
interaction?: Djs.CommandInteraction,
allowPrivate?: boolean
allowPrivate?: boolean,
lang: Djs.Locale = Djs.Locale.EnglishGB
) {
let header = ["user", "charName", "avatar", "channel"];
if (guildTemplate.statistics) {
header = header.concat(Object.keys(guildTemplate.statistics));
}
if (allowPrivate) header.push("isPrivate");
const ul = ln(interaction?.locale ?? ("en" as Djs.Locale));

const ul = ln(lang);
header.push("dice");
header = header.map((key) => key.unidecode());
//papaparse can't be used in Node, we need first to create a readable stream
Expand Down Expand Up @@ -287,7 +298,7 @@ export async function parseCSV(
if (csvData.length === 0) {
throw new InvalidCsvContent("url");
}
return await step(csvData, guildTemplate, interaction, allowPrivate);
return await step(csvData, guildTemplate, interaction, allowPrivate, lang);
}

/**
Expand All @@ -313,12 +324,13 @@ async function step(
csv: CSVRow[],
guildTemplate: StatisticalTemplate,
interaction?: Djs.CommandInteraction,
allowPrivate?: boolean
allowPrivate?: boolean,
lang: Djs.Locale = Djs.Locale.EnglishGB
) {
const members: {
[id: string]: UserData[];
} = {};
const ul = ln(interaction?.locale ?? ("en" as Djs.Locale));
const ul = ln(lang);
const errors: string[] = [];
//get the user id from the guild
for (const data of csv) {
Expand Down
12 changes: 9 additions & 3 deletions src/commands/admin/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,11 @@ export const generateTemplate = {
.setNameLocalizations(cmdLn("generate.options.damage.name"))
.setRequired(false)
),
async execute(interaction: Djs.CommandInteraction): Promise<void> {
async execute(interaction: Djs.CommandInteraction, client: EClient): Promise<void> {
if (!interaction.guild) return;
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const ul = ln(interaction.locale as Djs.Locale);
const lang = client.settings.get(interaction.guild.id, "lang") ?? interaction.locale;
const ul = ln(lang);
const name = options.getString(t("generate.options.stats.name")) ?? undefined;
let statServer: Statistic | undefined = undefined;
if (name) {
Expand Down Expand Up @@ -200,7 +201,11 @@ export const registerTemplate = {
if (!interaction.guild) return;
await interaction.deferReply({ ephemeral: true });
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const ul = ln(interaction.guild.preferredLocale ?? interaction.locale);
const langToUse =
client.settings.get(interaction.guild!.id, "lang") ??
interaction.guild?.preferredLocale ??
interaction.locale;
const ul = ln(langToUse);

const template = options.getAttachment(t("register.options.template.name"), true);
//fetch the template
Expand Down Expand Up @@ -355,6 +360,7 @@ export const registerTemplate = {
client.settings.set(guildId, json);
} else {
const newData: GuildData = {
lang: interaction.guild.preferredLocale ?? interaction.locale,
templateID: {
channelId: channel.id,
messageId: msg.id,
Expand Down
6 changes: 4 additions & 2 deletions src/commands/gimmick/display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export const displayUser = {
const guildData = client.settings.get(interaction.guildId as string);
if (!guildData) return;
const choices: string[] = [];
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData.lang ?? interaction.locale;
const ul = ln(lang);
let userID = options.get(t("display.userLowercase"))?.value ?? interaction.user.id;
if (typeof userID !== "string") userID = interaction.user.id;
if (fixed.name === t("common.character")) {
Expand All @@ -66,7 +67,8 @@ export const displayUser = {
async execute(interaction: Djs.CommandInteraction, client: EClient) {
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const guildData = client.settings.get(interaction.guildId as string);
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData?.lang ?? interaction.locale;
const ul = ln(lang);
if (!guildData) {
await reply(interaction, { embeds: [embedError(ul("error.noTemplate"), ul)] });
return;
Expand Down
6 changes: 4 additions & 2 deletions src/commands/gimmick/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ export const editAvatar = {
const guildData = client.settings.get(interaction.guildId as string);
if (!guildData) return;
const choices: string[] = [];
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData.lang ?? interaction.locale;
const ul = ln(lang);
let userID = options.get(t("display.userLowercase"))?.value ?? interaction.user.id;
if (typeof userID !== "string") userID = interaction.user.id;
if (fixed.name === t("common.character")) {
Expand All @@ -140,7 +141,8 @@ export const editAvatar = {
async execute(interaction: Djs.CommandInteraction, client: EClient) {
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const guildData = client.settings.get(interaction.guildId as string);
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData?.lang ?? interaction.locale;
const ul = ln(lang);
if (!guildData) {
await reply(interaction, { embeds: [embedError(ul("error.noTemplate"), ul)] });
return;
Expand Down
6 changes: 4 additions & 2 deletions src/commands/gimmick/graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ export const graph = {
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const fixed = options.getFocused(true);
const guildData = client.settings.get(interaction.guild!.id);
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData?.lang ?? interaction.locale;
const ul = ln(lang);
if (!guildData) return;
const choices: string[] = [];
let user = options.get(t("display.userLowercase"))?.value ?? interaction.user.id;
Expand Down Expand Up @@ -199,7 +200,8 @@ export const graph = {
const guildData = client.settings.get(interaction.guild!.id);
let min = options.getNumber(t("graph.min.name")) ?? undefined;
let max = options.getNumber(t("graph.max.name")) ?? undefined;
const ul = ln(interaction.locale as Djs.Locale);
const lang = guildData?.lang ?? interaction.locale;
const ul = ln(lang);
if (!guildData) {
await reply(interaction, { embeds: [embedError(ul("error.noTemplate"), ul)] });
return;
Expand Down
4 changes: 3 additions & 1 deletion src/commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ export const help = {
async execute(interaction: Djs.CommandInteraction, client: EClient): Promise<void> {
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const subcommand = options.getSubcommand(true);
const ul = ln(interaction.locale as Djs.Locale);
const lang =
client.settings.get(interaction.guildId as string, "lang") ?? interaction.locale;
const ul = ln(lang);
const link = interaction.locale === "fr" ? LINKS.fr : LINKS.en;
const commandsID = await interaction.guild?.commands.fetch();
if (!commandsID) return;
Expand Down
3 changes: 2 additions & 1 deletion src/commands/rolls/base_roll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ export const newScene = {
const option = interaction.options as Djs.CommandInteractionOptionResolver;
const scene = option.getString(t("scene.option.name"));
const bubble = option.getBoolean(t("scene.time.name"));
const ul = ln(interaction.locale as Djs.Locale);
const lang = client.settings.get(interaction.guild.id, "lang") ?? interaction.locale;
const ul = ln(lang);
if (!scene && !bubble) {
await reply(interaction, { content: ul("scene.noScene"), ephemeral: true });
return;
Expand Down
3 changes: 2 additions & 1 deletion src/commands/rolls/dbAtq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ export const dbd = {
if (!user) return;
let charOptions = options.getString(t("common.character")) ?? undefined;
const charName = charOptions?.normalize();
const ul = ln(interaction.locale as Djs.Locale);
const lang = client.settings.get(interaction.guild.id, "lang") ?? interaction.locale;
const ul = ln(lang);
try {
let userStatistique = await getUserFromMessage(
client.settings,
Expand Down
3 changes: 2 additions & 1 deletion src/commands/rolls/dbroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ export const dbRoll = {
if (!interaction.guild || !interaction.channel) return;
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const guildData = client.settings.get(interaction.guild.id);
const ul = ln(interaction.locale);
const lang = guildData?.lang ?? interaction.locale;
const ul = ln(lang);
if (!guildData) return;
let optionChar = options.getString(t("common.character")) ?? undefined;
const charName = optionChar?.standardize();
Expand Down
2 changes: 1 addition & 1 deletion src/commands/rolls/mj_roll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ export const mjRoll = {
if (!interaction.guild || !interaction.channel) return;
const options = interaction.options as Djs.CommandInteractionOptionResolver;
const guildData = client.settings.get(interaction.guild.id);
const ul = ln(interaction.locale);
const ul = ln(guildData?.lang ?? interaction.locale);
if (!guildData) return;

const user = options.getUser(t("display.userLowercase"), true);
Expand Down
Loading

0 comments on commit 4a81dd9

Please sign in to comment.