feat: allow disabling translation for specific languages (#1371)
This commit is contained in:
parent
e197a1dbe9
commit
b48b7f4c16
63
components/settings/SettingsTranslations.vue
Normal file
63
components/settings/SettingsTranslations.vue
Normal file
|
@ -0,0 +1,63 @@
|
|||
<script lang="ts" setup>
|
||||
import ISO6391 from 'iso-639-1'
|
||||
|
||||
const supportedTranslationLanguages = ISO6391.getLanguages([...supportedTranslationCodes])
|
||||
const userSettings = useUserSettings()
|
||||
|
||||
const language = ref<string | null>(null)
|
||||
|
||||
const availableOptions = computed(() => {
|
||||
return Object.values(supportedTranslationLanguages).filter((value) => {
|
||||
return !userSettings.value.disabledTranslationLanguages.includes(value.code)
|
||||
})
|
||||
})
|
||||
|
||||
function addDisabledTranslation() {
|
||||
if (language.value) {
|
||||
const uniqueValues = new Set(userSettings.value.disabledTranslationLanguages)
|
||||
uniqueValues.add(language.value)
|
||||
userSettings.value.disabledTranslationLanguages = [...uniqueValues]
|
||||
language.value = null
|
||||
}
|
||||
}
|
||||
function removeDisabledTranslation(code: string) {
|
||||
const uniqueValues = new Set(userSettings.value.disabledTranslationLanguages)
|
||||
uniqueValues.delete(code)
|
||||
userSettings.value.disabledTranslationLanguages = [...uniqueValues]
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<CommonCheckbox v-model="userSettings.preferences.hideTranslation" :label="$t('settings.preferences.hide_translation')" />
|
||||
<div v-if="!userSettings.preferences.hideTranslation" class="mt-1 ms-2">
|
||||
<p class=" mb-2">
|
||||
{{ $t('settings.language.translations.hide_specific') }}
|
||||
</p>
|
||||
<div class="ms-4">
|
||||
<ul>
|
||||
<li v-for="langCode in userSettings.disabledTranslationLanguages" :key="langCode" class="flex items-center">
|
||||
<div>{{ ISO6391.getNativeName(langCode) }}</div>
|
||||
<button class="btn-text" type="button" :title="$t('settings.language.translations.remove')" @click.prevent="removeDisabledTranslation(langCode)">
|
||||
<span class="block i-ri:close-line" aria-hidden="true" />
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="flex items-center mt-2">
|
||||
<select v-model="language" class="select-settings">
|
||||
<option disabled selected :value="null">
|
||||
{{ $t('settings.language.translations.choose_language') }}
|
||||
</option>
|
||||
<option v-for="availableOption in availableOptions" :key="availableOption.code" :value="availableOption.code">
|
||||
{{ availableOption.nativeName }}
|
||||
</option>
|
||||
</select>
|
||||
<button class="btn-text" @click="addDisabledTranslation">
|
||||
{{ $t('settings.language.translations.add') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -12,7 +12,7 @@ const {
|
|||
} = useTranslation(status, getLanguageCode())
|
||||
const preferenceHideTranslation = usePreferences('hideTranslation')
|
||||
|
||||
const showButton = computed(() => !preferenceHideTranslation.value && isTranslationEnabled && status.language !== getLanguageCode())
|
||||
const showButton = computed(() => !preferenceHideTranslation.value && isTranslationEnabled)
|
||||
|
||||
let translating = $ref(false)
|
||||
const toggleTranslation = async () => {
|
||||
|
|
|
@ -8,6 +8,40 @@ export interface TranslationResponse {
|
|||
}
|
||||
}
|
||||
|
||||
// @see https://github.com/LibreTranslate/LibreTranslate/tree/main/libretranslate/locales
|
||||
export const supportedTranslationCodes = [
|
||||
'ar',
|
||||
'az',
|
||||
'cs',
|
||||
'da',
|
||||
'de',
|
||||
'el',
|
||||
'en',
|
||||
'eo',
|
||||
'es',
|
||||
'fa',
|
||||
'fi',
|
||||
'fr',
|
||||
'ga',
|
||||
'he',
|
||||
'hi',
|
||||
'hu',
|
||||
'id',
|
||||
'it',
|
||||
'ja',
|
||||
'ko',
|
||||
'nl',
|
||||
'pl',
|
||||
'pt',
|
||||
'ru',
|
||||
'sk',
|
||||
'sv',
|
||||
'tr',
|
||||
'uk',
|
||||
'vi',
|
||||
'zh',
|
||||
] as const
|
||||
|
||||
export const getLanguageCode = () => {
|
||||
let code = 'en'
|
||||
const getCode = (code: string) => code.replace(/-.*$/, '')
|
||||
|
@ -63,9 +97,16 @@ export function useTranslation(status: mastodon.v1.Status | mastodon.v1.StatusEd
|
|||
translations.set(status, reactive({ visible: false, text: '', success: false, error: '' }))
|
||||
|
||||
const translation = translations.get(status)!
|
||||
const userSettings = useUserSettings()
|
||||
|
||||
const shouldTranslate = 'language' in status && status.language && status.language !== to
|
||||
&& supportedTranslationCodes.includes(to as any)
|
||||
&& supportedTranslationCodes.includes(status.language as any)
|
||||
&& !userSettings.value.disabledTranslationLanguages.includes(status.language)
|
||||
const enabled = /*! !useRuntimeConfig().public.translateApi && */ shouldTranslate
|
||||
|
||||
async function toggle() {
|
||||
if (!('language' in status))
|
||||
if (!shouldTranslate)
|
||||
return
|
||||
|
||||
if (!translation.text) {
|
||||
|
@ -79,7 +120,7 @@ export function useTranslation(status: mastodon.v1.Status | mastodon.v1.StatusEd
|
|||
}
|
||||
|
||||
return {
|
||||
enabled: !!useRuntimeConfig().public.translateApi,
|
||||
enabled,
|
||||
toggle,
|
||||
translation,
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ export interface UserSettings {
|
|||
colorMode?: ColorMode
|
||||
fontSize: FontSize
|
||||
language: string
|
||||
disabledTranslationLanguages: string[]
|
||||
zenMode: boolean
|
||||
themeColors?: ThemeColors
|
||||
}
|
||||
|
@ -56,6 +57,7 @@ export function getDefaultUserSettings(locales: string[]): UserSettings {
|
|||
return {
|
||||
language: getDefaultLanguage(locales),
|
||||
fontSize: DEFAULT_FONT_SIZE,
|
||||
disabledTranslationLanguages: [],
|
||||
zenMode: false,
|
||||
preferences: {},
|
||||
}
|
||||
|
|
|
@ -270,7 +270,14 @@
|
|||
},
|
||||
"language": {
|
||||
"display_language": "Anzeigesprache",
|
||||
"label": "Sprache"
|
||||
"label": "Sprache",
|
||||
"translations": {
|
||||
"add": "Hinzufügen",
|
||||
"choose_language": "Sprache wählen",
|
||||
"heading": "Übersetzungen",
|
||||
"hide_specific": "Bestimmte Übersetzungen ausblenden",
|
||||
"remove": "Entfernen"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"label": "Benachrichtigungen",
|
||||
|
@ -328,7 +335,7 @@
|
|||
"hide_boost_count": "Boost-Zähler ausblenden",
|
||||
"hide_favorite_count": "Favoritenzahl ausblenden",
|
||||
"hide_follower_count": "Anzahl der Follower ausblenden",
|
||||
"hide_translation": "Übersetzungen ausblenden",
|
||||
"hide_translation": "Übersetzungen komplett ausblenden",
|
||||
"label": "Einstellungen",
|
||||
"title": "Experimentelle Funktionen",
|
||||
"user_picker": "Benutzerauswahl",
|
||||
|
|
|
@ -316,7 +316,14 @@
|
|||
},
|
||||
"language": {
|
||||
"display_language": "Display Language",
|
||||
"label": "Language"
|
||||
"label": "Language",
|
||||
"translations": {
|
||||
"add": "Add",
|
||||
"choose_language": "Choose language",
|
||||
"heading": "Translations",
|
||||
"hide_specific": "Hide specific translations",
|
||||
"remove": "Remove"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"label": "Notifications",
|
||||
|
|
|
@ -18,6 +18,10 @@ useHeadFixed({
|
|||
<p font-medium>{{ $t('settings.language.display_language') }}</p>
|
||||
<SettingsLanguage select-settings />
|
||||
</label>
|
||||
<h2 py4 mt2 font-bold text-xl flex="~ gap-1" items-center>
|
||||
{{ $t('settings.language.translations.heading') }}
|
||||
</h2>
|
||||
<SettingsTranslations />
|
||||
</div>
|
||||
</MainContent>
|
||||
</template>
|
||||
|
|
|
@ -39,12 +39,6 @@ const userSettings = useUserSettings()
|
|||
>
|
||||
{{ $t('settings.preferences.hide_follower_count') }}
|
||||
</SettingsToggleItem>
|
||||
<SettingsToggleItem
|
||||
:checked="getPreferences(userSettings, 'hideTranslation')"
|
||||
@click="togglePreferences('hideTranslation')"
|
||||
>
|
||||
{{ $t('settings.preferences.hide_translation') }}
|
||||
</SettingsToggleItem>
|
||||
<SettingsToggleItem
|
||||
:checked="getPreferences(userSettings, 'hideAccountHoverCard')"
|
||||
@click="togglePreferences('hideAccountHoverCard')"
|
||||
|
|
Loading…
Reference in a new issue