diff --git a/lib/Service/InitialStateProvider.php b/lib/Service/InitialStateProvider.php index 48bfa733a29..2908b701cf6 100644 --- a/lib/Service/InitialStateProvider.php +++ b/lib/Service/InitialStateProvider.php @@ -9,6 +9,7 @@ use OCP\AppFramework\Services\IInitialState; use OCP\TaskProcessing\IManager; +use OCP\Translation\ITranslationManager; class InitialStateProvider { private const ASSISTANT_TASK_TYPES = [ @@ -24,6 +25,7 @@ class InitialStateProvider { public function __construct( private IInitialState $initialState, private ConfigService $configService, + private ITranslationManager $translationManager, private IManager $taskProcessingManager, private ?string $userId, ) { @@ -55,19 +57,17 @@ public function provideState(): void { $this->configService->isRichEditingEnabled() ); - $taskTypes = $this->taskProcessingManager->getAvailableTaskTypes(); - $fromLanguages = $taskTypes['core:text2text:translate']['inputShapeEnumValues']['origin_language'] ?? []; - $toLanguages = $taskTypes['core:text2text:translate']['inputShapeEnumValues']['target_language'] ?? []; + $this->initialState->provideInitialState( + 'translation_can_detect', + $this->translationManager->canDetectLanguage() + ); $this->initialState->provideInitialState( 'translation_languages', - [ - 'from' => $fromLanguages, - 'to' => $toLanguages, - ] + $this->translationManager->getLanguages() ); - $filteredTypes = array_filter($taskTypes, static function (string $taskType) { + $filteredTypes = array_filter($this->taskProcessingManager->getAvailableTaskTypes(), static function (string $taskType) { return in_array($taskType, self::ASSISTANT_TASK_TYPES, true); }, ARRAY_FILTER_USE_KEY); $this->initialState->provideInitialState( diff --git a/src/components/Assistant.vue b/src/components/Assistant.vue index fbf9b93e433..011c21a4d97 100644 --- a/src/components/Assistant.vue +++ b/src/components/Assistant.vue @@ -28,10 +28,7 @@ {{ type.name }} - + @@ -192,7 +189,7 @@ export default { STATUS_UNKNOWN, showTaskList: false, - canTranslate: loadState('text', 'translation_languages', []).from?.length > 0, + canTranslate: loadState('text', 'translation_languages', []).length > 0, } }, computed: { diff --git a/src/components/Menu/MenuBar.vue b/src/components/Menu/MenuBar.vue index 816b41a80cb..dfa82438260 100644 --- a/src/components/Menu/MenuBar.vue +++ b/src/components/Menu/MenuBar.vue @@ -134,7 +134,7 @@ export default { randomID: `menu-bar-${(Math.ceil((Math.random() * 10000) + 500)).toString(16)}`, displayHelp: false, isReady: false, - canTranslate: loadState('text', 'translation_languages', []).from?.length > 0, + canTranslate: loadState('text', 'translation_languages', []).length > 0, resize: null, } }, diff --git a/src/components/Modal/Translate.vue b/src/components/Modal/Translate.vue index 36c47f069ee..8b04b56e0a9 100644 --- a/src/components/Modal/Translate.vue +++ b/src/components/Modal/Translate.vue @@ -78,6 +78,11 @@ import { generateOcsUrl } from '@nextcloud/router' import { NcModal, NcButton, NcSelect, NcLoadingIcon, NcTextArea } from '@nextcloud/vue' import { useIsMobileMixin } from '../Editor.provider.js' +const detectLanguageEntry = { + id: null, + label: t('text', 'Detect language'), +} + export default { name: 'Translate', components: { @@ -104,9 +109,10 @@ export default { return { input: 'Hallo welt. Das ist ein Test.', result: '', - fromLanguage: null, + fromLanguage: loadState('text', 'translation_can_detect', false) === true ? detectLanguageEntry : null, toLanguage: null, languages: loadState('text', 'translation_languages', []), + canDetect: loadState('text', 'translation_can_detect'), loading: false, error: null, disableFromLanguageSelect: true, @@ -114,12 +120,16 @@ export default { }, computed: { fromLanguages() { - const result = [] - for (const item of this.languages.from) { - result.push({ - id: item.value, - label: !this.$isMobile ? item.name : t('text', 'Translate from {language}', { language: item.name }), - }) + const result = this.canDetect ? [detectLanguageEntry] : [] + const set = new Set() + for (const item of this.languages) { + if (!set.has(item.from)) { + set.add(item.from) + result.push({ + id: item.from, + label: !this.$isMobile ? item.fromLabel : t('text', 'Translate from {language}', { language: item.fromLabel }), + }) + } } return result }, @@ -128,18 +138,22 @@ export default { return [] } - const languages = this.languages.to.filter(l => { + const languages = this.languages.filter(l => { if (this.fromLanguage.id === null) { return true } - return l.value !== this.fromLanguage.id + return l.from === this.fromLanguage.id }) const result = [] + const set = new Set() for (const item of languages) { - result.push({ - id: item.value, - label: !this.$isMobile ? item.name : t('text', 'Translate to {language}', { language: item.name }), - }) + if (!set.has(item.to)) { + set.add(item.to) + result.push({ + id: item.to, + label: !this.$isMobile ? item.toLabel : t('text', 'Translate to {language}', { language: item.toLabel }), + }) + } } return result }, @@ -153,11 +167,6 @@ export default { this.error = null this.autosize() }, - fromLanguage(newVal) { - if (newVal.id === this.toLanguage.id) { - this.toLanguage = null - } - }, toLanguage() { this.result = '' this.error = null @@ -170,25 +179,12 @@ export default { async translate() { this.loading = true try { - const scheduleResponse = await axios.post(generateOcsUrl('taskprocessing/schedule'), { - input: { - origin_language: this.fromLanguage?.id ?? null, - input: this.input, - target_language: this.toLanguage.id, - }, - type: 'core:text2text:translate', - appId: 'text', + const result = await axios.post(generateOcsUrl('translation/translate'), { + text: this.input, + fromLanguage: this.fromLanguage?.id ?? null, + toLanguage: this.toLanguage.id, }) - const task = scheduleResponse.data.ocs.data.task - const getTaskOutput = async (task) => { - if (task.output) { - return task.output.output - } - await new Promise(resolve => setTimeout(resolve, 2000)) - const taskResponse = await axios.get(generateOcsUrl(`taskprocessing/task/${task.id}`)) - return getTaskOutput(taskResponse.data.ocs.data.task) - } - this.result = await getTaskOutput(task) + this.result = result.data.ocs.data.text } catch (e) { console.error('Failed to translate', e) this.error = t('text', 'Translation failed')