mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: Digital Release Dates in UI
This commit is contained in:
@@ -45,6 +45,7 @@ import {
|
|||||||
faCloud as fasCloud,
|
faCloud as fasCloud,
|
||||||
faCog as fasCog,
|
faCog as fasCog,
|
||||||
faCogs as fasCogs,
|
faCogs as fasCogs,
|
||||||
|
faCompactDisc as fasCompactDisc,
|
||||||
faCopy as fasCopy,
|
faCopy as fasCopy,
|
||||||
faDesktop as fasDesktop,
|
faDesktop as fasDesktop,
|
||||||
faDownload as fasDownload,
|
faDownload as fasDownload,
|
||||||
@@ -133,6 +134,7 @@ export const COLLAPSE = fasChevronCircleUp;
|
|||||||
export const COMPUTER = fasDesktop;
|
export const COMPUTER = fasDesktop;
|
||||||
export const DANGER = fasExclamationCircle;
|
export const DANGER = fasExclamationCircle;
|
||||||
export const DELETE = fasTrashAlt;
|
export const DELETE = fasTrashAlt;
|
||||||
|
export const DISC = fasCompactDisc;
|
||||||
export const DOWNLOAD = fasDownload;
|
export const DOWNLOAD = fasDownload;
|
||||||
export const DOWNLOADED = fasDownload;
|
export const DOWNLOADED = fasDownload;
|
||||||
export const DOWNLOADING = fasCloudDownloadAlt;
|
export const DOWNLOADING = fasCloudDownloadAlt;
|
||||||
|
@@ -40,6 +40,7 @@ import MovieDetailsLinks from './MovieDetailsLinks';
|
|||||||
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
|
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
|
||||||
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
|
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
|
||||||
import MovieTagsConnector from './MovieTagsConnector';
|
import MovieTagsConnector from './MovieTagsConnector';
|
||||||
|
import MovieReleaseDatesConnector from './MovieReleaseDatesConnector';
|
||||||
import styles from './MovieDetails.css';
|
import styles from './MovieDetails.css';
|
||||||
|
|
||||||
const defaultFontSize = parseInt(fonts.defaultFontSize);
|
const defaultFontSize = parseInt(fonts.defaultFontSize);
|
||||||
@@ -232,6 +233,9 @@ class MovieDetails extends Component {
|
|||||||
imdbId,
|
imdbId,
|
||||||
title,
|
title,
|
||||||
year,
|
year,
|
||||||
|
inCinemas,
|
||||||
|
physicalRelease,
|
||||||
|
digitalRelease,
|
||||||
runtime,
|
runtime,
|
||||||
certification,
|
certification,
|
||||||
ratings,
|
ratings,
|
||||||
@@ -398,7 +402,20 @@ class MovieDetails extends Component {
|
|||||||
{
|
{
|
||||||
year > 0 &&
|
year > 0 &&
|
||||||
<span className={styles.year}>
|
<span className={styles.year}>
|
||||||
{year}
|
<Popover
|
||||||
|
anchor={
|
||||||
|
year
|
||||||
|
}
|
||||||
|
title="Release Dates"
|
||||||
|
body={
|
||||||
|
<MovieReleaseDatesConnector
|
||||||
|
inCinemas={inCinemas}
|
||||||
|
physicalRelease={physicalRelease}
|
||||||
|
digitalRelease={digitalRelease}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
position={tooltipPositions.BOTTOM}
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,6 +741,8 @@ MovieDetails.propTypes = {
|
|||||||
youTubeTrailerId: PropTypes.string,
|
youTubeTrailerId: PropTypes.string,
|
||||||
isAvailable: PropTypes.bool.isRequired,
|
isAvailable: PropTypes.bool.isRequired,
|
||||||
inCinemas: PropTypes.string,
|
inCinemas: PropTypes.string,
|
||||||
|
physicalRelease: PropTypes.string,
|
||||||
|
digitalRelease: PropTypes.string,
|
||||||
overview: PropTypes.string.isRequired,
|
overview: PropTypes.string.isRequired,
|
||||||
images: PropTypes.arrayOf(PropTypes.object).isRequired,
|
images: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired,
|
alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||||
|
3
frontend/src/Movie/Details/MovieReleaseDates.css
Normal file
3
frontend/src/Movie/Details/MovieReleaseDates.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.dateIcon {
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
68
frontend/src/Movie/Details/MovieReleaseDates.js
Normal file
68
frontend/src/Movie/Details/MovieReleaseDates.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import { icons } from 'Helpers/Props';
|
||||||
|
import Icon from 'Components/Icon';
|
||||||
|
import getRelativeDate from 'Utilities/Date/getRelativeDate';
|
||||||
|
import styles from './MovieReleaseDates.css';
|
||||||
|
|
||||||
|
function MovieReleaseDates(props) {
|
||||||
|
const {
|
||||||
|
showRelativeDates,
|
||||||
|
shortDateFormat,
|
||||||
|
timeFormat,
|
||||||
|
inCinemas,
|
||||||
|
physicalRelease,
|
||||||
|
digitalRelease
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
!!inCinemas &&
|
||||||
|
<div >
|
||||||
|
<span className={styles.dateIcon}>
|
||||||
|
<Icon
|
||||||
|
name={icons.IN_CINEMAS}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
{getRelativeDate(inCinemas, shortDateFormat, showRelativeDates, { timeFormat, timeForToday: false })}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
!!physicalRelease &&
|
||||||
|
<div >
|
||||||
|
<span className={styles.dateIcon}>
|
||||||
|
<Icon
|
||||||
|
name={icons.DISC}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
{getRelativeDate(physicalRelease, shortDateFormat, showRelativeDates, { timeFormat, timeForToday: false })}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
!!digitalRelease &&
|
||||||
|
<div >
|
||||||
|
<span className={styles.dateIcon}>
|
||||||
|
<Icon
|
||||||
|
name={icons.MOVIE_FILE}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
{getRelativeDate(digitalRelease, shortDateFormat, showRelativeDates, { timeFormat, timeForToday: false })}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
MovieReleaseDates.propTypes = {
|
||||||
|
showRelativeDates: PropTypes.bool.isRequired,
|
||||||
|
shortDateFormat: PropTypes.string.isRequired,
|
||||||
|
longDateFormat: PropTypes.string.isRequired,
|
||||||
|
timeFormat: PropTypes.string.isRequired,
|
||||||
|
inCinemas: PropTypes.string,
|
||||||
|
physicalRelease: PropTypes.string,
|
||||||
|
digitalRelease: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MovieReleaseDates;
|
21
frontend/src/Movie/Details/MovieReleaseDatesConnector.js
Normal file
21
frontend/src/Movie/Details/MovieReleaseDatesConnector.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||||
|
import MovieReleaseDates from './MovieReleaseDates';
|
||||||
|
|
||||||
|
function createMapStateToProps() {
|
||||||
|
return createSelector(
|
||||||
|
createUISettingsSelector(),
|
||||||
|
(uiSettings) => {
|
||||||
|
return _.pick(uiSettings, [
|
||||||
|
'showRelativeDates',
|
||||||
|
'shortDateFormat',
|
||||||
|
'longDateFormat',
|
||||||
|
'timeFormat'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(createMapStateToProps, null)(MovieReleaseDates);
|
@@ -64,6 +64,15 @@ function MovieIndexSortMenu(props) {
|
|||||||
Added
|
Added
|
||||||
</SortMenuItem>
|
</SortMenuItem>
|
||||||
|
|
||||||
|
<SortMenuItem
|
||||||
|
name="year"
|
||||||
|
sortKey={sortKey}
|
||||||
|
sortDirection={sortDirection}
|
||||||
|
onPress={onSortSelect}
|
||||||
|
>
|
||||||
|
Year
|
||||||
|
</SortMenuItem>
|
||||||
|
|
||||||
<SortMenuItem
|
<SortMenuItem
|
||||||
name="inCinemas"
|
name="inCinemas"
|
||||||
sortKey={sortKey}
|
sortKey={sortKey}
|
||||||
@@ -82,6 +91,15 @@ function MovieIndexSortMenu(props) {
|
|||||||
Physical Release
|
Physical Release
|
||||||
</SortMenuItem>
|
</SortMenuItem>
|
||||||
|
|
||||||
|
<SortMenuItem
|
||||||
|
name="digitalRelease"
|
||||||
|
sortKey={sortKey}
|
||||||
|
sortDirection={sortDirection}
|
||||||
|
onPress={onSortSelect}
|
||||||
|
>
|
||||||
|
Digital Release
|
||||||
|
</SortMenuItem>
|
||||||
|
|
||||||
<SortMenuItem
|
<SortMenuItem
|
||||||
name="path"
|
name="path"
|
||||||
sortKey={sortKey}
|
sortKey={sortKey}
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
.added,
|
.added,
|
||||||
.inCinemas,
|
.inCinemas,
|
||||||
.physicalRelease,
|
.physicalRelease,
|
||||||
|
.digitalRelease,
|
||||||
.runtime,
|
.runtime,
|
||||||
.genres {
|
.genres {
|
||||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
.added,
|
.added,
|
||||||
.inCinemas,
|
.inCinemas,
|
||||||
.physicalRelease,
|
.physicalRelease,
|
||||||
|
.digitalRelease,
|
||||||
.runtime,
|
.runtime,
|
||||||
.genres {
|
.genres {
|
||||||
composes: cell;
|
composes: cell;
|
||||||
|
@@ -72,6 +72,7 @@ class MovieIndexRow extends Component {
|
|||||||
year,
|
year,
|
||||||
inCinemas,
|
inCinemas,
|
||||||
physicalRelease,
|
physicalRelease,
|
||||||
|
digitalRelease,
|
||||||
runtime,
|
runtime,
|
||||||
minimumAvailability,
|
minimumAvailability,
|
||||||
path,
|
path,
|
||||||
@@ -225,6 +226,17 @@ class MovieIndexRow extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name === 'digitalRelease') {
|
||||||
|
return (
|
||||||
|
<RelativeDateCellConnector
|
||||||
|
key={name}
|
||||||
|
className={styles[name]}
|
||||||
|
date={digitalRelease}
|
||||||
|
component={VirtualTableRowCell}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (name === 'runtime') {
|
if (name === 'runtime') {
|
||||||
return (
|
return (
|
||||||
<VirtualTableRowCell
|
<VirtualTableRowCell
|
||||||
@@ -401,6 +413,7 @@ MovieIndexRow.propTypes = {
|
|||||||
year: PropTypes.number,
|
year: PropTypes.number,
|
||||||
inCinemas: PropTypes.string,
|
inCinemas: PropTypes.string,
|
||||||
physicalRelease: PropTypes.string,
|
physicalRelease: PropTypes.string,
|
||||||
|
digitalRelease: PropTypes.string,
|
||||||
runtime: PropTypes.number,
|
runtime: PropTypes.number,
|
||||||
minimumAvailability: PropTypes.string.isRequired,
|
minimumAvailability: PropTypes.string.isRequired,
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
|
@@ -126,6 +126,10 @@ export const filterPredicates = {
|
|||||||
return dateFilterPredicate(item.physicalRelease, filterValue, type);
|
return dateFilterPredicate(item.physicalRelease, filterValue, type);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
digitalRelease: function(item, filterValue, type) {
|
||||||
|
return dateFilterPredicate(item.digitalRelease, filterValue, type);
|
||||||
|
},
|
||||||
|
|
||||||
ratings: function(item, filterValue, type) {
|
ratings: function(item, filterValue, type) {
|
||||||
const predicate = filterTypePredicates[type];
|
const predicate = filterTypePredicates[type];
|
||||||
|
|
||||||
|
@@ -119,6 +119,12 @@ export const defaultState = {
|
|||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'digitalRelease',
|
||||||
|
label: 'Digital Release',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'runtime',
|
name: 'runtime',
|
||||||
label: 'Runtime',
|
label: 'Runtime',
|
||||||
@@ -293,6 +299,12 @@ export const defaultState = {
|
|||||||
type: filterBuilderTypes.DATE,
|
type: filterBuilderTypes.DATE,
|
||||||
valueType: filterBuilderValueTypes.DATE
|
valueType: filterBuilderValueTypes.DATE
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'digitalRelease',
|
||||||
|
label: 'Digital Release',
|
||||||
|
type: filterBuilderTypes.DATE,
|
||||||
|
valueType: filterBuilderValueTypes.DATE
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'runtime',
|
name: 'runtime',
|
||||||
label: 'Runtime',
|
label: 'Runtime',
|
||||||
|
@@ -35,6 +35,7 @@ namespace Radarr.Api.V3.Movies
|
|||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public DateTime? InCinemas { get; set; }
|
public DateTime? InCinemas { get; set; }
|
||||||
public DateTime? PhysicalRelease { get; set; }
|
public DateTime? PhysicalRelease { get; set; }
|
||||||
|
public DateTime? DigitalRelease { get; set; }
|
||||||
public string PhysicalReleaseNote { get; set; }
|
public string PhysicalReleaseNote { get; set; }
|
||||||
public List<MediaCover> Images { get; set; }
|
public List<MediaCover> Images { get; set; }
|
||||||
public string Website { get; set; }
|
public string Website { get; set; }
|
||||||
@@ -94,6 +95,7 @@ namespace Radarr.Api.V3.Movies
|
|||||||
SortTitle = model.SortTitle,
|
SortTitle = model.SortTitle,
|
||||||
InCinemas = model.InCinemas,
|
InCinemas = model.InCinemas,
|
||||||
PhysicalRelease = model.PhysicalRelease,
|
PhysicalRelease = model.PhysicalRelease,
|
||||||
|
DigitalRelease = model.DigitalRelease,
|
||||||
HasFile = model.HasFile,
|
HasFile = model.HasFile,
|
||||||
|
|
||||||
SizeOnDisk = size,
|
SizeOnDisk = size,
|
||||||
@@ -156,6 +158,7 @@ namespace Radarr.Api.V3.Movies
|
|||||||
SortTitle = translatedTitle.NormalizeTitle(),
|
SortTitle = translatedTitle.NormalizeTitle(),
|
||||||
InCinemas = model.InCinemas,
|
InCinemas = model.InCinemas,
|
||||||
PhysicalRelease = model.PhysicalRelease,
|
PhysicalRelease = model.PhysicalRelease,
|
||||||
|
DigitalRelease = model.DigitalRelease,
|
||||||
HasFile = model.HasFile,
|
HasFile = model.HasFile,
|
||||||
|
|
||||||
SizeOnDisk = size,
|
SizeOnDisk = size,
|
||||||
@@ -217,6 +220,7 @@ namespace Radarr.Api.V3.Movies
|
|||||||
SortTitle = translatedTitle.NormalizeTitle(),
|
SortTitle = translatedTitle.NormalizeTitle(),
|
||||||
InCinemas = model.InCinemas,
|
InCinemas = model.InCinemas,
|
||||||
PhysicalRelease = model.PhysicalRelease,
|
PhysicalRelease = model.PhysicalRelease,
|
||||||
|
DigitalRelease = model.DigitalRelease,
|
||||||
HasFile = model.HasFile,
|
HasFile = model.HasFile,
|
||||||
|
|
||||||
SizeOnDisk = size,
|
SizeOnDisk = size,
|
||||||
|
Reference in New Issue
Block a user