Add provider arg to /translate command

7f2cf6f7e6afcfdcbb7ec4da5408559b837de243

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +33 -7Showing whitespace changes
public/scripts/extensions/translate/index.html+1 -1
@@ -15,7 +15,7 @@
1515 <label data-i18n="ext_translate_mode_provider" for="translation_provider">Provider</label>
1616 <div class="flex-container gap5px flexnowrap marginBot5">
1717 <select id="translation_provider" name="provider" class="margin0">
1818 <option value="libre">LibreLibreTranslate</option>
1919 <option value="google">Google</option>
2020 <option value="lingva">Lingva</option>
2121 <option value="deepl">DeepL</option>
public/scripts/extensions/translate/index.js+32 -6
@@ -14,6 +14,8 @@ import { POPUP_RESULT, POPUP_TYPE, callGenericPopup } from '../../popup.js';
1414import { findSecret, secret_state, writeSecret } from '../../secrets.js';
1515import { SlashCommand } from '../../slash-commands/SlashCommand.js';
1616import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
17+import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
18+import { enumTypes, SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js';
1719import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
1820import { splitRecursive } from '../../utils.js';
1921
@@ -395,9 +397,10 @@ async function chunkedTranslate(text, lang, translateFn, chunkSize = 5000) {
395397 * Translates text using the selected translation provider
396398 * @param {string} text Text to translate
397399 * @param {string} lang Target language code
400+ * @param {string} provider Translation provider to use
398401 * @returns {Promise<string>} Translated text
399402 */
400403async function translate(text, lang, provider = null) {
401404 try {
402405 if (text == '') {
403406 return '';
@@ -407,13 +410,17 @@ async function translate(text, lang) {
407410 lang = extension_settings.translate.target_language;
408411 }
409412
413+ if (!provider) {
414+ provider = extension_settings.translate.provider;
415+ }
416+
410417 // split text by embedded images links
411418 const chunks = text.split(/!\[.*?]\([^)]*\)/);
412419 const links = [...text.matchAll(/!\[.*?]\([^)]*\)/g)];
413420
414421 let result = '';
415422 for (let i = 0; i < chunks.length; i++) {
416423 result += await translateInner(chunks[i], lang, provider);
417424 if (i < links.length) result += links[i][0];
418425 }
419426
@@ -424,11 +431,21 @@ async function translate(text, lang) {
424431 }
425432}
426433
427-async function translateInner(text, lang) {
434+/**
435+ * Common translation function that handles the translation logic
436+ * @param {string} text Text to translate
437+ * @param {string} lang Target language code
438+ * @param {string} provider Translation provider to use
439+ * @returns {Promise<string>} Translated text
440+ */
441+async function translateInner(text, lang, provider) {
428442 if (text == '') {
429443 return '';
430444 }
431445 switchif (extension_settings.translate.!provider) {
446+ provider = extension_settings.translate.provider;
447+ }
448+ switch (provider) {
432449 case 'libre':
433450 return await translateProviderLibre(text, lang);
434451 case 'google':
@@ -446,7 +463,7 @@ async function translateInner(text, lang) {
446463 case 'yandex':
447464 return await translateProviderYandex(text, lang);
448465 default:
449466 console.error('Unknown translation provider', extension_settings.translate.provider);
450467 return text;
451468 }
452469}
@@ -688,6 +705,14 @@ jQuery(async () => {
688705 helpString: 'Translate text to a target language. If target language is not provided, the value from the extension settings will be used.',
689706 namedArgumentList: [
690707 new SlashCommandNamedArgument('target', 'The target language code to translate to', ARGUMENT_TYPE.STRING, false, false, '', Object.values(languageCodes)),
708+ SlashCommandNamedArgument.fromProps({
709+ name: 'provider',
710+ description: 'The translation provider to use. If not provided, the value from the extension settings will be used.',
711+ typeList: [ARGUMENT_TYPE.STRING],
712+ isRequired: false,
713+ acceptsMultiple: false,
714+ enumProvider: () => Array.from(document.getElementById('translation_provider').querySelectorAll('option')).map((option) => new SlashCommandEnumValue(option.value, option.text, enumTypes.name, enumIcons.server)),
715+ }),
691716 ],
692717 unnamedArgumentList: [
693718 new SlashCommandArgument('The text to translate', ARGUMENT_TYPE.STRING, true, false, ''),
@@ -696,7 +721,8 @@ jQuery(async () => {
696721 const target = args?.target && Object.values(languageCodes).includes(String(args.target))
697722 ? String(args.target)
698723 : extension_settings.translate.target_language;
699- return await translate(String(value), target);
724+ const provider = args?.provider || extension_settings.translate.provider;
725+ return await translate(String(value), target, provider);
700726 },
701727 returns: ARGUMENT_TYPE.STRING,
702728 }));