mirror of
https://github.com/mastodon/mastodon.git
synced 2025-07-14 08:18:15 +00:00
Compare commits
6 Commits
ec386eba6a
...
fabd675951
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fabd675951 | ||
![]() |
3a232d9626 | ||
![]() |
3e1e6762aa | ||
![]() |
0733590c3b | ||
![]() |
c50cf3b544 | ||
![]() |
429ab8d210 |
|
@ -10,7 +10,10 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
|||
|
||||
import { length } from 'stringz';
|
||||
|
||||
import debounce from 'lodash.debounce';
|
||||
|
||||
import { missingAltTextModal } from 'mastodon/initial_state';
|
||||
import { changeComposeLanguage } from 'mastodon/actions/compose';
|
||||
|
||||
import AutosuggestInput from 'mastodon/components/autosuggest_input';
|
||||
import AutosuggestTextarea from 'mastodon/components/autosuggest_textarea';
|
||||
|
@ -32,6 +35,8 @@ import { ReplyIndicator } from './reply_indicator';
|
|||
import { UploadForm } from './upload_form';
|
||||
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 messages = defineMessages({
|
||||
|
@ -42,6 +47,28 @@ const messages = defineMessages({
|
|||
reply: { id: 'compose_form.reply', defaultMessage: 'Reply' },
|
||||
});
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
currentLanguage: state.meta.get('locale'),
|
||||
});
|
||||
|
||||
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 {
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
|
@ -86,6 +113,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
this.textareaRef = createRef(null);
|
||||
this.debouncedHandleKeyUp = debounce(this._handleKeyUp.bind(this), 500);
|
||||
}
|
||||
|
||||
handleChange = (e) => {
|
||||
|
@ -98,6 +126,34 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
handleKeyUp = (e) => {
|
||||
this.debouncedHandleKeyUp(e);
|
||||
}
|
||||
|
||||
_handleKeyUp = async (e) => {
|
||||
if (!supportsLanguageDetector) {
|
||||
return;
|
||||
}
|
||||
if (!languageDetector) {
|
||||
languageDetector = await globalThis.LanguageDetector.create();
|
||||
}
|
||||
const text = this.getFulltextForCharacterCounting().trim();
|
||||
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 = () => {
|
||||
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
||||
};
|
||||
|
@ -163,6 +219,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
|
||||
componentWillUnmount () {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
this.debouncedHandleKeyUp.cancel();
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
|
@ -274,6 +331,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
suggestions={this.props.suggestions}
|
||||
onFocus={this.handleFocus}
|
||||
onKeyDown={this.handleKeyDown}
|
||||
onKeyUp={this.handleKeyUp}
|
||||
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
|
||||
onSuggestionSelected={this.onSuggestionSelected}
|
||||
|
@ -324,4 +382,4 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
|
||||
}
|
||||
|
||||
export default injectIntl(ComposeForm);
|
||||
export default injectIntl(connect(mapStateToProps)(ComposeForm));
|
||||
|
|
Loading…
Reference in New Issue
Block a user