mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-04-24 13:57:11 -04:00
New: Header search for quick manual search
This commit is contained in:
parent
867b61e4aa
commit
82eb6495d4
4 changed files with 7 additions and 184 deletions
|
@ -1,4 +1,3 @@
|
|||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Autosuggest from 'react-autosuggest';
|
||||
|
@ -7,7 +6,6 @@ import keyboardShortcuts, { shortcuts } from 'Components/keyboardShortcuts';
|
|||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import FuseWorker from './fuse.worker';
|
||||
import MovieSearchResult from './MovieSearchResult';
|
||||
import styles from './MovieSearchInput.css';
|
||||
|
||||
|
@ -22,7 +20,6 @@ class MovieSearchInput extends Component {
|
|||
super(props, context);
|
||||
|
||||
this._autosuggest = null;
|
||||
this._worker = null;
|
||||
|
||||
this.state = {
|
||||
value: '',
|
||||
|
@ -42,15 +39,6 @@ class MovieSearchInput extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
getWorker() {
|
||||
if (!this._worker) {
|
||||
this._worker = new FuseWorker();
|
||||
this._worker.addEventListener('message', this.onSuggestionsReceived, false);
|
||||
}
|
||||
|
||||
return this._worker;
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
|
@ -105,11 +93,6 @@ class MovieSearchInput extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
goToMovie(item) {
|
||||
this.setState({ value: '' });
|
||||
this.props.onGoToMovie(item.item.titleSlug);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.setState({
|
||||
value: '',
|
||||
|
@ -149,8 +132,7 @@ class MovieSearchInput extends Component {
|
|||
} = this.state;
|
||||
|
||||
const {
|
||||
highlightedSectionIndex,
|
||||
highlightedSuggestionIndex
|
||||
highlightedSectionIndex
|
||||
} = this._autosuggest.state;
|
||||
|
||||
if (!suggestions.length || highlightedSectionIndex) {
|
||||
|
@ -161,15 +143,6 @@ class MovieSearchInput extends Component {
|
|||
return;
|
||||
}
|
||||
|
||||
// If an suggestion is not selected go to the first movie,
|
||||
// otherwise go to the selected movie.
|
||||
|
||||
if (highlightedSuggestionIndex == null) {
|
||||
this.goToMovie(suggestions[0]);
|
||||
} else {
|
||||
this.goToMovie(suggestions[highlightedSuggestionIndex]);
|
||||
}
|
||||
|
||||
this._autosuggest.input.blur();
|
||||
this.reset();
|
||||
}
|
||||
|
@ -178,71 +151,6 @@ class MovieSearchInput extends Component {
|
|||
this.reset();
|
||||
}
|
||||
|
||||
onSuggestionsFetchRequested = ({ value }) => {
|
||||
if (!this.state.loading) {
|
||||
this.setState({
|
||||
loading: true
|
||||
});
|
||||
}
|
||||
|
||||
this.requestSuggestions(value);
|
||||
};
|
||||
|
||||
requestSuggestions = _.debounce((value) => {
|
||||
if (!this.state.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
const requestLoading = this.state.requestLoading;
|
||||
|
||||
this.setState({
|
||||
requestValue: value,
|
||||
requestLoading: true
|
||||
});
|
||||
|
||||
if (!requestLoading) {
|
||||
const payload = {
|
||||
value,
|
||||
movies: this.props.movies
|
||||
};
|
||||
|
||||
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,
|
||||
movies: this.props.movies
|
||||
};
|
||||
|
||||
this.getWorker().postMessage(payload);
|
||||
}
|
||||
}
|
||||
|
||||
onSuggestionsClearRequested = () => {
|
||||
this.setState({
|
||||
suggestions: [],
|
||||
|
@ -253,8 +161,6 @@ class MovieSearchInput extends Component {
|
|||
onSuggestionSelected = (event, { suggestion }) => {
|
||||
if (suggestion.type === ADD_NEW_TYPE) {
|
||||
this.props.onGoToAddNewMovie(this.state.value);
|
||||
} else {
|
||||
this.goToMovie(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,23 +169,13 @@ class MovieSearchInput extends Component {
|
|||
|
||||
render() {
|
||||
const {
|
||||
value,
|
||||
loading,
|
||||
suggestions
|
||||
value
|
||||
} = this.state;
|
||||
|
||||
const suggestionGroups = [];
|
||||
|
||||
if (suggestions.length || loading) {
|
||||
suggestionGroups.push({
|
||||
title: translate('ExistingMovies'),
|
||||
loading,
|
||||
suggestions
|
||||
});
|
||||
}
|
||||
|
||||
suggestionGroups.push({
|
||||
title: translate('AddNewMovie'),
|
||||
title: translate('SearchIndexers'),
|
||||
suggestions: [
|
||||
{
|
||||
type: ADD_NEW_TYPE,
|
||||
|
@ -328,8 +224,6 @@ class MovieSearchInput extends Component {
|
|||
getSuggestionValue={this.getSuggestionValue}
|
||||
renderSuggestion={this.renderSuggestion}
|
||||
onSuggestionSelected={this.onSuggestionSelected}
|
||||
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
||||
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -337,8 +231,6 @@ class MovieSearchInput extends Component {
|
|||
}
|
||||
|
||||
MovieSearchInput.propTypes = {
|
||||
movies: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onGoToMovie: PropTypes.func.isRequired,
|
||||
onGoToAddNewMovie: PropTypes.func.isRequired,
|
||||
bindShortcut: PropTypes.func.isRequired
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { push } from 'connected-react-router';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { setSearchDefault } from 'Store/Actions/releaseActions';
|
||||
import createAllIndexersSelector from 'Store/Selectors/createAllIndexersSelector';
|
||||
import createDeepEqualSelector from 'Store/Selectors/createDeepEqualSelector';
|
||||
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
||||
|
@ -58,12 +59,9 @@ function createMapStateToProps() {
|
|||
|
||||
function createMapDispatchToProps(dispatch, props) {
|
||||
return {
|
||||
onGoToMovie(titleSlug) {
|
||||
dispatch(push(`${window.Prowlarr.urlBase}/movie/${titleSlug}`));
|
||||
},
|
||||
|
||||
onGoToAddNewMovie(query) {
|
||||
dispatch(push(`${window.Prowlarr.urlBase}/add/new?term=${encodeURIComponent(query)}`));
|
||||
dispatch(setSearchDefault({ searchQuery: query, searchIndexerIds: [-1, -2] }));
|
||||
dispatch(push(`${window.Prowlarr.urlBase}search`));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
import Fuse from 'fuse.js';
|
||||
|
||||
const fuseOptions = {
|
||||
shouldSort: true,
|
||||
includeMatches: true,
|
||||
ignoreLocation: true,
|
||||
threshold: 0.3,
|
||||
minMatchCharLength: 1,
|
||||
keys: [
|
||||
'title',
|
||||
'alternateTitles.title',
|
||||
'tags.label'
|
||||
]
|
||||
};
|
||||
|
||||
function getSuggestions(movies, value) {
|
||||
const limit = 10;
|
||||
let suggestions = [];
|
||||
|
||||
if (value.length === 1) {
|
||||
for (let i = 0; i < movies.length; i++) {
|
||||
const s = movies[i];
|
||||
if (s.firstCharacter === value.toLowerCase()) {
|
||||
suggestions.push({
|
||||
item: movies[i],
|
||||
indices: [
|
||||
[0, 0]
|
||||
],
|
||||
matches: [
|
||||
{
|
||||
value: s.title,
|
||||
key: 'title'
|
||||
}
|
||||
],
|
||||
arrayIndex: 0
|
||||
});
|
||||
if (suggestions.length > limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const fuse = new Fuse(movies, fuseOptions);
|
||||
suggestions = fuse.search(value, { limit });
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
onmessage = function(e) {
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
movies,
|
||||
value
|
||||
} = e.data;
|
||||
|
||||
const suggestions = getSuggestions(movies, value);
|
||||
|
||||
const results = {
|
||||
value,
|
||||
suggestions
|
||||
};
|
||||
|
||||
self.postMessage(results);
|
||||
};
|
|
@ -321,6 +321,7 @@
|
|||
"TestAllClients": "Test All Clients",
|
||||
"Time": "Time",
|
||||
"Title": "Title",
|
||||
"SearchIndexers": "Search all Indexers",
|
||||
"Today": "Today",
|
||||
"Tomorrow": "Tomorrow",
|
||||
"Type": "Type",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue