Experimental language selector in Compose field

This commit is contained in:
Lim Chee Aun 2022-12-27 18:09:23 +08:00
parent 43e0f51bcf
commit cf42aab4b7
6 changed files with 1048 additions and 3 deletions

View file

@ -0,0 +1,20 @@
import fs from 'fs';
const url = 'https://mastodon.social/';
const html = await fetch(url).then((res) => res.text());
// Extract the JSON between <script id="initial-state" type="application/json"></script>
const json = html.match(
/<script id="initial-state" type="application\/json">(.*)<\/script>/,
)[1];
const initialState = JSON.parse(json);
const { languages } = initialState;
console.log(`Found ${languages.length} languages`);
// Write to file
const path = './src/data/status-supported-languages.json';
fs.writeFileSync(path, JSON.stringify(languages, null, '\t'), 'utf8');
console.log(`Wrote ${path}`);

View file

@ -184,6 +184,15 @@
filter: brightness(0.8);
}
#compose-container .toolbar-button .icon-text {
display: inline-block;
font-size: 14px;
font-weight: 500;
text-overflow: ellipsis;
overflow: hidden;
max-width: 100%;
}
#compose-container text-expander {
position: relative;
}

View file

@ -4,6 +4,7 @@ import '@github/text-expander-element';
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
import stringLength from 'string-length';
import supportedLanguages from '../data/status-supported-languages';
import urlRegex from '../data/url-regex';
import emojifyText from '../utils/emojify-text';
import openCompose from '../utils/open-compose';
@ -15,6 +16,15 @@ import Icon from './icon';
import Loader from './loader';
import Status from './status';
const supportedLanguagesMap = supportedLanguages.reduce((acc, l) => {
const [code, common, native] = l;
acc[code] = {
common,
native,
};
return acc;
}, {});
/* NOTES:
- Max character limit includes BOTH status text and Content Warning text
*/
@ -93,6 +103,9 @@ function Compose({
const spoilerTextRef = useRef();
const [visibility, setVisibility] = useState('public');
const [sensitive, setSensitive] = useState(false);
const [language, setLanguage] = useState(
store.session.get('currentLanguage') || 'en',
);
const [mediaAttachments, setMediaAttachments] = useState([]);
const [poll, setPoll] = useState(null);
@ -122,7 +135,7 @@ function Compose({
useEffect(() => {
if (replyToStatus) {
const { spoilerText, visibility, sensitive } = replyToStatus;
const { spoilerText, visibility, language, sensitive } = replyToStatus;
if (spoilerText && spoilerTextRef.current) {
spoilerTextRef.current.value = spoilerText;
}
@ -141,6 +154,7 @@ function Compose({
}
focusTextarea();
setVisibility(visibility);
setLanguage(language);
setSensitive(sensitive);
}
if (draftStatus) {
@ -148,6 +162,7 @@ function Compose({
status,
spoilerText,
visibility,
language,
sensitive,
poll,
mediaAttachments,
@ -162,11 +177,13 @@ function Compose({
focusTextarea();
spoilerTextRef.current.value = spoilerText;
setVisibility(visibility);
setLanguage(language);
setSensitive(sensitive);
setPoll(composablePoll);
setMediaAttachments(mediaAttachments);
} else if (editStatus) {
const { visibility, sensitive, poll, mediaAttachments } = editStatus;
const { visibility, language, sensitive, poll, mediaAttachments } =
editStatus;
const composablePoll = !!poll?.options && {
...poll,
options: poll.options.map((o) => o?.title || o),
@ -186,6 +203,7 @@ function Compose({
focusTextarea();
spoilerTextRef.current.value = spoilerText;
setVisibility(visibility);
setLanguage(language);
setSensitive(sensitive);
setPoll(composablePoll);
setMediaAttachments(mediaAttachments);
@ -465,6 +483,7 @@ function Compose({
status: textareaRef.current.value,
spoilerText: spoilerTextRef.current.value,
visibility,
language,
sensitive,
poll,
mediaAttachments: mediaAttachmentsWithIDs,
@ -539,6 +558,7 @@ function Compose({
status: textareaRef.current.value,
spoilerText: spoilerTextRef.current.value,
visibility,
language,
sensitive,
poll,
mediaAttachments: mediaAttachmentsWithIDs,
@ -675,6 +695,7 @@ function Compose({
status,
// spoilerText,
spoiler_text: spoilerText,
language,
sensitive,
poll,
// mediaIds: mediaAttachments.map((attachment) => attachment.id),
@ -932,6 +953,31 @@ function Compose({
/>{' '}
</>
)}
<label class="toolbar-button">
<span class="icon-text">
{supportedLanguagesMap[language].native}
</span>
<select
name="language"
value={language}
onChange={(e) => {
const { value } = e.target;
setLanguage(value);
store.session.set('language', value);
}}
disabled={uiState === 'loading'}
>
{supportedLanguages
.sort(([, commonA], [, commonB]) => {
return commonA.localeCompare(commonB);
})
.map(([code, common, native]) => (
<option value={code}>
{common} ({native})
</option>
))}
</select>
</label>{' '}
<button type="submit" class="large" disabled={uiState === 'loading'}>
{replyToStatus ? 'Reply' : editStatus ? 'Update' : 'Post'}
</button>

View file

@ -45,6 +45,7 @@ const ICONS = {
reply: ['mingcute:share-forward-line', '180deg', 'horizontal'],
thread: 'mingcute:route-line',
group: 'mingcute:group-line',
bot: 'mingcute:android-2-line',
};
function Icon({ icon, size = 'm', alt, title, class: className = '' }) {

View file

@ -385,6 +385,7 @@ function Status({
/>
{!!poll && (
<Poll
lang={language}
poll={poll}
readOnly={readOnly}
onUpdate={(newPoll) => {
@ -926,7 +927,7 @@ function Card({ card }) {
}
}
function Poll({ poll, readOnly, onUpdate = () => {} }) {
function Poll({ poll, lang, readOnly, onUpdate = () => {} }) {
const [uiState, setUIState] = useState('default');
const {
@ -980,6 +981,7 @@ function Poll({ poll, readOnly, onUpdate = () => {} }) {
return (
<div
lang={lang}
class={`poll ${readOnly ? 'read-only' : ''} ${
uiState === 'loading' ? 'loading' : ''
}`}

View file

@ -0,0 +1,967 @@
[
[
"aa",
"Afar",
"Afaraf"
],
[
"ab",
"Abkhaz",
"аҧсуа бызшәа"
],
[
"ae",
"Avestan",
"avesta"
],
[
"af",
"Afrikaans",
"Afrikaans"
],
[
"ak",
"Akan",
"Akan"
],
[
"am",
"Amharic",
"አማርኛ"
],
[
"an",
"Aragonese",
"aragonés"
],
[
"ar",
"Arabic",
"اللغة العربية"
],
[
"as",
"Assamese",
"অসমীয়া"
],
[
"av",
"Avaric",
"авар мацӀ"
],
[
"ay",
"Aymara",
"aymar aru"
],
[
"az",
"Azerbaijani",
"azərbaycan dili"
],
[
"ba",
"Bashkir",
"башҡорт теле"
],
[
"be",
"Belarusian",
"беларуская мова"
],
[
"bg",
"Bulgarian",
"български език"
],
[
"bh",
"Bihari",
"भोजपुरी"
],
[
"bi",
"Bislama",
"Bislama"
],
[
"bm",
"Bambara",
"bamanankan"
],
[
"bn",
"Bengali",
"বাংলা"
],
[
"bo",
"Tibetan",
"བོད་ཡིག"
],
[
"br",
"Breton",
"brezhoneg"
],
[
"bs",
"Bosnian",
"bosanski jezik"
],
[
"ca",
"Catalan",
"Català"
],
[
"ce",
"Chechen",
"нохчийн мотт"
],
[
"ch",
"Chamorro",
"Chamoru"
],
[
"co",
"Corsican",
"corsu"
],
[
"cr",
"Cree",
"ᓀᐦᐃᔭᐍᐏᐣ"
],
[
"cs",
"Czech",
"čeština"
],
[
"cu",
"Old Church Slavonic",
"ѩзыкъ словѣньскъ"
],
[
"cv",
"Chuvash",
"чӑваш чӗлхи"
],
[
"cy",
"Welsh",
"Cymraeg"
],
[
"da",
"Danish",
"dansk"
],
[
"de",
"German",
"Deutsch"
],
[
"dv",
"Divehi",
"Dhivehi"
],
[
"dz",
"Dzongkha",
"རྫོང་ཁ"
],
[
"ee",
"Ewe",
"Eʋegbe"
],
[
"el",
"Greek",
"Ελληνικά"
],
[
"en",
"English",
"English"
],
[
"eo",
"Esperanto",
"Esperanto"
],
[
"es",
"Spanish",
"Español"
],
[
"et",
"Estonian",
"eesti"
],
[
"eu",
"Basque",
"euskara"
],
[
"fa",
"Persian",
"فارسی"
],
[
"ff",
"Fula",
"Fulfulde"
],
[
"fi",
"Finnish",
"suomi"
],
[
"fj",
"Fijian",
"Vakaviti"
],
[
"fo",
"Faroese",
"føroyskt"
],
[
"fr",
"French",
"Français"
],
[
"fy",
"Western Frisian",
"Frysk"
],
[
"ga",
"Irish",
"Gaeilge"
],
[
"gd",
"Scottish Gaelic",
"Gàidhlig"
],
[
"gl",
"Galician",
"galego"
],
[
"gu",
"Gujarati",
"ગુજરાતી"
],
[
"gv",
"Manx",
"Gaelg"
],
[
"ha",
"Hausa",
"هَوُسَ"
],
[
"he",
"Hebrew",
"עברית"
],
[
"hi",
"Hindi",
"हिन्दी"
],
[
"ho",
"Hiri Motu",
"Hiri Motu"
],
[
"hr",
"Croatian",
"Hrvatski"
],
[
"ht",
"Haitian",
"Kreyòl ayisyen"
],
[
"hu",
"Hungarian",
"magyar"
],
[
"hy",
"Armenian",
"Հայերեն"
],
[
"hz",
"Herero",
"Otjiherero"
],
[
"ia",
"Interlingua",
"Interlingua"
],
[
"id",
"Indonesian",
"Bahasa Indonesia"
],
[
"ie",
"Interlingue",
"Interlingue"
],
[
"ig",
"Igbo",
"Asụsụ Igbo"
],
[
"ii",
"Nuosu",
"ꆈꌠ꒿ Nuosuhxop"
],
[
"ik",
"Inupiaq",
"Iñupiaq"
],
[
"io",
"Ido",
"Ido"
],
[
"is",
"Icelandic",
"Íslenska"
],
[
"it",
"Italian",
"Italiano"
],
[
"iu",
"Inuktitut",
"ᐃᓄᒃᑎᑐᑦ"
],
[
"ja",
"Japanese",
"日本語"
],
[
"jv",
"Javanese",
"basa Jawa"
],
[
"ka",
"Georgian",
"ქართული"
],
[
"kg",
"Kongo",
"Kikongo"
],
[
"ki",
"Kikuyu",
"Gĩkũyũ"
],
[
"kj",
"Kwanyama",
"Kuanyama"
],
[
"kk",
"Kazakh",
"қазақ тілі"
],
[
"kl",
"Kalaallisut",
"kalaallisut"
],
[
"km",
"Khmer",
"ខេមរភាសា"
],
[
"kn",
"Kannada",
"ಕನ್ನಡ"
],
[
"ko",
"Korean",
"한국어"
],
[
"kr",
"Kanuri",
"Kanuri"
],
[
"ks",
"Kashmiri",
"कश्मीरी"
],
[
"ku",
"Kurmanji (Kurdish)",
"Kurmancî"
],
[
"kv",
"Komi",
"коми кыв"
],
[
"kw",
"Cornish",
"Kernewek"
],
[
"ky",
"Kyrgyz",
"Кыргызча"
],
[
"la",
"Latin",
"latine"
],
[
"lb",
"Luxembourgish",
"Lëtzebuergesch"
],
[
"lg",
"Ganda",
"Luganda"
],
[
"li",
"Limburgish",
"Limburgs"
],
[
"ln",
"Lingala",
"Lingála"
],
[
"lo",
"Lao",
"ລາວ"
],
[
"lt",
"Lithuanian",
"lietuvių kalba"
],
[
"lu",
"Luba-Katanga",
"Tshiluba"
],
[
"lv",
"Latvian",
"latviešu valoda"
],
[
"mg",
"Malagasy",
"fiteny malagasy"
],
[
"mh",
"Marshallese",
"Kajin M̧ajeļ"
],
[
"mi",
"Māori",
"te reo Māori"
],
[
"mk",
"Macedonian",
"македонски јазик"
],
[
"ml",
"Malayalam",
"മലയാളം"
],
[
"mn",
"Mongolian",
"Монгол хэл"
],
[
"mr",
"Marathi",
"मराठी"
],
[
"ms",
"Malay",
"Bahasa Melayu"
],
[
"mt",
"Maltese",
"Malti"
],
[
"my",
"Burmese",
"ဗမာစာ"
],
[
"na",
"Nauru",
"Ekakairũ Naoero"
],
[
"nb",
"Norwegian Bokmål",
"Norsk bokmål"
],
[
"nd",
"Northern Ndebele",
"isiNdebele"
],
[
"ne",
"Nepali",
"नेपाली"
],
[
"ng",
"Ndonga",
"Owambo"
],
[
"nl",
"Dutch",
"Nederlands"
],
[
"nn",
"Norwegian Nynorsk",
"Norsk Nynorsk"
],
[
"no",
"Norwegian",
"Norsk"
],
[
"nr",
"Southern Ndebele",
"isiNdebele"
],
[
"nv",
"Navajo",
"Diné bizaad"
],
[
"ny",
"Chichewa",
"chiCheŵa"
],
[
"oc",
"Occitan",
"occitan"
],
[
"oj",
"Ojibwe",
"ᐊᓂᔑᓈᐯᒧᐎᓐ"
],
[
"om",
"Oromo",
"Afaan Oromoo"
],
[
"or",
"Oriya",
"ଓଡ଼ିଆ"
],
[
"os",
"Ossetian",
"ирон æвзаг"
],
[
"pa",
"Panjabi",
"ਪੰਜਾਬੀ"
],
[
"pi",
"Pāli",
"पाऴि"
],
[
"pl",
"Polish",
"Polski"
],
[
"ps",
"Pashto",
"پښتو"
],
[
"pt",
"Portuguese",
"Português"
],
[
"qu",
"Quechua",
"Runa Simi"
],
[
"rm",
"Romansh",
"rumantsch grischun"
],
[
"rn",
"Kirundi",
"Ikirundi"
],
[
"ro",
"Romanian",
"Română"
],
[
"ru",
"Russian",
"Русский"
],
[
"rw",
"Kinyarwanda",
"Ikinyarwanda"
],
[
"sa",
"Sanskrit",
"संस्कृतम्"
],
[
"sc",
"Sardinian",
"sardu"
],
[
"sd",
"Sindhi",
"सिन्धी"
],
[
"se",
"Northern Sami",
"Davvisámegiella"
],
[
"sg",
"Sango",
"yângâ tî sängö"
],
[
"si",
"Sinhala",
"සිංහල"
],
[
"sk",
"Slovak",
"slovenčina"
],
[
"sl",
"Slovenian",
"slovenščina"
],
[
"sn",
"Shona",
"chiShona"
],
[
"so",
"Somali",
"Soomaaliga"
],
[
"sq",
"Albanian",
"Shqip"
],
[
"sr",
"Serbian",
"српски језик"
],
[
"ss",
"Swati",
"SiSwati"
],
[
"st",
"Southern Sotho",
"Sesotho"
],
[
"su",
"Sundanese",
"Basa Sunda"
],
[
"sv",
"Swedish",
"Svenska"
],
[
"sw",
"Swahili",
"Kiswahili"
],
[
"ta",
"Tamil",
"தமிழ்"
],
[
"te",
"Telugu",
"తెలుగు"
],
[
"tg",
"Tajik",
"тоҷикӣ"
],
[
"th",
"Thai",
"ไทย"
],
[
"ti",
"Tigrinya",
"ትግርኛ"
],
[
"tk",
"Turkmen",
"Türkmen"
],
[
"tl",
"Tagalog",
"Wikang Tagalog"
],
[
"tn",
"Tswana",
"Setswana"
],
[
"to",
"Tonga",
"faka Tonga"
],
[
"tr",
"Turkish",
"Türkçe"
],
[
"ts",
"Tsonga",
"Xitsonga"
],
[
"tt",
"Tatar",
"татар теле"
],
[
"tw",
"Twi",
"Twi"
],
[
"ty",
"Tahitian",
"Reo Tahiti"
],
[
"ug",
"Uyghur",
"ئۇيغۇرچە‎"
],
[
"uk",
"Ukrainian",
"Українська"
],
[
"ur",
"Urdu",
"اردو"
],
[
"uz",
"Uzbek",
"Ўзбек"
],
[
"ve",
"Venda",
"Tshivenḓa"
],
[
"vi",
"Vietnamese",
"Tiếng Việt"
],
[
"vo",
"Volapük",
"Volapük"
],
[
"wa",
"Walloon",
"walon"
],
[
"wo",
"Wolof",
"Wollof"
],
[
"xh",
"Xhosa",
"isiXhosa"
],
[
"yi",
"Yiddish",
"ייִדיש"
],
[
"yo",
"Yoruba",
"Yorùbá"
],
[
"za",
"Zhuang",
"Saɯ cueŋƅ"
],
[
"zh",
"Chinese",
"中文"
],
[
"zu",
"Zulu",
"isiZulu"
],
[
"ast",
"Asturian",
"Asturianu"
],
[
"ckb",
"Sorani (Kurdish)",
"سۆرانی"
],
[
"jbo",
"Lojban",
"la .lojban."
],
[
"kab",
"Kabyle",
"Taqbaylit"
],
[
"kmr",
"Kurmanji (Kurdish)",
"Kurmancî"
],
[
"ldn",
"Láadan",
"Láadan"
],
[
"lfn",
"Lingua Franca Nova",
"lingua franca nova"
],
[
"sco",
"Scots",
"Scots"
],
[
"tok",
"Toki Pona",
"toki pona"
],
[
"zba",
"Balaibalan",
"باليبلن"
],
[
"zgh",
"Standard Moroccan Tamazight",
"ⵜⴰⵎⴰⵣⵉⵖⵜ"
]
]