mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-16 10:03:51 -07:00
Lazy Loading fuse-worker and fixed some potential timing issues
Fixes #1489 Fixes #1463 Co-Authored-By: Taloth <Taloth@users.noreply.github.com>
This commit is contained in:
parent
8453c5ef04
commit
de830b9c1f
3 changed files with 114 additions and 42 deletions
|
@ -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 var(--toolbarColor);
|
border: 1px solid var(--toolbarColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.addNewArtistSuggestion {
|
.addNewArtistSuggestion {
|
||||||
padding: 0 3px;
|
padding: 5px 3px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,7 @@ import ArtistSearchResult from './ArtistSearchResult';
|
||||||
import FuseWorker from './fuse.worker';
|
import FuseWorker from './fuse.worker';
|
||||||
import styles from './ArtistSearchInput.css';
|
import styles from './ArtistSearchInput.css';
|
||||||
|
|
||||||
const LOADING_TYPE = 'suggestionsLoading';
|
|
||||||
const ADD_NEW_TYPE = 'addNew';
|
const ADD_NEW_TYPE = 'addNew';
|
||||||
const workerInstance = new FuseWorker();
|
|
||||||
|
|
||||||
class ArtistSearchInput extends Component {
|
class ArtistSearchInput extends Component {
|
||||||
|
|
||||||
|
@ -23,6 +21,7 @@ class ArtistSearchInput 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 ArtistSearchInput extends Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.bindShortcut(shortcuts.ARTIST_SEARCH_INPUT.key, this.focusInput);
|
this.props.bindShortcut(shortcuts.ARTIST_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 ArtistSearchInput 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 ArtistSearchInput extends Component {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.type === LOADING_TYPE) {
|
|
||||||
return (
|
|
||||||
<LoadingIndicator
|
|
||||||
className={styles.loading}
|
|
||||||
rippleClassName={styles.ripple}
|
|
||||||
size={30}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ArtistSearchResult
|
<ArtistSearchResult
|
||||||
{...item.item}
|
{...item.item}
|
||||||
|
@ -98,7 +112,8 @@ class ArtistSearchInput extends Component {
|
||||||
reset() {
|
reset() {
|
||||||
this.setState({
|
this.setState({
|
||||||
value: '',
|
value: '',
|
||||||
suggestions: []
|
suggestions: [],
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +129,15 @@ class ArtistSearchInput 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;
|
||||||
}
|
}
|
||||||
|
@ -154,35 +178,74 @@ class ArtistSearchInput extends Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
onSuggestionsFetchRequested = ({ value }) => {
|
onSuggestionsFetchRequested = ({ value }) => {
|
||||||
|
if (!this.state.loading) {
|
||||||
this.setState({
|
this.setState({
|
||||||
suggestions: [
|
loading: true
|
||||||
{
|
|
||||||
type: LOADING_TYPE,
|
|
||||||
title: value
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.requestSuggestions(value);
|
this.requestSuggestions(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
requestSuggestions = _.debounce((value) => {
|
requestSuggestions = _.debounce((value) => {
|
||||||
|
if (!this.state.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestLoading = this.state.requestLoading;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
requestValue: value,
|
||||||
|
requestLoading: true
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!requestLoading) {
|
||||||
const payload = {
|
const payload = {
|
||||||
value,
|
value,
|
||||||
artists: this.props.artists
|
artists: this.props.artists
|
||||||
};
|
};
|
||||||
|
|
||||||
workerInstance.postMessage(payload);
|
this.getWorker().postMessage(payload);
|
||||||
|
}
|
||||||
}, 250);
|
}, 250);
|
||||||
|
|
||||||
onSuggestionsReceived = (message) => {
|
onSuggestionsReceived = (message) => {
|
||||||
|
const {
|
||||||
|
value,
|
||||||
|
suggestions
|
||||||
|
} = message.data;
|
||||||
|
|
||||||
|
if (!this.state.loading) {
|
||||||
this.setState({
|
this.setState({
|
||||||
suggestions: message.data
|
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,
|
||||||
|
artists: this.props.artists
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getWorker().postMessage(payload);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onSuggestionsClearRequested = () => {
|
onSuggestionsClearRequested = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
suggestions: []
|
suggestions: [],
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -200,14 +263,16 @@ class ArtistSearchInput 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 Artist',
|
title: 'Existing Artist',
|
||||||
|
loading,
|
||||||
suggestions
|
suggestions
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ import Fuse from 'fuse.js';
|
||||||
const fuseOptions = {
|
const fuseOptions = {
|
||||||
shouldSort: true,
|
shouldSort: true,
|
||||||
includeMatches: true,
|
includeMatches: true,
|
||||||
|
ignoreLocation: true,
|
||||||
threshold: 0.3,
|
threshold: 0.3,
|
||||||
location: 0,
|
maxPatternLength: 32,
|
||||||
distance: 100,
|
|
||||||
minMatchCharLength: 1,
|
minMatchCharLength: 1,
|
||||||
keys: [
|
keys: [
|
||||||
'artistName',
|
'artistName',
|
||||||
|
@ -47,7 +47,7 @@ function getSuggestions(artists, 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(artists, value));
|
const suggestions = getSuggestions(artists, value);
|
||||||
});
|
|
||||||
|
const results = {
|
||||||
|
value,
|
||||||
|
suggestions
|
||||||
|
};
|
||||||
|
|
||||||
|
self.postMessage(results);
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue