New: Many UI Updates and Performance Tweaks

This commit is contained in:
Qstick
2019-04-12 23:25:58 -04:00
parent b24a40797f
commit 6275737ced
389 changed files with 7961 additions and 5635 deletions

View File

@@ -17,7 +17,7 @@
}
.searchInput {
composes: input from 'Components/Form/TextInput.css';
composes: input from '~Components/Form/TextInput.css';
height: 46px;
border-radius: 0;

View File

@@ -99,7 +99,7 @@ class AddNewMovie extends Component {
className={styles.searchInput}
name="movieLookup"
value={term}
placeholder="eg. Some Movie, tmdb:####, imdb:####"
placeholder="eg. The Dark Knight, tmdb:155, imdb:tt0468569"
onChange={this.onSearchInputChange}
/>

View File

@@ -10,7 +10,7 @@ import AddNewMovie from './AddNewMovie';
function createMapStateToProps() {
return createSelector(
(state) => state.addMovie,
(state) => state.routing.location,
(state) => state.router.location,
(addMovie, location) => {
const { params } = parseUrl(location.search);

View File

@@ -36,24 +36,24 @@
}
.searchForMissingEpisodesContainer {
composes: container from 'Components/Form/CheckInput.css';
composes: container from '~Components/Form/CheckInput.css';
flex: 0 1 0;
}
.searchForMissingEpisodesInput {
composes: input from 'Components/Form/CheckInput.css';
composes: input from '~Components/Form/CheckInput.css';
margin-top: 0;
}
.modalFooter {
composes: modalFooter from 'Components/Modal/ModalFooter.css';
composes: modalFooter from '~Components/Modal/ModalFooter.css';
}
.addButton {
@add-mixin truncate;
composes: button from 'Components/Link/SpinnerButton.css';
composes: button from '~Components/Link/SpinnerButton.css';
}
@media only screen and (max-width: $breakpointSmall) {

View File

@@ -97,7 +97,7 @@ class ImportMovie extends Component {
} = this.state;
return (
<PageContent title="Import Series">
<PageContent title="Import Movies">
<PageContentBodyConnector
ref={this.setContentBodyRef}
onScroll={this.onScroll}
@@ -115,7 +115,7 @@ class ImportMovie extends Component {
{
!rootFoldersError && rootFoldersPopulated && !unmappedFolders.length &&
<div>
All series in {path} have been imported
All movies in {path} have been imported
</div>
}

View File

@@ -14,7 +14,7 @@
}
.importButton {
composes: button from 'Components/Link/SpinnerButton.css';
composes: button from '~Components/Link/SpinnerButton.css';
height: 35px;
}
@@ -26,7 +26,7 @@
}
.loading {
composes: loading from 'Components/Loading/LoadingIndicator.css';
composes: loading from '~Components/Loading/LoadingIndicator.css';
margin: 0 10px 0 12px;
text-align: left;

View File

@@ -1,25 +1,25 @@
.folder {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
flex: 1 0 200px;
}
.monitor {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
flex: 0 1 200px;
min-width: 185px;
}
.qualityProfile {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
flex: 0 1 250px;
min-width: 170px;
}
.movie {
composes: headerCell from 'Components/Table/VirtualTableHeaderCell.css';
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
flex: 0 1 400px;
min-width: 300px;

View File

@@ -1,30 +1,30 @@
.selectInput {
composes: input from 'Components/Form/CheckInput.css';
composes: input from '~Components/Form/CheckInput.css';
}
.folder {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
flex: 1 0 200px;
line-height: 36px;
}
.monitor {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
flex: 0 1 200px;
min-width: 185px;
}
.qualityProfile {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
flex: 0 1 250px;
min-width: 170px;
}
.series {
composes: cell from 'Components/Table/Cells/VirtualTableRowCell.css';
composes: cell from '~Components/Table/Cells/VirtualTableRowCell.css';
flex: 0 1 400px;
min-width: 300px;

View File

@@ -1,3 +1,3 @@
.input {
composes: input from 'Components/Form/CheckInput.css';
composes: input from '~Components/Form/CheckInput.css';
}

View File

@@ -3,7 +3,7 @@
}
.button {
composes: link from 'Components/Link/Link.css';
composes: link from '~Components/Link/Link.css';
position: relative;
display: flex;
@@ -64,7 +64,7 @@
}
.searchInput {
composes: input from 'Components/Form/TextInput.css';
composes: input from '~Components/Form/TextInput.css';
border-radius: 0;
}

View File

@@ -34,6 +34,8 @@ class ImportMovieSelectMovie extends Component {
super(props, context);
this._movieLookupTimeout = null;
this._buttonRef = {};
this._contentRef = {};
this.state = {
term: props.id,
@@ -44,14 +46,6 @@ class ImportMovieSelectMovie extends Component {
//
// Control
_setButtonRef = (ref) => {
this._buttonRef = ref;
}
_setContentRef = (ref) => {
this._contentRef = ref;
}
_addListener() {
window.addEventListener('click', this.onWindowClick);
}
@@ -64,14 +58,18 @@ class ImportMovieSelectMovie extends Component {
// Listeners
onWindowClick = (event) => {
const button = ReactDOM.findDOMNode(this._buttonRef);
const content = ReactDOM.findDOMNode(this._contentRef);
const button = ReactDOM.findDOMNode(this._buttonRef.current);
const content = ReactDOM.findDOMNode(this._contentRef.current);
if (!button) {
if (!button || !content) {
return;
}
if (!button.contains(event.target) && content && !content.contains(event.target) && this.state.isOpen) {
if (
!button.contains(event.target) &&
!content.contains(event.target) &&
this.state.isOpen
) {
this.setState({ isOpen: false });
this._removeListener();
}
@@ -120,7 +118,7 @@ class ImportMovieSelectMovie extends Component {
isPopulated,
error,
items,
queued,
isQueued,
isLookingUpMovie
} = this.props;
@@ -134,124 +132,145 @@ class ImportMovieSelectMovie extends Component {
element: styles.tether
}}
{...tetherOptions}
>
<Link
ref={this._setButtonRef}
className={styles.button}
component="div"
onPress={this.onPress}
>
{
isLookingUpMovie && queued && !isPopulated &&
<LoadingIndicator
className={styles.loading}
size={20}
/>
}
renderTarget={
(ref) => {
this._buttonRef = ref;
{
isPopulated && selectedMovie && isExistingMovie &&
<Icon
className={styles.warningIcon}
name={icons.WARNING}
kind={kinds.WARNING}
/>
}
return (
<div ref={ref}>
<Link
className={styles.button}
component="div"
onPress={this.onPress}
>
{
isLookingUpMovie && isQueued && !isPopulated ?
<LoadingIndicator
className={styles.loading}
size={20}
/> :
null
}
{
isPopulated && selectedMovie &&
<ImportMovieTitle
title={selectedMovie.title}
year={selectedMovie.year}
network={selectedMovie.network}
isExistingMovie={isExistingMovie}
/>
}
{
isPopulated && selectedMovie && isExistingMovie ?
<Icon
className={styles.warningIcon}
name={icons.WARNING}
kind={kinds.WARNING}
/> :
null
}
{
isPopulated && !selectedMovie &&
<div>
<Icon
className={styles.warningIcon}
name={icons.WARNING}
kind={kinds.WARNING}
/>
{
isPopulated && selectedMovie ?
<ImportMovieTitle
title={selectedMovie.title}
year={selectedMovie.year}
network={selectedMovie.network}
isExistingMovie={isExistingMovie}
/> :
null
}
{
isPopulated && !selectedMovie ?
<div>
<Icon
className={styles.warningIcon}
name={icons.WARNING}
kind={kinds.WARNING}
/>
No match found!
</div>
}
</div> :
null
}
{
!isFetching && !!error &&
<div>
<Icon
className={styles.warningIcon}
title={errorMessage}
name={icons.WARNING}
kind={kinds.WARNING}
/>
{
!isFetching && !!error ?
<div>
<Icon
className={styles.warningIcon}
title={errorMessage}
name={icons.WARNING}
kind={kinds.WARNING}
/>
Search failed, please try again later.
</div> :
null
}
<div className={styles.dropdownArrowContainer}>
<Icon
name={icons.CARET_DOWN}
/>
</div>
</Link>
</div>
);
}
}
renderElement={
(ref) => {
this._contentRef = ref;
<div className={styles.dropdownArrowContainer}>
<Icon
name={icons.CARET_DOWN}
/>
</div>
</Link>
if (!this.state.isOpen) {
return;
}
{
this.state.isOpen &&
<div
ref={this._setContentRef}
className={styles.contentContainer}
>
<div className={styles.content}>
<div className={styles.searchContainer}>
<div className={styles.searchIconContainer}>
<Icon name={icons.SEARCH} />
return (
<div
ref={ref}
className={styles.contentContainer}
>
<div className={styles.content}>
<div className={styles.searchContainer}>
<div className={styles.searchIconContainer}>
<Icon name={icons.SEARCH} />
</div>
<TextInput
className={styles.searchInput}
name={`${name}_textInput`}
value={this.state.term}
onChange={this.onSearchInputChange}
/>
<FormInputButton
kind={kinds.DEFAULT}
spinnerIcon={icons.REFRESH}
canSpin={true}
isSpinning={isFetching}
onPress={this.onRefreshPress}
>
<Icon name={icons.REFRESH} />
</FormInputButton>
</div>
<TextInput
className={styles.searchInput}
name={`${name}_textInput`}
value={this.state.term}
onChange={this.onSearchInputChange}
/>
<FormInputButton
kind={kinds.DEFAULT}
spinnerIcon={icons.REFRESH}
canSpin={true}
isSpinning={isFetching}
onPress={this.onRefreshPress}
>
<Icon name={icons.REFRESH} />
</FormInputButton>
</div>
<div className={styles.results}>
{
items.map((item) => {
return (
<ImportMovieSearchResultConnector
key={item.tmdbId}
tmdbId={item.tmdbId}
title={item.title}
year={item.year}
studio={item.studio}
onPress={this.onMovieSelect}
/>
);
})
}
<div className={styles.results}>
{
items.map((item) => {
return (
<ImportMovieSearchResultConnector
key={item.tmdbId}
tmdbId={item.tmdbId}
title={item.title}
year={item.year}
studio={item.studio}
onPress={this.onMovieSelect}
/>
);
})
}
</div>
</div>
</div>
</div>
);
}
}
</TetherComponent>
/>
);
}
}
@@ -264,7 +283,7 @@ ImportMovieSelectMovie.propTypes = {
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
queued: PropTypes.bool.isRequired,
isQueued: PropTypes.bool.isRequired,
isLookingUpMovie: PropTypes.bool.isRequired,
onSearchInputChange: PropTypes.func.isRequired,
onMovieSelect: PropTypes.func.isRequired
@@ -274,7 +293,7 @@ ImportMovieSelectMovie.defaultProps = {
isFetching: true,
isPopulated: false,
items: [],
queued: true
isQueued: true
};
export default ImportMovieSelectMovie;

View File

@@ -1,18 +1,18 @@
.link {
composes: link from 'Components/Link/Link.css';
composes: link from '~Components/Link/Link.css';
display: block;
}
.freeSpace,
.unmappedFolders {
composes: cell from 'Components/Table/Cells/TableRowCell.css';
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 150px;
}
.actions {
composes: cell from 'Components/Table/Cells/TableRowCell.css';
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 45px;
}

View File

@@ -76,7 +76,7 @@ class ImportMovieSelectFolder extends Component {
} = this.props;
return (
<PageContent title="Import Series">
<PageContent title="Import Movies">
<PageContentBodyConnector>
{
isFetching && !isPopulated &&
@@ -99,7 +99,7 @@ class ImportMovieSelectFolder extends Component {
Some tips to ensure the import goes smoothly:
<ul>
<li className={styles.tip}>
Make sure your files include the quality in the name. eg. <span className={styles.code}>episode.s02e15.bluray.mkv</span>
Make sure your files include the quality in the name. eg. <span className={styles.code}>movie.2008.bluray.mkv</span>
</li>
<li className={styles.tip}>
Point Radarr to the folder containing all of your movies not a specific one. eg. <span className={styles.code}>"{isWindows ? 'C:\\movies' : '/movies'}"</span> and not <span className={styles.code}>"{isWindows ? 'C:\\movies\\the matrix' : '/movies/the matrix'}"</span>

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { push } from 'react-router-redux';
import { push } from 'connected-react-router';
import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector';
import { fetchRootFolders, addRootFolder, deleteRootFolder } from 'Store/Actions/rootFolderActions';
import ImportMovieSelectFolder from './ImportMovieSelectFolder';