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()));
+361 -148
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": {
"unsupported-locale": "Bahasa {{target}} tidak didukung oleh perangkat lunak terjemahan kami.", 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.",
}, },
es: { es: {
"no-message-content": "No se encontró contenido del mensaje.", "button": {
"subscription-required": code: "Código fuente",
"Debes estar suscrito para traducir mensajes.", support: "ĀæNecesitas ayuda?",
"translation": },
"{{translation}}\n-# Detectado {{language}} con {{confidence}}% de confianza.", "embed": {
"unsupported-locale": "El idioma {{target}} no es compatible con nuestro software de traducción.", 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.",
"subscription-required": "Debes estar suscrito para traducir mensajes.",
"translation": "{{translation}}\n-# Detectado {{language}} con {{confidence}}% de confianza.",
"unsupported-locale": "El idioma {{target}} no es compatible con nuestro software de traducción.",
}, },
pt: { pt: {
"no-message-content": "Nenhum conteĆŗdo de mensagem encontrado.", "button": {
"subscription-required": code: "Código fonte",
"VocĆŖ deve estar inscrito para traduzir mensagens.", support: "Precisa de ajuda?",
"translation": },
"{{translation}}\n-# Detectado {{language}} com {{confidence}}% de confianƧa.", "embed": {
"unsupported-locale": "O idioma {{target}} não é suportado pelo nosso software de tradução.", 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.",
"subscription-required": "VocĆŖ precisa ser assinante para traduzir mensagens.",
"translation": "{{translation}}\n-# Detectado {{language}} com {{confidence}}% de confianƧa.",
"unsupported-locale": "O idioma {{target}} não é suportado pelo nosso software de tradução.",
}, },
[Locale.Czech]: { [Locale.Czech]: {
"no-message-content": "Nebyl nalezen žÔdný obsah zprÔvy.", "button": {
"subscription-required": code: "Zdrojový kód",
"MusĆ­te být přihlÔŔeni k překladu zprĆ”v.", support: "Potřebujete pomoc?",
"translation": },
"{{translation}}\n-# DetekovĆ”no {{language}} s dÅÆvěrou {{confidence}}%.", "embed": {
"unsupported-locale": "Jazyk {{target}} nenĆ­ podporovĆ”n naŔím překladovým softwarem.", 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.",
"subscription-required": "Pro překlĆ”dĆ”nĆ­ zprĆ”v musĆ­te mĆ­t předplatnĆ©.",
"translation": "{{translation}}\n-# DetekovƔn jazyk {{language}} s {{confidence}}% jistotou.",
"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": {
"unsupported-locale": "Sproget {{target}} understøttes ikke af vores oversættelsessoftware.", 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.",
}, },
[Locale.Dutch]: { [Locale.Dutch]: {
"no-message-content": "Geen berichtinhoud gevonden.", "button": {
"subscription-required": code: "Broncode",
"U moet zijn geabonneerd om berichten te vertalen.", support: "Hulp nodig?",
"translation": },
"{{translation}}\n-# Gedetecteerd {{language}} met {{confidence}}% vertrouwen.", "embed": {
"unsupported-locale": "Taal {{target}} wordt niet ondersteund door onze vertaalsoftware.", 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.",
"subscription-required": "Je moet geabonneerd zijn om berichten te vertalen.",
"translation": "{{translation}}\n-# Gedetecteerd {{language}} met {{confidence}}% zekerheid.",
"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]: {
"no-message-content": "Aucun contenu de message trouvƩ.", "button": {
"subscription-required": code: "Code source",
"Vous devez être abonné pour traduire les messages.", support: "Besoin d'aide ?",
"translation": },
"{{translation}}\n-# DƩtectƩ {{language}} avec {{confidence}}% de confiance.", "embed": {
"unsupported-locale": "La langue {{target}} n'est pas prise en charge par notre logiciel de traduction.", 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Ʃ.",
"subscription-required": "Vous devez être abonné pour traduire les messages.",
"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.",
}, },
[Locale.German]: { [Locale.German]: {
"no-message-content": "Kein Nachrichteninhalt gefunden.", "button": {
"subscription-required": code: "Quellcode",
"Sie müssen abonniert sein, um Nachrichten zu übersetzen.", support: "Hilfe benötigt?",
"translation": },
"{{translation}}\n-# Erkannt {{language}} mit {{confidence}}% Vertrauen.", "embed": {
"unsupported-locale": "Die Sprache {{target}} wird von unserer Übersetzungssoftware nicht unterstützt.", 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.",
"subscription-required": "Sie müssen abonniert sein, um Nachrichten zu übersetzen.",
"translation": "{{translation}}\n-# Erkannt {{language}} mit {{confidence}}% Sicherheit.",
"unsupported-locale": "Die Sprache {{target}} wird von unserer Übersetzungssoftware nicht unterstützt.",
}, },
[Locale.Greek]: { [Locale.Greek]: {
"no-message-content": "Δεν βρέθηκε Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„ĪæĻ‚.", "button": {
"subscription-required": code: "Πηγαίος ĪŗĻŽĪ“Ī¹ĪŗĪ±Ļ‚",
"Πρέπει να ĪµĪÆĻƒĻ„Īµ ĻƒĻ…Ī½Ī“ĻĪæĪ¼Ī·Ļ„Ī®Ļ‚ για να Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĻ„Īµ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„Ī±.", support: "Ī§ĻĪµĪ¹Ī¬Ī¶ĪµĻƒĻ„Īµ βοήθεια;",
"translation": },
"{{translation}}\n-# Ī‘Ī½Ī¹Ļ‡Ī½ĪµĻĪøĪ·ĪŗĪµ {{language}} με {{confidence}}% ĪµĪ¼Ļ€Ī¹ĻƒĻ„ĪæĻƒĻĪ½Ī·.", "embed": {
"unsupported-locale": "Ī— Ī³Ī»ĻŽĻƒĻƒĪ± {{target}} Γεν Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¶ĪµĻ„Ī±Ī¹ Ī±Ļ€ĻŒ το λογισμικό Ī¼ĪµĻ„Ī¬Ļ†ĻĪ±ĻƒĪ®Ļ‚ μας.", commit: "Τρέχον Commit",
description: "Ī— Aria Iuvo είναι ένα bot Discord που Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹ĪµĪÆ το LibreTranslate για να παρέχει Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĪ¹Ļ‚ μηνυμάτων. Ī‘Ī½Ī±Ļ€Ļ„ĻĻ‡ĪøĪ·ĪŗĪµ Ī±Ļ€ĻŒ τον NHCarrigan. Για να Ļ‡ĻĪ·ĻƒĪ¹Ī¼ĪæĻ€ĪæĪ¹Ī®ĻƒĪµĻ„Īµ το bot, κάντε Γεξί κλικ σε ένα μήνυμα, επιλέξτε `Apps`, ĻƒĻ„Ī· ĻƒĻ…Ī½Ī­Ļ‡ĪµĪ¹Ī± επιλέξτε `Translate message`!",
title: "Σχετικά με την Aria Iuvo",
version: "Ī¤ĻĪ­Ļ‡ĪæĻ…ĻƒĪ± ΈκΓοση",
},
"no-message-content": "Δεν βρέθηκε Ļ€ĪµĻĪ¹ĪµĻ‡ĻŒĪ¼ĪµĪ½Īæ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„ĪæĻ‚.",
"subscription-required": "Πρέπει να ĪµĪÆĻƒĻ„Īµ ĻƒĻ…Ī½Ī“ĻĪæĪ¼Ī·Ļ„Ī®Ļ‚ για να Ī¼ĪµĻ„Ī±Ļ†ĻĪ¬ĻƒĪµĻ„Īµ Ī¼Ī·Ī½ĻĪ¼Ī±Ļ„Ī±.",
"translation": "{{translation}}\n-# Ī•Ī½Ļ„ĪæĻ€ĪÆĻƒĻ„Ī·ĪŗĪµ {{language}} με {{confidence}}% Ī²ĪµĪ²Ī±Ī¹ĻŒĻ„Ī·Ļ„Ī±.",
"unsupported-locale": "Ī— Ī³Ī»ĻŽĻƒĻƒĪ± {{target}} Γεν Ļ…Ļ€ĪæĻƒĻ„Ī·ĻĪÆĪ¶ĪµĻ„Ī±Ī¹ Ī±Ļ€ĻŒ το λογισμικό Ī¼ĪµĻ„Ī¬Ļ†ĻĪ±ĻƒĪ®Ļ‚ μας.",
}, },
[Locale.Hindi]: { [Locale.Hindi]: {
"no-message-content": "ą¤•ą„‹ą¤ˆ ą¤øą¤‚ą¤¦ą„‡ą¤¶ ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤Øą¤¹ą„€ą¤‚ ą¤®ą¤æą¤²ą„€ą„¤", "button": {
"subscription-required": code: "ą¤øą„‹ą¤°ą„ą¤ø ą¤•ą„‹ą¤”",
"ą¤†ą¤Ŗą¤•ą„‹ ą¤øą¤‚ą¤¦ą„‡ą¤¶ ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤øą¤¬ą„ą¤øą¤•ą„ą¤°ą¤¾ą¤‡ą¤¬ करना ą¤¹ą„‹ą¤—ą¤¾ą„¤", support: "मदद ą¤šą¤¾ą¤¹ą¤æą¤?",
"translation": },
"{{translation}}\n-# {{confidence}}% ą¤µą¤æą¤¶ą„ą¤µą¤¾ą¤ø ą¤•ą„‡ साऄ {{language}} का पता लगाया ą¤—ą¤Æą¤¾ą„¤", "embed": {
"unsupported-locale": "ą¤¹ą¤®ą¤¾ą¤°ą„‡ ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤øą„‰ą¤«ą¤¼ą„ą¤Ÿą¤µą„‡ą¤Æą¤° ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ {{target}} भाषा का ą¤øą¤®ą¤°ą„ą¤„ą¤Ø ą¤Øą¤¹ą„€ą¤‚ किया जाता ą¤¹ą„ˆą„¤", commit: "ą¤µą¤°ą„ą¤¤ą¤®ą¤¾ą¤Ø ą¤•ą¤®ą¤æą¤Ÿ",
description: "Aria Iuvo ą¤ą¤• Discord ą¤¬ą„‰ą¤Ÿ ą¤¹ą„ˆ ą¤œą„‹ ą¤øą¤‚ą¤¦ą„‡ą¤¶ą„‹ą¤‚ ą¤•ą„‡ ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤•ą„‡ ą¤²ą¤æą¤ LibreTranslate का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤¤ą„€ ą¤¹ą„ˆą„¤ ą¤‡ą¤øą„‡ NHCarrigan ą¤¦ą„ą¤µą¤¾ą¤°ą¤¾ विकसित किया गया ą¤¹ą„ˆą„¤ ą¤¬ą„‰ą¤Ÿ का ą¤‰ą¤Ŗą¤Æą„‹ą¤— ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤, ą¤•ą¤æą¤øą„€ ą¤øą¤‚ą¤¦ą„‡ą¤¶ पर ą¤°ą¤¾ą¤‡ą¤Ÿ ą¤•ą„ą¤²ą¤æą¤• ą¤•ą¤°ą„‡ą¤‚, `Apps` ą¤šą„ą¤Øą„‡ą¤‚, फिर `Translate message` ą¤šą„ą¤Øą„‡ą¤‚!",
title: "Aria Iuvo ą¤•ą„‡ ą¤¬ą¤¾ą¤°ą„‡ ą¤®ą„‡ą¤‚",
version: "चल रहा ą¤øą¤‚ą¤øą„ą¤•ą¤°ą¤£",
},
"no-message-content": "ą¤•ą„‹ą¤ˆ ą¤øą¤‚ą¤¦ą„‡ą¤¶ ą¤øą¤¾ą¤®ą¤—ą„ą¤°ą„€ ą¤Øą¤¹ą„€ą¤‚ ą¤®ą¤æą¤²ą„€ą„¤",
"subscription-required": "ą¤øą¤‚ą¤¦ą„‡ą¤¶ą„‹ą¤‚ का ą¤…ą¤Øą„ą¤µą¤¾ą¤¦ ą¤•ą¤°ą¤Øą„‡ ą¤•ą„‡ ą¤²ą¤æą¤ ą¤†ą¤Ŗą¤•ą„‹ ą¤øą¤¦ą¤øą„ą¤Æą¤¤ą¤¾ ą¤²ą„‡ą¤Øą„€ ą¤¹ą„‹ą¤—ą„€ą„¤",
"translation": "{{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]: {
"no-message-content": "Nessun contenuto del messaggio trovato.", "button": {
"subscription-required": code: "Codice sorgente",
"Devi essere abbonato per tradurre i messaggi.", support: "Hai bisogno di aiuto?",
"translation": },
"{{translation}}\n-# Rilevato {{language}} con {{confidence}}% di fiducia.", "embed": {
"unsupported-locale": "La lingua {{target}} non ĆØ supportata dal nostro software di traduzione.", 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.",
"subscription-required": "Devi essere abbonato per tradurre i messaggi.",
"translation": "{{translation}}\n-# Rilevato {{language}} con {{confidence}}% di affidabilitĆ .",
"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]: {
"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.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]: {
"no-message-content": "Nie znaleziono treści wiadomości.", "button": {
"subscription-required": code: "Kod Åŗródłowy",
"Aby tłumaczyć wiadomości, musisz być subskrybentem.", support: "Potrzebujesz pomocy?",
"translation": },
"{{translation}}\n-# Wykryto {{language}} z {{confidence}}% pewnością.", "embed": {
"unsupported-locale": "Język {{target}} nie jest obsługiwany przez nasze oprogramowanie do tłumaczenia.", 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.",
"subscription-required": "Musisz być subskrybentem, aby tłumaczyć wiadomości.",
"translation": "{{translation}}\n-# Wykryto {{language}} z {{confidence}}% pewnością.",
"unsupported-locale": "Język {{target}} nie jest obsługiwany przez nasze oprogramowanie do tłumaczeń.",
}, },
sv: { sv: {
"no-message-content": "Inget meddelandeinnehƄll hittades.", "button": {
"subscription-required": code: "KƤllkod",
"Du mƄste prenumerera fƶr att ƶversƤtta meddelanden.", support: "Behƶver du hjƤlp?",
"translation": },
"{{translation}}\n-# UpptƤckt {{language}} med {{confidence}}% fƶrtroende.", "embed": {
"unsupported-locale": "SprƄket {{target}} stƶds inte av vƄr ƶversƤttningsprogramvara.", 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.",
"subscription-required": "Du mƄste prenumerera fƶr att ƶversƤtta meddelanden.",
"translation": "{{translation}}\n-# UpptƤckte {{language}} med {{confidence}}% sƤkerhet.",
"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]: {
"no-message-content": "ДоГержимое ŃŠ¾Š¾Š±Ń‰ŠµŠ½ŠøŃ не найГено.", "button": {
"subscription-required": code: "Š˜ŃŃ…Š¾Š“Š½Ń‹Š¹ коГ",
"Š’Ń‹ Голжны Š±Ń‹Ń‚ŃŒ поГписаны на перевоГ сообщений.", support: "ŠŃƒŠ¶Š½Š° ŠæŠ¾Š¼Š¾Ń‰ŃŒ?",
"translation": },
"{{translation}}\n-# ŠžŠ±Š½Š°Ń€ŃƒŠ¶ŠµŠ½ {{language}} с {{confidence}}% ŃƒŠ²ŠµŃ€ŠµŠ½Š½Š¾ŃŃ‚ŃŒŃŽ.", "embed": {
"unsupported-locale": "Язык {{target}} не ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ нашим программным обеспечением Š“Š»Ń перевоГа.", 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}} не ŠæŠ¾Š“Š“ŠµŃ€Š¶ŠøŠ²Š°ŠµŃ‚ŃŃ нашим программным обеспечением Š“Š»Ń перевоГа.",
}, },
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]: {
"no-message-content": "ą¹„ąø”ą¹ˆąøžąøšą¹€ąø™ąø·ą¹‰ąø­ąø«ąø²ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”", "button": {
"subscription-required": code: "ąø‹ąø­ąø£ą¹ŒąøŖą¹‚ąø„ą¹‰ąø”",
"ąø„ąøøąø“ąø•ą¹‰ąø­ąø‡ąøŖąø”ąø±ąø„ąø£ąøŖąø”ąø²ąøŠąø“ąøą¹€ąøžąø·ą¹ˆąø­ą¹ąø›ąø„ąø‚ą¹‰ąø­ąø„ąø§ąø²ąø”", support: "ąø•ą¹‰ąø­ąø‡ąøąø²ąø£ąø„ąø§ąø²ąø”ąøŠą¹ˆąø§ąø¢ą¹€ąø«ąø„ąø·ąø­?",
"translation": },
"{{translation}}\n-# ąø•ąø£ąø§ąøˆąøžąøš {{language}} ąø”ą¹‰ąø§ąø¢ąø„ąø§ąø²ąø”ąø”ąø±ą¹ˆąø™ą¹ƒąøˆ {{confidence}}%", "embed": {
"unsupported-locale": "ภาษา {{target}} ą¹„ąø”ą¹ˆą¹„ąø”ą¹‰ąø£ąø±ąøšąøąø²ąø£ąøŖąø™ąø±ąøšąøŖąø™ąøøąø™ą¹‚ąø”ąø¢ąø‹ąø­ąøŸąø•ą¹Œą¹ąø§ąø£ą¹Œą¹ąø›ąø„ąø‚ąø­ąø‡ą¹€ąø£ąø²", 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}} ą¹„ąø”ą¹ˆąø£ąø­ąø‡ąø£ąø±ąøšą¹‚ąø”ąø¢ąø‹ąø­ąøŸąø•ą¹Œą¹ąø§ąø£ą¹Œą¹ąø›ąø„ąø ąø²ąø©ąø²ąø‚ąø­ąø‡ą¹€ąø£ąø²",
}, },
[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": {
"unsupported-locale": "Мова {{target}} не ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ”Ń‚ŃŒŃŃ нашим програмним Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŠµŠ½Š½ŃŠ¼ Š“Š»Ń ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ.", 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}} не ŠæŃ–Š“Ń‚Ń€ŠøŠ¼ŃƒŃ”Ń‚ŃŒŃŃ нашим програмним Š·Š°Š±ŠµŠ·ŠæŠµŃ‡ŠµŠ½Š½ŃŠ¼ Š“Š»Ń ŠæŠµŃ€ŠµŠŗŠ»Š°Š“Ńƒ.",
}, },
}; };
+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.
+11 -1
View File
@@ -5,6 +5,9 @@
*/ */
import { import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
MessageFlags, MessageFlags,
type MessageContextMenuCommandInteraction, type MessageContextMenuCommandInteraction,
} from "discord.js"; } from "discord.js";
@@ -28,8 +31,15 @@ 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({
content: i18n("subscription-required", targetLocale), components: [ row ],
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);
+67 -9
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)(
expect.assertions(1); "%s should be supported by libretranslate",
expect(localesSupportedByLibretranslate, `${lang} is not supported by libretranslate`).toContain(lang); (lang) => {
}); expect.assertions(1);
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))(
expect.assertions(1); "%s should be mapped to a supported locale",
expect(supportedLocales, `${lang} is not supported by our app`).toContain(lang); (lang) => {
}); expect.assertions(1);
expect(supportedLocales, `${lang} is not supported by our app`).toContain(
lang,
);
},
);
}); });