Skip to content

Commit

Permalink
feat: allow disabling translation for specific languages (#1371)
Browse files Browse the repository at this point in the history
  • Loading branch information
niklaswolf authored Jan 29, 2023
1 parent e197a1d commit b48b7f4
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 12 deletions.
63 changes: 63 additions & 0 deletions components/settings/SettingsTranslations.vue
Original file line number Diff line number Diff line change
@@ -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>
2 changes: 1 addition & 1 deletion components/status/StatusTranslation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
45 changes: 43 additions & 2 deletions composables/masto/translate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(/-.*$/, '')
Expand Down Expand Up @@ -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) {
Expand All @@ -79,7 +120,7 @@ export function useTranslation(status: mastodon.v1.Status | mastodon.v1.StatusEd
}

return {
enabled: !!useRuntimeConfig().public.translateApi,
enabled,
toggle,
translation,
}
Expand Down
2 changes: 2 additions & 0 deletions composables/settings/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export interface UserSettings {
colorMode?: ColorMode
fontSize: FontSize
language: string
disabledTranslationLanguages: string[]
zenMode: boolean
themeColors?: ThemeColors
}
Expand Down Expand Up @@ -56,6 +57,7 @@ export function getDefaultUserSettings(locales: string[]): UserSettings {
return {
language: getDefaultLanguage(locales),
fontSize: DEFAULT_FONT_SIZE,
disabledTranslationLanguages: [],
zenMode: false,
preferences: {},
}
Expand Down
11 changes: 9 additions & 2 deletions locales/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
9 changes: 8 additions & 1 deletion locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions pages/settings/language/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
6 changes: 0 additions & 6 deletions pages/settings/preferences/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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')"
Expand Down

0 comments on commit b48b7f4

Please sign in to comment.