mirror of
https://github.com/mastodon/mastodon.git
synced 2025-11-29 19:03:41 +00:00
Add language detection to compose widget
This commit is contained in:
parent
204ff46f7e
commit
429ab8d210
|
|
@ -11,6 +11,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { length } from 'stringz';
|
import { length } from 'stringz';
|
||||||
|
|
||||||
import { missingAltTextModal } from 'mastodon/initial_state';
|
import { missingAltTextModal } from 'mastodon/initial_state';
|
||||||
|
import { changeComposeLanguage } from 'mastodon/actions/compose';
|
||||||
|
|
||||||
import AutosuggestInput from '../../../components/autosuggest_input';
|
import AutosuggestInput from '../../../components/autosuggest_input';
|
||||||
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
|
import AutosuggestTextarea from '../../../components/autosuggest_textarea';
|
||||||
|
|
@ -31,6 +32,8 @@ import { ReplyIndicator } from './reply_indicator';
|
||||||
import { UploadForm } from './upload_form';
|
import { UploadForm } from './upload_form';
|
||||||
import { Warning } from './warning';
|
import { Warning } from './warning';
|
||||||
|
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
|
@ -41,6 +44,28 @@ const messages = defineMessages({
|
||||||
reply: { id: 'compose_form.reply', defaultMessage: 'Reply' },
|
reply: { id: 'compose_form.reply', defaultMessage: 'Reply' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
currentLanguage: state.compose.get('language'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const languageDetectorInGlobalThis = 'LanguageDetector' in globalThis;
|
||||||
|
let supportsLanguageDetector = languageDetectorInGlobalThis && await globalThis.LanguageDetector.availability() === 'available';
|
||||||
|
let languageDetector;
|
||||||
|
// If the API is supported, but the model not loaded yet…
|
||||||
|
if (languageDetectorInGlobalThis && !supportsLanguageDetector) {
|
||||||
|
// …trigger the model download
|
||||||
|
LanguageDetector.create().then((_languageDetector) => {
|
||||||
|
supportsLanguageDetector = true
|
||||||
|
languageDetector = _languageDetector
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function countLetters(text) {
|
||||||
|
const segmenter = new Intl.Segmenter('und', { granularity: 'grapheme' })
|
||||||
|
const letters = [...segmenter.segment(text)]
|
||||||
|
return letters.length
|
||||||
|
}
|
||||||
|
|
||||||
class ComposeForm extends ImmutablePureComponent {
|
class ComposeForm extends ImmutablePureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
intl: PropTypes.object.isRequired,
|
intl: PropTypes.object.isRequired,
|
||||||
|
|
@ -97,6 +122,30 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleKeyUp = async (e) => {
|
||||||
|
if (!supportsLanguageDetector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!languageDetector) {
|
||||||
|
languageDetector = await globalThis.LanguageDetector.create();
|
||||||
|
}
|
||||||
|
const text = this.getFulltextForCharacterCounting();
|
||||||
|
const currentLanguage = this.props.currentLanguage;
|
||||||
|
if (!text || countLetters(text) <= 5) {
|
||||||
|
this.props.dispatch(changeComposeLanguage(currentLanguage));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let detectedLanguage = (await languageDetector.detect(text))[0].detectedLanguage
|
||||||
|
detectedLanguage = detectedLanguage === 'und' ? currentLanguage : detectedLanguage.substring(0, 2);
|
||||||
|
this.props.dispatch(changeComposeLanguage(detectedLanguage));
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
this.props.dispatch(changeComposeLanguage(currentLanguage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getFulltextForCharacterCounting = () => {
|
getFulltextForCharacterCounting = () => {
|
||||||
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
||||||
};
|
};
|
||||||
|
|
@ -274,6 +323,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
suggestions={this.props.suggestions}
|
suggestions={this.props.suggestions}
|
||||||
onFocus={this.handleFocus}
|
onFocus={this.handleFocus}
|
||||||
onKeyDown={this.handleKeyDown}
|
onKeyDown={this.handleKeyDown}
|
||||||
|
onKeyUp={this.handleKeyUp}
|
||||||
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
||||||
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
|
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
|
||||||
onSuggestionSelected={this.onSuggestionSelected}
|
onSuggestionSelected={this.onSuggestionSelected}
|
||||||
|
|
@ -318,4 +368,4 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default injectIntl(ComposeForm);
|
export default injectIntl(connect(mapStateToProps)(ComposeForm));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user