kopia lustrzana https://github.com/elk-zone/elk
				
				
				
			feat: allow disabling translation for specific languages (#1371)
							rodzic
							
								
									e197a1dbe9
								
							
						
					
					
						commit
						b48b7f4c16
					
				| 
						 | 
				
			
			@ -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')"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue