Removing sorting of search uris in favor of source selection dropdown

This commit is contained in:
James Barnsley
2018-05-04 09:08:01 +12:00
parent 2cfb7afed5
commit 75099b732b
10 changed files with 192 additions and 111 deletions

View File

@ -718,11 +718,7 @@ var getFromUri = exports.getFromUri = function getFromUri(element) {
case 'searchcontext':
if (exploded[0] == "search") {
var available_views = ["all", "artist", "album", "playlist", "track"];
var view = available_views.indexOf(exploded[1]);
if (view > -1) {
return exploded[1];
}
return exploded[1];
}
break;
@ -20944,6 +20940,7 @@ var DropdownField = function (_React$Component) {
_this.state = {
expanded: false
};
_this.handleClick = _this.handleClick.bind(_this);
return _this;
}
@ -20963,19 +20960,40 @@ var DropdownField = function (_React$Component) {
value: function handleClick(e) {
// TODO: remove dependency on jQuery and explore the performance of this functionality
if ($(e.target).closest('.dropdown-field').data('key') != this.props.name.replace(' ', '_').toLowerCase() && this.state.expanded) {
this.setState({ expanded: false });
this.setState({
expanded: false
});
}
}
}, {
key: 'handleChange',
value: function handleChange(value) {
this.setState({ expanded: !this.state.expanded });
return this.props.handleChange(value);
value: function handleChange(value, is_selected) {
this.setState({
expanded: !this.state.expanded
});
var current_value = this.props.value;
if (current_value instanceof Array) {
if (is_selected) {
var index = current_value.indexOf(value);
current_value.splice(index, 1);
var new_value = current_value;
} else {
current_value.push(value);
var new_value = current_value;
}
} else {
var new_value = value;
}
return this.props.handleChange(new_value);
}
}, {
key: 'handleToggle',
value: function handleToggle() {
this.setState({ expanded: !this.state.expanded });
this.setState({
expanded: !this.state.expanded
});
}
}, {
key: 'render',
@ -21002,9 +21020,11 @@ var DropdownField = function (_React$Component) {
if (this.props.className) {
className += ' ' + this.props.className;
}
var current_value = this.props.options[0].value;
var current_value = null;
if (this.props.value) {
current_value = this.props.value;
} else if (this.props.options.length > 0) {
current_value = this.props.options[0].value;
}
var icon = _react2.default.createElement(_reactFontawesome2.default, { name: 'check' });
@ -21040,12 +21060,17 @@ var DropdownField = function (_React$Component) {
'div',
{ className: 'options' },
this.props.options.map(function (option) {
if (current_value instanceof Array) {
var is_selected = current_value.indexOf(option.value) > -1;
} else {
var is_selected = current_value == option.value;
}
return _react2.default.createElement(
'div',
{ className: 'option', key: option.value, onClick: function onClick(e) {
return _this2.handleChange(option.value);
return _this2.handleChange(option.value, is_selected);
} },
!_this2.props.no_status_icon && option.value == current_value ? icon : null,
!_this2.props.no_status_icon && is_selected ? icon : null,
option.label
);
})
@ -70283,11 +70308,19 @@ var Search = function (_React$Component) {
}, {
value: 'duration',
label: 'Duration'
}, {
value: 'uri',
label: 'Source'
}];
var provider_options = [{
value: 'all',
label: 'All'
}];
for (var i = 0; i < this.props.uri_schemes.length; i++) {
provider_options.push({
value: this.props.uri_schemes[i],
label: helpers.titleCase(this.props.uri_schemes[i].replace(':', '').replace('+', ' '))
});
}
var options = _react2.default.createElement(
'span',
null,
@ -70297,17 +70330,20 @@ var Search = function (_React$Component) {
value: this.props.sort,
options: sort_options,
reverse: this.props.sort_reverse,
handleChange: function handleChange(val) {
_this3.setSort(val);_this3.props.uiActions.hideContextMenu();
} }),
_react2.default.createElement(
'button',
{ className: 'no-hover', onClick: function onClick(e) {
return _this3.props.uiActions.openModal('search_uri_schemes', { query: _this3.props.params.query });
} },
_react2.default.createElement(_reactFontawesome2.default, { name: 'wrench' }),
'\xA0 Sources'
)
handleChange: function handleChange(value) {
_this3.setSort(value);_this3.props.uiActions.hideContextMenu();
}
}),
_react2.default.createElement(_DropdownField2.default, {
icon: 'database',
name: 'Source',
value: this.props.search_uri_schemes,
options: provider_options,
reverse: this.props.sort_reverse,
handleChange: function handleChange(value) {
_this3.props.uiActions.set({ search_uri_schemes: value });_this3.props.uiActions.hideContextMenu();
}
})
);
return _react2.default.createElement(
@ -70320,7 +70356,8 @@ var Search = function (_React$Component) {
}),
_react2.default.createElement(_SearchForm2.default, {
query: this.props.params.query ? this.props.params.query : '',
view: this.props.params.view ? this.props.params.view : 'all' }),
view: this.props.params.view ? this.props.params.view : 'all'
}),
_react2.default.createElement(
'div',
{ className: 'content-wrapper' },
@ -70341,6 +70378,7 @@ var mapStateToProps = function mapStateToProps(state, ownProps) {
playlists: state.core.playlists ? state.core.playlists : [],
tracks: state.core.tracks ? state.core.tracks : [],
search_uri_schemes: state.ui.search_uri_schemes ? state.ui.search_uri_schemes : [],
uri_schemes: state.mopidy.uri_schemes ? state.mopidy.uri_schemes : [],
mopidy_search_results: state.mopidy.search_results ? state.mopidy.search_results : {},
spotify_search_results: state.spotify.search_results ? state.spotify.search_results : {},
sort: state.ui.search_results_sort ? state.ui.search_results_sort : 'name',
@ -70455,6 +70493,10 @@ var SearchForm = function (_React$Component) {
_reactRouter.hashHistory.push(global.baseURL + 'playlist/' + encodeURIComponent(this.state.query));
break;
case 'track':
_reactRouter.hashHistory.push(global.baseURL + 'track/' + encodeURIComponent(this.state.query));
break;
default:
var available_views = ["artist", "album", "playlist", "track"];
var view_defined = false;
@ -77665,15 +77707,34 @@ var LibraryAlbums = function (_React$Component) {
_react2.default.createElement(_FilterField2.default, { handleChange: function handleChange(value) {
return _this3.setState({ filter: value, limit: _this3.state.per_page });
} }),
_react2.default.createElement(_DropdownField2.default, { icon: 'sort', name: 'Sort', value: this.props.sort, options: sort_options, reverse: this.props.sort_reverse, handleChange: function handleChange(val) {
_react2.default.createElement(_DropdownField2.default, {
icon: 'sort',
name: 'Sort',
value: this.props.sort,
options: sort_options,
reverse: this.props.sort_reverse,
handleChange: function handleChange(val) {
_this3.setSort(val);_this3.props.uiActions.hideContextMenu();
} }),
_react2.default.createElement(_DropdownField2.default, { icon: 'eye', name: 'View', value: this.props.view, options: view_options, handleChange: function handleChange(val) {
}
}),
_react2.default.createElement(_DropdownField2.default, {
icon: 'eye',
name: 'View',
value: this.props.view,
options: view_options,
handleChange: function handleChange(val) {
_this3.props.uiActions.set({ library_albums_view: val });_this3.props.uiActions.hideContextMenu();
} }),
_react2.default.createElement(_DropdownField2.default, { icon: 'database', name: 'Source', value: this.props.source, options: source_options, handleChange: function handleChange(val) {
}
}),
_react2.default.createElement(_DropdownField2.default, {
icon: 'database',
name: 'Source',
value: this.props.source,
options: source_options,
handleChange: function handleChange(val) {
_this3.props.uiActions.set({ library_albums_source: val });_this3.props.uiActions.hideContextMenu();
} })
}
})
);
return _react2.default.createElement(

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -77,7 +77,7 @@
// Release details
// These are automatically injected to built HTML
var build = "1525309512";
var build = "1525381100";
var version = "3.18.0";
// Construct the script tag

View File

@ -12,31 +12,53 @@ export default class DropdownField extends React.Component{
this.state = {
expanded: false
}
this.handleClick = this.handleClick.bind(this)
this.handleClick = this.handleClick.bind(this);
}
componentDidMount(){
window.addEventListener("click", this.handleClick, false)
window.addEventListener("click", this.handleClick, false);
}
componentWillUnmount(){
window.removeEventListener("click", this.handleClick, false)
window.removeEventListener("click", this.handleClick, false);
}
handleClick(e){
// TODO: remove dependency on jQuery and explore the performance of this functionality
if ($(e.target).closest('.dropdown-field').data('key') != this.props.name.replace(' ','_').toLowerCase() && this.state.expanded){
this.setState({ expanded: false })
this.setState({
expanded: false
});
}
}
handleChange(value){
this.setState({ expanded: !this.state.expanded })
return this.props.handleChange(value )
handleChange(value, is_selected){
this.setState({
expanded: !this.state.expanded
});
var current_value = this.props.value;
if (current_value instanceof Array){
if (is_selected){
var index = current_value.indexOf(value);
current_value.splice(index, 1);
var new_value = current_value;
} else {
current_value.push(value);
var new_value = current_value;
}
} else {
var new_value = value;
}
return this.props.handleChange(new_value);
}
handleToggle(){
this.setState({ expanded: !this.state.expanded })
this.setState({
expanded: !this.state.expanded
});
}
render(){
@ -60,9 +82,11 @@ export default class DropdownField extends React.Component{
if (this.props.className){
className += ' '+this.props.className;
}
var current_value = this.props.options[0].value
var current_value = null;
if (this.props.value){
current_value = this.props.value;
} else if (this.props.options.length > 0){
current_value = this.props.options[0].value;
}
var icon = <FontAwesome name="check" />
@ -83,9 +107,14 @@ export default class DropdownField extends React.Component{
<div className="options">
{
this.props.options.map(option => {
if (current_value instanceof Array){
var is_selected = current_value.indexOf(option.value) > -1;
} else {
var is_selected = current_value == option.value;
}
return (
<div className="option" key={ option.value } onClick={ e => this.handleChange(option.value) }>
{!this.props.no_status_icon && (option.value == current_value) ? icon : null}
<div className="option" key={option.value} onClick={e => this.handleChange(option.value, is_selected)}>
{!this.props.no_status_icon && is_selected ? icon : null}
{option.label}
</div>
)

View File

@ -50,6 +50,10 @@ class SearchForm extends React.Component{
hashHistory.push(global.baseURL+'playlist/'+encodeURIComponent(this.state.query))
break
case 'track':
hashHistory.push(global.baseURL+'track/'+encodeURIComponent(this.state.query))
break
default:
var available_views = ["artist","album","playlist","track"];
var view_defined = false;

View File

@ -451,11 +451,7 @@ export let getFromUri = function(element, uri = ""){
case 'searchcontext':
if (exploded[0] == "search"){
var available_views = ["all","artist","album","playlist","track"];
var view = available_views.indexOf(exploded[1]);
if (view > -1){
return exploded[1];
}
return exploded[1];
}
break

View File

@ -319,13 +319,20 @@ class Search extends React.Component{
{
value: 'duration',
label: 'Duration'
},
{
value: 'uri',
label: 'Source'
}
];
var provider_options = [{
value: 'all',
label: 'All'
}];
for (var i = 0; i < this.props.uri_schemes.length; i++){
provider_options.push({
value: this.props.uri_schemes[i],
label: helpers.titleCase(this.props.uri_schemes[i].replace(':','').replace('+',' '))
});
}
var options = (
<span>
<DropdownField
@ -334,13 +341,16 @@ class Search extends React.Component{
value={this.props.sort}
options={sort_options}
reverse={this.props.sort_reverse}
handleChange={val => {this.setSort(val); this.props.uiActions.hideContextMenu() }} />
<button className="no-hover" onClick={e => this.props.uiActions.openModal('search_uri_schemes', {query: this.props.params.query})}>
<FontAwesome name="wrench" />&nbsp;
Sources
</button>
handleChange={value => {this.setSort(value); this.props.uiActions.hideContextMenu()}}
/>
<DropdownField
icon="database"
name="Source"
value={this.props.search_uri_schemes}
options={provider_options}
reverse={this.props.sort_reverse}
handleChange={value => {this.props.uiActions.set({search_uri_schemes: value}); this.props.uiActions.hideContextMenu()}}
/>
</span>
)
@ -354,7 +364,8 @@ class Search extends React.Component{
<SearchForm
query={(this.props.params.query ? this.props.params.query : '')}
view={(this.props.params.view ? this.props.params.view : 'all')} />
view={(this.props.params.view ? this.props.params.view : 'all')}
/>
<div className="content-wrapper">
{ this.renderResults() }
@ -372,6 +383,7 @@ const mapStateToProps = (state, ownProps) => {
playlists: (state.core.playlists ? state.core.playlists : []),
tracks: (state.core.tracks ? state.core.tracks : []),
search_uri_schemes: (state.ui.search_uri_schemes ? state.ui.search_uri_schemes : []),
uri_schemes: (state.mopidy.uri_schemes ? state.mopidy.uri_schemes : []),
mopidy_search_results: (state.mopidy.search_results ? state.mopidy.search_results : {}),
spotify_search_results: (state.spotify.search_results ? state.spotify.search_results : {}),
sort: (state.ui.search_results_sort ? state.ui.search_results_sort : 'name'),

View File

@ -249,9 +249,28 @@ class LibraryAlbums extends React.Component{
var options = (
<span>
<FilterField handleChange={value => this.setState({filter: value, limit: this.state.per_page})} />
<DropdownField icon="sort" name="Sort" value={this.props.sort} options={sort_options} reverse={this.props.sort_reverse} handleChange={val => {this.setSort(val); this.props.uiActions.hideContextMenu() }} />
<DropdownField icon="eye" name="View" value={this.props.view} options={view_options} handleChange={val => {this.props.uiActions.set({ library_albums_view: val }); this.props.uiActions.hideContextMenu() }} />
<DropdownField icon="database" name="Source" value={this.props.source} options={source_options} handleChange={val => {this.props.uiActions.set({ library_albums_source: val}); this.props.uiActions.hideContextMenu() }} />
<DropdownField
icon="sort"
name="Sort"
value={this.props.sort}
options={sort_options}
reverse={this.props.sort_reverse}
handleChange={val => {this.setSort(val); this.props.uiActions.hideContextMenu() }}
/>
<DropdownField
icon="eye"
name="View"
value={this.props.view}
options={view_options}
handleChange={val => {this.props.uiActions.set({ library_albums_view: val }); this.props.uiActions.hideContextMenu() }}
/>
<DropdownField
icon="database"
name="Source"
value={this.props.source}
options={source_options}
handleChange={val => {this.props.uiActions.set({ library_albums_source: val}); this.props.uiActions.hideContextMenu() }}
/>
</span>
)