mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-22 23:20:44 +01:00
Add warning when selected and detected language is different in web UI
This commit is contained in:
parent
27e79da6b9
commit
e3dc8200be
6 changed files with 105 additions and 3 deletions
|
@ -238,6 +238,7 @@ class LanguageDropdown extends PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
value: PropTypes.string,
|
value: PropTypes.string,
|
||||||
frequentlyUsedLanguages: PropTypes.arrayOf(PropTypes.string),
|
frequentlyUsedLanguages: PropTypes.arrayOf(PropTypes.string),
|
||||||
|
guess: PropTypes.string,
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
@ -281,7 +282,7 @@ class LanguageDropdown extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, intl, frequentlyUsedLanguages } = this.props;
|
const { value, guess, intl, frequentlyUsedLanguages } = this.props;
|
||||||
const { open, placement } = this.state;
|
const { open, placement } = this.state;
|
||||||
const current = preloadedLanguages.find(lang => lang[0] === value) ?? [];
|
const current = preloadedLanguages.find(lang => lang[0] === value) ?? [];
|
||||||
|
|
||||||
|
@ -294,7 +295,7 @@ class LanguageDropdown extends PureComponent {
|
||||||
onClick={this.handleToggle}
|
onClick={this.handleToggle}
|
||||||
onMouseDown={this.handleMouseDown}
|
onMouseDown={this.handleMouseDown}
|
||||||
onKeyDown={this.handleButtonKeyDown}
|
onKeyDown={this.handleButtonKeyDown}
|
||||||
className={classNames('dropdown-button', { active: open })}
|
className={classNames('dropdown-button', { active: open, warning: guess !== '' && guess !== value })}
|
||||||
>
|
>
|
||||||
<Icon icon={TranslateIcon} />
|
<Icon icon={TranslateIcon} />
|
||||||
<span className='dropdown-button__label'>{current[2] ?? value}</span>
|
<span className='dropdown-button__label'>{current[2] ?? value}</span>
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { Map as ImmutableMap } from 'immutable';
|
import { Map as ImmutableMap } from 'immutable';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import lande from 'lande';
|
||||||
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
import { changeComposeLanguage } from 'mastodon/actions/compose';
|
import { changeComposeLanguage } from 'mastodon/actions/compose';
|
||||||
|
|
||||||
|
@ -16,9 +18,80 @@ const getFrequentlyUsedLanguages = createSelector([
|
||||||
.toArray()
|
.toArray()
|
||||||
));
|
));
|
||||||
|
|
||||||
|
const ISO_639_MAP = {
|
||||||
|
afr: 'af', // Afrikaans
|
||||||
|
ara: 'ar', // Arabic
|
||||||
|
aze: 'az', // Azerbaijani
|
||||||
|
bel: 'be', // Belarusian
|
||||||
|
ben: 'bn', // Bengali
|
||||||
|
bul: 'bg', // Bulgarian
|
||||||
|
cat: 'ca', // Catalan
|
||||||
|
ces: 'cs', // Czech
|
||||||
|
ckb: 'ku', // Kurdish
|
||||||
|
cmn: 'zh', // Mandarin
|
||||||
|
dan: 'da', // Danish
|
||||||
|
deu: 'de', // German
|
||||||
|
ell: 'el', // Greek
|
||||||
|
eng: 'en', // English
|
||||||
|
est: 'et', // Estonian
|
||||||
|
eus: 'eu', // Basque
|
||||||
|
fin: 'fi', // Finnish
|
||||||
|
fra: 'fr', // French
|
||||||
|
hau: 'ha', // Hausa
|
||||||
|
heb: 'he', // Hebrew
|
||||||
|
hin: 'hi', // Hindi
|
||||||
|
hrv: 'hr', // Croatian
|
||||||
|
hun: 'hu', // Hungarian
|
||||||
|
hye: 'hy', // Armenian
|
||||||
|
ind: 'id', // Indonesian
|
||||||
|
isl: 'is', // Icelandic
|
||||||
|
ita: 'it', // Italian
|
||||||
|
jpn: 'ja', // Japanese
|
||||||
|
kat: 'ka', // Georgian
|
||||||
|
kaz: 'kk', // Kazakh
|
||||||
|
kor: 'ko', // Korean
|
||||||
|
lit: 'lt', // Lithuanian
|
||||||
|
mar: 'mr', // Marathi
|
||||||
|
mkd: 'mk', // Macedonian
|
||||||
|
nld: 'nl', // Dutch
|
||||||
|
nob: 'no', // Norwegian
|
||||||
|
pes: 'fa', // Persian
|
||||||
|
pol: 'pl', // Polish
|
||||||
|
por: 'pt', // Portuguese
|
||||||
|
ron: 'ro', // Romanian
|
||||||
|
run: 'rn', // Rundi
|
||||||
|
rus: 'ru', // Russian
|
||||||
|
slk: 'sk', // Slovak
|
||||||
|
spa: 'es', // Spanish
|
||||||
|
srp: 'sr', // Serbian
|
||||||
|
swe: 'sv', // Swedish
|
||||||
|
tgl: 'tl', // Tagalog
|
||||||
|
tur: 'tr', // Turkish
|
||||||
|
ukr: 'uk', // Ukrainian
|
||||||
|
vie: 'vi', // Vietnamese
|
||||||
|
};
|
||||||
|
|
||||||
|
const debouncedLande = debounce((text) => lande(text), 500, { trailing: true });
|
||||||
|
|
||||||
|
const detectedLanguage = createSelector([
|
||||||
|
state => state.getIn(['compose', 'text']),
|
||||||
|
], text => {
|
||||||
|
if (text.length > 20) {
|
||||||
|
const guesses = debouncedLande(text);
|
||||||
|
const [lang, confidence] = guesses[0];
|
||||||
|
|
||||||
|
if (confidence > 0.8) {
|
||||||
|
return ISO_639_MAP[lang];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
frequentlyUsedLanguages: getFrequentlyUsedLanguages(state),
|
frequentlyUsedLanguages: getFrequentlyUsedLanguages(state),
|
||||||
value: state.getIn(['compose', 'language']),
|
value: state.getIn(['compose', 'language']),
|
||||||
|
guess: detectedLanguage(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
|
|
@ -935,6 +935,16 @@ body > [data-popper-placement] {
|
||||||
border-color: $ui-highlight-color;
|
border-color: $ui-highlight-color;
|
||||||
color: $primary-text-color;
|
color: $primary-text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
border-color: var(--goldenrod-2);
|
||||||
|
color: var(--goldenrod-2);
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: var(--goldenrod-2);
|
||||||
|
color: var(--indigo-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.character-counter {
|
.character-counter {
|
||||||
|
|
|
@ -4,7 +4,7 @@ const { env, settings } = require('../configuration');
|
||||||
|
|
||||||
// Those modules contain modern ES code that need to be transpiled for Webpack to process it
|
// Those modules contain modern ES code that need to be transpiled for Webpack to process it
|
||||||
const nodeModulesToProcess = [
|
const nodeModulesToProcess = [
|
||||||
'@reduxjs', 'fuzzysort'
|
'@reduxjs', 'fuzzysort', 'toygrad'
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -82,6 +82,7 @@
|
||||||
"imports-loader": "^1.2.0",
|
"imports-loader": "^1.2.0",
|
||||||
"intl-messageformat": "^10.3.5",
|
"intl-messageformat": "^10.3.5",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
|
"lande": "^1.0.10",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mark-loader": "^0.1.6",
|
"mark-loader": "^0.1.6",
|
||||||
"marky": "^1.2.5",
|
"marky": "^1.2.5",
|
||||||
|
|
17
yarn.lock
17
yarn.lock
|
@ -2930,6 +2930,7 @@ __metadata:
|
||||||
jest: "npm:^29.5.0"
|
jest: "npm:^29.5.0"
|
||||||
jest-environment-jsdom: "npm:^29.5.0"
|
jest-environment-jsdom: "npm:^29.5.0"
|
||||||
js-yaml: "npm:^4.1.0"
|
js-yaml: "npm:^4.1.0"
|
||||||
|
lande: "npm:^1.0.10"
|
||||||
lint-staged: "npm:^15.0.0"
|
lint-staged: "npm:^15.0.0"
|
||||||
lodash: "npm:^4.17.21"
|
lodash: "npm:^4.17.21"
|
||||||
mark-loader: "npm:^0.1.6"
|
mark-loader: "npm:^0.1.6"
|
||||||
|
@ -11322,6 +11323,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"lande@npm:^1.0.10":
|
||||||
|
version: 1.0.10
|
||||||
|
resolution: "lande@npm:1.0.10"
|
||||||
|
dependencies:
|
||||||
|
toygrad: "npm:^2.6.0"
|
||||||
|
checksum: 10c0/27300be5937b6b9e245a7ea7a8216a0dcf5286a3b7ae38886c10c5c75b83fbfa1a69cd6754ab26bb38c6bd18aa8a2dcb62dea873506accb245cf82084acfee71
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"language-subtag-registry@npm:^0.3.20":
|
"language-subtag-registry@npm:^0.3.20":
|
||||||
version: 0.3.22
|
version: 0.3.22
|
||||||
resolution: "language-subtag-registry@npm:0.3.22"
|
resolution: "language-subtag-registry@npm:0.3.22"
|
||||||
|
@ -17127,6 +17137,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"toygrad@npm:^2.6.0":
|
||||||
|
version: 2.6.0
|
||||||
|
resolution: "toygrad@npm:2.6.0"
|
||||||
|
checksum: 10c0/96e42ced87431e99cec7d9b446c7827fe7782c2fd82bb5fc8c4a0855679011d809f9967096a60b4c8ceca867a29f1aadd62af447bdb652cb6f7fee279ae743ed
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"tr46@npm:^1.0.1":
|
"tr46@npm:^1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "tr46@npm:1.0.1"
|
resolution: "tr46@npm:1.0.1"
|
||||||
|
|
Loading…
Reference in a new issue