kopia lustrzana https://github.com/cheeaun/phanpy
Time to migrate away from Lingva
rodzic
de83092259
commit
e586b77a3e
3
.env
3
.env
|
@ -1,4 +1,5 @@
|
|||
PHANPY_CLIENT_NAME=Phanpy
|
||||
PHANPY_WEBSITE=https://phanpy.social
|
||||
PHANPY_LINGVA_INSTANCES="lingva.phanpy.social lingva.lunar.icu lingva.garudalinux.org translate.plausibility.cloud"
|
||||
PHANPY_PRIVACY_POLICY_URL="https://github.com/cheeaun/phanpy/blob/main/PRIVACY.MD"
|
||||
PHANPY_PRIVACY_POLICY_URL="https://github.com/cheeaun/phanpy/blob/main/PRIVACY.MD"
|
||||
PHANPY_TRANSLANG_INSTANCES="translang.phanpy.social"
|
|
@ -238,11 +238,15 @@ Available variables:
|
|||
- This is applied with the `<meta>` tag on the client-side.
|
||||
- The policy can also be set with `Referrer-Policy` header configured on the server-side (not this variable).
|
||||
- Note that since Phanpy uses hash-based URLs, the referrer does not include the hash part.
|
||||
- `PHANPY_LINGVA_INSTANCES` (optional, space-separated list, default: `lingva.phanpy.social [...hard-coded list of fallback instances]`):
|
||||
- `PHANPY_LINGVA_INSTANCES` (**DEPRECATED**, optional, space-separated list, default: `lingva.phanpy.social [...hard-coded list of fallback instances]`):
|
||||
- Specify a space-separated list of instances. First will be used as default before falling back to the subsequent instances. If there's only 1 instance, means no fallback.
|
||||
- May specify a self-hosted Lingva instance, powered by either [lingva-translate](https://github.com/thedaviddelta/lingva-translate) or [lingva-api](https://github.com/cheeaun/lingva-api)
|
||||
- List of fallback instances hard-coded in `/.env`
|
||||
- [↗️ List of lingva-translate instances](https://github.com/thedaviddelta/lingva-translate?tab=readme-ov-file#instances)
|
||||
- `PHANPY_TRANSLANG_INSTANCES` (optional, space-separated list, default: `translang.phanpy.social`):
|
||||
- Specify a space-separated list of instances. First will be used as default before falling back to the subsequent instances. If there's only 1 instance, means no fallback.
|
||||
- May specify a self-hosted Translating instance, powered by [translang-api](https://github.com/cheeaun/translang-api).
|
||||
- List of instances hard-coded in `/.env`
|
||||
- `PHANPY_IMG_ALT_API_URL` (optional, no defaults):
|
||||
- API endpoint for self-hosted instance of [img-alt-api](https://github.com/cheeaun/img-alt-api).
|
||||
- If provided, a setting will appear for users to enable the image description generator in the composer. Disabled by default.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import fs from 'fs';
|
||||
|
||||
fetch('https://translang.phanpy.social/api/v1/languages')
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
const file = './src/data/translang-languages.json';
|
||||
console.log(`Writing ${file}...`);
|
||||
fs.writeFileSync(file, JSON.stringify(json, null, '\t'), 'utf8');
|
||||
});
|
|
@ -119,8 +119,17 @@ function getPollText(poll) {
|
|||
)
|
||||
.join('\n')}`;
|
||||
}
|
||||
function getPostText(status) {
|
||||
const { spoilerText, content, poll } = status;
|
||||
function getPostText(status, opts) {
|
||||
const { maskCustomEmojis } = opts || {};
|
||||
const { spoilerText, poll, emojis } = status;
|
||||
let { content } = status;
|
||||
if (maskCustomEmojis && emojis?.length) {
|
||||
const emojisRegex = new RegExp(
|
||||
`:(${emojis.map((e) => e.shortcode).join('|')}):`,
|
||||
'g',
|
||||
);
|
||||
content = content.replace(emojisRegex, '⬚');
|
||||
}
|
||||
return (
|
||||
(spoilerText ? `${spoilerText}\n\n` : '') +
|
||||
getHTMLText(content) +
|
||||
|
@ -139,8 +148,16 @@ function forgivingQSA(selectors = [], dom = document) {
|
|||
return [];
|
||||
}
|
||||
|
||||
function isTranslateble(content) {
|
||||
function isTranslateble(content, emojis) {
|
||||
if (!content) return false;
|
||||
// Remove custom emojis
|
||||
if (emojis?.length) {
|
||||
const emojisRegex = new RegExp(
|
||||
`:(${emojis.map((e) => e.shortcode).join('|')}):`,
|
||||
'g',
|
||||
);
|
||||
content = content.replace(emojisRegex, '');
|
||||
}
|
||||
content = content.trim();
|
||||
if (!content) return false;
|
||||
const text = getHTMLText(content, {
|
||||
|
@ -2212,7 +2229,7 @@ function Status({
|
|||
/>
|
||||
)}
|
||||
{(((enableTranslate || inlineTranslate) &&
|
||||
isTranslateble(content) &&
|
||||
isTranslateble(content, emojis) &&
|
||||
differentLanguage) ||
|
||||
forceTranslate) && (
|
||||
<TranslationBlock
|
||||
|
@ -2220,7 +2237,9 @@ function Status({
|
|||
mini={!isSizeLarge && !withinContext}
|
||||
sourceLanguage={language}
|
||||
autoDetected={languageAutoDetected}
|
||||
text={getPostText(status)}
|
||||
text={getPostText(status, {
|
||||
maskCustomEmojis: true,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{!previewMode &&
|
||||
|
|
|
@ -5,7 +5,7 @@ import pRetry from 'p-retry';
|
|||
import pThrottle from 'p-throttle';
|
||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||
|
||||
import sourceLanguages from '../data/lingva-source-languages';
|
||||
import languages from '../data/translang-languages';
|
||||
import {
|
||||
translate as browserTranslate,
|
||||
supportsBrowserTranslator,
|
||||
|
@ -18,9 +18,14 @@ import Icon from './icon';
|
|||
import LazyShazam from './lazy-shazam';
|
||||
import Loader from './loader';
|
||||
|
||||
const { PHANPY_LINGVA_INSTANCES } = import.meta.env;
|
||||
const LINGVA_INSTANCES = PHANPY_LINGVA_INSTANCES
|
||||
? PHANPY_LINGVA_INSTANCES.split(/\s+/)
|
||||
const sourceLanguages = Object.entries(languages.sl).map(([code, name]) => ({
|
||||
code,
|
||||
name,
|
||||
}));
|
||||
|
||||
const { PHANPY_TRANSLANG_INSTANCES } = import.meta.env;
|
||||
const TRANSLANG_INSTANCES = PHANPY_TRANSLANG_INSTANCES
|
||||
? PHANPY_TRANSLANG_INSTANCES.split(/\s+/)
|
||||
: [];
|
||||
|
||||
const throttle = pThrottle({
|
||||
|
@ -28,50 +33,70 @@ const throttle = pThrottle({
|
|||
interval: 2000,
|
||||
});
|
||||
|
||||
let currentLingvaInstance = 0;
|
||||
const TRANSLATED_MAX_AGE = 1000 * 60 * 60; // 1 hour
|
||||
let currentTranslangInstance = 0;
|
||||
|
||||
function _lingvaTranslate(text, source, target) {
|
||||
function _translangTranslate(text, source, target) {
|
||||
console.log('TRANSLATE', text, source, target);
|
||||
const fetchCall = () => {
|
||||
let instance = LINGVA_INSTANCES[currentLingvaInstance];
|
||||
return fetch(
|
||||
`https://${instance}/api/v1/${source}/${target}/${encodeURIComponent(
|
||||
text,
|
||||
)}`,
|
||||
)
|
||||
let instance = TRANSLANG_INSTANCES[currentTranslangInstance];
|
||||
const tooLong = text.length > 2000;
|
||||
let fetchPromise;
|
||||
if (tooLong) {
|
||||
// POST
|
||||
fetchPromise = fetch(`https://${instance}/api/v1/translate`, {
|
||||
method: 'POST',
|
||||
priority: 'low',
|
||||
referrerPolicy: 'no-referrer',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
sl: source,
|
||||
tl: target,
|
||||
text,
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
// GET
|
||||
fetchPromise = fetch(
|
||||
`https://${instance}/api/v1/translate?sl=${encodeURIComponent(source)}&tl=${encodeURIComponent(target)}&text=${encodeURIComponent(text)}`,
|
||||
{
|
||||
priority: 'low',
|
||||
referrerPolicy: 'no-referrer',
|
||||
},
|
||||
);
|
||||
}
|
||||
return fetchPromise
|
||||
.then((res) => {
|
||||
if (!res.ok) throw new Error(res.statusText);
|
||||
return res.json();
|
||||
})
|
||||
.then((res) => {
|
||||
return {
|
||||
provider: 'lingva',
|
||||
content: res.translation,
|
||||
detectedSourceLanguage: res.info?.detectedSource,
|
||||
info: res.info,
|
||||
provider: 'translang',
|
||||
content: res.translated_text,
|
||||
detectedSourceLanguage: res.detected_language,
|
||||
pronunciation: res.pronunciation,
|
||||
};
|
||||
});
|
||||
};
|
||||
return pRetry(fetchCall, {
|
||||
retries: 3,
|
||||
onFailedAttempt: (e) => {
|
||||
currentLingvaInstance =
|
||||
(currentLingvaInstance + 1) % LINGVA_INSTANCES.length;
|
||||
currentTranslangInstance =
|
||||
(currentTranslangInstance + 1) % TRANSLANG_INSTANCES.length;
|
||||
console.log(
|
||||
'Retrying translation with another instance',
|
||||
currentLingvaInstance,
|
||||
currentTranslangInstance,
|
||||
);
|
||||
},
|
||||
});
|
||||
// return masto.v1.statuses.$select(id).translate({
|
||||
// lang: DEFAULT_LANG,
|
||||
// });
|
||||
}
|
||||
const TRANSLATED_MAX_AGE = 1000 * 60 * 60; // 1 hour
|
||||
const lingvaTranslate = pmem(_lingvaTranslate, {
|
||||
const translangTranslate = pmem(_translangTranslate, {
|
||||
maxAge: TRANSLATED_MAX_AGE,
|
||||
});
|
||||
const throttledLingvaTranslate = pmem(throttle(lingvaTranslate), {
|
||||
const throttledTranslangTranslate = pmem(throttle(translangTranslate), {
|
||||
// I know, this is double-layered memoization
|
||||
maxAge: TRANSLATED_MAX_AGE,
|
||||
});
|
||||
|
@ -99,11 +124,6 @@ function TranslationBlock({
|
|||
const apiSourceLang = useRef('auto');
|
||||
|
||||
if (!onTranslate) {
|
||||
// onTranslate = supportsBrowserTranslator
|
||||
// ? browserTranslate
|
||||
// : mini
|
||||
// ? throttledLingvaTranslate
|
||||
// : lingvaTranslate;
|
||||
onTranslate = async (...args) => {
|
||||
if (supportsBrowserTranslator) {
|
||||
const result = await browserTranslate(...args);
|
||||
|
@ -112,8 +132,8 @@ function TranslationBlock({
|
|||
}
|
||||
}
|
||||
return mini
|
||||
? await throttledLingvaTranslate(...args)
|
||||
: await lingvaTranslate(...args);
|
||||
? await throttledTranslangTranslate(...args)
|
||||
: await translangTranslate(...args);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -127,8 +147,8 @@ function TranslationBlock({
|
|||
const detectedLangText = localeCode2Text(detectedSourceLanguage);
|
||||
setDetectedLang(detectedLangText);
|
||||
}
|
||||
if (provider === 'lingva') {
|
||||
const pronunciation = props?.info?.pronunciation?.query;
|
||||
if (provider === 'translang') {
|
||||
const pronunciation = props?.pronunciation;
|
||||
if (pronunciation) {
|
||||
setPronunciationContent(pronunciation);
|
||||
}
|
||||
|
@ -235,14 +255,14 @@ function TranslationBlock({
|
|||
code: l.code,
|
||||
locale: l.code,
|
||||
});
|
||||
const showCommon = common !== native;
|
||||
const showCommon = native && common !== native;
|
||||
return (
|
||||
<option value={l.code}>
|
||||
{l.code === 'auto'
|
||||
? t`Auto (${detectedLang ?? '…'})`
|
||||
: showCommon
|
||||
? `${native} - ${common}`
|
||||
: native}
|
||||
: common}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
|
@ -280,4 +300,4 @@ function TranslationBlock({
|
|||
);
|
||||
}
|
||||
|
||||
export default LINGVA_INSTANCES?.length ? TranslationBlock : () => null;
|
||||
export default TRANSLANG_INSTANCES?.length ? TranslationBlock : () => null;
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
[
|
||||
"ca-ES",
|
||||
<<<<<<< HEAD
|
||||
"es-ES",
|
||||
"fi-FI",
|
||||
"gl-ES",
|
||||
"it-IT",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
"zh-CN",
|
||||
"eo-UY",
|
||||
"ru-RU",
|
||||
"eu-ES",
|
||||
"lt-LT",
|
||||
"kab",
|
||||
"de-DE",
|
||||
"uk-UA",
|
||||
"fr-FR",
|
||||
"ko-KR",
|
||||
"cs-CZ",
|
||||
"nl-NL",
|
||||
"fa-IR",
|
||||
"pl-PL"
|
||||
=======
|
||||
"cs-CZ",
|
||||
"de-DE",
|
||||
"eo-UY",
|
||||
"es-ES",
|
||||
"eu-ES",
|
||||
"fa-IR",
|
||||
"fi-FI",
|
||||
"fr-FR",
|
||||
"gl-ES",
|
||||
"it-IT",
|
||||
"kab",
|
||||
"ko-KR",
|
||||
"lt-LT",
|
||||
"nl-NL",
|
||||
"pl-PL",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
"ru-RU",
|
||||
"uk-UA",
|
||||
"zh-CN"
|
||||
>>>>>>> 8eeab341 (Move percentage threshold to build time)
|
||||
]
|
|
@ -0,0 +1,251 @@
|
|||
{
|
||||
"ab": "Аҧсшәа",
|
||||
"ace": "Acèh",
|
||||
"ach": "Lëbacoli",
|
||||
"aa": "Afár",
|
||||
"af": "Afrikaans",
|
||||
"sq": "Shqip",
|
||||
"alz": "Dhalur",
|
||||
"am": "አማርኛ",
|
||||
"ar": "العربية",
|
||||
"hy": "Հայերեն",
|
||||
"as": "অসমীয়া",
|
||||
"av": "Авар мацӀ",
|
||||
"awa": "अवधी",
|
||||
"ay": "Aymar aru",
|
||||
"az": "Azərbaycanca",
|
||||
"ban": "Basa Bali",
|
||||
"bal": "بلوچی",
|
||||
"bm": "Bamanankan",
|
||||
"bci": "Baoulé",
|
||||
"ba": "Башҡортса",
|
||||
"eu": "Euskara",
|
||||
"btx": "Batak Karo",
|
||||
"bts": "Batak Simalungun",
|
||||
"bbc": "Batak Toba",
|
||||
"be": "Беларуская",
|
||||
"bem": "Ichibemba",
|
||||
"bn": "বাংলা",
|
||||
"bew": "Betawi",
|
||||
"bho": "भोजपुरी",
|
||||
"bik": "Bikol",
|
||||
"bs": "Bosanski",
|
||||
"br": "Brezhoneg",
|
||||
"bg": "Български",
|
||||
"bua": "Буряад",
|
||||
"yue": "粵語",
|
||||
"ca": "Català",
|
||||
"ceb": "Cebuano",
|
||||
"ch": "Chamoru",
|
||||
"ce": "Нохчийн мотт",
|
||||
"ny": "Chichewa",
|
||||
"zh-CN": "简体中文",
|
||||
"zh-TW": "繁體中文",
|
||||
"chk": "Kapasen Chuuk",
|
||||
"cv": "Чӑвашла",
|
||||
"co": "Corsu",
|
||||
"crh": "Qırımtatarca (Кирилл)",
|
||||
"crh-Latn": "Qırımtatarca (Latin)",
|
||||
"hr": "Hrvatski",
|
||||
"cs": "Čeština",
|
||||
"da": "Dansk",
|
||||
"fa-AF": "درى",
|
||||
"dv": "ދިވެހި",
|
||||
"din": "Thuɔŋjäŋ",
|
||||
"doi": "डोगरी",
|
||||
"dov": "Dombe",
|
||||
"nl": "Nederlands",
|
||||
"dyu": "Jula",
|
||||
"dz": "རྫོང་ཁ",
|
||||
"en": "English",
|
||||
"eo": "Esperanto",
|
||||
"et": "Eesti",
|
||||
"ee": "Eʋegbe",
|
||||
"fo": "Føroyskt",
|
||||
"fj": "Vosa Vakaviti",
|
||||
"tl": "Tagalog",
|
||||
"fi": "Suomi",
|
||||
"fon": "Fon",
|
||||
"fr": "Français",
|
||||
"fr-CA": "Français (Canada)",
|
||||
"fy": "Frysk",
|
||||
"fur": "Furlan",
|
||||
"ff": "Fulfulde",
|
||||
"gaa": "Gã",
|
||||
"gl": "Galego",
|
||||
"ka": "ქართული",
|
||||
"de": "Deutsch",
|
||||
"el": "Ελληνικά",
|
||||
"gn": "Avañe'ẽ",
|
||||
"gu": "ગુજરાતી",
|
||||
"ht": "Kreyòl ayisyen",
|
||||
"cnh": "Hakha Chin",
|
||||
"ha": "Hausa",
|
||||
"haw": "ʻŌlelo Hawaiʻi",
|
||||
"iw": "עברית",
|
||||
"hil": "Hiligaynon",
|
||||
"hi": "हिन्दी",
|
||||
"hmn": "Hmoob",
|
||||
"hu": "Magyar",
|
||||
"hrx": "Hunsrik",
|
||||
"iba": "Iban",
|
||||
"is": "Íslenska",
|
||||
"ig": "Igbo",
|
||||
"ilo": "Iloko",
|
||||
"id": "Bahasa Indonesia",
|
||||
"iu-Latn": "Inuktitut (Latin)",
|
||||
"iu": "ᐃᓄᒃᑎᑐᑦ",
|
||||
"ga": "Gaeilge",
|
||||
"it": "Italiano",
|
||||
"jam": "Patwa",
|
||||
"ja": "日本語",
|
||||
"jw": "Basa Jawa",
|
||||
"kac": "Jinghpaw",
|
||||
"kl": "Kalaallisut",
|
||||
"kn": "ಕನ್ನಡ",
|
||||
"kr": "Kanuri",
|
||||
"pam": "Kapampangan",
|
||||
"kk": "Қазақша",
|
||||
"kha": "Khasi",
|
||||
"km": "ភាសាខ្មែរ",
|
||||
"cgg": "Rukiga",
|
||||
"kg": "Kikongo",
|
||||
"rw": "Kinyarwanda",
|
||||
"ktu": "Kituba",
|
||||
"trp": "Kokborok",
|
||||
"kv": "Коми кыв",
|
||||
"gom": "कोंकणी",
|
||||
"ko": "한국어",
|
||||
"kri": "Krio",
|
||||
"ku": "Kurdî (Kurmancî)",
|
||||
"ckb": "کوردی (سۆرانی)",
|
||||
"ky": "Кыргызча",
|
||||
"lo": "ລາວ",
|
||||
"ltg": "Latgaļu",
|
||||
"la": "Latina",
|
||||
"lv": "Latviešu",
|
||||
"lij": "Ligure",
|
||||
"li": "Limburgs",
|
||||
"ln": "Lingála",
|
||||
"lt": "Lietuvių",
|
||||
"lmo": "Lombard",
|
||||
"lg": "Luganda",
|
||||
"luo": "Dholuo",
|
||||
"lb": "Lëtzebuergesch",
|
||||
"mk": "Македонски",
|
||||
"mad": "Madhurâ",
|
||||
"mai": "मैथिली",
|
||||
"mak": "Makassar",
|
||||
"mg": "Malagasy",
|
||||
"ms": "Bahasa Melayu",
|
||||
"ms-Arab": "بهاس ملايو",
|
||||
"ml": "മലയാളം",
|
||||
"mt": "Malti",
|
||||
"mam": "Mam",
|
||||
"gv": "Gaelg",
|
||||
"mi": "Te Reo Māori",
|
||||
"mr": "मराठी",
|
||||
"mh": "Kajin M̧ajeļ",
|
||||
"mwr": "मारवाड़ी",
|
||||
"mfe": "Kreol Morisien",
|
||||
"chm": "Олык марий",
|
||||
"mni-Mtei": "ꯃꯤꯇꯩꯂꯣꯟ",
|
||||
"min": "Baso Minang",
|
||||
"lus": "Mizo ṭawng",
|
||||
"mn": "Монгол",
|
||||
"my": "မြန်မာစာ",
|
||||
"nhe": "Náhuatl",
|
||||
"ndc-ZW": "Ndau",
|
||||
"nr": "isiNdebele",
|
||||
"new": "नेपाल भाषा",
|
||||
"ne": "नेपाली",
|
||||
"bm-Nkoo": "ߒߞߏ",
|
||||
"no": "Norsk",
|
||||
"nus": "Thok Nath",
|
||||
"oc": "Occitan",
|
||||
"or": "ଓଡ଼ିଆ",
|
||||
"om": "Afaan Oromoo",
|
||||
"os": "Ирон æвзаг",
|
||||
"pag": "Pangasinan",
|
||||
"pap": "Papiamentu",
|
||||
"ps": "پښتو",
|
||||
"fa": "فارسی",
|
||||
"pl": "Polski",
|
||||
"pt": "Português (Brasil)",
|
||||
"pt-PT": "Português (Portugal)",
|
||||
"pa": "ਪੰਜਾਬੀ",
|
||||
"pa-Arab": "پنجابی",
|
||||
"qu": "Runa Simi",
|
||||
"kek": "Qʼeqchiʼ",
|
||||
"rom": "Romani čhib",
|
||||
"ro": "Română",
|
||||
"rn": "Ikirundi",
|
||||
"ru": "Русский",
|
||||
"se": "Davvisámegiella",
|
||||
"sm": "Gagana Samoa",
|
||||
"sg": "Sängö",
|
||||
"sa": "संस्कृतम्",
|
||||
"sat-Latn": "Santali (Latin)",
|
||||
"sat": "ᱥᱟᱱᱛᱟᱲᱤ",
|
||||
"gd": "Gàidhlig",
|
||||
"nso": "Sepedi",
|
||||
"sr": "Српски",
|
||||
"st": "Sesotho",
|
||||
"crs": "Kreol seselwa",
|
||||
"shn": "လိၵ်ႈတႆး",
|
||||
"sn": "chiShona",
|
||||
"scn": "Sicilianu",
|
||||
"szl": "Ślōnskŏ",
|
||||
"sd": "سنڌي",
|
||||
"si": "සිංහල",
|
||||
"sk": "Slovenčina",
|
||||
"sl": "Slovenščina",
|
||||
"so": "Soomaali",
|
||||
"es": "Español",
|
||||
"su": "Basa Sunda",
|
||||
"sus": "Susu",
|
||||
"sw": "Kiswahili",
|
||||
"ss": "siSwati",
|
||||
"sv": "Svenska",
|
||||
"ty": "Reo Tahiti",
|
||||
"tg": "Тоҷикӣ",
|
||||
"ber-Latn": "Tamazight (Latin)",
|
||||
"ber": "ⵜⴰⵎⴰⵣⵉⵖⵜ",
|
||||
"ta": "தமிழ்",
|
||||
"tt": "Татарча",
|
||||
"te": "తెలుగు",
|
||||
"tet": "Tetun",
|
||||
"th": "ไทย",
|
||||
"bo": "བོད་ཡིག",
|
||||
"ti": "ትግርኛ",
|
||||
"tiv": "Tiv",
|
||||
"tpi": "Tok Pisin",
|
||||
"to": "Lea fakatonga",
|
||||
"lua": "Tshiluba",
|
||||
"ts": "Xitsonga",
|
||||
"tn": "Setswana",
|
||||
"tcy": "ತುಳು",
|
||||
"tum": "chiTumbuka",
|
||||
"tr": "Türkçe",
|
||||
"tk": "Türkmençe",
|
||||
"tyv": "Тыва дыл",
|
||||
"ak": "Akankasa",
|
||||
"udm": "Удмурт кыл",
|
||||
"uk": "Українська",
|
||||
"ur": "اردو",
|
||||
"ug": "ئۇيغۇرچە",
|
||||
"uz": "Oʻzbekcha",
|
||||
"ve": "Tshivenḓa",
|
||||
"vec": "Vèneto",
|
||||
"vi": "Tiếng Việt",
|
||||
"war": "Winaray",
|
||||
"cy": "Cymraeg",
|
||||
"wo": "Wolof",
|
||||
"xh": "isiXhosa",
|
||||
"sah": "Саха тыла",
|
||||
"yi": "ייִדיש",
|
||||
"yo": "Yorùbá",
|
||||
"yua": "Màaya T'àan",
|
||||
"zap": "Didxazá",
|
||||
"zu": "isiZulu"
|
||||
}
|
|
@ -0,0 +1,506 @@
|
|||
{
|
||||
"sl": {
|
||||
"auto": "Detect language",
|
||||
"ab": "Abkhaz",
|
||||
"ace": "Acehnese",
|
||||
"ach": "Acholi",
|
||||
"aa": "Afar",
|
||||
"af": "Afrikaans",
|
||||
"sq": "Albanian",
|
||||
"alz": "Alur",
|
||||
"am": "Amharic",
|
||||
"ar": "Arabic",
|
||||
"hy": "Armenian",
|
||||
"as": "Assamese",
|
||||
"av": "Avar",
|
||||
"awa": "Awadhi",
|
||||
"ay": "Aymara",
|
||||
"az": "Azerbaijani",
|
||||
"ban": "Balinese",
|
||||
"bal": "Baluchi",
|
||||
"bm": "Bambara",
|
||||
"bci": "Baoulé",
|
||||
"ba": "Bashkir",
|
||||
"eu": "Basque",
|
||||
"btx": "Batak Karo",
|
||||
"bts": "Batak Simalungun",
|
||||
"bbc": "Batak Toba",
|
||||
"be": "Belarusian",
|
||||
"bem": "Bemba",
|
||||
"bn": "Bengali",
|
||||
"bew": "Betawi",
|
||||
"bho": "Bhojpuri",
|
||||
"bik": "Bikol",
|
||||
"bs": "Bosnian",
|
||||
"br": "Breton",
|
||||
"bg": "Bulgarian",
|
||||
"bua": "Buryat",
|
||||
"yue": "Cantonese",
|
||||
"ca": "Catalan",
|
||||
"ceb": "Cebuano",
|
||||
"ch": "Chamorro",
|
||||
"ce": "Chechen",
|
||||
"ny": "Chichewa",
|
||||
"zh-CN": "Chinese (Simplified)",
|
||||
"zh-TW": "Chinese (Traditional)",
|
||||
"chk": "Chuukese",
|
||||
"cv": "Chuvash",
|
||||
"co": "Corsican",
|
||||
"crh": "Crimean Tatar (Cyrillic)",
|
||||
"crh-Latn": "Crimean Tatar (Latin)",
|
||||
"hr": "Croatian",
|
||||
"cs": "Czech",
|
||||
"da": "Danish",
|
||||
"fa-AF": "Dari",
|
||||
"dv": "Dhivehi",
|
||||
"din": "Dinka",
|
||||
"doi": "Dogri",
|
||||
"dov": "Dombe",
|
||||
"nl": "Dutch",
|
||||
"dyu": "Dyula",
|
||||
"dz": "Dzongkha",
|
||||
"en": "English",
|
||||
"eo": "Esperanto",
|
||||
"et": "Estonian",
|
||||
"ee": "Ewe",
|
||||
"fo": "Faroese",
|
||||
"fj": "Fijian",
|
||||
"tl": "Filipino",
|
||||
"fi": "Finnish",
|
||||
"fon": "Fon",
|
||||
"fr": "French",
|
||||
"fr-CA": "French (Canada)",
|
||||
"fy": "Frisian",
|
||||
"fur": "Friulian",
|
||||
"ff": "Fulani",
|
||||
"gaa": "Ga",
|
||||
"gl": "Galician",
|
||||
"ka": "Georgian",
|
||||
"de": "German",
|
||||
"el": "Greek",
|
||||
"gn": "Guarani",
|
||||
"gu": "Gujarati",
|
||||
"ht": "Haitian Creole",
|
||||
"cnh": "Hakha Chin",
|
||||
"ha": "Hausa",
|
||||
"haw": "Hawaiian",
|
||||
"iw": "Hebrew",
|
||||
"hil": "Hiligaynon",
|
||||
"hi": "Hindi",
|
||||
"hmn": "Hmong",
|
||||
"hu": "Hungarian",
|
||||
"hrx": "Hunsrik",
|
||||
"iba": "Iban",
|
||||
"is": "Icelandic",
|
||||
"ig": "Igbo",
|
||||
"ilo": "Ilocano",
|
||||
"id": "Indonesian",
|
||||
"iu-Latn": "Inuktut (Latin)",
|
||||
"iu": "Inuktut (Syllabics)",
|
||||
"ga": "Irish",
|
||||
"it": "Italian",
|
||||
"jam": "Jamaican Patois",
|
||||
"ja": "Japanese",
|
||||
"jw": "Javanese",
|
||||
"kac": "Jingpo",
|
||||
"kl": "Kalaallisut",
|
||||
"kn": "Kannada",
|
||||
"kr": "Kanuri",
|
||||
"pam": "Kapampangan",
|
||||
"kk": "Kazakh",
|
||||
"kha": "Khasi",
|
||||
"km": "Khmer",
|
||||
"cgg": "Kiga",
|
||||
"kg": "Kikongo",
|
||||
"rw": "Kinyarwanda",
|
||||
"ktu": "Kituba",
|
||||
"trp": "Kokborok",
|
||||
"kv": "Komi",
|
||||
"gom": "Konkani",
|
||||
"ko": "Korean",
|
||||
"kri": "Krio",
|
||||
"ku": "Kurdish (Kurmanji)",
|
||||
"ckb": "Kurdish (Sorani)",
|
||||
"ky": "Kyrgyz",
|
||||
"lo": "Lao",
|
||||
"ltg": "Latgalian",
|
||||
"la": "Latin",
|
||||
"lv": "Latvian",
|
||||
"lij": "Ligurian",
|
||||
"li": "Limburgish",
|
||||
"ln": "Lingala",
|
||||
"lt": "Lithuanian",
|
||||
"lmo": "Lombard",
|
||||
"lg": "Luganda",
|
||||
"luo": "Luo",
|
||||
"lb": "Luxembourgish",
|
||||
"mk": "Macedonian",
|
||||
"mad": "Madurese",
|
||||
"mai": "Maithili",
|
||||
"mak": "Makassar",
|
||||
"mg": "Malagasy",
|
||||
"ms": "Malay",
|
||||
"ms-Arab": "Malay (Jawi)",
|
||||
"ml": "Malayalam",
|
||||
"mt": "Maltese",
|
||||
"mam": "Mam",
|
||||
"gv": "Manx",
|
||||
"mi": "Maori",
|
||||
"mr": "Marathi",
|
||||
"mh": "Marshallese",
|
||||
"mwr": "Marwadi",
|
||||
"mfe": "Mauritian Creole",
|
||||
"chm": "Meadow Mari",
|
||||
"mni-Mtei": "Meiteilon (Manipuri)",
|
||||
"min": "Minang",
|
||||
"lus": "Mizo",
|
||||
"mn": "Mongolian",
|
||||
"my": "Myanmar (Burmese)",
|
||||
"nhe": "Nahuatl (Eastern Huasteca)",
|
||||
"ndc-ZW": "Ndau",
|
||||
"nr": "Ndebele (South)",
|
||||
"new": "Nepalbhasa (Newari)",
|
||||
"ne": "Nepali",
|
||||
"bm-Nkoo": "NKo",
|
||||
"no": "Norwegian",
|
||||
"nus": "Nuer",
|
||||
"oc": "Occitan",
|
||||
"or": "Odia (Oriya)",
|
||||
"om": "Oromo",
|
||||
"os": "Ossetian",
|
||||
"pag": "Pangasinan",
|
||||
"pap": "Papiamento",
|
||||
"ps": "Pashto",
|
||||
"fa": "Persian",
|
||||
"pl": "Polish",
|
||||
"pt": "Portuguese (Brazil)",
|
||||
"pt-PT": "Portuguese (Portugal)",
|
||||
"pa": "Punjabi (Gurmukhi)",
|
||||
"pa-Arab": "Punjabi (Shahmukhi)",
|
||||
"qu": "Quechua",
|
||||
"kek": "Qʼeqchiʼ",
|
||||
"rom": "Romani",
|
||||
"ro": "Romanian",
|
||||
"rn": "Rundi",
|
||||
"ru": "Russian",
|
||||
"se": "Sami (North)",
|
||||
"sm": "Samoan",
|
||||
"sg": "Sango",
|
||||
"sa": "Sanskrit",
|
||||
"sat-Latn": "Santali (Latin)",
|
||||
"sat": "Santali (Ol Chiki)",
|
||||
"gd": "Scots Gaelic",
|
||||
"nso": "Sepedi",
|
||||
"sr": "Serbian",
|
||||
"st": "Sesotho",
|
||||
"crs": "Seychellois Creole",
|
||||
"shn": "Shan",
|
||||
"sn": "Shona",
|
||||
"scn": "Sicilian",
|
||||
"szl": "Silesian",
|
||||
"sd": "Sindhi",
|
||||
"si": "Sinhala",
|
||||
"sk": "Slovak",
|
||||
"sl": "Slovenian",
|
||||
"so": "Somali",
|
||||
"es": "Spanish",
|
||||
"su": "Sundanese",
|
||||
"sus": "Susu",
|
||||
"sw": "Swahili",
|
||||
"ss": "Swati",
|
||||
"sv": "Swedish",
|
||||
"ty": "Tahitian",
|
||||
"tg": "Tajik",
|
||||
"ber-Latn": "Tamazight",
|
||||
"ber": "Tamazight (Tifinagh)",
|
||||
"ta": "Tamil",
|
||||
"tt": "Tatar",
|
||||
"te": "Telugu",
|
||||
"tet": "Tetum",
|
||||
"th": "Thai",
|
||||
"bo": "Tibetan",
|
||||
"ti": "Tigrinya",
|
||||
"tiv": "Tiv",
|
||||
"tpi": "Tok Pisin",
|
||||
"to": "Tongan",
|
||||
"lua": "Tshiluba",
|
||||
"ts": "Tsonga",
|
||||
"tn": "Tswana",
|
||||
"tcy": "Tulu",
|
||||
"tum": "Tumbuka",
|
||||
"tr": "Turkish",
|
||||
"tk": "Turkmen",
|
||||
"tyv": "Tuvan",
|
||||
"ak": "Twi",
|
||||
"udm": "Udmurt",
|
||||
"uk": "Ukrainian",
|
||||
"ur": "Urdu",
|
||||
"ug": "Uyghur",
|
||||
"uz": "Uzbek",
|
||||
"ve": "Venda",
|
||||
"vec": "Venetian",
|
||||
"vi": "Vietnamese",
|
||||
"war": "Waray",
|
||||
"cy": "Welsh",
|
||||
"wo": "Wolof",
|
||||
"xh": "Xhosa",
|
||||
"sah": "Yakut",
|
||||
"yi": "Yiddish",
|
||||
"yo": "Yoruba",
|
||||
"yua": "Yucatec Maya",
|
||||
"zap": "Zapotec",
|
||||
"zu": "Zulu"
|
||||
},
|
||||
"tl": {
|
||||
"ab": "Abkhaz",
|
||||
"ace": "Acehnese",
|
||||
"ach": "Acholi",
|
||||
"aa": "Afar",
|
||||
"af": "Afrikaans",
|
||||
"sq": "Albanian",
|
||||
"alz": "Alur",
|
||||
"am": "Amharic",
|
||||
"ar": "Arabic",
|
||||
"hy": "Armenian",
|
||||
"as": "Assamese",
|
||||
"av": "Avar",
|
||||
"awa": "Awadhi",
|
||||
"ay": "Aymara",
|
||||
"az": "Azerbaijani",
|
||||
"ban": "Balinese",
|
||||
"bal": "Baluchi",
|
||||
"bm": "Bambara",
|
||||
"bci": "Baoulé",
|
||||
"ba": "Bashkir",
|
||||
"eu": "Basque",
|
||||
"btx": "Batak Karo",
|
||||
"bts": "Batak Simalungun",
|
||||
"bbc": "Batak Toba",
|
||||
"be": "Belarusian",
|
||||
"bem": "Bemba",
|
||||
"bn": "Bengali",
|
||||
"bew": "Betawi",
|
||||
"bho": "Bhojpuri",
|
||||
"bik": "Bikol",
|
||||
"bs": "Bosnian",
|
||||
"br": "Breton",
|
||||
"bg": "Bulgarian",
|
||||
"bua": "Buryat",
|
||||
"yue": "Cantonese",
|
||||
"ca": "Catalan",
|
||||
"ceb": "Cebuano",
|
||||
"ch": "Chamorro",
|
||||
"ce": "Chechen",
|
||||
"ny": "Chichewa",
|
||||
"zh-CN": "Chinese (Simplified)",
|
||||
"zh-TW": "Chinese (Traditional)",
|
||||
"chk": "Chuukese",
|
||||
"cv": "Chuvash",
|
||||
"co": "Corsican",
|
||||
"crh": "Crimean Tatar (Cyrillic)",
|
||||
"crh-Latn": "Crimean Tatar (Latin)",
|
||||
"hr": "Croatian",
|
||||
"cs": "Czech",
|
||||
"da": "Danish",
|
||||
"fa-AF": "Dari",
|
||||
"dv": "Dhivehi",
|
||||
"din": "Dinka",
|
||||
"doi": "Dogri",
|
||||
"dov": "Dombe",
|
||||
"nl": "Dutch",
|
||||
"dyu": "Dyula",
|
||||
"dz": "Dzongkha",
|
||||
"en": "English",
|
||||
"eo": "Esperanto",
|
||||
"et": "Estonian",
|
||||
"ee": "Ewe",
|
||||
"fo": "Faroese",
|
||||
"fj": "Fijian",
|
||||
"tl": "Filipino",
|
||||
"fi": "Finnish",
|
||||
"fon": "Fon",
|
||||
"fr": "French",
|
||||
"fr-CA": "French (Canada)",
|
||||
"fy": "Frisian",
|
||||
"fur": "Friulian",
|
||||
"ff": "Fulani",
|
||||
"gaa": "Ga",
|
||||
"gl": "Galician",
|
||||
"ka": "Georgian",
|
||||
"de": "German",
|
||||
"el": "Greek",
|
||||
"gn": "Guarani",
|
||||
"gu": "Gujarati",
|
||||
"ht": "Haitian Creole",
|
||||
"cnh": "Hakha Chin",
|
||||
"ha": "Hausa",
|
||||
"haw": "Hawaiian",
|
||||
"iw": "Hebrew",
|
||||
"hil": "Hiligaynon",
|
||||
"hi": "Hindi",
|
||||
"hmn": "Hmong",
|
||||
"hu": "Hungarian",
|
||||
"hrx": "Hunsrik",
|
||||
"iba": "Iban",
|
||||
"is": "Icelandic",
|
||||
"ig": "Igbo",
|
||||
"ilo": "Ilocano",
|
||||
"id": "Indonesian",
|
||||
"iu-Latn": "Inuktut (Latin)",
|
||||
"iu": "Inuktut (Syllabics)",
|
||||
"ga": "Irish",
|
||||
"it": "Italian",
|
||||
"jam": "Jamaican Patois",
|
||||
"ja": "Japanese",
|
||||
"jw": "Javanese",
|
||||
"kac": "Jingpo",
|
||||
"kl": "Kalaallisut",
|
||||
"kn": "Kannada",
|
||||
"kr": "Kanuri",
|
||||
"pam": "Kapampangan",
|
||||
"kk": "Kazakh",
|
||||
"kha": "Khasi",
|
||||
"km": "Khmer",
|
||||
"cgg": "Kiga",
|
||||
"kg": "Kikongo",
|
||||
"rw": "Kinyarwanda",
|
||||
"ktu": "Kituba",
|
||||
"trp": "Kokborok",
|
||||
"kv": "Komi",
|
||||
"gom": "Konkani",
|
||||
"ko": "Korean",
|
||||
"kri": "Krio",
|
||||
"ku": "Kurdish (Kurmanji)",
|
||||
"ckb": "Kurdish (Sorani)",
|
||||
"ky": "Kyrgyz",
|
||||
"lo": "Lao",
|
||||
"ltg": "Latgalian",
|
||||
"la": "Latin",
|
||||
"lv": "Latvian",
|
||||
"lij": "Ligurian",
|
||||
"li": "Limburgish",
|
||||
"ln": "Lingala",
|
||||
"lt": "Lithuanian",
|
||||
"lmo": "Lombard",
|
||||
"lg": "Luganda",
|
||||
"luo": "Luo",
|
||||
"lb": "Luxembourgish",
|
||||
"mk": "Macedonian",
|
||||
"mad": "Madurese",
|
||||
"mai": "Maithili",
|
||||
"mak": "Makassar",
|
||||
"mg": "Malagasy",
|
||||
"ms": "Malay",
|
||||
"ms-Arab": "Malay (Jawi)",
|
||||
"ml": "Malayalam",
|
||||
"mt": "Maltese",
|
||||
"mam": "Mam",
|
||||
"gv": "Manx",
|
||||
"mi": "Maori",
|
||||
"mr": "Marathi",
|
||||
"mh": "Marshallese",
|
||||
"mwr": "Marwadi",
|
||||
"mfe": "Mauritian Creole",
|
||||
"chm": "Meadow Mari",
|
||||
"mni-Mtei": "Meiteilon (Manipuri)",
|
||||
"min": "Minang",
|
||||
"lus": "Mizo",
|
||||
"mn": "Mongolian",
|
||||
"my": "Myanmar (Burmese)",
|
||||
"nhe": "Nahuatl (Eastern Huasteca)",
|
||||
"ndc-ZW": "Ndau",
|
||||
"nr": "Ndebele (South)",
|
||||
"new": "Nepalbhasa (Newari)",
|
||||
"ne": "Nepali",
|
||||
"bm-Nkoo": "NKo",
|
||||
"no": "Norwegian",
|
||||
"nus": "Nuer",
|
||||
"oc": "Occitan",
|
||||
"or": "Odia (Oriya)",
|
||||
"om": "Oromo",
|
||||
"os": "Ossetian",
|
||||
"pag": "Pangasinan",
|
||||
"pap": "Papiamento",
|
||||
"ps": "Pashto",
|
||||
"fa": "Persian",
|
||||
"pl": "Polish",
|
||||
"pt": "Portuguese (Brazil)",
|
||||
"pt-PT": "Portuguese (Portugal)",
|
||||
"pa": "Punjabi (Gurmukhi)",
|
||||
"pa-Arab": "Punjabi (Shahmukhi)",
|
||||
"qu": "Quechua",
|
||||
"kek": "Qʼeqchiʼ",
|
||||
"rom": "Romani",
|
||||
"ro": "Romanian",
|
||||
"rn": "Rundi",
|
||||
"ru": "Russian",
|
||||
"se": "Sami (North)",
|
||||
"sm": "Samoan",
|
||||
"sg": "Sango",
|
||||
"sa": "Sanskrit",
|
||||
"sat-Latn": "Santali (Latin)",
|
||||
"sat": "Santali (Ol Chiki)",
|
||||
"gd": "Scots Gaelic",
|
||||
"nso": "Sepedi",
|
||||
"sr": "Serbian",
|
||||
"st": "Sesotho",
|
||||
"crs": "Seychellois Creole",
|
||||
"shn": "Shan",
|
||||
"sn": "Shona",
|
||||
"scn": "Sicilian",
|
||||
"szl": "Silesian",
|
||||
"sd": "Sindhi",
|
||||
"si": "Sinhala",
|
||||
"sk": "Slovak",
|
||||
"sl": "Slovenian",
|
||||
"so": "Somali",
|
||||
"es": "Spanish",
|
||||
"su": "Sundanese",
|
||||
"sus": "Susu",
|
||||
"sw": "Swahili",
|
||||
"ss": "Swati",
|
||||
"sv": "Swedish",
|
||||
"ty": "Tahitian",
|
||||
"tg": "Tajik",
|
||||
"ber-Latn": "Tamazight",
|
||||
"ber": "Tamazight (Tifinagh)",
|
||||
"ta": "Tamil",
|
||||
"tt": "Tatar",
|
||||
"te": "Telugu",
|
||||
"tet": "Tetum",
|
||||
"th": "Thai",
|
||||
"bo": "Tibetan",
|
||||
"ti": "Tigrinya",
|
||||
"tiv": "Tiv",
|
||||
"tpi": "Tok Pisin",
|
||||
"to": "Tongan",
|
||||
"lua": "Tshiluba",
|
||||
"ts": "Tsonga",
|
||||
"tn": "Tswana",
|
||||
"tcy": "Tulu",
|
||||
"tum": "Tumbuka",
|
||||
"tr": "Turkish",
|
||||
"tk": "Turkmen",
|
||||
"tyv": "Tuvan",
|
||||
"ak": "Twi",
|
||||
"udm": "Udmurt",
|
||||
"uk": "Ukrainian",
|
||||
"ur": "Urdu",
|
||||
"ug": "Uyghur",
|
||||
"uz": "Uzbek",
|
||||
"ve": "Venda",
|
||||
"vec": "Venetian",
|
||||
"vi": "Vietnamese",
|
||||
"war": "Waray",
|
||||
"cy": "Welsh",
|
||||
"wo": "Wolof",
|
||||
"xh": "Xhosa",
|
||||
"sah": "Yakut",
|
||||
"yi": "Yiddish",
|
||||
"yo": "Yoruba",
|
||||
"yua": "Yucatec Maya",
|
||||
"zap": "Zapotec",
|
||||
"zu": "Zulu"
|
||||
},
|
||||
"al": {}
|
||||
}
|
Plik diff jest za duży
Load Diff
|
@ -10,7 +10,7 @@ import Icon from '../components/icon';
|
|||
import LangSelector from '../components/lang-selector';
|
||||
import Link from '../components/link';
|
||||
import RelativeTime from '../components/relative-time';
|
||||
import targetLanguages from '../data/lingva-target-languages';
|
||||
import languages from '../data/translang-languages';
|
||||
import { api } from '../utils/api';
|
||||
import getTranslateTargetLanguage from '../utils/get-translate-target-language';
|
||||
import localeCode2Text from '../utils/localeCode2Text';
|
||||
|
@ -32,10 +32,18 @@ const TEXT_SIZES = [14, 15, 16, 17, 18, 19, 20];
|
|||
const {
|
||||
PHANPY_WEBSITE: WEBSITE,
|
||||
PHANPY_PRIVACY_POLICY_URL: PRIVACY_POLICY_URL,
|
||||
PHANPY_TRANSLANG_INSTANCES: TRANSLANG_INSTANCES,
|
||||
PHANPY_IMG_ALT_API_URL: IMG_ALT_API_URL,
|
||||
PHANPY_GIPHY_API_KEY: GIPHY_API_KEY,
|
||||
} = import.meta.env;
|
||||
|
||||
const targetLanguages = Object.entries(languages.tl).map(([code, name]) => ({
|
||||
code,
|
||||
name,
|
||||
}));
|
||||
|
||||
const TRANSLATION_API_NAME = 'TransLang API';
|
||||
|
||||
function Settings({ onClose }) {
|
||||
const { t } = useLingui();
|
||||
const snapStates = useSnapshot(states);
|
||||
|
@ -363,46 +371,77 @@ function Settings({ onClose }) {
|
|||
<Trans>Boosts carousel</Trans>
|
||||
</label>
|
||||
</li>
|
||||
<li class="block">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={snapStates.settings.contentTranslation}
|
||||
onChange={(e) => {
|
||||
const { checked } = e.target;
|
||||
states.settings.contentTranslation = checked;
|
||||
if (!checked) {
|
||||
states.settings.contentTranslationTargetLanguage = null;
|
||||
}
|
||||
}}
|
||||
/>{' '}
|
||||
<Trans>Post translation</Trans>
|
||||
</label>
|
||||
<div
|
||||
class={`sub-section ${
|
||||
!snapStates.settings.contentTranslation
|
||||
? 'more-insignificant'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<label>
|
||||
<Trans>Translate to </Trans>{' '}
|
||||
<select
|
||||
value={targetLanguage || ''}
|
||||
disabled={!snapStates.settings.contentTranslation}
|
||||
style={{ width: '10em' }}
|
||||
onChange={(e) => {
|
||||
states.settings.contentTranslationTargetLanguage =
|
||||
e.target.value || null;
|
||||
}}
|
||||
>
|
||||
<option value="">
|
||||
<Trans>
|
||||
System language ({systemTargetLanguageText})
|
||||
</Trans>
|
||||
</option>
|
||||
<option disabled>──────────</option>
|
||||
{!!TRANSLANG_INSTANCES && (
|
||||
<li class="block">
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={snapStates.settings.contentTranslation}
|
||||
onChange={(e) => {
|
||||
const { checked } = e.target;
|
||||
states.settings.contentTranslation = checked;
|
||||
if (!checked) {
|
||||
states.settings.contentTranslationTargetLanguage = null;
|
||||
}
|
||||
}}
|
||||
/>{' '}
|
||||
<Trans>Post translation</Trans>
|
||||
</label>
|
||||
<div
|
||||
class={`sub-section ${
|
||||
!snapStates.settings.contentTranslation
|
||||
? 'more-insignificant'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
<div>
|
||||
<label>
|
||||
<Trans>Translate to </Trans>{' '}
|
||||
<select
|
||||
value={targetLanguage || ''}
|
||||
disabled={!snapStates.settings.contentTranslation}
|
||||
style={{ width: '10em' }}
|
||||
onChange={(e) => {
|
||||
states.settings.contentTranslationTargetLanguage =
|
||||
e.target.value || null;
|
||||
}}
|
||||
>
|
||||
<option value="">
|
||||
<Trans>
|
||||
System language ({systemTargetLanguageText})
|
||||
</Trans>
|
||||
</option>
|
||||
<option disabled>──────────</option>
|
||||
{targetLanguages.map((lang) => {
|
||||
const common = localeCode2Text({
|
||||
code: lang.code,
|
||||
fallback: lang.name,
|
||||
});
|
||||
const native = localeCode2Text({
|
||||
code: lang.code,
|
||||
locale: lang.code,
|
||||
});
|
||||
const showCommon = native && common !== native;
|
||||
return (
|
||||
<option value={lang.code}>
|
||||
{showCommon ? `${native} - ${common}` : common}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="checkbox-fieldset">
|
||||
<Plural
|
||||
value={
|
||||
snapStates.settings.contentTranslationHideLanguages
|
||||
.length
|
||||
}
|
||||
_0={`Hide "Translate" button for:`}
|
||||
other={`Hide "Translate" button for (#):`}
|
||||
/>
|
||||
<div class="checkbox-fields">
|
||||
{targetLanguages.map((lang) => {
|
||||
const common = localeCode2Text({
|
||||
code: lang.code,
|
||||
|
@ -412,120 +451,86 @@ function Settings({ onClose }) {
|
|||
code: lang.code,
|
||||
locale: lang.code,
|
||||
});
|
||||
const showCommon = common !== native;
|
||||
const showCommon = native && common !== native;
|
||||
return (
|
||||
<option value={lang.code}>
|
||||
{showCommon ? `${native} - ${common}` : common}
|
||||
</option>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={snapStates.settings.contentTranslationHideLanguages.includes(
|
||||
lang.code,
|
||||
)}
|
||||
onChange={(e) => {
|
||||
const { checked } = e.target;
|
||||
if (checked) {
|
||||
states.settings.contentTranslationHideLanguages.push(
|
||||
lang.code,
|
||||
);
|
||||
} else {
|
||||
states.settings.contentTranslationHideLanguages =
|
||||
snapStates.settings.contentTranslationHideLanguages.filter(
|
||||
(code) => code !== lang.code,
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>{' '}
|
||||
{showCommon ? (
|
||||
<span>
|
||||
{native}{' '}
|
||||
<span class="insignificant ib">- {common}</span>
|
||||
</span>
|
||||
) : (
|
||||
common
|
||||
)}
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="checkbox-fieldset">
|
||||
<Plural
|
||||
value={
|
||||
snapStates.settings.contentTranslationHideLanguages.length
|
||||
}
|
||||
_0={`Hide "Translate" button for:`}
|
||||
other={`Hide "Translate" button for (#):`}
|
||||
/>
|
||||
<div class="checkbox-fields">
|
||||
{targetLanguages.map((lang) => {
|
||||
const common = localeCode2Text({
|
||||
code: lang.code,
|
||||
fallback: lang.name,
|
||||
});
|
||||
const native = localeCode2Text({
|
||||
code: lang.code,
|
||||
locale: lang.code,
|
||||
});
|
||||
const showCommon = common !== native;
|
||||
return (
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={snapStates.settings.contentTranslationHideLanguages.includes(
|
||||
lang.code,
|
||||
)}
|
||||
onChange={(e) => {
|
||||
const { checked } = e.target;
|
||||
if (checked) {
|
||||
states.settings.contentTranslationHideLanguages.push(
|
||||
lang.code,
|
||||
);
|
||||
} else {
|
||||
states.settings.contentTranslationHideLanguages =
|
||||
snapStates.settings.contentTranslationHideLanguages.filter(
|
||||
(code) => code !== lang.code,
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>{' '}
|
||||
{showCommon ? (
|
||||
<span>
|
||||
{native}{' '}
|
||||
<span class="insignificant">- {common}</span>
|
||||
</span>
|
||||
) : (
|
||||
common
|
||||
)}
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="insignificant">
|
||||
<small>
|
||||
<Trans>
|
||||
Note: This feature uses external translation services,
|
||||
powered by{' '}
|
||||
<a
|
||||
href="https://github.com/cheeaun/lingva-api"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
Lingva API
|
||||
</a>{' '}
|
||||
&{' '}
|
||||
<a
|
||||
href="https://github.com/thedaviddelta/lingva-translate"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
Lingva Translate
|
||||
</a>
|
||||
.
|
||||
</Trans>
|
||||
</small>
|
||||
</p>
|
||||
<hr />
|
||||
<div>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={snapStates.settings.contentTranslationAutoInline}
|
||||
disabled={!snapStates.settings.contentTranslation}
|
||||
onChange={(e) => {
|
||||
states.settings.contentTranslationAutoInline =
|
||||
e.target.checked;
|
||||
}}
|
||||
/>{' '}
|
||||
<Trans>Auto inline translation</Trans>
|
||||
</label>
|
||||
<p class="insignificant">
|
||||
<small>
|
||||
<Trans>
|
||||
Automatically show translation for posts in timeline.
|
||||
Only works for <b>short</b> posts without content
|
||||
warning, media and poll.
|
||||
Note: This feature uses external translation services,
|
||||
powered by{' '}
|
||||
<a
|
||||
href="https://github.com/cheeaun/translang-api"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
{TRANSLATION_API_NAME}
|
||||
</a>
|
||||
.
|
||||
</Trans>
|
||||
</small>
|
||||
</p>
|
||||
<hr />
|
||||
<div>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={
|
||||
snapStates.settings.contentTranslationAutoInline
|
||||
}
|
||||
disabled={!snapStates.settings.contentTranslation}
|
||||
onChange={(e) => {
|
||||
states.settings.contentTranslationAutoInline =
|
||||
e.target.checked;
|
||||
}}
|
||||
/>{' '}
|
||||
<Trans>Auto inline translation</Trans>
|
||||
</label>
|
||||
<p class="insignificant">
|
||||
<small>
|
||||
<Trans>
|
||||
Automatically show translation for posts in timeline.
|
||||
Only works for <b>short</b> posts without content
|
||||
warning, media and poll.
|
||||
</Trans>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</li>
|
||||
)}
|
||||
{!!GIPHY_API_KEY && authenticated && (
|
||||
<li class="block">
|
||||
<label>
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
import translationTargetLanguages from '../data/lingva-target-languages';
|
||||
import languages from '../data/translang-languages';
|
||||
|
||||
import localeMatch from './locale-match';
|
||||
import mem from './mem';
|
||||
import states from './states';
|
||||
|
||||
const translationTargetLanguages = Object.entries(languages).map(
|
||||
([code, { name }]) => ({
|
||||
code,
|
||||
name,
|
||||
}),
|
||||
);
|
||||
|
||||
const locales = mem(() => [
|
||||
new Intl.DateTimeFormat().resolvedOptions().locale,
|
||||
...navigator.languages,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { i18n } from '@lingui/core';
|
||||
|
||||
import translangLanguagesNative from '../data/translang-languages-native';
|
||||
|
||||
import mem from './mem';
|
||||
|
||||
// Some codes are not supported by Intl.DisplayNames
|
||||
|
@ -28,6 +30,8 @@ function _localeCode2Text(code) {
|
|||
if (!fallback) {
|
||||
const anotherText = IntlDN(code).of(code);
|
||||
if (anotherText !== code) return anotherText;
|
||||
const yetAnotherText = translangLanguagesNative?.[locale];
|
||||
if (yetAnotherText !== code) return yetAnotherText;
|
||||
}
|
||||
return fallback || '';
|
||||
} catch (e) {
|
||||
|
|
Ładowanie…
Reference in New Issue