Lazy Loading fuse-worker and fixed some potential timing issues when it's slow. Also keep last result while typing.

(cherry picked from commit 1e98002b8f3b01e41bff011644a9345c37c259c1)
pull/1205/head
Taloth Saldono 3 years ago committed by ta264
parent 468ebc3307
commit ba9f618405

@ -4,15 +4,15 @@
} }
.loading { .loading {
margin-top: 18px; position: absolute;
margin-bottom: 18px; display: inline-block;
text-align: center; margin-left: 5px;
} }
.ripple { .ripple {
composes: ripple from '~Components/Loading/LoadingIndicator.css'; composes: ripple from '~Components/Loading/LoadingIndicator.css';
border: 2px solid $toolbarColor; border: 1px solid $toolbarColor;
} }
.input { .input {

@ -10,9 +10,7 @@ import AuthorSearchResult from './AuthorSearchResult';
import FuseWorker from './fuse.worker'; import FuseWorker from './fuse.worker';
import styles from './AuthorSearchInput.css'; import styles from './AuthorSearchInput.css';
const LOADING_TYPE = 'suggestionsLoading';
const ADD_NEW_TYPE = 'addNew'; const ADD_NEW_TYPE = 'addNew';
const workerInstance = new FuseWorker();
class AuthorSearchInput extends Component { class AuthorSearchInput extends Component {
@ -23,6 +21,7 @@ class AuthorSearchInput extends Component {
super(props, context); super(props, context);
this._autosuggest = null; this._autosuggest = null;
this._worker = null;
this.state = { this.state = {
value: '', value: '',
@ -32,7 +31,23 @@ class AuthorSearchInput extends Component {
componentDidMount() { componentDidMount() {
this.props.bindShortcut(shortcuts.AUTHOR_SEARCH_INPUT.key, this.focusInput); this.props.bindShortcut(shortcuts.AUTHOR_SEARCH_INPUT.key, this.focusInput);
workerInstance.addEventListener('message', this.onSuggestionsReceived, false); }
componentWillUnmount() {
if (this._worker) {
this._worker.removeEventListener('message', this.onSuggestionsReceived, false);
this._worker.terminate();
this._worker = null;
}
}
getWorker() {
if (!this._worker) {
this._worker = new FuseWorker();
this._worker.addEventListener('message', this.onSuggestionsReceived, false);
}
return this._worker;
} }
// //
@ -55,6 +70,15 @@ class AuthorSearchInput extends Component {
return ( return (
<div className={styles.sectionTitle}> <div className={styles.sectionTitle}>
{section.title} {section.title}
{
section.loading &&
<LoadingIndicator
className={styles.loading}
rippleClassName={styles.ripple}
size={20}
/>
}
</div> </div>
); );
} }
@ -72,16 +96,6 @@ class AuthorSearchInput extends Component {
); );
} }
if (item.type === LOADING_TYPE) {
return (
<LoadingIndicator
className={styles.loading}
rippleClassName={styles.ripple}
size={30}
/>
);
}
return ( return (
<AuthorSearchResult <AuthorSearchResult
{...item.item} {...item.item}
@ -98,7 +112,8 @@ class AuthorSearchInput extends Component {
reset() { reset() {
this.setState({ this.setState({
value: '', value: '',
suggestions: [] suggestions: [],
loading: false
}); });
} }
@ -114,6 +129,15 @@ class AuthorSearchInput extends Component {
} }
onKeyDown = (event) => { onKeyDown = (event) => {
if (event.shiftKey || event.altKey || event.ctrlKey) {
return;
}
if (event.key === 'Escape') {
this.reset();
return;
}
if (event.key !== 'Tab' && event.key !== 'Enter') { if (event.key !== 'Tab' && event.key !== 'Enter') {
return; return;
} }
@ -128,7 +152,7 @@ class AuthorSearchInput extends Component {
highlightedSuggestionIndex highlightedSuggestionIndex
} = this._autosuggest.state; } = this._autosuggest.state;
if (!suggestions.length || suggestions[0].type === LOADING_TYPE || highlightedSectionIndex) { if (!suggestions.length || highlightedSectionIndex) {
this.props.onGoToAddNewAuthor(value); this.props.onGoToAddNewAuthor(value);
this._autosuggest.input.blur(); this._autosuggest.input.blur();
this.reset(); this.reset();
@ -154,35 +178,74 @@ class AuthorSearchInput extends Component {
} }
onSuggestionsFetchRequested = ({ value }) => { onSuggestionsFetchRequested = ({ value }) => {
this.setState({ if (!this.state.loading) {
suggestions: [ this.setState({
{ loading: true
type: LOADING_TYPE, });
title: value }
}
]
});
this.requestSuggestions(value); this.requestSuggestions(value);
}; };
requestSuggestions = _.debounce((value) => { requestSuggestions = _.debounce((value) => {
const payload = { if (!this.state.loading) {
value, return;
authors: this.props.authors }
};
workerInstance.postMessage(payload); const requestLoading = this.state.requestLoading;
}, 250);
onSuggestionsReceived = (message) => {
this.setState({ this.setState({
suggestions: message.data requestValue: value,
requestLoading: true
}); });
if (!requestLoading) {
const payload = {
value,
authors: this.props.authors
};
this.getWorker().postMessage(payload);
}
}, 250);
onSuggestionsReceived = (message) => {
const {
value,
suggestions
} = message.data;
if (!this.state.loading) {
this.setState({
requestValue: null,
requestLoading: false
});
} else if (value === this.state.requestValue) {
this.setState({
suggestions,
requestValue: null,
requestLoading: false,
loading: false
});
} else {
this.setState({
suggestions,
requestLoading: true
});
const payload = {
value: this.state.requestValue,
authors: this.props.authors
};
this.getWorker().postMessage(payload);
}
} }
onSuggestionsClearRequested = () => { onSuggestionsClearRequested = () => {
this.setState({ this.setState({
suggestions: [] suggestions: [],
loading: false
}); });
} }
@ -200,14 +263,16 @@ class AuthorSearchInput extends Component {
render() { render() {
const { const {
value, value,
loading,
suggestions suggestions
} = this.state; } = this.state;
const suggestionGroups = []; const suggestionGroups = [];
if (suggestions.length) { if (suggestions.length || loading) {
suggestionGroups.push({ suggestionGroups.push({
title: 'Existing Author', title: 'Existing Author',
loading,
suggestions suggestions
}); });
} }

@ -47,7 +47,7 @@ function getSuggestions(authors, value) {
return suggestions; return suggestions;
} }
self.addEventListener('message', (e) => { onmessage = function(e) {
if (!e) { if (!e) {
return; return;
} }
@ -57,5 +57,12 @@ self.addEventListener('message', (e) => {
value value
} = e.data; } = e.data;
self.postMessage(getSuggestions(authors, value)); const suggestions = getSuggestions(authors, value);
});
const results = {
value,
suggestions
};
self.postMessage(results);
};

Loading…
Cancel
Save