mirror of
https://github.com/lidarr/Lidarr
synced 2024-12-26 01:27:00 +00:00
New: Add Star Rating to Album table (#365)
This commit is contained in:
parent
73157534e0
commit
18b29f8208
6 changed files with 102 additions and 2 deletions
|
@ -9,6 +9,7 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
|||
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
|
||||
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
|
||||
import AlbumTitleLink from 'Album/AlbumTitleLink';
|
||||
import StarRating from 'Components/StarRating';
|
||||
import styles from './AlbumRow.css';
|
||||
|
||||
function getTrackCountKind(monitored, trackFileCount, trackCount) {
|
||||
|
@ -74,6 +75,7 @@ class AlbumRow extends Component {
|
|||
mediumCount,
|
||||
secondaryTypes,
|
||||
title,
|
||||
ratings,
|
||||
isSaving,
|
||||
artistMonitored,
|
||||
foreignAlbumId,
|
||||
|
@ -169,6 +171,19 @@ class AlbumRow extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
if (name === 'rating') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
{
|
||||
<StarRating
|
||||
rating={ratings.value}
|
||||
votes={ratings.votes}
|
||||
/>
|
||||
}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'releaseDate') {
|
||||
return (
|
||||
<RelativeDateCellConnector
|
||||
|
@ -223,6 +238,7 @@ AlbumRow.propTypes = {
|
|||
mediumCount: PropTypes.number.isRequired,
|
||||
duration: PropTypes.number.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
ratings: PropTypes.object.isRequired,
|
||||
secondaryTypes: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
foreignAlbumId: PropTypes.string.isRequired,
|
||||
isSaving: PropTypes.bool,
|
||||
|
|
|
@ -4,10 +4,12 @@ import PropTypes from 'prop-types';
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import connectSection from 'Store/connectSection';
|
||||
import { findCommand } from 'Utilities/Command';
|
||||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import { toggleAlbumsMonitored, setAlbumsTableOption, setAlbumsSort } from 'Store/Actions/albumActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
|
@ -16,7 +18,7 @@ import ArtistDetailsSeason from './ArtistDetailsSeason';
|
|||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state, { label }) => label,
|
||||
(state) => state.albums,
|
||||
createClientSideCollectionSelector(),
|
||||
createArtistSelector(),
|
||||
createCommandsSelector(),
|
||||
createDimensionsSelector(),
|
||||
|
@ -94,4 +96,10 @@ ArtistDetailsSeasonConnector.propTypes = {
|
|||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(ArtistDetailsSeasonConnector);
|
||||
export default connectSection(
|
||||
createMapStateToProps,
|
||||
mapDispatchToProps,
|
||||
undefined,
|
||||
undefined,
|
||||
{ section: 'albums' }
|
||||
)(ArtistDetailsSeasonConnector);
|
||||
|
|
19
frontend/src/Components/StarRating.css
Normal file
19
frontend/src/Components/StarRating.css
Normal file
|
@ -0,0 +1,19 @@
|
|||
.starRating {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.backStar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
color: #515253;
|
||||
}
|
||||
|
||||
.frontStar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
color: #ffbc0b;
|
||||
}
|
44
frontend/src/Components/StarRating.js
Normal file
44
frontend/src/Components/StarRating.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import Icon from 'Components/Icon';
|
||||
import styles from './StarRating.css';
|
||||
|
||||
function StarRating({ rating, votes, iconSize }) {
|
||||
const starWidth = {
|
||||
width: `${rating * 10}%`
|
||||
};
|
||||
|
||||
const helpText = `${rating/2} (${votes} Votes)`;
|
||||
|
||||
return (
|
||||
<span className={styles.starRating} title={helpText}>
|
||||
<div className={styles.backStar}>
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<div className={styles.frontStar} style={starWidth}>
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
<Icon name={icons.STAR_FULL} size={iconSize} />
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
StarRating.propTypes = {
|
||||
rating: PropTypes.number.isRequired,
|
||||
votes: PropTypes.number.isRequired,
|
||||
iconSize: PropTypes.number.isRequired
|
||||
};
|
||||
|
||||
StarRating.defaultProps = {
|
||||
iconSize: 14
|
||||
};
|
||||
|
||||
export default StarRating;
|
|
@ -79,6 +79,7 @@ import fasSpinner from '@fortawesome/fontawesome-free-solid/faSpinner';
|
|||
import fasSort from '@fortawesome/fontawesome-free-solid/faSort';
|
||||
import fasSortDown from '@fortawesome/fontawesome-free-solid/faSortDown';
|
||||
import fasSortUp from '@fortawesome/fontawesome-free-solid/faSortUp';
|
||||
import fasStar from '@fortawesome/fontawesome-free-solid/faStar';
|
||||
import fasStop from '@fortawesome/fontawesome-free-solid/faStop';
|
||||
import fasSync from '@fortawesome/fontawesome-free-solid/faSync';
|
||||
import fasTags from '@fortawesome/fontawesome-free-solid/faTags';
|
||||
|
@ -178,6 +179,7 @@ export const SORT = fasSort;
|
|||
export const SORT_ASCENDING = fasSortUp;
|
||||
export const SORT_DESCENDING = fasSortDown;
|
||||
export const SPINNER = fasSpinner;
|
||||
export const STAR_FULL = fasStar;
|
||||
export const SUBTRACT = fasMinus;
|
||||
export const SYSTEM = fasLaptop;
|
||||
export const TAGS = fasTags;
|
||||
|
|
|
@ -31,6 +31,11 @@ export const defaultState = {
|
|||
sortDirection: sortDirections.DESCENDING,
|
||||
items: [],
|
||||
pendingChanges: {},
|
||||
sortPredicates: {
|
||||
rating: function(item) {
|
||||
return item.ratings.value;
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{
|
||||
|
@ -73,6 +78,12 @@ export const defaultState = {
|
|||
isSortable: true,
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'rating',
|
||||
label: 'Rating',
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'status',
|
||||
label: 'Status',
|
||||
|
|
Loading…
Reference in a new issue