mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-10 23:33:38 -07:00
New: Search by Tag
This commit is contained in:
parent
ef93ae3792
commit
d79139976c
4 changed files with 124 additions and 25 deletions
|
@ -1,4 +1,3 @@
|
||||||
import _ from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Autosuggest from 'react-autosuggest';
|
import Autosuggest from 'react-autosuggest';
|
||||||
|
@ -71,6 +70,7 @@ class ArtistSearchInput extends Component {
|
||||||
return (
|
return (
|
||||||
<ArtistSearchResult
|
<ArtistSearchResult
|
||||||
query={query}
|
query={query}
|
||||||
|
cleanQuery={jdu.replace(query).toLowerCase()}
|
||||||
{...item}
|
{...item}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -138,14 +138,15 @@ class ArtistSearchInput extends Component {
|
||||||
onSuggestionsFetchRequested = ({ value }) => {
|
onSuggestionsFetchRequested = ({ value }) => {
|
||||||
const lowerCaseValue = jdu.replace(value).toLowerCase();
|
const lowerCaseValue = jdu.replace(value).toLowerCase();
|
||||||
|
|
||||||
const suggestions = _.filter(this.props.artist, (artist) => {
|
const suggestions = this.props.artist.filter((artist) => {
|
||||||
// Check the title first and if there isn't a match fallback to the alternate titles
|
// Check the title first and if there isn't a match fallback to
|
||||||
|
// the alternate titles and finally the tags.
|
||||||
|
|
||||||
const titleMatch = jdu.replace(artist.artistName).toLowerCase().contains(lowerCaseValue);
|
return (
|
||||||
|
artist.cleanName.contains(lowerCaseValue) ||
|
||||||
return titleMatch || _.some(artist.alternateTitles, (alternateTitle) => {
|
// artist.alternateTitles.some((alternateTitle) => alternateTitle.cleanTitle.contains(lowerCaseValue)) ||
|
||||||
return jdu.replace(alternateTitle.title).toLowerCase().contains(lowerCaseValue);
|
artist.tags.some((tag) => tag.cleanLabel.contains(lowerCaseValue))
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setState({ suggestions });
|
this.setState({ suggestions });
|
||||||
|
|
|
@ -1,16 +1,80 @@
|
||||||
import _ from 'lodash';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { push } from 'react-router-redux';
|
import { push } from 'react-router-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
|
import jdu from 'jdu';
|
||||||
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
|
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
|
||||||
|
import createTagsSelector from 'Store/Selectors/createTagsSelector';
|
||||||
import ArtistSearchInput from './ArtistSearchInput';
|
import ArtistSearchInput from './ArtistSearchInput';
|
||||||
|
|
||||||
|
function createCleanTagsSelector() {
|
||||||
|
return createSelector(
|
||||||
|
createTagsSelector(),
|
||||||
|
(tags) => {
|
||||||
|
return tags.map((tag) => {
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
label
|
||||||
|
} = tag;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
label,
|
||||||
|
cleanLabel: jdu.replace(label).toLowerCase()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCleanArtistSelector() {
|
||||||
|
return createSelector(
|
||||||
|
createAllArtistSelector(),
|
||||||
|
createCleanTagsSelector(),
|
||||||
|
(allArtists, allTags) => {
|
||||||
|
return allArtists.map((artist) => {
|
||||||
|
const {
|
||||||
|
artistName,
|
||||||
|
sortName,
|
||||||
|
images,
|
||||||
|
// alternateTitles,
|
||||||
|
tags
|
||||||
|
} = artist;
|
||||||
|
|
||||||
|
return {
|
||||||
|
artistName,
|
||||||
|
sortName,
|
||||||
|
images,
|
||||||
|
cleanName: jdu.replace(artistName).toLowerCase(),
|
||||||
|
// alternateTitles: alternateTitles.map((alternateTitle) => {
|
||||||
|
// return {
|
||||||
|
// title: alternateTitle.title,
|
||||||
|
// cleanTitle: jdu.replace(alternateTitle.title).toLowerCase()
|
||||||
|
// };
|
||||||
|
// }),
|
||||||
|
tags: tags.map((id) => {
|
||||||
|
return allTags.find((tag) => tag.id === id);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}).sort((a, b) => {
|
||||||
|
if (a.cleanName < b.cleanName) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a.cleanName > b.cleanName) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
createAllArtistSelector(),
|
createCleanArtistSelector(),
|
||||||
(artist) => {
|
(artist) => {
|
||||||
return {
|
return {
|
||||||
artist: _.sortBy(artist, 'sortName')
|
artist
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,12 +19,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.alternateTitle {
|
.alternateTitle {
|
||||||
flex: 1 1 1px;
|
composes: title;
|
||||||
margin-left: 5px;
|
|
||||||
color: $disabledColor;
|
color: $disabledColor;
|
||||||
font-size: $smallFontSize;
|
font-size: $smallFontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tagContainer {
|
||||||
|
composes: title;
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointSmall) {
|
||||||
.titles,
|
.titles,
|
||||||
.title,
|
.title,
|
||||||
|
|
|
@ -1,27 +1,43 @@
|
||||||
import _ from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { kinds } from 'Helpers/Props';
|
||||||
|
import Label from 'Components/Label';
|
||||||
import ArtistPoster from 'Artist/ArtistPoster';
|
import ArtistPoster from 'Artist/ArtistPoster';
|
||||||
import styles from './ArtistSearchResult.css';
|
import styles from './ArtistSearchResult.css';
|
||||||
|
|
||||||
function getMatchingAlternateTile(alternateTitles, query) {
|
// function findMatchingAlternateTitle(alternateTitles, cleanQuery) {
|
||||||
return _.first(alternateTitles, (alternateTitle) => {
|
// return alternateTitles.find((alternateTitle) => {
|
||||||
return alternateTitle.title.toLowerCase().contains(query.toLowerCase());
|
// return alternateTitle.cleanTitle.contains(cleanQuery);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
function getMatchingTag(tags, cleanQuery) {
|
||||||
|
return tags.find((tag) => {
|
||||||
|
return tag.cleanLabel.contains(cleanQuery);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ArtistSearchResult(props) {
|
function ArtistSearchResult(props) {
|
||||||
const {
|
const {
|
||||||
query,
|
cleanQuery,
|
||||||
artistName,
|
artistName,
|
||||||
|
cleanName,
|
||||||
|
images,
|
||||||
// alternateTitles,
|
// alternateTitles,
|
||||||
images
|
tags
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const index = artistName.toLowerCase().indexOf(query.toLowerCase());
|
const titleContains = cleanName.contains(cleanQuery);
|
||||||
// const alternateTitle = index === -1 ?
|
// let alternateTitle = null;
|
||||||
// getMatchingAlternateTile(alternateTitles, query) :
|
let tag = null;
|
||||||
// null;
|
|
||||||
|
// if (!titleContains) {
|
||||||
|
// alternateTitle = findMatchingAlternateTitle(alternateTitles, cleanQuery);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (!titleContains) { // && !alternateTitle) {
|
||||||
|
tag = getMatchingTag(tags, cleanQuery);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.result}>
|
<div className={styles.result}>
|
||||||
|
@ -44,16 +60,30 @@ function ArtistSearchResult(props) {
|
||||||
// {alternateTitle.title}
|
// {alternateTitle.title}
|
||||||
// </div>
|
// </div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
!!tag &&
|
||||||
|
<div className={styles.tagContainer}>
|
||||||
|
<Label
|
||||||
|
key={tag.id}
|
||||||
|
kind={kinds.INFO}
|
||||||
|
>
|
||||||
|
{tag.label}
|
||||||
|
</Label>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArtistSearchResult.propTypes = {
|
ArtistSearchResult.propTypes = {
|
||||||
query: PropTypes.string.isRequired,
|
cleanQuery: PropTypes.string.isRequired,
|
||||||
artistName: PropTypes.string.isRequired,
|
artistName: PropTypes.string.isRequired,
|
||||||
// alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
// alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
images: PropTypes.arrayOf(PropTypes.object).isRequired
|
cleanName: PropTypes.string.isRequired,
|
||||||
|
images: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
tags: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ArtistSearchResult;
|
export default ArtistSearchResult;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue