Add provider arg to /translate command
| @@ -15,7 +15,7 @@ | |||
| 15 | <label data-i18n="ext_translate_mode_provider" for="translation_provider">Provider</label> | 15 | <label data-i18n="ext_translate_mode_provider" for="translation_provider">Provider</label> |
| 16 | <div class="flex-container gap5px flexnowrap marginBot5"> | 16 | <div class="flex-container gap5px flexnowrap marginBot5"> |
| 17 | <select id="translation_provider" name="provider" class="margin0"> | 17 | <select id="translation_provider" name="provider" class="margin0"> |
| 18 | <option value="libre">Libre</option> | 18 | <option value="libre">LibreTranslate</option> |
| 19 | <option value="google">Google</option> | 19 | <option value="google">Google</option> |
| 20 | <option value="lingva">Lingva</option> | 20 | <option value="lingva">Lingva</option> |
| 21 | <option value="deepl">DeepL</option> | 21 | <option value="deepl">DeepL</option> |
| @@ -35,4 +35,4 @@ | |||
| 35 | </div> | 35 | </div> |
| 36 | </div> | 36 | </div> |
| 37 | </div> | 37 | </div> |
| 38 | </div> | ||
| 38 | \ No newline at end of file | \ No newline at end of file | |
| 38 | </div> | ||
| @@ -14,6 +14,8 @@ import { POPUP_RESULT, POPUP_TYPE, callGenericPopup } from '../../popup.js'; | |||
| 14 | import { findSecret, secret_state, writeSecret } from '../../secrets.js'; | 14 | import { findSecret, secret_state, writeSecret } from '../../secrets.js'; |
| 15 | import { SlashCommand } from '../../slash-commands/SlashCommand.js'; | 15 | import { SlashCommand } from '../../slash-commands/SlashCommand.js'; |
| 16 | import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js'; | 16 | import { 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'; | ||
| 17 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; | 19 | import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js'; |
| 18 | import { splitRecursive } from '../../utils.js'; | 20 | import { splitRecursive } from '../../utils.js'; |
| 19 | 21 | ||
| @@ -395,9 +397,10 @@ async function chunkedTranslate(text, lang, translateFn, chunkSize = 5000) { | |||
| 395 | * Translates text using the selected translation provider | 397 | * Translates text using the selected translation provider |
| 396 | * @param {string} text Text to translate | 398 | * @param {string} text Text to translate |
| 397 | * @param {string} lang Target language code | 399 | * @param {string} lang Target language code |
| 400 | * @param {string} provider Translation provider to use | ||
| 398 | * @returns {Promise<string>} Translated text | 401 | * @returns {Promise<string>} Translated text |
| 399 | */ | 402 | */ |
| 400 | async function translate(text, lang) { | 403 | async function translate(text, lang, provider = null) { |
| 401 | try { | 404 | try { |
| 402 | if (text == '') { | 405 | if (text == '') { |
| 403 | return ''; | 406 | return ''; |
| @@ -407,13 +410,17 @@ async function translate(text, lang) { | |||
| 407 | lang = extension_settings.translate.target_language; | 410 | lang = extension_settings.translate.target_language; |
| 408 | } | 411 | } |
| 409 | 412 | ||
| 413 | if (!provider) { | ||
| 414 | provider = extension_settings.translate.provider; | ||
| 415 | } | ||
| 416 | |||
| 410 | // split text by embedded images links | 417 | // split text by embedded images links |
| 411 | const chunks = text.split(/!\[.*?]\([^)]*\)/); | 418 | const chunks = text.split(/!\[.*?]\([^)]*\)/); |
| 412 | const links = [...text.matchAll(/!\[.*?]\([^)]*\)/g)]; | 419 | const links = [...text.matchAll(/!\[.*?]\([^)]*\)/g)]; |
| 413 | 420 | ||
| 414 | let result = ''; | 421 | let result = ''; |
| 415 | for (let i = 0; i < chunks.length; i++) { | 422 | for (let i = 0; i < chunks.length; i++) { |
| 416 | result += await translateInner(chunks[i], lang); | 423 | result += await translateInner(chunks[i], lang, provider); |
| 417 | if (i < links.length) result += links[i][0]; | 424 | if (i < links.length) result += links[i][0]; |
| 418 | } | 425 | } |
| 419 | 426 | ||
| @@ -424,11 +431,21 @@ async function translate(text, lang) { | |||
| 424 | } | 431 | } |
| 425 | } | 432 | } |
| 426 | 433 | ||
| 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) { | ||
| 428 | if (text == '') { | 442 | if (text == '') { |
| 429 | return ''; | 443 | return ''; |
| 430 | } | 444 | } |
| 431 | switch (extension_settings.translate.provider) { | 445 | if (!provider) { |
| 446 | provider = extension_settings.translate.provider; | ||
| 447 | } | ||
| 448 | switch (provider) { | ||
| 432 | case 'libre': | 449 | case 'libre': |
| 433 | return await translateProviderLibre(text, lang); | 450 | return await translateProviderLibre(text, lang); |
| 434 | case 'google': | 451 | case 'google': |
| @@ -446,7 +463,7 @@ async function translateInner(text, lang) { | |||
| 446 | case 'yandex': | 463 | case 'yandex': |
| 447 | return await translateProviderYandex(text, lang); | 464 | return await translateProviderYandex(text, lang); |
| 448 | default: | 465 | default: |
| 449 | console.error('Unknown translation provider', extension_settings.translate.provider); | 466 | console.error('Unknown translation provider', provider); |
| 450 | return text; | 467 | return text; |
| 451 | } | 468 | } |
| 452 | } | 469 | } |
| @@ -688,6 +705,14 @@ jQuery(async () => { | |||
| 688 | helpString: 'Translate text to a target language. If target language is not provided, the value from the extension settings will be used.', | 705 | helpString: 'Translate text to a target language. If target language is not provided, the value from the extension settings will be used.', |
| 689 | namedArgumentList: [ | 706 | namedArgumentList: [ |
| 690 | new SlashCommandNamedArgument('target', 'The target language code to translate to', ARGUMENT_TYPE.STRING, false, false, '', Object.values(languageCodes)), | 707 | 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 | }), | ||
| 691 | ], | 716 | ], |
| 692 | unnamedArgumentList: [ | 717 | unnamedArgumentList: [ |
| 693 | new SlashCommandArgument('The text to translate', ARGUMENT_TYPE.STRING, true, false, ''), | 718 | new SlashCommandArgument('The text to translate', ARGUMENT_TYPE.STRING, true, false, ''), |
| @@ -696,7 +721,8 @@ jQuery(async () => { | |||
| 696 | const target = args?.target && Object.values(languageCodes).includes(String(args.target)) | 721 | const target = args?.target && Object.values(languageCodes).includes(String(args.target)) |
| 697 | ? String(args.target) | 722 | ? String(args.target) |
| 698 | : extension_settings.translate.target_language; | 723 | : 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); | ||
| 700 | }, | 726 | }, |
| 701 | returns: ARGUMENT_TYPE.STRING, | 727 | returns: ARGUMENT_TYPE.STRING, |
| 702 | })); | 728 | })); |