diff --git a/frontend/src/App/State/MoviesAppState.ts b/frontend/src/App/State/MoviesAppState.ts index 24c0493bf..20b706c24 100644 --- a/frontend/src/App/State/MoviesAppState.ts +++ b/frontend/src/App/State/MoviesAppState.ts @@ -27,6 +27,7 @@ export interface MovieIndexAppState { showTmdbRating: boolean; showImdbRating: boolean; showRottenTomatoesRating: boolean; + showTraktRating: boolean; showTags: boolean; showSearchAction: boolean; }; diff --git a/frontend/src/Components/TraktRating.css b/frontend/src/Components/TraktRating.css new file mode 100644 index 000000000..0dd8f64ec --- /dev/null +++ b/frontend/src/Components/TraktRating.css @@ -0,0 +1,5 @@ +.image { + align-content: center; + margin-right: 5px; + vertical-align: -0.125em; +} diff --git a/frontend/src/Components/TraktRating.css.d.ts b/frontend/src/Components/TraktRating.css.d.ts new file mode 100644 index 000000000..c5c2756fa --- /dev/null +++ b/frontend/src/Components/TraktRating.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'image': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/TraktRating.tsx b/frontend/src/Components/TraktRating.tsx new file mode 100644 index 000000000..80a03a806 --- /dev/null +++ b/frontend/src/Components/TraktRating.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import Tooltip from 'Components/Tooltip/Tooltip'; +import { kinds, tooltipPositions } from 'Helpers/Props'; +import { Ratings } from 'Movie/Movie'; +import translate from 'Utilities/String/translate'; +import styles from './TraktRating.css'; + +interface TraktRatingProps { + ratings: Ratings; + iconSize?: number; + hideIcon?: boolean; +} + +function TraktRating(props: TraktRatingProps) { + const { ratings, iconSize = 14, hideIcon = false } = props; + + const traktImage = + 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTguMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiAgICAgdmlld0JveD0iMCAwIDE0NC44IDE0NC44IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxNDQuOCAxNDQuOCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+ICAgIDxwYXRoIGZpbGw9IiNFRDIyMjQiIGQ9Ik0yOS41LDExMS44YzEwLjYsMTEuNiwyNS45LDE4LjgsNDIuOSwxOC44YzguNywwLDE2LjktMS45LDI0LjMtNS4zTDU2LjMsODVMMjkuNSwxMTEuOHoiLz4gICAgPHBhdGggZmlsbD0iI0VEMjIyNCIgZD0iTTU2LjEsNjAuNkwyNS41LDkxLjFMMjEuNCw4N2wzMi4yLTMyLjJoMGwzNy42LTM3LjZjLTUuOS0yLTEyLjItMy4xLTE4LjgtMy4xYy0zMi4yLDAtNTguMywyNi4xLTU4LjMsNTguMyAgICAgICBjMCwxMy4xLDQuMywyNS4yLDExLjcsMzVsMzAuNS0zMC41bDIuMSwybDQzLjcsNDMuN2MwLjktMC41LDEuNy0xLDIuNS0xLjZMNTYuMyw3Mi43TDI3LDEwMmwtNC4xLTQuMWwzMy40LTMzLjRsMi4xLDJsNTEsNTAuOSAgICAgICBjMC44LTAuNiwxLjUtMS4zLDIuMi0xLjlsLTU1LTU1TDU2LjEsNjAuNnoiLz4gICAgPHBhdGggZmlsbD0iI0VEMUMyNCIgZD0iTTExNS43LDExMS40YzkuMy0xMC4zLDE1LTI0LDE1LTM5YzAtMjMuNC0xMy44LTQzLjUtMzMuNi01Mi44TDYwLjQsNTYuMkwxMTUuNywxMTEuNHogTTc0LjUsNjYuOGwtNC4xLTQuMSAgICAgICBsMjguOS0yOC45bDQuMSw0LjFMNzQuNSw2Ni44eiBNMTAxLjksMjcuMUw2OC42LDYwLjRsLTQuMS00LjFMOTcuOCwyM0wxMDEuOSwyNy4xeiIvPiAgICA8Zz4gICAgICAgPGc+ICAgICAgICAgIDxwYXRoIGZpbGw9IiNFRDIyMjQiIGQ9Ik03Mi40LDE0NC44QzMyLjUsMTQ0LjgsMCwxMTIuMywwLDcyLjRDMCwzMi41LDMyLjUsMCw3Mi40LDBzNzIuNCwzMi41LDcyLjQsNzIuNCAgICAgICAgICAgICBDMTQ0LjgsMTEyLjMsMTEyLjMsMTQ0LjgsNzIuNCwxNDQuOHogTTcyLjQsNy4zQzM2LjUsNy4zLDcuMywzNi41LDcuMyw3Mi40czI5LjIsNjUuMSw2NS4xLDY1LjFzNjUuMS0yOS4yLDY1LjEtNjUuMSAgICAgICAgICAgICBTMTA4LjMsNy4zLDcyLjQsNy4zeiIvPiAgICAgICA8L2c+ICAgIDwvZz48L2c+PC9zdmc+'; + + const { value = 0, votes = 0 } = ratings.trakt; + + return ( + + {!hideIcon && ( + {translate('TraktRating')} + )} + {(value * 10).toFixed()}% + + } + tooltip={translate('CountVotes', { votes })} + kind={kinds.INVERSE} + position={tooltipPositions.TOP} + /> + ); +} + +export default TraktRating; diff --git a/frontend/src/DiscoverMovie/Menus/DiscoverMovieSortMenu.js b/frontend/src/DiscoverMovie/Menus/DiscoverMovieSortMenu.js index 5b823c6ff..b402355c9 100644 --- a/frontend/src/DiscoverMovie/Menus/DiscoverMovieSortMenu.js +++ b/frontend/src/DiscoverMovie/Menus/DiscoverMovieSortMenu.js @@ -110,6 +110,15 @@ function DiscoverMovieSortMenu(props) { {translate('RottenTomatoesRating')} + + {translate('TraktRating')} + + ) : null} + {showTraktRating && !!ratings.trakt ? ( +
+ +
+ ) : null} + @@ -274,6 +283,7 @@ DiscoverMoviePoster.propTypes = { showTmdbRating: PropTypes.bool.isRequired, showImdbRating: PropTypes.bool.isRequired, showRottenTomatoesRating: PropTypes.bool.isRequired, + showTraktRating: PropTypes.bool.isRequired, ratings: PropTypes.object.isRequired, showRelativeDates: PropTypes.bool.isRequired, shortDateFormat: PropTypes.string.isRequired, diff --git a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js index aba00c799..4feb8d89b 100644 --- a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js +++ b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js @@ -4,6 +4,7 @@ import Icon from 'Components/Icon'; import ImdbRating from 'Components/ImdbRating'; import RottenTomatoRating from 'Components/RottenTomatoRating'; import TmdbRating from 'Components/TmdbRating'; +import TraktRating from 'Components/TraktRating'; import { icons } from 'Helpers/Props'; import getMovieStatusDetails from 'Movie/getMovieStatusDetails'; import formatRuntime from 'Utilities/Date/formatRuntime'; @@ -28,7 +29,8 @@ function DiscoverMoviePosterInfo(props) { movieRuntimeFormat, showTmdbRating, showImdbRating, - showRottenTomatoesRating + showRottenTomatoesRating, + showTraktRating } = props; if (sortKey === 'status' && status) { @@ -141,6 +143,14 @@ function DiscoverMoviePosterInfo(props) { ); } + if (!showTraktRating && sortKey === 'traktRating' && !!ratings.trakt) { + return ( +
+ +
+ ); + } + return null; } @@ -160,7 +170,8 @@ DiscoverMoviePosterInfo.propTypes = { movieRuntimeFormat: PropTypes.string.isRequired, showTmdbRating: PropTypes.bool.isRequired, showImdbRating: PropTypes.bool.isRequired, - showRottenTomatoesRating: PropTypes.bool.isRequired + showRottenTomatoesRating: PropTypes.bool.isRequired, + showTraktRating: PropTypes.bool.isRequired }; export default DiscoverMoviePosterInfo; diff --git a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosters.js b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosters.js index ae3cccb0f..f3fba2932 100644 --- a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosters.js +++ b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosters.js @@ -39,7 +39,8 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions) showTitle, showTmdbRating, showImdbRating, - showRottenTomatoesRating + showRottenTomatoesRating, + showTraktRating } = posterOptions; const heights = [ @@ -64,6 +65,10 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions) heights.push(19); } + if (showTraktRating) { + heights.push(19); + } + switch (sortKey) { case 'studio': case 'inCinemas': @@ -88,6 +93,11 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions) heights.push(19); } break; + case 'traktRating': + if (!showTraktRating) { + heights.push(19); + } + break; default: // No need to add a height of 0 } @@ -219,7 +229,8 @@ class DiscoverMoviePosters extends Component { showTitle, showTmdbRating, showImdbRating, - showRottenTomatoesRating + showRottenTomatoesRating, + showTraktRating } = posterOptions; const movieIdx = rowIndex * columnCount + columnIndex; @@ -248,6 +259,7 @@ class DiscoverMoviePosters extends Component { showTmdbRating={showTmdbRating} showImdbRating={showImdbRating} showRottenTomatoesRating={showRottenTomatoesRating} + showTraktRating={showTraktRating} showRelativeDates={showRelativeDates} shortDateFormat={shortDateFormat} timeFormat={timeFormat} diff --git a/frontend/src/DiscoverMovie/Posters/Options/DiscoverMoviePosterOptionsModalContent.js b/frontend/src/DiscoverMovie/Posters/Options/DiscoverMoviePosterOptionsModalContent.js index 93eb68a6f..d411e420a 100644 --- a/frontend/src/DiscoverMovie/Posters/Options/DiscoverMoviePosterOptionsModalContent.js +++ b/frontend/src/DiscoverMovie/Posters/Options/DiscoverMoviePosterOptionsModalContent.js @@ -48,6 +48,7 @@ class DiscoverMoviePosterOptionsModalContent extends Component { showTmdbRating: props.showTmdbRating, showImdbRating: props.showImdbRating, showRottenTomatoesRating: props.showRottenTomatoesRating, + showTraktRating: props.showTraktRating, includeRecommendations: props.includeRecommendations, includeTrending: props.includeTrending, includePopular: props.includePopular @@ -61,6 +62,7 @@ class DiscoverMoviePosterOptionsModalContent extends Component { showTmdbRating, showImdbRating, showRottenTomatoesRating, + showTraktRating, includeRecommendations, includeTrending, includePopular @@ -88,6 +90,10 @@ class DiscoverMoviePosterOptionsModalContent extends Component { state.showRottenTomatoesRating = showRottenTomatoesRating; } + if (showTraktRating !== prevProps.showTraktRating) { + state.showTraktRating = showTraktRating; + } + if (includeRecommendations !== prevProps.includeRecommendations) { state.includeRecommendations = includeRecommendations; } @@ -140,6 +146,7 @@ class DiscoverMoviePosterOptionsModalContent extends Component { showTmdbRating, showImdbRating, showRottenTomatoesRating, + showTraktRating, includeRecommendations, includeTrending, includePopular @@ -248,6 +255,18 @@ class DiscoverMoviePosterOptionsModalContent extends Component { onChange={this.onChangePosterOption} /> + + + {translate('ShowTraktRating')} + + + @@ -269,6 +288,7 @@ DiscoverMoviePosterOptionsModalContent.propTypes = { showTmdbRating: PropTypes.bool.isRequired, showImdbRating: PropTypes.bool.isRequired, showRottenTomatoesRating: PropTypes.bool.isRequired, + showTraktRating: PropTypes.bool.isRequired, includeRecommendations: PropTypes.bool.isRequired, includeTrending: PropTypes.bool.isRequired, includePopular: PropTypes.bool.isRequired, diff --git a/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css b/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css index 5b6328392..f8d01a39a 100644 --- a/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css +++ b/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css @@ -35,6 +35,7 @@ .tmdbRating, .imdbRating, .rottenTomatoesRating, +.traktRating, .runtime { composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css'; diff --git a/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css.d.ts b/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css.d.ts index 3f525862d..0e3bc5093 100644 --- a/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css.d.ts +++ b/frontend/src/DiscoverMovie/Table/DiscoverMovieHeader.css.d.ts @@ -21,6 +21,7 @@ interface CssExports { 'status': string; 'studio': string; 'tmdbRating': string; + 'traktRating': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css index b93d41b67..7b4be74db 100644 --- a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css +++ b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css @@ -60,6 +60,7 @@ .tmdbRating, .imdbRating, .rottenTomatoesRating, +.traktRating, .runtime { composes: cell; diff --git a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css.d.ts b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css.d.ts index c0e7b1be7..2d8ef2b72 100644 --- a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css.d.ts +++ b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.css.d.ts @@ -27,6 +27,7 @@ interface CssExports { 'statusIcon': string; 'studio': string; 'tmdbRating': string; + 'traktRating': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js index f07857bf4..f3d57856f 100644 --- a/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js +++ b/frontend/src/DiscoverMovie/Table/DiscoverMovieRow.js @@ -11,6 +11,7 @@ import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell'; import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell'; import TmdbRating from 'Components/TmdbRating'; import Popover from 'Components/Tooltip/Popover'; +import TraktRating from 'Components/TraktRating'; import AddNewDiscoverMovieModal from 'DiscoverMovie/AddNewDiscoverMovieModal'; import ExcludeMovieModal from 'DiscoverMovie/Exclusion/ExcludeMovieModal'; import { icons } from 'Helpers/Props'; @@ -291,6 +292,17 @@ class DiscoverMovieRow extends Component { ); } + if (name === 'traktRating') { + return ( + + {ratings.trakt ? : null} + + ); + } + if (name === 'popularity') { return ( diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index f5aaa0630..4e321c017 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -20,6 +20,7 @@ import RottenTomatoRating from 'Components/RottenTomatoRating'; import TmdbRating from 'Components/TmdbRating'; import Popover from 'Components/Tooltip/Popover'; import Tooltip from 'Components/Tooltip/Tooltip'; +import TraktRating from 'Components/TraktRating'; import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props'; import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; @@ -497,31 +498,44 @@ class MovieDetails extends Component {
{ - !!ratings.tmdb && + ratings.tmdb ? - + : + null } { - !!ratings.imdb && + ratings.imdb ? - + : + null } { - !!ratings.rottenTomatoes && + ratings.rottenTomatoes ? - + : + null + } + { + ratings.trakt ? + + + : + null }
diff --git a/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx b/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx index 6c8e23df7..bf740141f 100644 --- a/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx +++ b/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx @@ -136,6 +136,15 @@ function MovieIndexSortMenu(props: MovieIndexSortMenuProps) { {translate('RottenTomatoesRating')}
+ + {translate('TraktRating')} + + ) : null} + {showTraktRating && !!ratings.trakt ? ( +
+ +
+ ) : null} + {showTags && tags.length ? (
@@ -347,6 +355,7 @@ function MovieIndexPoster(props: MovieIndexPosterProps) { showTmdbRating={showTmdbRating} showImdbRating={showImdbRating} showRottenTomatoesRating={showRottenTomatoesRating} + showTraktRating={showTraktRating} showTags={showTags} /> diff --git a/frontend/src/Movie/Index/Posters/MovieIndexPosterInfo.tsx b/frontend/src/Movie/Index/Posters/MovieIndexPosterInfo.tsx index 225d91d63..72269c8cc 100644 --- a/frontend/src/Movie/Index/Posters/MovieIndexPosterInfo.tsx +++ b/frontend/src/Movie/Index/Posters/MovieIndexPosterInfo.tsx @@ -4,6 +4,7 @@ import ImdbRating from 'Components/ImdbRating'; import RottenTomatoRating from 'Components/RottenTomatoRating'; import TagListConnector from 'Components/TagListConnector'; import TmdbRating from 'Components/TmdbRating'; +import TraktRating from 'Components/TraktRating'; import { icons } from 'Helpers/Props'; import Language from 'Language/Language'; import { Ratings } from 'Movie/Movie'; @@ -43,6 +44,7 @@ interface MovieIndexPosterInfoProps { showTmdbRating: boolean; showImdbRating: boolean; showRottenTomatoesRating: boolean; + showTraktRating: boolean; showTags: boolean; } @@ -76,6 +78,7 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) { showTmdbRating, showImdbRating, showRottenTomatoesRating, + showTraktRating, showTags, } = props; @@ -221,6 +224,14 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) { ); } + if (!showTraktRating && sortKey === 'traktRating' && !!ratings.trakt) { + return ( +
+ +
+ ); + } + if (!showTags && sortKey === 'tags' && tags.length) { return (
diff --git a/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx b/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx index afa7bf07f..5b2d7b2bf 100644 --- a/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx +++ b/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx @@ -150,6 +150,7 @@ export default function MovieIndexPosters(props: MovieIndexPostersProps) { showTmdbRating, showImdbRating, showRottenTomatoesRating, + showTraktRating, showTags, } = posterOptions; @@ -199,6 +200,10 @@ export default function MovieIndexPosters(props: MovieIndexPostersProps) { heights.push(19); } + if (showTraktRating) { + heights.push(19); + } + if (showTags) { heights.push(21); } @@ -253,6 +258,11 @@ export default function MovieIndexPosters(props: MovieIndexPostersProps) { heights.push(19); } break; + case 'traktRating': + if (!showTraktRating) { + heights.push(19); + } + break; case 'tags': if (!showTags) { heights.push(21); diff --git a/frontend/src/Movie/Index/Posters/Options/MovieIndexPosterOptionsModalContent.tsx b/frontend/src/Movie/Index/Posters/Options/MovieIndexPosterOptionsModalContent.tsx index 85d33eeae..903200d2b 100644 --- a/frontend/src/Movie/Index/Posters/Options/MovieIndexPosterOptionsModalContent.tsx +++ b/frontend/src/Movie/Index/Posters/Options/MovieIndexPosterOptionsModalContent.tsx @@ -59,6 +59,7 @@ function MovieIndexPosterOptionsModalContent( showTmdbRating, showImdbRating, showRottenTomatoesRating, + showTraktRating, showTags, showSearchAction, } = posterOptions; @@ -222,6 +223,18 @@ function MovieIndexPosterOptionsModalContent( /> + + {translate('ShowTraktRating')} + + + + {translate('ShowTags')} diff --git a/frontend/src/Movie/Index/Table/MovieIndexRow.css b/frontend/src/Movie/Index/Table/MovieIndexRow.css index 9049fc689..6beffe079 100644 --- a/frontend/src/Movie/Index/Table/MovieIndexRow.css +++ b/frontend/src/Movie/Index/Table/MovieIndexRow.css @@ -92,7 +92,8 @@ .imdbRating, .tmdbRating, -.rottenTomatoesRating { +.rottenTomatoesRating, +.traktRating { composes: cell; flex: 0 0 80px; diff --git a/frontend/src/Movie/Index/Table/MovieIndexRow.css.d.ts b/frontend/src/Movie/Index/Table/MovieIndexRow.css.d.ts index 7438a7603..413d5226b 100644 --- a/frontend/src/Movie/Index/Table/MovieIndexRow.css.d.ts +++ b/frontend/src/Movie/Index/Table/MovieIndexRow.css.d.ts @@ -30,6 +30,7 @@ interface CssExports { 'studio': string; 'tags': string; 'tmdbRating': string; + 'traktRating': string; 'year': string; } export const cssExports: CssExports; diff --git a/frontend/src/Movie/Index/Table/MovieIndexRow.tsx b/frontend/src/Movie/Index/Table/MovieIndexRow.tsx index 7863766c8..de6857a1f 100644 --- a/frontend/src/Movie/Index/Table/MovieIndexRow.tsx +++ b/frontend/src/Movie/Index/Table/MovieIndexRow.tsx @@ -14,6 +14,7 @@ import Column from 'Components/Table/Column'; import TagListConnector from 'Components/TagListConnector'; import TmdbRating from 'Components/TmdbRating'; import Tooltip from 'Components/Tooltip/Tooltip'; +import TraktRating from 'Components/TraktRating'; import { icons, kinds } from 'Helpers/Props'; import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; import MovieDetailsLinks from 'Movie/Details/MovieDetailsLinks'; @@ -387,6 +388,14 @@ function MovieIndexRow(props: MovieIndexRowProps) { ); } + if (name === 'traktRating') { + return ( + + {ratings.trakt ? : null} + + ); + } + if (name === 'popularity') { return ( diff --git a/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css b/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css index 5481d275a..3fcc249ad 100644 --- a/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css +++ b/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css @@ -82,7 +82,8 @@ .imdbRating, .tmdbRating, -.rottenTomatoesRating { +.rottenTomatoesRating, +.traktRating { composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css'; flex: 0 0 80px; diff --git a/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css.d.ts b/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css.d.ts index 5e999f716..a182e33cd 100644 --- a/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css.d.ts +++ b/frontend/src/Movie/Index/Table/MovieIndexTableHeader.css.d.ts @@ -27,6 +27,7 @@ interface CssExports { 'studio': string; 'tags': string; 'tmdbRating': string; + 'traktRating': string; 'year': string; } export const cssExports: CssExports; diff --git a/frontend/src/Movie/Movie.ts b/frontend/src/Movie/Movie.ts index 22235a1bc..96a334d7d 100644 --- a/frontend/src/Movie/Movie.ts +++ b/frontend/src/Movie/Movie.ts @@ -37,6 +37,7 @@ export interface Ratings { tmdb: RatingValues; metacritic: RatingValues; rottenTomatoes: RatingValues; + trakt: RatingValues; } export interface AlternativeTitle extends ModelBase { diff --git a/frontend/src/Store/Actions/discoverMovieActions.js b/frontend/src/Store/Actions/discoverMovieActions.js index b6d218c75..c658b7ed5 100644 --- a/frontend/src/Store/Actions/discoverMovieActions.js +++ b/frontend/src/Store/Actions/discoverMovieActions.js @@ -61,7 +61,8 @@ export const defaultState = { showTitle: false, showTmdbRating: false, showImdbRating: false, - showRottenTomatoesRating: false + showRottenTomatoesRating: false, + showTraktRating: false }, overviewOptions: { @@ -180,6 +181,12 @@ export const defaultState = { isSortable: true, isVisible: false }, + { + name: 'traktRating', + label: () => translate('TraktRating'), + isSortable: true, + isVisible: false + }, { name: 'popularity', label: () => translate('Popularity'), @@ -293,6 +300,10 @@ export const defaultState = { rottenTomatoesRating: function({ ratings = {} }) { return ratings.rottenTomatoes ? ratings.rottenTomatoes.value : -1; + }, + + traktRating: function({ ratings = {} }) { + return ratings.trakt ? ratings.trakt.value : 0; } }, @@ -482,6 +493,16 @@ export const defaultState = { label: () => translate('ImdbVotes'), type: filterBuilderTypes.NUMBER }, + { + name: 'traktRating', + label: () => translate('TraktRating'), + type: filterBuilderTypes.NUMBER + }, + { + name: 'traktVotes', + label: () => translate('TraktVotes'), + type: filterBuilderTypes.NUMBER + }, { name: 'popularity', label: () => translate('Popularity'), diff --git a/frontend/src/Store/Actions/movieActions.js b/frontend/src/Store/Actions/movieActions.js index 32d961ceb..7b3826858 100644 --- a/frontend/src/Store/Actions/movieActions.js +++ b/frontend/src/Store/Actions/movieActions.js @@ -156,42 +156,58 @@ export const filterPredicates = { return dateFilterPredicate(item.digitalRelease, filterValue, type); }, - tmdbRating: function(item, filterValue, type) { + tmdbRating: function({ ratings = {} }, filterValue, type) { const predicate = filterTypePredicates[type]; - const rating = item.ratings.tmdb ? item.ratings.tmdb.value : 0; + const rating = ratings.tmdb ? ratings.tmdb.value : 0; return predicate(rating * 10, filterValue); }, - tmdbVotes: function(item, filterValue, type) { + tmdbVotes: function({ ratings = {} }, filterValue, type) { const predicate = filterTypePredicates[type]; - const rating = item.ratings.tmdb ? item.ratings.tmdb.votes : 0; + const rating = ratings.tmdb ? ratings.tmdb.votes : 0; return predicate(rating, filterValue); }, - imdbRating: function(item, filterValue, type) { + imdbRating: function({ ratings = {} }, filterValue, type) { const predicate = filterTypePredicates[type]; - const rating = item.ratings.imdb ? item.ratings.imdb.value : 0; + const rating = ratings.imdb ? ratings.imdb.value : 0; return predicate(rating, filterValue); }, - rottenTomatoesRating: function(item, filterValue, type) { + imdbVotes: function({ ratings = {} }, filterValue, type) { const predicate = filterTypePredicates[type]; - const rating = item.ratings.rottenTomatoes ? item.ratings.rottenTomatoes.value : 0; + const rating = ratings.imdb ? ratings.imdb.votes : 0; return predicate(rating, filterValue); }, - imdbVotes: function(item, filterValue, type) { + rottenTomatoesRating: function({ ratings = {} }, filterValue, type) { const predicate = filterTypePredicates[type]; - const rating = item.ratings.imdb ? item.ratings.imdb.votes : 0; + const rating = ratings.rottenTomatoes ? ratings.rottenTomatoes.value : 0; + + return predicate(rating, filterValue); + }, + + traktRating: function({ ratings = {} }, filterValue, type) { + const predicate = filterTypePredicates[type]; + + const rating = ratings.trakt ? ratings.trakt.value : 0; + + return predicate(rating * 10, filterValue); + }, + + traktVotes: function({ ratings = {} }, filterValue, type) { + const predicate = filterTypePredicates[type]; + + const rating = ratings.trakt ? ratings.trakt.votes : 0; return predicate(rating, filterValue); }, diff --git a/frontend/src/Store/Actions/movieIndexActions.js b/frontend/src/Store/Actions/movieIndexActions.js index cbaecc78a..1730ff185 100644 --- a/frontend/src/Store/Actions/movieIndexActions.js +++ b/frontend/src/Store/Actions/movieIndexActions.js @@ -40,6 +40,7 @@ export const defaultState = { showTmdbRating: false, showImdbRating: false, showRottenTomatoesRating: false, + showTraktRating: false, showTags: false, showSearchAction: false }, @@ -158,7 +159,7 @@ export const defaultState = { }, { name: 'minimumAvailability', - label: () => translate('MinAvailability'), + label: () => translate('MinimumAvailability'), isSortable: true, isVisible: false }, @@ -204,6 +205,12 @@ export const defaultState = { isSortable: true, isVisible: false }, + { + name: 'traktRating', + label: () => translate('TraktRating'), + isSortable: true, + isVisible: false + }, { name: 'popularity', label: () => translate('Popularity'), @@ -278,6 +285,10 @@ export const defaultState = { rottenTomatoesRating: function({ ratings = {} }) { return ratings.rottenTomatoes ? ratings.rottenTomatoes.value : -1; + }, + + traktRating: function({ ratings = {} }) { + return ratings.trakt ? ratings.trakt.value : 0; } }, @@ -492,14 +503,24 @@ export const defaultState = { type: filterBuilderTypes.NUMBER, numberFractionDigits: 1 }, + { + name: 'imdbVotes', + label: () => translate('ImdbVotes'), + type: filterBuilderTypes.NUMBER + }, { name: 'rottenTomatoesRating', label: () => translate('RottenTomatoesRating'), type: filterBuilderTypes.NUMBER }, { - name: 'imdbVotes', - label: () => translate('ImdbVotes'), + name: 'traktRating', + label: () => translate('TraktRating'), + type: filterBuilderTypes.NUMBER + }, + { + name: 'traktVotes', + label: () => translate('TraktVotes'), type: filterBuilderTypes.NUMBER }, { diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index df13e3e01..8004785a4 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1616,6 +1616,8 @@ "ShowTitleHelpText": "Show movie title under poster", "ShowTmdbRating": "Show TMDb Rating", "ShowTmdbRatingHelpText": "Show TMDb rating under poster", + "ShowTraktRating": "Show Trakt Rating", + "ShowTraktRatingPosterHelpText": "Show Trakt rating under poster", "ShowUnknownMovieItems": "Show Unknown Movie Items", "ShowUnknownMovieItemsHelpText": "Show items without a movie in the queue. This could include removed movies or anything else in {appName}'s category", "ShowYear": "Show Year", @@ -1731,6 +1733,8 @@ "Trace": "Trace", "Trailer": "Trailer", "Trakt": "Trakt", + "TraktRating": "Trakt Rating", + "TraktVotes": "Trakt Votes", "Trending": "Trending", "Trigger": "Trigger", "True": "True", diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/RatingResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/RatingResource.cs index 20bd8a296..aba216626 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/RatingResource.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/RatingResource.cs @@ -6,6 +6,7 @@ public class RatingResource public RatingItem Imdb { get; set; } public RatingItem Metacritic { get; set; } public RatingItem RottenTomatoes { get; set; } + public RatingItem Trakt { get; set; } } public class RatingItem diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index db6fd6188..d70883052 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -670,6 +670,16 @@ private static Ratings MapRatings(RatingResource ratings) }; } + if (ratings.Trakt != null) + { + mappedRatings.Trakt = new RatingChild + { + Type = (RatingType)Enum.Parse(typeof(RatingType), ratings.Trakt.Type), + Value = ratings.Trakt.Value, + Votes = ratings.Trakt.Count + }; + } + return mappedRatings; } diff --git a/src/NzbDrone.Core/Movies/Ratings.cs b/src/NzbDrone.Core/Movies/Ratings.cs index e2103938d..b3106bcac 100644 --- a/src/NzbDrone.Core/Movies/Ratings.cs +++ b/src/NzbDrone.Core/Movies/Ratings.cs @@ -9,6 +9,7 @@ public class Ratings : MemberwiseEquatable, IEmbeddedDocument public RatingChild Tmdb { get; set; } public RatingChild Metacritic { get; set; } public RatingChild RottenTomatoes { get; set; } + public RatingChild Trakt { get; set; } } public class RatingChild