feat: allow disabling translation for specific languages (#1371)

This commit is contained in:
Niklas Wolf 2023-01-29 13:18:49 +01:00 committed by GitHub
parent e197a1dbe9
commit b48b7f4c16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 130 additions and 12 deletions

View 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>

View file

@ -12,7 +12,7 @@ const {
} = useTranslation(status, getLanguageCode()) } = useTranslation(status, getLanguageCode())
const preferenceHideTranslation = usePreferences('hideTranslation') const preferenceHideTranslation = usePreferences('hideTranslation')
const showButton = computed(() => !preferenceHideTranslation.value && isTranslationEnabled && status.language !== getLanguageCode()) const showButton = computed(() => !preferenceHideTranslation.value && isTranslationEnabled)
let translating = $ref(false) let translating = $ref(false)
const toggleTranslation = async () => { const toggleTranslation = async () => {

View file

@ -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 = () => { export const getLanguageCode = () => {
let code = 'en' let code = 'en'
const getCode = (code: string) => code.replace(/-.*$/, '') 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: '' })) translations.set(status, reactive({ visible: false, text: '', success: false, error: '' }))
const translation = translations.get(status)! 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() { async function toggle() {
if (!('language' in status)) if (!shouldTranslate)
return return
if (!translation.text) { if (!translation.text) {
@ -79,7 +120,7 @@ export function useTranslation(status: mastodon.v1.Status | mastodon.v1.StatusEd
} }
return { return {
enabled: !!useRuntimeConfig().public.translateApi, enabled,
toggle, toggle,
translation, translation,
} }

View file

@ -26,6 +26,7 @@ export interface UserSettings {
colorMode?: ColorMode colorMode?: ColorMode
fontSize: FontSize fontSize: FontSize
language: string language: string
disabledTranslationLanguages: string[]
zenMode: boolean zenMode: boolean
themeColors?: ThemeColors themeColors?: ThemeColors
} }
@ -56,6 +57,7 @@ export function getDefaultUserSettings(locales: string[]): UserSettings {
return { return {
language: getDefaultLanguage(locales), language: getDefaultLanguage(locales),
fontSize: DEFAULT_FONT_SIZE, fontSize: DEFAULT_FONT_SIZE,
disabledTranslationLanguages: [],
zenMode: false, zenMode: false,
preferences: {}, preferences: {},
} }

View file

@ -270,7 +270,14 @@
}, },
"language": { "language": {
"display_language": "Anzeigesprache", "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": { "notifications": {
"label": "Benachrichtigungen", "label": "Benachrichtigungen",
@ -328,7 +335,7 @@
"hide_boost_count": "Boost-Zähler ausblenden", "hide_boost_count": "Boost-Zähler ausblenden",
"hide_favorite_count": "Favoritenzahl ausblenden", "hide_favorite_count": "Favoritenzahl ausblenden",
"hide_follower_count": "Anzahl der Follower ausblenden", "hide_follower_count": "Anzahl der Follower ausblenden",
"hide_translation": "Übersetzungen ausblenden", "hide_translation": "Übersetzungen komplett ausblenden",
"label": "Einstellungen", "label": "Einstellungen",
"title": "Experimentelle Funktionen", "title": "Experimentelle Funktionen",
"user_picker": "Benutzerauswahl", "user_picker": "Benutzerauswahl",

View file

@ -316,7 +316,14 @@
}, },
"language": { "language": {
"display_language": "Display 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": { "notifications": {
"label": "Notifications", "label": "Notifications",

View file

@ -18,6 +18,10 @@ useHeadFixed({
<p font-medium>{{ $t('settings.language.display_language') }}</p> <p font-medium>{{ $t('settings.language.display_language') }}</p>
<SettingsLanguage select-settings /> <SettingsLanguage select-settings />
</label> </label>
<h2 py4 mt2 font-bold text-xl flex="~ gap-1" items-center>
{{ $t('settings.language.translations.heading') }}
</h2>
<SettingsTranslations />
</div> </div>
</MainContent> </MainContent>
</template> </template>

View file

@ -39,12 +39,6 @@ const userSettings = useUserSettings()
> >
{{ $t('settings.preferences.hide_follower_count') }} {{ $t('settings.preferences.hide_follower_count') }}
</SettingsToggleItem> </SettingsToggleItem>
<SettingsToggleItem
:checked="getPreferences(userSettings, 'hideTranslation')"
@click="togglePreferences('hideTranslation')"
>
{{ $t('settings.preferences.hide_translation') }}
</SettingsToggleItem>
<SettingsToggleItem <SettingsToggleItem
:checked="getPreferences(userSettings, 'hideAccountHoverCard')" :checked="getPreferences(userSettings, 'hideAccountHoverCard')"
@click="togglePreferences('hideAccountHoverCard')" @click="togglePreferences('hideAccountHoverCard')"