feat: add an about command #2

Merged
naomi merged 4 commits from feat/about into main 2025-02-10 15:43:06 -08:00
10 changed files with 662 additions and 190 deletions
+1 -1
View File
@@ -23,7 +23,7 @@
"vitest": "3.0.5" "vitest": "3.0.5"
}, },
"dependencies": { "dependencies": {
"discord.js": "14.17.3", "discord.js": "14.18.0",
"fastify": "5.2.1", "fastify": "5.2.1",
"winston": "3.17.0" "winston": "3.17.0"
} }
+23 -23
View File
@@ -9,8 +9,8 @@ importers:
.: .:
dependencies: dependencies:
discord.js: discord.js:
specifier: 14.17.3 specifier: 14.18.0
version: 14.17.3 version: 14.18.0
fastify: fastify:
specifier: 5.2.1 specifier: 5.2.1
version: 5.2.1 version: 5.2.1
@@ -116,8 +116,8 @@ packages:
'@dabh/diagnostics@2.0.3': '@dabh/diagnostics@2.0.3':
resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
'@discordjs/builders@1.10.0': '@discordjs/builders@1.10.1':
resolution: {integrity: sha512-ikVZsZP+3shmVJ5S1oM+7SveUCK3L9fTyfA8aJ7uD9cNQlTqF+3Irbk2Y22KXTb3C3RNUahRkSInClJMkHrINg==} resolution: {integrity: sha512-OWo1fY4ztL1/M/DUyRPShB4d/EzVfuUvPTRRHRIt/YxBrUYSz0a+JicD5F5zHFoNs2oTuWavxCOVFV1UljHTng==}
engines: {node: '>=16.11.0'} engines: {node: '>=16.11.0'}
'@discordjs/collection@1.5.3': '@discordjs/collection@1.5.3':
@@ -132,16 +132,16 @@ packages:
resolution: {integrity: sha512-YIruKw4UILt/ivO4uISmrGq2GdMY6EkoTtD0oS0GvkJFRZbTSdPhzYiUILbJ/QslsvC9H9nTgGgnarnIl4jMfw==} resolution: {integrity: sha512-YIruKw4UILt/ivO4uISmrGq2GdMY6EkoTtD0oS0GvkJFRZbTSdPhzYiUILbJ/QslsvC9H9nTgGgnarnIl4jMfw==}
engines: {node: '>=16.11.0'} engines: {node: '>=16.11.0'}
'@discordjs/rest@2.4.2': '@discordjs/rest@2.4.3':
resolution: {integrity: sha512-9bOvXYLQd5IBg/kKGuEFq3cstVxAMJ6wMxO2U3wjrgO+lHv8oNCT+BBRpuzVQh7BoXKvk/gpajceGvQUiRoJ8g==} resolution: {integrity: sha512-+SO4RKvWsM+y8uFHgYQrcTl/3+cY02uQOH7/7bKbVZsTfrfpoE62o5p+mmV+s7FVhTX82/kQUGGbu4YlV60RtA==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@discordjs/util@1.1.1': '@discordjs/util@1.1.1':
resolution: {integrity: sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==} resolution: {integrity: sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==}
engines: {node: '>=18'} engines: {node: '>=18'}
'@discordjs/ws@1.2.0': '@discordjs/ws@1.2.1':
resolution: {integrity: sha512-QH5CAFe3wHDiedbO+EI3OOiyipwWd+Q6BdoFZUw/Wf2fw5Cv2fgU/9UEtJRmJa9RecI+TAhdGPadMaEIur5yJg==} resolution: {integrity: sha512-PBvenhZG56a6tMWF/f4P6f4GxZKJTBG95n7aiGSPTnodmz4N5g60t79rSIAq7ywMbv8A4jFtexMruH+oe51aQQ==}
engines: {node: '>=16.11.0'} engines: {node: '>=16.11.0'}
'@es-joy/jsdoccomment@0.49.0': '@es-joy/jsdoccomment@0.49.0':
@@ -1021,8 +1021,8 @@ packages:
discord-api-types@0.37.119: discord-api-types@0.37.119:
resolution: {integrity: sha512-WasbGFXEB+VQWXlo6IpW3oUv73Yuau1Ig4AZF/m13tXcTKnMpc/mHjpztIlz4+BM9FG9BHQkEXiPto3bKduQUg==} resolution: {integrity: sha512-WasbGFXEB+VQWXlo6IpW3oUv73Yuau1Ig4AZF/m13tXcTKnMpc/mHjpztIlz4+BM9FG9BHQkEXiPto3bKduQUg==}
discord.js@14.17.3: discord.js@14.18.0:
resolution: {integrity: sha512-8/j8udc3CU7dz3Eqch64UaSHoJtUT6IXK4da5ixjbav4NAXJicloWswD/iwn1ImZEMoAV3LscsdO0zhBh6H+0Q==} resolution: {integrity: sha512-SvU5kVUvwunQhN2/+0t55QW/1EHfB1lp0TtLZUSXVHDmyHTrdOj5LRKdR0zLcybaA15F+NtdWuWmGOX9lE+CAw==}
engines: {node: '>=18'} engines: {node: '>=18'}
doctrine@2.1.0: doctrine@2.1.0:
@@ -2296,8 +2296,8 @@ packages:
undici-types@6.20.0: undici-types@6.20.0:
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
undici@6.19.8: undici@6.21.1:
resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==} resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==}
engines: {node: '>=18.17'} engines: {node: '>=18.17'}
update-browserslist-db@1.1.2: update-browserslist-db@1.1.2:
@@ -2567,7 +2567,7 @@ snapshots:
enabled: 2.0.0 enabled: 2.0.0
kuler: 2.0.0 kuler: 2.0.0
'@discordjs/builders@1.10.0': '@discordjs/builders@1.10.1':
dependencies: dependencies:
'@discordjs/formatters': 0.6.0 '@discordjs/formatters': 0.6.0
'@discordjs/util': 1.1.1 '@discordjs/util': 1.1.1
@@ -2585,7 +2585,7 @@ snapshots:
dependencies: dependencies:
discord-api-types: 0.37.119 discord-api-types: 0.37.119
'@discordjs/rest@2.4.2': '@discordjs/rest@2.4.3':
dependencies: dependencies:
'@discordjs/collection': 2.1.1 '@discordjs/collection': 2.1.1
'@discordjs/util': 1.1.1 '@discordjs/util': 1.1.1
@@ -2595,14 +2595,14 @@ snapshots:
discord-api-types: 0.37.119 discord-api-types: 0.37.119
magic-bytes.js: 1.10.0 magic-bytes.js: 1.10.0
tslib: 2.8.1 tslib: 2.8.1
undici: 6.19.8 undici: 6.21.1
'@discordjs/util@1.1.1': {} '@discordjs/util@1.1.1': {}
'@discordjs/ws@1.2.0': '@discordjs/ws@1.2.1':
dependencies: dependencies:
'@discordjs/collection': 2.1.1 '@discordjs/collection': 2.1.1
'@discordjs/rest': 2.4.2 '@discordjs/rest': 2.4.3
'@discordjs/util': 1.1.1 '@discordjs/util': 1.1.1
'@sapphire/async-queue': 1.5.5 '@sapphire/async-queue': 1.5.5
'@types/ws': 8.5.14 '@types/ws': 8.5.14
@@ -3477,20 +3477,20 @@ snapshots:
discord-api-types@0.37.119: {} discord-api-types@0.37.119: {}
discord.js@14.17.3: discord.js@14.18.0:
dependencies: dependencies:
'@discordjs/builders': 1.10.0 '@discordjs/builders': 1.10.1
'@discordjs/collection': 1.5.3 '@discordjs/collection': 1.5.3
'@discordjs/formatters': 0.6.0 '@discordjs/formatters': 0.6.0
'@discordjs/rest': 2.4.2 '@discordjs/rest': 2.4.3
'@discordjs/util': 1.1.1 '@discordjs/util': 1.1.1
'@discordjs/ws': 1.2.0 '@discordjs/ws': 1.2.1
'@sapphire/snowflake': 3.5.3 '@sapphire/snowflake': 3.5.3
discord-api-types: 0.37.119 discord-api-types: 0.37.119
fast-deep-equal: 3.1.3 fast-deep-equal: 3.1.3
lodash.snakecase: 4.1.1 lodash.snakecase: 4.1.1
tslib: 2.8.1 tslib: 2.8.1
undici: 6.19.8 undici: 6.21.1
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
- utf-8-validate - utf-8-validate
@@ -5018,7 +5018,7 @@ snapshots:
undici-types@6.20.0: {} undici-types@6.20.0: {}
undici@6.19.8: {} undici@6.21.1: {}
update-browserslist-db@1.1.2(browserslist@4.24.4): update-browserslist-db@1.1.2(browserslist@4.24.4):
dependencies: dependencies:
+87
View File
@@ -0,0 +1,87 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import {
ApplicationIntegrationType,
SlashCommandBuilder,
InteractionContextType,
Locale,
} from "discord.js";
const command = new SlashCommandBuilder().
setContexts(
InteractionContextType.BotDM,
InteractionContextType.Guild,
InteractionContextType.PrivateChannel,
).
setIntegrationTypes(ApplicationIntegrationType.UserInstall).
setName("about").
setNameLocalizations({
[Locale.Indonesian]: "tentang",
[Locale.EnglishGB]: "about",
[Locale.EnglishUS]: "about",
[Locale.Bulgarian]: "за",
[Locale.ChineseCN]: "å…³äŗŽ",
[Locale.ChineseTW]: "é—œę–¼",
[Locale.Czech]: "o-aplikaci",
[Locale.Danish]: "om",
[Locale.Dutch]: "over",
[Locale.Finnish]: "tietoja",
[Locale.French]: "Ć -propos",
[Locale.German]: "über",
[Locale.Greek]: "ĻƒĻ‡ĪµĻ„Ī¹ĪŗĪ¬-με",
[Locale.Hindi]: "ą¤•ą„‡-ą¤¬ą¤¾ą¤°ą„‡-ą¤®ą„‡ą¤‚",
[Locale.Hungarian]: "rólunk",
[Locale.Italian]: "informazioni",
[Locale.Japanese]: "ē“„",
[Locale.Korean]: "약",
[Locale.Lithuanian]: "apie",
[Locale.Polish]: "o-nas",
[Locale.PortugueseBR]: "sobre",
[Locale.Romanian]: "despre",
[Locale.Russian]: "о",
[Locale.SpanishES]: "acerca-de",
[Locale.SpanishLATAM]: "acerca-de",
[Locale.Swedish]: "om",
[Locale.Thai]: "ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøš",
[Locale.Turkish]: "hakkında",
[Locale.Ukrainian]: "про",
}).
setDescription("Learn more about this bot!").
setDescriptionLocalizations({
[Locale.Indonesian]: "Pelajari lebih lanjut tentang bot ini!",
[Locale.EnglishGB]: "Learn more about this bot!",
[Locale.EnglishUS]: "Learn more about this bot!",
[Locale.Bulgarian]: "ŠŠ°ŃƒŃ‡ŠµŃ‚Šµ повече за този бот!",
[Locale.ChineseCN]: "äŗ†č§£ęœ‰å…³ę­¤ęœŗå™Øäŗŗēš„ę›“å¤šäæ”ęÆļ¼",
[Locale.ChineseTW]: "äŗ†č§£ęœ‰é—œę­¤ę©Ÿå™Øäŗŗēš„ę›“å¤šäæ”ęÆļ¼",
[Locale.Czech]: "Dozvědět se vƭce o tomto botovi!",
[Locale.Danish]: "LƦr mere om denne bot!",
[Locale.Dutch]: "Leer meer over deze bot!",
[Locale.Finnish]: "LisƤtietoja tƤstƤ botista!",
[Locale.French]: "En savoir plus sur ce bot!",
[Locale.German]: "Erfahren Sie mehr über diesen Bot!",
[Locale.Greek]: "ĪœĪ¬ĪøĪµĻ„Īµ Ļ€ĪµĻĪ¹ĻƒĻƒĻŒĻ„ĪµĻĪ± για Ī±Ļ…Ļ„ĻŒ το bot!",
[Locale.Hindi]: "इस ą¤¬ą„‰ą¤Ÿ ą¤•ą„‡ ą¤¬ą¤¾ą¤°ą„‡ ą¤®ą„‡ą¤‚ और अधिक ą¤œą¤¾ą¤Øą„‡ą¤‚!",
[Locale.Hungarian]: "Tudj meg tƶbbet erről a botról!",
[Locale.Italian]: "Scopri di più su questo bot!",
[Locale.Japanese]: "ć“ć®ćƒœćƒƒćƒˆć«ć¤ć„ć¦ć‚‚ć£ćØč©³ć—ćēŸ„ć‚‹ļ¼",
[Locale.Korean]: "ģ“ 듇에 ėŒ€ķ•“ ė” ģ•Œģ•„ė³“źø°!",
[Locale.Lithuanian]: "Sužinokite daugiau apie Ŕį botą!",
[Locale.Polish]: "Dowiedz się więcej o tym bocie!",
[Locale.PortugueseBR]: "Saiba mais sobre este bot!",
[Locale.Romanian]: "Aflați mai multe despre acest bot!",
[Locale.Russian]: "Узнайте больше об ŃŃ‚Š¾Š¼ боте!",
[Locale.SpanishES]: "”Obtén mÔs información sobre este bot!",
[Locale.SpanishLATAM]: "”Obtén mÔs información sobre este bot!",
[Locale.Swedish]: "LƤr dig mer om denna bot!",
[Locale.Thai]: "ą¹€ąø£ąøµąø¢ąø™ąø£ąø¹ą¹‰ą¹€ąøžąø“ą¹ˆąø”ą¹€ąø•ąø“ąø”ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøšąøšąø­ąø•ąø™ąøµą¹‰!",
[Locale.Turkish]: "Bu bot hakkında daha fazla bilgi edinin!",
[Locale.Ukrainian]: "Š”Ń–Š·Š½Š°Š¹Ń‚ŠµŃŃ Š±Ń–Š»ŃŒŃˆŠµ про Ń†ŃŒŠ¾Š³Š¾ бота!",
});
// eslint-disable-next-line no-console -- We don't need our logger here as this never runs in production.
console.log(JSON.stringify(command.toJSON()));
+334 -121
View File
@@ -6,10 +6,21 @@
/* eslint-disable @typescript-eslint/naming-convention -- This is the convention for these keys. */ /* eslint-disable @typescript-eslint/naming-convention -- This is the convention for these keys. */
/* eslint-disable stylistic/max-len -- These are going to be long strings and that's okay. */ /* eslint-disable stylistic/max-len -- These are going to be long strings and that's okay. */
/* eslint-disable max-lines -- massive chonky boi*/
import { Locale } from "discord.js"; import { Locale } from "discord.js";
export const responses: Record<string, { "no-message-content": string; "subscription-required": string; "translation": string; "unsupported-locale": string }> = { export const responses: Record<string, { "no-message-content": string; "subscription-required": string; "translation": string; "unsupported-locale": string; "embed": { title: string; description: string; commit: string; version: string }; "button": { support: string; code: string } }> = {
en: { en: {
"button": {
code: "Source code",
support: "Need help?",
},
"embed": {
commit: "Current Commit",
description: "Aria Iuvo is a Discord bot that uses LibreTranslate to provide translations for messages. She is developed by NHCarrigan. To use the bot, right click on a message, select `Apps`, then select `Translate message`!",
title: "About Aria Iuvo",
version: "Running Version",
},
"no-message-content": "No message content found.", "no-message-content": "No message content found.",
"subscription-required": "subscription-required":
"You must be subscribed to translate messages.", "You must be subscribed to translate messages.",
@@ -18,201 +29,403 @@ export const responses: Record<string, { "no-message-content": string; "subscrip
"unsupported-locale": "Language {{target}} is not supported by our translation software.", "unsupported-locale": "Language {{target}} is not supported by our translation software.",
}, },
[Locale.Indonesian]: { [Locale.Indonesian]: {
"no-message-content": "Tidak ada konten pesan ditemukan.", "button": {
"subscription-required": code: "Kode sumber",
"Anda harus berlangganan untuk menerjemahkan pesan.", support: "Butuh bantuan?",
"translation": },
"{{translation}}\n-# Mendeteksi {{language}} dengan kepercayaan {{confidence}}%.", "embed": {
commit: "Commit Saat Ini",
description: "Aria Iuvo adalah bot Discord yang menggunakan LibreTranslate untuk menyediakan terjemahan pesan. Dia dikembangkan oleh NHCarrigan. Untuk menggunakan bot, klik kanan pada pesan, pilih `Apps`, lalu pilih `Translate message`!",
title: "Tentang Aria Iuvo",
version: "Versi Berjalan",
},
"no-message-content": "Tidak ditemukan konten pesan.",
"subscription-required": "Anda harus berlangganan untuk menerjemahkan pesan.",
"translation": "{{translation}}\n-# Terdeteksi {{language}} dengan tingkat kepercayaan {{confidence}}%.",
"unsupported-locale": "Bahasa {{target}} tidak didukung oleh perangkat lunak terjemahan kami.", "unsupported-locale": "Bahasa {{target}} tidak didukung oleh perangkat lunak terjemahan kami.",
}, },
es: { es: {
"button": {
code: "Código fuente",
support: "ĀæNecesitas ayuda?",
},
"embed": {
commit: "Commit Actual",
description: "Aria Iuvo es un bot de Discord que usa LibreTranslate para proporcionar traducciones de mensajes. EstÔ desarrollada por NHCarrigan. Para usar el bot, haz clic derecho en un mensaje, selecciona `Apps`, ”luego selecciona `Translate message`!",
title: "Sobre Aria Iuvo",
version: "Versión en Ejecución",
},
"no-message-content": "No se encontró contenido del mensaje.", "no-message-content": "No se encontró contenido del mensaje.",
"subscription-required": "subscription-required": "Debes estar suscrito para traducir mensajes.",
"Debes estar suscrito para traducir mensajes.", "translation": "{{translation}}\n-# Detectado {{language}} con {{confidence}}% de confianza.",
"translation":
"{{translation}}\n-# Detectado {{language}} con {{confidence}}% de confianza.",
"unsupported-locale": "El idioma {{target}} no es compatible con nuestro software de traducción.", "unsupported-locale": "El idioma {{target}} no es compatible con nuestro software de traducción.",
}, },
pt: { pt: {
"button": {
code: "Código fonte",
support: "Precisa de ajuda?",
},
"embed": {
commit: "Commit Atual",
description: "Aria Iuvo é um bot do Discord que usa LibreTranslate para fornecer traduções de mensagens. Ela é desenvolvida por NHCarrigan. Para usar o bot, clique com o botão direito em uma mensagem, selecione `Apps`, depois selecione `Translate message`!",
title: "Sobre Aria Iuvo",
version: "Versão em Execução",
},
"no-message-content": "Nenhum conteĆŗdo de mensagem encontrado.", "no-message-content": "Nenhum conteĆŗdo de mensagem encontrado.",
"subscription-required": "subscription-required": "VocĆŖ precisa ser assinante para traduzir mensagens.",
"Você deve estar inscrito para traduzir mensagens.", "translation": "{{translation}}\n-# Detectado {{language}} com {{confidence}}% de confiança.",
"translation":
"{{translation}}\n-# Detectado {{language}} com {{confidence}}% de confianƧa.",
"unsupported-locale": "O idioma {{target}} não é suportado pelo nosso software de tradução.", "unsupported-locale": "O idioma {{target}} não é suportado pelo nosso software de tradução.",
}, },
[Locale.Czech]: { [Locale.Czech]: {
"button": {
code: "Zdrojový kód",
support: "Potřebujete pomoc?",
},
"embed": {
commit: "AktuƔlnƭ Commit",
description: "Aria Iuvo je Discord bot, který používĆ” LibreTranslate k poskytovĆ”nĆ­ překladÅÆ zprĆ”v. Je vyvĆ­jena NHCarriganem. Pro použitĆ­ bota klikněte pravým tlačƭtkem na zprĆ”vu, vyberte `Apps`, pak vyberte `Translate message`!",
title: "O Aria Iuvo",
version: "AktuƔlnƭ Verze",
},
"no-message-content": "Nebyl nalezen žÔdný obsah zprÔvy.", "no-message-content": "Nebyl nalezen žÔdný obsah zprÔvy.",
"subscription-required": "subscription-required": "Pro překlĆ”dĆ”nĆ­ zprĆ”v musĆ­te mĆ­t předplatnĆ©.",
"MusĆ­te být přihlÔŔeni k překladu zprĆ”v.", "translation": "{{translation}}\n-# DetekovĆ”n jazyk {{language}} s {{confidence}}% jistotou.",
"translation":
"{{translation}}\n-# DetekovĆ”no {{language}} s dÅÆvěrou {{confidence}}%.",
"unsupported-locale": "Jazyk {{target}} nenĆ­ podporovĆ”n naŔím překladovým softwarem.", "unsupported-locale": "Jazyk {{target}} nenĆ­ podporovĆ”n naŔím překladovým softwarem.",
}, },
[Locale.Danish]: { [Locale.Danish]: {
"no-message-content": "Ingen beskedindhold fundet.", "button": {
"subscription-required": code: "Kildekode",
"Du skal vƦre tilmeldt for at oversƦtte beskeder.", support: "Brug for hjƦlp?",
"translation": },
"{{translation}}\n-# Detekteret {{language}} med {{confidence}}% tillid.", "embed": {
commit: "NuvƦrende Commit",
description: "Aria Iuvo er en Discord bot, der bruger LibreTranslate til at levere oversættelser af beskeder. Hun er udviklet af NHCarrigan. For at bruge botten, højreklik pÄ en besked, vælg `Apps`, vælg derefter `Translate message`!",
title: "Om Aria Iuvo",
version: "KĆørende Version",
},
"no-message-content": "Intet beskedindhold fundet.",
"subscription-required": "Du skal vƦre abonnent for at oversƦtte beskeder.",
"translation": "{{translation}}\n-# Detekteret {{language}} med {{confidence}}% sikkerhed.",
"unsupported-locale": "Sproget {{target}} understøttes ikke af vores oversættelsessoftware.", "unsupported-locale": "Sproget {{target}} understøttes ikke af vores oversættelsessoftware.",
}, },
[Locale.Dutch]: { [Locale.Dutch]: {
"button": {
code: "Broncode",
support: "Hulp nodig?",
},
"embed": {
commit: "Huidige Commit",
description: "Aria Iuvo is een Discord bot die LibreTranslate gebruikt om vertalingen voor berichten te verzorgen. Ze is ontwikkeld door NHCarrigan. Om de bot te gebruiken, klik met de rechtermuisknop op een bericht, selecteer `Apps`, selecteer vervolgens `Translate message`!",
title: "Over Aria Iuvo",
version: "Huidige Versie",
},
"no-message-content": "Geen berichtinhoud gevonden.", "no-message-content": "Geen berichtinhoud gevonden.",
"subscription-required": "subscription-required": "Je moet geabonneerd zijn om berichten te vertalen.",
"U moet zijn geabonneerd om berichten te vertalen.", "translation": "{{translation}}\n-# Gedetecteerd {{language}} met {{confidence}}% zekerheid.",
"translation":
"{{translation}}\n-# Gedetecteerd {{language}} met {{confidence}}% vertrouwen.",
"unsupported-locale": "Taal {{target}} wordt niet ondersteund door onze vertaalsoftware.", "unsupported-locale": "Taal {{target}} wordt niet ondersteund door onze vertaalsoftware.",
}, },
[Locale.Finnish]: { [Locale.Finnish]: {
"no-message-content": "Ei viestisisƤltƶƤ lƶytynyt.", "button": {
"subscription-required": code: "LƤhdekoodi",
"Sinun on tilattava viestien kƤƤntƤmiseksi.", support: "Tarvitsetko apua?",
"translation": },
"{{translation}}\n-# Havaittu {{language}} {{confidence}}% luottamuksella.", "embed": {
"unsupported-locale": "KieltƤ {{target}} ei tueta kƤƤnnƶssovelluksellamme.", commit: "Nykyinen Commit",
description: "Aria Iuvo on Discord-botti, joka kƤyttƤƤ LibreTranslatea viestien kƤƤntƤmiseen. Sen on kehittƤnyt NHCarrigan. KƤyttƤƤksesi bottia, napsauta hiiren oikealla painikkeella viestiƤ, valitse `Apps`, sitten valitse `Translate message`!",
title: "Tietoja Aria Iuvosta",
version: "KƤynnissƤ Oleva Versio",
},
"no-message-content": "Viestin sisƤltƶƤ ei lƶytynyt.",
"subscription-required": "Sinun tƤytyy olla tilaaja kƤƤntƤƤksesi viestejƤ.",
"translation": "{{translation}}\n-# Tunnistettu {{language}} {{confidence}}% varmuudella.",
"unsupported-locale": "Kieli {{target}} ei ole kƤƤnnƶsohjelmistomme tukema.",
}, },
[Locale.French]: { [Locale.French]: {
"button": {
code: "Code source",
support: "Besoin d'aide ?",
},
"embed": {
commit: "Commit Actuel",
description: "Aria Iuvo est un bot Discord qui utilise LibreTranslate pour fournir des traductions de messages. Elle est dƩveloppƩe par NHCarrigan. Pour utiliser le bot, faites un clic droit sur un message, sƩlectionnez `Apps`, puis sƩlectionnez `Translate message` !",
title: "ƀ propos d'Aria Iuvo",
version: "Version en Cours",
},
"no-message-content": "Aucun contenu de message trouvƩ.", "no-message-content": "Aucun contenu de message trouvƩ.",
"subscription-required": "subscription-required": "Vous devez être abonné pour traduire les messages.",
"Vous devez être abonné pour traduire les messages.", "translation": "{{translation}}\n-# Détecté {{language}} avec {{confidence}}% de confiance.",
"translation":
"{{translation}}\n-# DƩtectƩ {{language}} avec {{confidence}}% de confiance.",
"unsupported-locale": "La langue {{target}} n'est pas prise en charge par notre logiciel de traduction.", "unsupported-locale": "La langue {{target}} n'est pas prise en charge par notre logiciel de traduction.",
}, },
[Locale.German]: { [Locale.German]: {
"button": {
code: "Quellcode",
support: "Hilfe benƶtigt?",
},
"embed": {
commit: "Aktueller Commit",
description: "Aria Iuvo ist ein Discord-Bot, der LibreTranslate verwendet, um Übersetzungen für Nachrichten bereitzustellen. Sie wurde von NHCarrigan entwickelt. Um den Bot zu verwenden, klicken Sie mit der rechten Maustaste auf eine Nachricht, wählen Sie `Apps` und dann `Translate message`!",
title: "Über Aria Iuvo",
version: "Laufende Version",
},
"no-message-content": "Kein Nachrichteninhalt gefunden.", "no-message-content": "Kein Nachrichteninhalt gefunden.",
"subscription-required": "subscription-required": "Sie müssen abonniert sein, um Nachrichten zu übersetzen.",
"Sie müssen abonniert sein, um Nachrichten zu übersetzen.", "translation": "{{translation}}\n-# Erkannt {{language}} mit {{confidence}}% Sicherheit.",
"translation":
"{{translation}}\n-# Erkannt {{language}} mit {{confidence}}% Vertrauen.",
"unsupported-locale": "Die Sprache {{target}} wird von unserer Übersetzungssoftware nicht unterstützt.", "unsupported-locale": "Die Sprache {{target}} wird von unserer Übersetzungssoftware nicht unterstützt.",
}, },
[Locale.Greek]: { [Locale.Greek]: {
"button": {
code: "Πηγαίος ĪŗĻŽĪ“Ī¹ĪŗĪ±Ļ‚",
support: "Ī§ĻĪµĪ¹Ī¬Ī¶ĪµĻƒĻ„Īµ βοήθεια;",
},
"embed": {
commit: "Τρέχον Commit",
description: "Ī— Aria Iuvo είναι ένα bot Discord που Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το LibreTranslate για να παρέχει Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĪ¹Ļ‚ μηνυμάτων. Ī‘Ī½Ī±Ļ€Ļ„ĻĻ‡ĪøĪ·ĪŗĪµ Ī±Ļ€ĻŒ τον NHCarrigan. Για να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ το bot, κάντε Γεξί κλικ σε ένα μήνυμα, επιλέξτε `Apps`, ĻƒĻ„Ī· ĻƒĻ…Ī½Ī­Ļ‡ĪµĪ¹Ī± επιλέξτε `Translate message`!",
title: "Σχετικά με την Aria Iuvo",
version: "Ī¤ĻĪ­Ļ‡ĪæĻ…ĻƒĪ± ΈκΓοση",
},
"no-message-content": "Δεν βρέθηκε Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„ĪæĻ‚.", "no-message-content": "Δεν βρέθηκε Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„ĪæĻ‚.",
"subscription-required": "subscription-required": "Πρέπει να ĪµĪÆĻƒĻ„Īµ ĻƒĻ…Ī½Ī“ĻĪæĪ¼Ī·Ļ„Ī®Ļ‚ για να Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĻ„Īµ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„Ī±.",
"Πρέπει να ĪµĪÆĻƒĻ„Īµ ĻƒĻ…Ī½Ī“ĻĪæĪ¼Ī·Ļ„Ī®Ļ‚ για να Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĻ„Īµ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„Ī±.", "translation": "{{translation}}\n-# Ī•Ī½Ļ„ĪæĻ€ĪÆĻƒĻ„Ī·ĪŗĪµ {{language}} με {{confidence}}% Ī²ĪµĪ²Ī±Ī¹ĻŒĻ„Ī·Ļ„Ī±.",
"translation":
"{{translation}}\n-# Ī‘Ī½Ī¹Ļ‡Ī½ĪµĻĪøĪ·ĪŗĪµ {{language}} με {{confidence}}% ĪµĪ¼Ļ€Ī¹ĻƒĻ„ĪæĻƒĻĪ½Ī·.",
"unsupported-locale": "Ī— Ī³Ī»ĻŽĻƒĻƒĪ± {{target}} Γεν Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¶ĪµĻ„Ī±Ī¹ Ī±Ļ€ĻŒ το λογισμικό Ī¼ĪµĻ„Ī¬Ļ†ĻĪ±ĻƒĪ®Ļ‚ μας.", "unsupported-locale": "Ī— Ī³Ī»ĻŽĻƒĻƒĪ± {{target}} Γεν Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¶ĪµĻ„Ī±Ī¹ Ī±Ļ€ĻŒ το λογισμικό Ī¼ĪµĻ„Ī¬Ļ†ĻĪ±ĻƒĪ®Ļ‚ μας.",
}, },
[Locale.Hindi]: { [Locale.Hindi]: {
"button": {
code: "ą¤øą„‹ą¤°ą„ą¤ø ą¤•ą„‹ą¤”",
support: "मदद ą¤šą¤¾ą¤¹ą¤æą¤?",
},
"embed": {
commit: "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤•ą¤®ą¤æą¤Ÿ",
description: "Aria Iuvo ą¤ą¤• Discord ą¤¬ą„‰ą¤Ÿ ą¤¹ą„ˆ ą¤œą„‹ ą¤øą¤‚ą¤¦ą„‡ą¤¶ą„‹ą¤‚ ą¤•ą„‡ ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤•ą„‡ ą¤²ą¤æą¤ LibreTranslate का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤ ą¤‡ą¤øą„‡ NHCarrigan ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ विकसित किया गया ą¤¹ą„ˆą„¤ ą¤¬ą„‰ą¤Ÿ का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤, ą¤•ą¤æą¤øą„€ ą¤øą¤‚ą¤¦ą„‡ą¤¶ पर ą¤°ą¤¾ą¤‡ą¤Ÿ ą¤•ą„ą¤²ą¤æą¤• ą¤•ą¤°ą„‡ą¤‚, `Apps` ą¤šą„ą¤Øą„‡ą¤‚, फिर `Translate message` ą¤šą„ą¤Øą„‡ą¤‚!",
title: "Aria Iuvo ą¤•ą„‡ ą¤¬ą¤¾ą¤°ą„‡ ą¤®ą„‡ą¤‚",
version: "चल रहा ą¤øą¤‚ą¤øą„ą¤•ą¤°ą¤£",
},
"no-message-content": "ą¤•ą„‹ą¤ˆ ą¤øą¤‚ą¤¦ą„‡ą¤¶ ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤Øą¤¹ą„€ą¤‚ ą¤®ą¤æą¤²ą„€ą„¤", "no-message-content": "ą¤•ą„‹ą¤ˆ ą¤øą¤‚ą¤¦ą„‡ą¤¶ ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤Øą¤¹ą„€ą¤‚ ą¤®ą¤æą¤²ą„€ą„¤",
"subscription-required": "subscription-required": "ą¤øą¤‚ą¤¦ą„‡ą¤¶ą„‹ą¤‚ का ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤†ą¤Ŗą¤•ą„‹ ą¤øą¤¦ą¤øą„ą¤Æą¤¤ą¤¾ ą¤²ą„‡ą¤Øą„€ ą¤¹ą„‹ą¤—ą„€ą„¤",
"ą¤†ą¤Ŗą¤•ą„‹ ą¤øą¤‚ą¤¦ą„‡ą¤¶ ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤øą¤¬ą„ą¤øą¤•ą„ą¤°ą¤¾ą¤‡ą¤¬ करना ą¤¹ą„‹ą¤—ą¤¾ą„¤", "translation": "{{translation}}\n-# {{confidence}}% ą¤µą¤æą¤¶ą„ą¤µą¤¾ą¤ø ą¤•ą„‡ साऄ {{language}} का पता ą¤šą¤²ą¤¾ą„¤",
"translation": "unsupported-locale": "भाषा {{target}} ą¤¹ą¤®ą¤¾ą¤°ą„‡ ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤øą„‰ą¤«ą„ą¤Ÿą¤µą„‡ą¤Æą¤° ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ ą¤øą¤®ą¤°ą„ą¤„ą¤æą¤¤ ą¤Øą¤¹ą„€ą¤‚ ą¤¹ą„ˆą„¤",
"{{translation}}\n-# {{confidence}}% ą¤µą¤æą¤¶ą„ą¤µą¤¾ą¤ø ą¤•ą„‡ साऄ {{language}} का पता लगाया ą¤—ą¤Æą¤¾ą„¤",
"unsupported-locale": "ą¤¹ą¤®ą¤¾ą¤°ą„‡ ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤øą„‰ą¤«ą¤¼ą„ą¤Ÿą¤µą„‡ą¤Æą¤° ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ {{target}} भाषा का ą¤øą¤®ą¤°ą„ą¤„ą¤Ø ą¤Øą¤¹ą„€ą¤‚ किया जाता ą¤¹ą„ˆą„¤",
}, },
[Locale.Hungarian]: { [Locale.Hungarian]: {
"no-message-content": "Nem talÔlható üzenettartalom.", "button": {
"subscription-required": code: "ForrÔskód",
"Fel kell iratkoznia az üzenetek fordítÔsÔhoz.", support: "Segítségre van szüksége?",
"translation": },
"{{translation}}\n-# {{language}} ƩrzƩkelve {{confidence}}% bizalommal.", "embed": {
"unsupported-locale": "A {{target}} nyelvet nem tÔmogatja fordító szoftverünk.", commit: "Jelenlegi Commit",
description: "Az Aria Iuvo egy Discord bot, amely a LibreTranslate-et hasznĆ”lja üzenetek fordĆ­tĆ”sĆ”hoz. NHCarrigan fejlesztette. A bot hasznĆ”latĆ”hoz kattintson jobb gombbal egy üzenetre, vĆ”lassza az `Apps` lehetősĆ©get, majd vĆ”lassza a `Translate message` opciót!",
title: "Az Aria Iuvoról",
version: "Futó Verzió",
},
"no-message-content": "Nem talÔlható üzenet tartalom.",
"subscription-required": "FeliratkozÔs szükséges az üzenetek fordítÔsÔhoz.",
"translation": "{{translation}}\n-# {{language}} nyelv Ʃszlelve {{confidence}}% biztonsƔggal.",
"unsupported-locale": "A(z) {{target}} nyelvet nem tÔmogatja a fordító szoftverünk.",
}, },
[Locale.Italian]: { [Locale.Italian]: {
"button": {
code: "Codice sorgente",
support: "Hai bisogno di aiuto?",
},
"embed": {
commit: "Commit Attuale",
description: "Aria Iuvo è un bot Discord che utilizza LibreTranslate per fornire traduzioni dei messaggi. È sviluppata da NHCarrigan. Per utilizzare il bot, fai clic destro su un messaggio, seleziona `Apps`, quindi seleziona `Translate message`!",
title: "Informazioni su Aria Iuvo",
version: "Versione in Esecuzione",
},
"no-message-content": "Nessun contenuto del messaggio trovato.", "no-message-content": "Nessun contenuto del messaggio trovato.",
"subscription-required": "subscription-required": "Devi essere abbonato per tradurre i messaggi.",
"Devi essere abbonato per tradurre i messaggi.", "translation": "{{translation}}\n-# Rilevato {{language}} con {{confidence}}% di affidabilitĆ .",
"translation":
"{{translation}}\n-# Rilevato {{language}} con {{confidence}}% di fiducia.",
"unsupported-locale": "La lingua {{target}} non ĆØ supportata dal nostro software di traduzione.", "unsupported-locale": "La lingua {{target}} non ĆØ supportata dal nostro software di traduzione.",
}, },
[Locale.Japanese]: { [Locale.Japanese]: {
"no-message-content": "ćƒ”ćƒƒć‚»ćƒ¼ć‚øć‚³ćƒ³ćƒ†ćƒ³ćƒ„ćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“ć€‚", "button": {
"subscription-required": code: "ć‚½ćƒ¼ć‚¹ć‚³ćƒ¼ćƒ‰",
"ćƒ”ćƒƒć‚»ćƒ¼ć‚øć‚’ēæ»čØ³ć™ć‚‹ć«ćÆč³¼čŖ­ć™ć‚‹åæ…č¦ćŒć‚ć‚Šć¾ć™ć€‚", support: "ć‚µćƒćƒ¼ćƒˆćŒåæ…č¦ć§ć™ć‹ļ¼Ÿ",
"translation": },
"{{translation}}\n-# {{confidence}}% の俔頼度で {{language}} ć‚’ę¤œå‡ŗć—ć¾ć—ćŸć€‚", "embed": {
"unsupported-locale": "{{target}} čØ€čŖžćÆć€ēæ»čØ³ć‚½ćƒ•ćƒˆć‚¦ć‚§ć‚¢ć§ć‚µćƒćƒ¼ćƒˆć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚", commit: "ē¾åœØć®ć‚³ćƒŸćƒƒćƒˆ",
description: "Aria Iuvoは、LibreTranslateć‚’ä½æē”Øć—ć¦ćƒ”ćƒƒć‚»ćƒ¼ć‚øć®ēæ»čØ³ć‚’ęä¾›ć™ć‚‹Discord惜惃惈恧恙怂NHCarriganć«ć‚ˆć£ć¦é–‹ē™ŗć•ć‚Œć¾ć—ćŸć€‚ćƒœćƒƒćƒˆć‚’ä½æē”Øć™ć‚‹ć«ćÆć€ćƒ”ćƒƒć‚»ćƒ¼ć‚øć‚’å³ć‚ÆćƒŖćƒƒć‚Æć—ć€`Apps`ć‚’éøęŠžć—ć€`Translate message`ć‚’éøęŠžć—ć¦ćć ć•ć„ļ¼",
title: "Aria Iuvo恫恤恄恦",
version: "å®Ÿč”Œäø­ć®ćƒćƒ¼ć‚øćƒ§ćƒ³",
},
"no-message-content": "ćƒ”ćƒƒć‚»ćƒ¼ć‚øć®å†…å®¹ćŒč¦‹ć¤ć‹ć‚Šć¾ć›ć‚“ć€‚",
"subscription-required": "ćƒ”ćƒƒć‚»ćƒ¼ć‚øć‚’ēæ»čØ³ć™ć‚‹ć«ćÆč³¼čŖ­ćŒåæ…č¦ć§ć™ć€‚",
"translation": "{{translation}}\n-# {{confidence}}%ć®ē¢ŗēŽ‡ć§{{language}}ć‚’ę¤œå‡ŗć—ć¾ć—ćŸć€‚",
"unsupported-locale": "čØ€čŖž{{target}}ćÆēæ»čØ³ć‚½ćƒ•ćƒˆć‚¦ć‚§ć‚¢ć§ć‚µćƒćƒ¼ćƒˆć•ć‚Œć¦ć„ć¾ć›ć‚“ć€‚",
}, },
[Locale.Korean]: { [Locale.Korean]: {
"button": {
code: "ģ†ŒģŠ¤ ģ½”ė“œ",
support: "ė„ģ›€ģ“ ķ•„ģš”ķ•˜ģ‹ ź°€ģš”?",
},
"embed": {
commit: "ķ˜„ģž¬ 커밋",
description: "Aria IuvoėŠ” LibreTranslate넼 ģ‚¬ģš©ķ•˜ģ—¬ ė©”ģ‹œģ§€ ė²ˆģ—­ģ„ ģ œź³µķ•˜ėŠ” Discord ė“‡ģž…ė‹ˆė‹¤. NHCarriganģ“ ź°œė°œķ–ˆģŠµė‹ˆė‹¤. ė“‡ģ„ ģ‚¬ģš©ķ•˜ė ¤ė©“ ė©”ģ‹œģ§€ė„¼ 마우스 오넸쪽 ė²„ķŠ¼ģœ¼ė”œ ķ“ė¦­ķ•˜ź³  `Apps`넼 ģ„ ķƒķ•œ ė‹¤ģŒ `Translate message`넼 ģ„ ķƒķ•˜ģ„øģš”!",
title: "Aria Iuvo ģ†Œź°œ",
version: "실행 ģ¤‘ģø 버전",
},
"no-message-content": "ė©”ģ‹œģ§€ ė‚“ģš©ģ„ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤.", "no-message-content": "ė©”ģ‹œģ§€ ė‚“ģš©ģ„ ģ°¾ģ„ 수 ģ—†ģŠµė‹ˆė‹¤.",
"subscription-required": "subscription-required": "ė©”ģ‹œģ§€ė„¼ ė²ˆģ—­ķ•˜ė ¤ė©“ źµ¬ė…ģ“ ķ•„ģš”ķ•©ė‹ˆė‹¤.",
"ė©”ģ‹œģ§€ė„¼ ė²ˆģ—­ķ•˜ė ¤ė©“ źµ¬ė…ķ•“ģ•¼ ķ•©ė‹ˆė‹¤.", "translation": "{{translation}}\n-# {{confidence}}% ģ‹ ė¢°ė„ė”œ {{language}} 감지됨.",
"translation": "unsupported-locale": "ģ–øģ–“ {{target}}ėŠ” ė²ˆģ—­ ģ†Œķ”„ķŠøģ›Øģ–“ģ—ģ„œ ģ§€ģ›ė˜ģ§€ ģ•ŠģŠµė‹ˆė‹¤.",
"{{translation}}\n-# {{confidence}}% ģ‹ ė¢°ė„ė”œ {{language}} 감지.",
"unsupported-locale": "{{target}} ģ–øģ–“ėŠ” ė²ˆģ—­ ģ†Œķ”„ķŠøģ›Øģ–“ģ—ģ„œ ģ§€ģ›ė˜ģ§€ ģ•ŠģŠµė‹ˆė‹¤.",
}, },
[Locale.Lithuanian]: { [Locale.Lithuanian]: {
"no-message-content": "Nerasta jokio praneŔimo turinio.", "button": {
"subscription-required": code: "IŔeities kodas",
"Norint iŔversti žinutes, turite būti prenumeratorius.", support: "Reikia pagalbos?",
"translation": },
"{{translation}}\n-# Aptikta {{language}} su {{confidence}}% pasitikėjimu.", "embed": {
"unsupported-locale": "{{target}} kalba nepalaikoma mūsų vertimo programine įranga.", commit: "Dabartinis Commit",
description: "Aria Iuvo yra Discord botas, naudojantis LibreTranslate žinučių vertimams. Ją sukÅ«rė NHCarrigan. Norėdami naudoti botą, deÅ”iniuoju pelės klaviÅ”u spustelėkite žinutę, pasirinkite `Apps`, tada pasirinkite `Translate message`!",
title: "Apie Aria Iuvo",
version: "Veikianti Versija",
},
"no-message-content": "Žinutės turinio nerasta.",
"subscription-required": "Turite būti prenumeratorius, kad galėtumėte versti žinutes.",
"translation": "{{translation}}\n-# Aptikta {{language}} su {{confidence}}% tikimybe.",
"unsupported-locale": "Kalba {{target}} nėra palaikoma mÅ«sų vertimo programinės ÄÆrangos.",
}, },
[Locale.Polish]: { [Locale.Polish]: {
"button": {
code: "Kod Åŗródłowy",
support: "Potrzebujesz pomocy?",
},
"embed": {
commit: "Aktualny Commit",
description: "Aria Iuvo to bot Discord, który używa LibreTranslate do tłumaczenia wiadomości. Została stworzona przez NHCarrigan. Aby użyć bota, kliknij prawym przyciskiem myszy na wiadomość, wybierz `Apps`, następnie wybierz `Translate message`!",
title: "O Aria Iuvo",
version: "Aktualna Wersja",
},
"no-message-content": "Nie znaleziono treści wiadomości.", "no-message-content": "Nie znaleziono treści wiadomości.",
"subscription-required": "subscription-required": "Musisz być subskrybentem, aby tłumaczyć wiadomości.",
"Aby tłumaczyć wiadomości, musisz być subskrybentem.", "translation": "{{translation}}\n-# Wykryto {{language}} z {{confidence}}% pewnością.",
"translation": "unsupported-locale": "Język {{target}} nie jest obsługiwany przez nasze oprogramowanie do tłumaczeń.",
"{{translation}}\n-# Wykryto {{language}} z {{confidence}}% pewnością.",
"unsupported-locale": "Język {{target}} nie jest obsługiwany przez nasze oprogramowanie do tłumaczenia.",
}, },
sv: { sv: {
"button": {
code: "KƤllkod",
support: "Behƶver du hjƤlp?",
},
"embed": {
commit: "Nuvarande Commit",
description: "Aria Iuvo Ƥr en Discord-bot som anvƤnder LibreTranslate fƶr att tillhandahƄlla ƶversƤttningar av meddelanden. Hon Ƥr utvecklad av NHCarrigan. Fƶr att anvƤnda boten, hƶgerklicka pƄ ett meddelande, vƤlj `Apps`, vƤlj sedan `Translate message`!",
title: "Om Aria Iuvo",
version: "Kƶrande Version",
},
"no-message-content": "Inget meddelandeinnehƄll hittades.", "no-message-content": "Inget meddelandeinnehƄll hittades.",
"subscription-required": "subscription-required": "Du mƄste prenumerera fƶr att ƶversƤtta meddelanden.",
"Du mƄste prenumerera fƶr att ƶversƤtta meddelanden.", "translation": "{{translation}}\n-# UpptƤckte {{language}} med {{confidence}}% sƤkerhet.",
"translation":
"{{translation}}\n-# UpptƤckt {{language}} med {{confidence}}% fƶrtroende.",
"unsupported-locale": "SprƄket {{target}} stƶds inte av vƄr ƶversƤttningsprogramvara.", "unsupported-locale": "SprƄket {{target}} stƶds inte av vƄr ƶversƤttningsprogramvara.",
}, },
[Locale.Romanian]: { [Locale.Romanian]: {
"no-message-content": "Nu s-a găsit niciun conținut de mesaj.", "button": {
"subscription-required": code: "Cod sursă",
"Trebuie să fiți abonat pentru a traduce mesajele.", support: "Aveți nevoie de ajutor?",
"translation": },
"{{translation}}\n-# Detectat {{language}} cu {{confidence}}% Ʈncredere.", "embed": {
"unsupported-locale": "Limba {{target}} nu este acceptată de software-ul nostru de traducere.", commit: "Commit Curent",
description: "Aria Iuvo este un bot Discord care folosește LibreTranslate pentru a furniza traduceri pentru mesaje. Este dezvoltat de NHCarrigan. Pentru a folosi botul, faceți clic dreapta pe un mesaj, selectați `Apps`, apoi selectați `Translate message`!",
title: "Despre Aria Iuvo",
version: "Versiunea Curentă",
},
"no-message-content": "Nu s-a găsit conținutul mesajului.",
"subscription-required": "Trebuie să fiți abonat pentru a traduce mesaje.",
"translation": "{{translation}}\n-# Detectat {{language}} cu {{confidence}}% Ʈncredere.",
"unsupported-locale": "Limba {{target}} nu este suportată de software-ul nostru de traducere.",
}, },
[Locale.Russian]: { [Locale.Russian]: {
"button": {
code: "Š˜ŃŃ…Š¾Š“Š½Ń‹Š¹ коГ",
support: "ŠŃƒŠ¶Š½Š° ŠæŠ¾Š¼Š¾Ń‰ŃŒ?",
},
"embed": {
commit: "Š¢ŠµŠŗŃƒŃ‰ŠøŠ¹ ŠšŠ¾Š¼Š¼ŠøŃ‚",
description: "Aria Iuvo - ŃŃ‚Š¾ Discord бот, ŠøŃŠæŠ¾Š»ŃŒŠ·ŃƒŃŽŃ‰ŠøŠ¹ LibreTranslate Š“Š»Ń перевоГа сообщений. Разработан NHCarrigan. Чтобы ŠøŃŠæŠ¾Š»ŃŒŠ·Š¾Š²Š°Ń‚ŃŒ бота, щелкните правой кнопкой Š¼Ń‹ŃˆŠø по ŃŠ¾Š¾Š±Ń‰ŠµŠ½ŠøŃŽ, выберите `Apps`, затем выберите `Translate message`!",
title: "Šž Aria Iuvo",
version: "Š¢ŠµŠŗŃƒŃ‰Š°Ń Š’ŠµŃ€ŃŠøŃ",
},
"no-message-content": "ДоГержимое ŃŠ¾Š¾Š±Ń‰ŠµŠ½ŠøŃ не найГено.", "no-message-content": "ДоГержимое ŃŠ¾Š¾Š±Ń‰ŠµŠ½ŠøŃ не найГено.",
"subscription-required": "subscription-required": "Š”Š»Ń перевоГа сообщений необхоГима поГписка.",
"Š’Ń‹ Голжны Š±Ń‹Ń‚ŃŒ поГписаны на перевоГ сообщений.", "translation": "{{translation}}\n-# ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠµŠ½ {{language}} с ŃƒŠ²ŠµŃ€ŠµŠ½Š½Š¾ŃŃ‚ŃŒŃŽ {{confidence}}%.",
"translation":
"{{translation}}\n-# ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠµŠ½ {{language}} с {{confidence}}% ŃƒŠ²ŠµŃ€ŠµŠ½Š½Š¾ŃŃ‚ŃŒŃŽ.",
"unsupported-locale": "Язык {{target}} не ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ нашим программным обеспечением Š“Š»Ń перевоГа.", "unsupported-locale": "Язык {{target}} не ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ нашим программным обеспечением Š“Š»Ń перевоГа.",
}, },
zh: { zh: {
"button": {
code: "源代码",
support: "éœ€č¦åø®åŠ©ļ¼Ÿ",
},
"embed": {
commit: "å½“å‰ęäŗ¤",
description: "Aria Iuvoę˜Æäø€äøŖä½æē”ØLibreTranslateęä¾›ę¶ˆęÆēæ»čÆ‘ēš„Discordęœŗå™Øäŗŗć€‚ē”±NHCarriganå¼€å‘ć€‚č¦ä½æē”Øęœŗå™Øäŗŗļ¼Œå³é”®ē‚¹å‡»ę¶ˆęÆļ¼Œé€‰ę‹©`Apps`ļ¼Œē„¶åŽé€‰ę‹©`Translate message`!",
title: "å…³äŗŽAria Iuvo",
version: "čæč”Œē‰ˆęœ¬",
},
"no-message-content": "ęœŖę‰¾åˆ°ę¶ˆęÆå†…å®¹ć€‚", "no-message-content": "ęœŖę‰¾åˆ°ę¶ˆęÆå†…å®¹ć€‚",
"subscription-required": "ę‚Øåæ…é”»č®¢é˜…ä»„ēæ»čÆ‘ę¶ˆęÆć€‚", "subscription-required": "ę‚Øåæ…é”»č®¢é˜…ę‰čƒ½ēæ»čÆ‘ę¶ˆęÆć€‚",
"translation": "translation": "{{translation}}\n-# ę£€ęµ‹åˆ°{{language}},置俔度为{{confidence}}%怂",
"{{translation}}\n-# ę£€ęµ‹åˆ° {{language}},{{confidence}}% ēš„äæ”åæƒć€‚", "unsupported-locale": "ęˆ‘ä»¬ēš„ēæ»čÆ‘č½Æä»¶äøę”ÆęŒ{{target}}语言。",
"unsupported-locale": "ęˆ‘ä»¬ēš„ēæ»čÆ‘č½Æä»¶äøę”ÆęŒ {{target}} 语言。",
}, },
zt: { zt: {
"no-message-content": "ęœŖę‰¾åˆ°ę¶ˆęÆå†…å®¹ć€‚", "button": {
"subscription-required": "ę‚Øåæ…é”»č®¢é˜…ä»„ēæ»čÆ‘ę¶ˆęÆć€‚", code: "åŽŸå§‹ē¢¼",
"translation": support: "éœ€č¦å¹«åŠ©ļ¼Ÿ",
"{{translation}}\n-# ę£€ęµ‹åˆ° {{language}},{{confidence}}% ēš„äæ”åæƒć€‚", },
"unsupported-locale": "ęˆ‘ä»¬ēš„ēæ»čÆ‘č½Æä»¶äøę”ÆęŒ {{target}} 语言。", "embed": {
commit: "ē•¶å‰ęäŗ¤",
description: "Aria Iuvoę˜Æäø€å€‹ä½æē”ØLibreTranslateęä¾›čØŠęÆēæ»č­Æēš„Discordę©Ÿå™Øäŗŗć€‚ē”±NHCarrigané–‹ē™¼ć€‚č¦ä½æē”Øę©Ÿå™Øäŗŗļ¼Œå³éµé»žę“ŠčØŠęÆļ¼Œéøę“‡`Apps`ļ¼Œē„¶å¾Œéøę“‡`Translate message`!",
title: "é—œę–¼Aria Iuvo",
version: "é‹č”Œē‰ˆęœ¬",
},
"no-message-content": "ęœŖę‰¾åˆ°čØŠęÆå…§å®¹ć€‚",
"subscription-required": "ę‚Øåæ…é ˆčØ‚é–±ę‰čƒ½ēæ»č­ÆčØŠęÆć€‚",
"translation": "{{translation}}\n-# 檢測到{{language}}ļ¼Œē½®äæ”åŗ¦ē‚ŗ{{confidence}}%怂",
"unsupported-locale": "ęˆ‘å€‘ēš„ēæ»č­Æč»Ÿä»¶äøę”ÆęŒ{{target}}čŖžčØ€ć€‚",
}, },
[Locale.Thai]: { [Locale.Thai]: {
"button": {
code: "ąø‹ąø­ąø£ą¹ŒąøŖą¹‚ąø„ą¹‰ąø”",
support: "ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąø„ąø§ąø²ąø”ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­?",
},
"embed": {
commit: "ąø„ąø­ąø”ąø”ąø“ąø•ąø›ąø±ąøˆąøˆąøøąøšąø±ąø™",
description: "Aria Iuvo ą¹€ąø›ą¹‡ąø™ąøšąø­ąø— Discord ąø—ąøµą¹ˆą¹ƒąøŠą¹‰ LibreTranslate ą¹€ąøžąø·ą¹ˆąø­ą¹ąø›ąø„ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø” ąøžąø±ąø’ąø™ąø²ą¹‚ąø”ąø¢ NHCarrigan ą¹ƒąø™ąøąø²ąø£ą¹ƒąøŠą¹‰ąøšąø­ąø— ą¹ƒąø«ą¹‰ąø„ąø„ąø“ąøąø‚ąø§ąø²ąø—ąøµą¹ˆąø‚ą¹‰ąø­ąø„ąø§ąø²ąø” เคือก `Apps` ąøˆąø²ąøąø™ąø±ą¹‰ąø™ą¹€ąø„ąø·ąø­ąø `Translate message`!",
title: "ą¹€ąøąøµą¹ˆąø¢ąø§ąøąø±ąøš Aria Iuvo",
version: "ą¹€ąø§ąø­ąø£ą¹ŒąøŠąø±ąø™ąø—ąøµą¹ˆą¹ƒąøŠą¹‰ąø‡ąø²ąø™",
},
"no-message-content": "ą¹„ąø”ą¹ˆąøžąøšą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”", "no-message-content": "ą¹„ąø”ą¹ˆąøžąøšą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”",
"subscription-required": "subscription-required": "ąø„ąøøąø“ąø•ą¹‰ąø­ąø‡ą¹€ąø›ą¹‡ąø™ąøŖąø”ąø²ąøŠąø“ąøą¹€ąøžąø·ą¹ˆąø­ą¹ąø›ąø„ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”",
"ąø„ąøøąø“ąø•ą¹‰ąø­ąø‡ąøŖąø”ąø±ąø„ąø£ąøŖąø”ąø²ąøŠąø“ąøą¹€ąøžąø·ą¹ˆąø­ą¹ąø›ąø„ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”", "translation": "{{translation}}\n-# ąø•ąø£ąø§ąøˆąøžąøš {{language}} ąø”ą¹‰ąø§ąø¢ąø„ąø§ąø²ąø”ą¹€ąøŠąø·ą¹ˆąø­ąø”ąø±ą¹ˆąø™ {{confidence}}%",
"translation": "unsupported-locale": "ภาษา {{target}} ą¹„ąø”ą¹ˆąø£ąø­ąø‡ąø£ąø±ąøšą¹‚ąø”ąø¢ąø‹ąø­ąøŸąø•ą¹Œą¹ąø§ąø£ą¹Œą¹ąø›ąø„ąø ąø²ąø©ąø²ąø‚ąø­ąø‡ą¹€ąø£ąø²",
"{{translation}}\n-# ąø•ąø£ąø§ąøˆąøžąøš {{language}} ąø”ą¹‰ąø§ąø¢ąø„ąø§ąø²ąø”ąø”ąø±ą¹ˆąø™ą¹ƒąøˆ {{confidence}}%",
"unsupported-locale": "ภาษา {{target}} ą¹„ąø”ą¹ˆą¹„ąø”ą¹‰ąø£ąø±ąøšąøąø²ąø£ąøŖąø™ąø±ąøšąøŖąø™ąøøąø™ą¹‚ąø”ąø¢ąø‹ąø­ąøŸąø•ą¹Œą¹ąø§ąø£ą¹Œą¹ąø›ąø„ąø‚ąø­ąø‡ą¹€ąø£ąø²",
}, },
[Locale.Turkish]: { [Locale.Turkish]: {
"no-message-content": "Hiçbir mesaj içeriği bulunamadı.", "button": {
"subscription-required": code: "Kaynak kodu",
"Mesajları Ƨevirmek iƧin abone olmalısınız.", support: "Yardıma mı ihtiyacınız var?",
"translation": },
"{{translation}}\n-# {{confidence}}% güvenle {{language}} tespit edildi.", "embed": {
"unsupported-locale": "{{target}} dilimiz tarafından desteklenmiyor.", commit: "Mevcut Commit",
description: "Aria Iuvo, mesajlar için çeviri sağlamak üzere LibreTranslate kullanan bir Discord botudur. NHCarrigan tarafından geliştirilmiştir. Botu kullanmak için, bir mesaja sağ tıklayın, `Apps`'i seçin, ardından `Translate message`'ı seçin!",
title: "Aria Iuvo Hakkında",
version: "Ƈalışan Sürüm",
},
"no-message-content": "Mesaj içeriği bulunamadı.",
"subscription-required": "Mesajları Ƨevirmek iƧin abone olmanız gerekiyor.",
"translation": "{{translation}}\n-# {{confidence}}% güvenle {{language}} tespit edildi.",
"unsupported-locale": "{{target}} dili Ƨeviri yazılımımız tarafından desteklenmiyor.",
}, },
[Locale.Ukrainian]: { [Locale.Ukrainian]: {
"no-message-content": "ŠŠµ знайГено Š²Š¼Ń–ŃŃ‚Ńƒ ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŠµŠ½Š½Ń.", "button": {
"subscription-required": code: "ВихіГний коГ",
"Š’Šø повинні ŠæŃ–Š“ŠæŠøŃŠ°Ń‚ŠøŃŃ на переклаГ ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŠµŠ½ŃŒ.", support: "ŠŸŠ¾Ń‚Ń€Ń–Š±Š½Š° Гопомога?",
"translation": },
"{{translation}}\n-# Š’ŠøŃŠ²Š»ŠµŠ½Š¾ {{language}} Š· {{confidence}}% Š²ŠæŠµŠ²Š½ŠµŠ½Ń–ŃŃ‚ŃŽ.", "embed": {
commit: "ŠŸŠ¾Ń‚Š¾Ń‡Š½ŠøŠ¹ ŠšŠ¾Š¼Ń–Ń‚",
description: "Aria Iuvo - це Discord бот, ŃŠŗŠøŠ¹ Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŃ” LibreTranslate Š“Š»Ń ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŠµŠ½ŃŒ. Розроблений NHCarrigan. Щоб Š²ŠøŠŗŠ¾Ń€ŠøŃŃ‚Š¾Š²ŃƒŠ²Š°Ń‚Šø бота, ŠŗŠ»Š°Ń†Š½Ń–Ń‚ŃŒ ŠæŃ€Š°Š²Š¾ŃŽ ŠŗŠ½Š¾ŠæŠŗŠ¾ŃŽ Š¼ŠøŃˆŃ– на повіГомленні, Š²ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ `Apps`, потім Š²ŠøŠ±ŠµŃ€Ń–Ń‚ŃŒ `Translate message`!",
title: "ŠŸŃ€Š¾ Aria Iuvo",
version: "ŠŸŠ¾Ń‚Š¾Ń‡Š½Š° Š’ŠµŃ€ŃŃ–Ń",
},
"no-message-content": "Вміст ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŠµŠ½Š½Ń не знайГено.",
"subscription-required": "Š”Š»Ń ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ ŠæŠ¾Š²Ń–Š“Š¾Š¼Š»ŠµŠ½ŃŒ потрібна піГписка.",
"translation": "{{translation}}\n-# Š’ŠøŃŠ²Š»ŠµŠ½Š¾ {{language}} Š· Š²ŠæŠµŠ²Š½ŠµŠ½Ń–ŃŃ‚ŃŽ {{confidence}}%.",
"unsupported-locale": "Мова {{target}} не ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ”Ń‚ŃŒŃŃ нашим програмним Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŠµŠ½Š½ŃŠ¼ Š“Š»Ń ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ.", "unsupported-locale": "Мова {{target}} не ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ”Ń‚ŃŒŃŃ нашим програмним Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŠµŠ½Š½ŃŠ¼ Š“Š»Ń ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ.",
}, },
}; };
+4
View File
@@ -4,6 +4,7 @@
* @author Naomi Carrigan * @author Naomi Carrigan
*/ */
import { Client, Events } from "discord.js"; import { Client, Events } from "discord.js";
import { about } from "./modules/about.js";
import { translate } from "./modules/translate.js"; import { translate } from "./modules/translate.js";
import { instantiateServer } from "./server/serve.js"; import { instantiateServer } from "./server/serve.js";
import { logHandler } from "./utils/logHandler.js"; import { logHandler } from "./utils/logHandler.js";
@@ -16,6 +17,9 @@ client.on(Events.InteractionCreate, (interaction) => {
if (interaction.isMessageContextMenuCommand()) { if (interaction.isMessageContextMenuCommand()) {
void translate(interaction); void translate(interaction);
} }
if (interaction.isChatInputCommand()) {
void about(interaction);
}
}); });
client.on(Events.ClientReady, () => { client.on(Events.ClientReady, () => {
+67
View File
@@ -0,0 +1,67 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { execSync } from "node:child_process";
import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
EmbedBuilder,
MessageFlags,
type ChatInputCommandInteraction,
} from "discord.js";
import { i18n } from "../utils/i18n.js";
import { getLocale } from "./getLocale.js";
/**
* Responds with information about the bot.
* @param interaction -- The interaction payload from Discord.
*/
export const about
= async(interaction: ChatInputCommandInteraction): Promise<void> => {
await interaction.deferReply({ flags: [ MessageFlags.Ephemeral ] });
const targetLocale = getLocale(interaction);
const version = process.env.npm_package_version ?? "Unknown";
const commit = execSync("git rev-parse --short HEAD").toString().
trim();
const embed = new EmbedBuilder();
embed.setTitle(i18n("embed.title", targetLocale));
embed.setDescription(i18n("embed.description", targetLocale));
embed.addFields(
{
name: i18n("embed.version", targetLocale),
value: version,
},
{
name: i18n("embed.commit", targetLocale),
value: commit,
},
);
const supportButton = new ButtonBuilder().
setLabel(i18n("button.support", targetLocale)).
setStyle(ButtonStyle.Link).
setURL("https://chat.nhcarrigan.com");
const sourceButton = new ButtonBuilder().
setLabel(i18n("button.code", targetLocale)).
setStyle(ButtonStyle.Link).
setURL("https://git.nhcarrigan.com/nhcarrigan/aria-iuvo");
const subscribeButton = new ButtonBuilder().
setStyle(ButtonStyle.Premium).
setSKUId("1338596712121499669");
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
supportButton,
sourceButton,
subscribeButton,
);
await interaction.editReply({
components: [ row ],
embeds: [ embed ],
});
};
+2 -2
View File
@@ -5,7 +5,7 @@
*/ */
import { mappedLocales } from "../config/locales.js"; import { mappedLocales } from "../config/locales.js";
import type { MessageContextMenuCommandInteraction } from "discord.js"; import type { CommandInteraction } from "discord.js";
/** /**
* Parses the locale from the interaction, using our mapped * Parses the locale from the interaction, using our mapped
@@ -14,7 +14,7 @@ import type { MessageContextMenuCommandInteraction } from "discord.js";
* @returns The locale string. * @returns The locale string.
*/ */
export const getLocale = ( export const getLocale = (
interaction: MessageContextMenuCommandInteraction, interaction: CommandInteraction,
): string => { ): string => {
if (mappedLocales[interaction.locale] !== undefined) { if (mappedLocales[interaction.locale] !== undefined) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- It's not undefined. // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- It's not undefined.
+10
View File
@@ -5,6 +5,9 @@
*/ */
import { import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
MessageFlags, MessageFlags,
type MessageContextMenuCommandInteraction, type MessageContextMenuCommandInteraction,
} from "discord.js"; } from "discord.js";
@@ -28,7 +31,14 @@ export const translate = async(
}); });
if (!isEntitled && interaction.user.id !== "465650873650118659") { if (!isEntitled && interaction.user.id !== "465650873650118659") {
const subscribeButton = new ButtonBuilder().
setStyle(ButtonStyle.Premium).
setSKUId("1338596712121499669");
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
subscribeButton,
);
await interaction.editReply({ await interaction.editReply({
components: [ row ],
content: i18n("subscription-required", targetLocale), content: i18n("subscription-required", targetLocale),
}); });
return; return;
+39 -6
View File
@@ -3,25 +3,58 @@
* @license Naomi's Public License * @license Naomi's Public License
* @author Naomi Carrigan * @author Naomi Carrigan
*/ */
/* eslint-disable @typescript-eslint/no-non-null-assertion -- We've already asserted the language exists through our typeguard.*/
/* eslint-disable unicorn/no-array-reduce -- It's a clean approach here and makes sense. */
/* eslint-disable @typescript-eslint/consistent-type-assertions -- We have likely over-engineered the hell out of this...*/
import { responses } from "../i18n/responses.js"; import { responses } from "../i18n/responses.js";
const isTranslatedLocale = (
locale: string,
): locale is keyof typeof responses => {
return locale in responses;
};
/** /**
* Translates a key to the specified locale, performing * Translates a key to the specified locale, performing
* interpolation on the string. * interpolation on the string.
* @param key -- The key to translate. * @param key -- The key to translate.
* @param locale -- The user's locale. * @param rawLocale -- The user's locale.
* @param interpolation -- An object of keys to replace with values. * @param interpolation -- An object of keys to replace with values.
* @returns The translated string. * @returns The translated string.
*/ */
export const i18n = ( export const i18n = (
key: keyof (typeof responses)["en"], key:
locale: string, | keyof (typeof responses)["en"]
| `embed.${keyof (typeof responses)["en"]["embed"]}`
| `button.${keyof (typeof responses)["en"]["button"]}`,
rawLocale: string,
interpolation: Record<string, unknown> = {}, interpolation: Record<string, unknown> = {},
): string => { ): string => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- We know the en key exists, but having the loose type helps. const locale: keyof typeof responses = isTranslatedLocale(rawLocale)
const string = responses[locale]?.[key] ?? responses.en![key]; ? rawLocale
// eslint-disable-next-line unicorn/no-array-reduce -- This is the cleanest way to do it, really. : "en";
const isNestedProperty = key.startsWith("embed.")
|| key.startsWith("button.");
if (isNestedProperty) {
const [ category, property ] = key.split(".") as
| ["embed", keyof (typeof responses)["en"]["embed"]]
| ["button", keyof (typeof responses)["en"]["button"]];
if (category === "embed") {
const string = responses[locale]![category][property];
return Object.entries(interpolation).reduce((accumulator, [ k, v ]) => {
return accumulator.replace(`{{${k}}}`, String(v));
}, string);
}
const string = responses[locale]![category][property];
return Object.entries(interpolation).reduce((accumulator, [ k, v ]) => {
return accumulator.replace(`{{${k}}}`, String(v));
}, string);
}
const string
= responses[locale]![
key as Exclude<keyof (typeof responses)["en"], "embed" | "button">
];
return Object.entries(interpolation).reduce((accumulator, [ k, v ]) => { return Object.entries(interpolation).reduce((accumulator, [ k, v ]) => {
return accumulator.replace(`{{${k}}}`, String(v)); return accumulator.replace(`{{${k}}}`, String(v));
}, string); }, string);
+65 -7
View File
@@ -7,16 +7,74 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { supportedLocales, mappedLocales } from "../src/config/locales.js"; import { supportedLocales, mappedLocales } from "../src/config/locales.js";
const localesSupportedByLibretranslate = [ "ar", "az", "bg", "bn", "ca", "cs", "da", "de", "el", "en", "eo", "es", "et", "eu", "fa", "fi", "fr", "ga", "gl", "he", "hi", "hu", "id", "it", "ja", "ko", "lt", "lv", "ms", "nb", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sq", "sv", "th", "tl", "tr", "uk", "ur", "zh", "zt" ]; const localesSupportedByLibretranslate = [
"ar",
"az",
"bg",
"bn",
"ca",
"cs",
"da",
"de",
"el",
"en",
"eo",
"es",
"et",
"eu",
"fa",
"fi",
"fr",
"ga",
"gl",
"he",
"hi",
"hu",
"id",
"it",
"ja",
"ko",
"lt",
"lv",
"ms",
"nb",
"nl",
"pl",
"pt",
"ro",
"ru",
"sk",
"sl",
"sq",
"sv",
"th",
"tl",
"tr",
"uk",
"ur",
"zh",
"zt",
];
describe("i18n locales", () => { describe("i18n locales", () => {
it.each(supportedLocales)("%s should be supported by libretranslate", (lang) => { it.each(supportedLocales)(
"%s should be supported by libretranslate",
(lang) => {
expect.assertions(1); expect.assertions(1);
expect(localesSupportedByLibretranslate, `${lang} is not supported by libretranslate`).toContain(lang); expect(
}); localesSupportedByLibretranslate,
`${lang} is not supported by libretranslate`,
).toContain(lang);
},
);
it.each(Object.values(mappedLocales))("%s should be mapped to a supported locale", (lang) => { it.each(Object.values(mappedLocales))(
"%s should be mapped to a supported locale",
(lang) => {
expect.assertions(1); expect.assertions(1);
expect(supportedLocales, `${lang} is not supported by our app`).toContain(lang); expect(supportedLocales, `${lang} is not supported by our app`).toContain(
}); lang,
);
},
);
}); });