diff --git a/src/components/dialogs/UserDialog/UserDialog.vue b/src/components/dialogs/UserDialog/UserDialog.vue index 5f171e53..361f38f8 100644 --- a/src/components/dialogs/UserDialog/UserDialog.vue +++ b/src/components/dialogs/UserDialog/UserDialog.vue @@ -249,7 +249,7 @@ style="margin-left: 5px" @click="showBioDialog"> -
+
@@ -1310,10 +1310,9 @@ const { t } = useI18n(); - const advancedSettingsStore = useAdvancedSettingsStore(); - const { hideUserNotes, hideUserMemos } = storeToRefs(useAppearanceSettingsStore()); - const { bioLanguage, avatarRemoteDatabase } = storeToRefs(useAdvancedSettingsStore()); + const { bioLanguage, avatarRemoteDatabase, translationApi } = storeToRefs(useAdvancedSettingsStore()); + const { translateText } = useAdvancedSettingsStore(); const { userDialog, languageDialog, currentUser, isLocalUserVrcPlusSupporter } = storeToRefs(useUserStore()); const { cachedUsers, @@ -1427,6 +1426,13 @@ pronouns: '' }); + const bioCache = ref({ + userId: null, + original: null, + translated: null, + showingTranslated: false + }); + const userDialogAvatars = computed(() => { const { avatars, avatarReleaseStatus } = userDialog.value; if (avatarReleaseStatus === 'public' || avatarReleaseStatus === 'private') { @@ -2277,26 +2283,24 @@ D.visible = true; } - const bioCache = ref({ - userID: null, - original: null, - translated: null, - showingTranslated: false - }); async function translateBio() { const bio = userDialog.value.ref.bio; - if (!bio || bio === '-' || !advancedSettingsStore.translationApi) return; + if (!bio) { + return; + } const targetLang = bioLanguage.value; - if (bioCache.value.userID !== userDialog.value.id) { - bioCache.value.userID = userDialog.value.id; + if (bioCache.value.userId !== userDialog.value.id) { + bioCache.value.userId = userDialog.value.id; bioCache.value.original = null; bioCache.value.translated = null; bioCache.value.showingTranslated = false; } - if (!bioCache.value.original) bioCache.value.original = bio; + if (!bioCache.value.original) { + bioCache.value.original = bio; + } if (bioCache.value.showingTranslated) { userDialog.value.ref.bio = bioCache.value.original; @@ -2311,9 +2315,10 @@ } try { - const translated = await advancedSettingsStore.translateText(bio + '\n\nTranslated by Google', targetLang); - - if (!translated) throw new Error('No translation returned'); + const translated = await translateText(bio + '\n\nTranslated by Google', targetLang); + if (!translated) { + throw new Error('No translation returned'); + } bioCache.value.translated = translated; bioCache.value.showingTranslated = true; diff --git a/src/localization/en/en.json b/src/localization/en/en.json index 92359062..3e603c96 100644 --- a/src/localization/en/en.json +++ b/src/localization/en/en.json @@ -640,10 +640,10 @@ "enable_tooltip": "Fetches video titles for use with gameLog and duration for overlay progress bar" }, "translation_api": { - "header": "Translation API", + "header": "Google Translate API", "enable": "Enable", - "translation_api_key": "Translation API Key", - "enable_tooltip": "Translates user bios using a button on the bottom right" + "translation_api_key": "Google Translate API Key", + "enable_tooltip": "Translate user bios" }, "video_progress_pie": { "header": "Progress pie overlay for videos", @@ -1305,10 +1305,10 @@ "save": "Save" }, "translation_api": { - "header": "Translation API", - "description": "Enter your Translation API Key (optional)", - "placeholder": "Translation API Key", - "guide": "Guide (skip the restrict usage part)", + "header": "Google Translate API", + "description": "Enter your Google translate API Key", + "placeholder": "Google Translate API Key", + "guide": "Guide", "save": "Save" }, "set_world_tags": { diff --git a/src/stores/settings/advanced.js b/src/stores/settings/advanced.js index 2c61c2c5..af774cbb 100644 --- a/src/stores/settings/advanced.js +++ b/src/stores/settings/advanced.js @@ -41,8 +41,8 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => { const screenshotHelperModifyFilename = ref(false); const screenshotHelperCopyToClipboard = ref(false); const youTubeApi = ref(false); - const translationApi = ref(false); const youTubeApiKey = ref(''); + const translationApi = ref(false); const translationApiKey = ref(''); const progressPie = ref(false); const progressPieFilter = ref(true); @@ -87,8 +87,8 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => { screenshotHelperModifyFilenameConfig, screenshotHelperCopyToClipboardConfig, youTubeApiConfig, - translationApiConfig, youTubeApiKeyConfig, + translationApiConfig, translationApiKeyConfig, progressPieConfig, progressPieFilterConfig, @@ -128,8 +128,8 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => { false ), configRepository.getBool('VRCX_youtubeAPI', false), - configRepository.getBool('VRCX_translationAPI', false), configRepository.getString('VRCX_youtubeAPIKey', ''), + configRepository.getBool('VRCX_translationAPI', false), configRepository.getString('VRCX_translationAPIKey', ''), configRepository.getBool('VRCX_progressPie', false), configRepository.getBool('VRCX_progressPieFilter', true), @@ -175,8 +175,8 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => { screenshotHelperCopyToClipboard.value = screenshotHelperCopyToClipboardConfig; youTubeApi.value = youTubeApiConfig; - translationApi.value = translationApiConfig; youTubeApiKey.value = youTubeApiKeyConfig; + translationApi.value = translationApiConfig; translationApiKey.value = translationApiKeyConfig; progressPie.value = progressPieConfig; progressPieFilter.value = progressPieFilterConfig; @@ -584,26 +584,43 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => { } async function translateText(text, targetLang) { - if (!translationApiKey.value) return null; + if (!translationApiKey.value) { + ElMessage({ + message: 'No Translation API key configured', + type: 'warning' + }); + return null; + } try { - const res = await fetch( - `https://translation.googleapis.com/language/translate/v2?key=${translationApiKey.value}`, - { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - q: text, - target: targetLang, - format: 'text' - }) - } - ); - const data = await res.json(); - - if (data.error) return null; + const response = await webApiService.execute({ + url: `https://translation.googleapis.com/language/translate/v2?key=${translationApiKey.value}`, + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Referer: 'https://vrcx.app' + }, + body: JSON.stringify({ + q: text, + target: targetLang, + format: 'text' + }) + }); + if (response.status !== 200) { + throw new Error( + `Translation API error: ${response.status} - ${response.data}` + ); + } + const data = JSON.parse(response.data); + if (AppDebug.debugWebRequests) { + console.log(data, response); + } return data.data.translations[0].translatedText; } catch (err) { + ElMessage({ + message: `Translation failed: ${err.message}`, + type: 'error' + }); return null; } } diff --git a/src/views/Settings/components/Tabs/AdvancedTab.vue b/src/views/Settings/components/Tabs/AdvancedTab.vue index 9e2ef674..d10d7a8b 100644 --- a/src/views/Settings/components/Tabs/AdvancedTab.vue +++ b/src/views/Settings/components/Tabs/AdvancedTab.vue @@ -146,9 +146,10 @@ :long-label="true" @change="changeTranslationAPI('VRCX_translationAPI')" />
- {{ - t('view.settings.advanced.advanced.translation_api.translation_api_key') - }} + {{ t('view.settings.advanced.advanced.translation_api.translation_api_key') }}
diff --git a/src/views/Settings/dialogs/TranslationApiDialog.vue b/src/views/Settings/dialogs/TranslationApiDialog.vue index d10527bf..ca4e3eeb 100644 --- a/src/views/Settings/dialogs/TranslationApiDialog.vue +++ b/src/views/Settings/dialogs/TranslationApiDialog.vue @@ -3,11 +3,11 @@ class="x-dialog" :model-value="isTranslationApiDialogVisible" :title="t('dialog.translation_api.header')" - width="400px" + width="450px" @close="closeDialog">
{{ t('view.settings.appearance.appearance.bio_language') }} - + {{ messages[bioLanguage]?.language || bioLanguage }} @@ -25,6 +25,7 @@
+
{{ t('dialog.translation_api.description') }}
{{ t('dialog.youtube_api.description') }}