mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-08 05:51:47 -07:00
Misc Frontend Updates
This commit is contained in:
parent
729d1142b0
commit
f69559e4da
11 changed files with 107 additions and 46 deletions
|
@ -1,6 +1,7 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styles from './Form.css';
|
import { kinds } from 'Helpers/Props';
|
||||||
|
import Alert from 'Components/Alert';
|
||||||
|
|
||||||
function Form({ children, validationErrors, validationWarnings, ...otherProps }) {
|
function Form({ children, validationErrors, validationWarnings, ...otherProps }) {
|
||||||
return (
|
return (
|
||||||
|
@ -9,12 +10,12 @@ function Form({ children, validationErrors, validationWarnings, ...otherProps })
|
||||||
{
|
{
|
||||||
validationErrors.map((error, index) => {
|
validationErrors.map((error, index) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<Alert
|
||||||
key={index}
|
key={index}
|
||||||
className={styles.error}
|
kind={kinds.DANGER}
|
||||||
>
|
>
|
||||||
{error.errorMessage}
|
{error.errorMessage}
|
||||||
</div>
|
</Alert>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -22,12 +23,12 @@ function Form({ children, validationErrors, validationWarnings, ...otherProps })
|
||||||
{
|
{
|
||||||
validationWarnings.map((warning, index) => {
|
validationWarnings.map((warning, index) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<Alert
|
||||||
key={index}
|
key={index}
|
||||||
className={styles.error}
|
kind={kinds.WARNING}
|
||||||
>
|
>
|
||||||
{warning.errorMessage}
|
{warning.errorMessage}
|
||||||
</div>
|
</Alert>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,9 +247,9 @@ class PageSidebar extends Component {
|
||||||
window.addEventListener('click', this.onWindowClick, { capture: true });
|
window.addEventListener('click', this.onWindowClick, { capture: true });
|
||||||
window.addEventListener('scroll', this.onWindowScroll);
|
window.addEventListener('scroll', this.onWindowScroll);
|
||||||
window.addEventListener('touchstart', this.onTouchStart);
|
window.addEventListener('touchstart', this.onTouchStart);
|
||||||
|
window.addEventListener('touchmove', this.onTouchMove);
|
||||||
window.addEventListener('touchend', this.onTouchEnd);
|
window.addEventListener('touchend', this.onTouchEnd);
|
||||||
window.addEventListener('touchcancel', this.onTouchCancel);
|
window.addEventListener('touchcancel', this.onTouchCancel);
|
||||||
window.addEventListener('touchmove', this.onTouchMove);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,9 +274,9 @@ class PageSidebar extends Component {
|
||||||
window.removeEventListener('click', this.onWindowClick, { capture: true });
|
window.removeEventListener('click', this.onWindowClick, { capture: true });
|
||||||
window.removeEventListener('scroll', this.onWindowScroll);
|
window.removeEventListener('scroll', this.onWindowScroll);
|
||||||
window.removeEventListener('touchstart', this.onTouchStart);
|
window.removeEventListener('touchstart', this.onTouchStart);
|
||||||
|
window.removeEventListener('touchmove', this.onTouchMove);
|
||||||
window.removeEventListener('touchend', this.onTouchEnd);
|
window.removeEventListener('touchend', this.onTouchEnd);
|
||||||
window.removeEventListener('touchcancel', this.onTouchCancel);
|
window.removeEventListener('touchcancel', this.onTouchCancel);
|
||||||
window.removeEventListener('touchmove', this.onTouchMove);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,20 +322,22 @@ class PageSidebar extends Component {
|
||||||
|
|
||||||
onTouchStart = (event) => {
|
onTouchStart = (event) => {
|
||||||
const touches = event.touches;
|
const touches = event.touches;
|
||||||
const touchStart = touches[0].pageX;
|
const touchStartX = touches[0].pageX;
|
||||||
|
const touchStartY = touches[0].pageY;
|
||||||
const isSidebarVisible = this.props.isSidebarVisible;
|
const isSidebarVisible = this.props.isSidebarVisible;
|
||||||
|
|
||||||
if (touches.length !== 1) {
|
if (touches.length !== 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSidebarVisible && (touchStart > 210 || touchStart < 50)) {
|
if (isSidebarVisible && (touchStartX > 210 || touchStartX < 50)) {
|
||||||
return;
|
return;
|
||||||
} else if (!isSidebarVisible && touchStart > 50) {
|
} else if (!isSidebarVisible && touchStartX > 50) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._touchStartX = touchStart;
|
this._touchStartX = touchStartX;
|
||||||
|
this._touchStartY = touchStartY;
|
||||||
}
|
}
|
||||||
|
|
||||||
onTouchEnd = (event) => {
|
onTouchEnd = (event) => {
|
||||||
|
|
|
@ -54,7 +54,7 @@ class SelectAlbumModalContentConnector extends Component {
|
||||||
this.props.updateInteractiveImportItem({
|
this.props.updateInteractiveImportItem({
|
||||||
id,
|
id,
|
||||||
album,
|
album,
|
||||||
episodes: []
|
tracks: []
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,24 @@
|
||||||
|
|
||||||
@media only screen and (max-width: $breakpointSmall) {
|
@media only screen and (max-width: $breakpointSmall) {
|
||||||
.footer {
|
.footer {
|
||||||
|
.leftButtons,
|
||||||
|
.centerButtons,
|
||||||
|
.rightButtons {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftButtons {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.centerButtons {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightButtons {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
a,
|
a,
|
||||||
button {
|
button {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
|
|
|
@ -74,7 +74,7 @@ class InteractiveImportRow extends Component {
|
||||||
|
|
||||||
const isValid = !!(
|
const isValid = !!(
|
||||||
artist &&
|
artist &&
|
||||||
album != null &&
|
album &&
|
||||||
tracks.length &&
|
tracks.length &&
|
||||||
quality &&
|
quality &&
|
||||||
language
|
language
|
||||||
|
|
|
@ -6,17 +6,19 @@ import { cancelTestDownloadClient, cancelSaveDownloadClient } from 'Store/Action
|
||||||
import EditDownloadClientModal from './EditDownloadClientModal';
|
import EditDownloadClientModal from './EditDownloadClientModal';
|
||||||
|
|
||||||
function createMapDispatchToProps(dispatch, props) {
|
function createMapDispatchToProps(dispatch, props) {
|
||||||
|
const section = 'downloadClients';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dispatchClearPendingChanges() {
|
dispatchClearPendingChanges() {
|
||||||
dispatch(clearPendingChanges);
|
dispatch(clearPendingChanges({ section }));
|
||||||
},
|
},
|
||||||
|
|
||||||
dispatchCancelTestDownloadClient() {
|
dispatchCancelTestDownloadClient() {
|
||||||
dispatch(cancelTestDownloadClient);
|
dispatch(cancelTestDownloadClient({ section }));
|
||||||
},
|
},
|
||||||
|
|
||||||
dispatchCancelSaveDownloadClient() {
|
dispatchCancelSaveDownloadClient() {
|
||||||
dispatch(cancelSaveDownloadClient);
|
dispatch(cancelSaveDownloadClient({ section }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -27,9 +29,9 @@ class EditDownloadClientModalConnector extends Component {
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
onModalClose = () => {
|
onModalClose = () => {
|
||||||
this.props.dispatchClearPendingChanges({ section: 'downloadClients' });
|
this.props.dispatchClearPendingChanges();
|
||||||
this.props.dispatchCancelTestDownloadClient({ section: 'downloadClients' });
|
this.props.dispatchCancelTestDownloadClient();
|
||||||
this.props.dispatchCancelSaveDownloadClient({ section: 'downloadClients' });
|
this.props.dispatchCancelSaveDownloadClient();
|
||||||
this.props.onModalClose();
|
this.props.onModalClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,19 @@ import { cancelTestIndexer, cancelSaveIndexer } from 'Store/Actions/settingsActi
|
||||||
import EditIndexerModal from './EditIndexerModal';
|
import EditIndexerModal from './EditIndexerModal';
|
||||||
|
|
||||||
function createMapDispatchToProps(dispatch, props) {
|
function createMapDispatchToProps(dispatch, props) {
|
||||||
|
const section = 'indexers';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dispatchClearPendingChanges() {
|
dispatchClearPendingChanges() {
|
||||||
dispatch(clearPendingChanges);
|
dispatch(clearPendingChanges)({ section });
|
||||||
},
|
},
|
||||||
|
|
||||||
dispatchCancelTestIndexer() {
|
dispatchCancelTestIndexer() {
|
||||||
dispatch(cancelTestIndexer);
|
dispatch(cancelTestIndexer({ section }));
|
||||||
},
|
},
|
||||||
|
|
||||||
dispatchCancelSaveIndexer() {
|
dispatchCancelSaveIndexer() {
|
||||||
dispatch(cancelSaveIndexer);
|
dispatch(cancelSaveIndexer({ section }));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -27,9 +29,9 @@ class EditIndexerModalConnector extends Component {
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
onModalClose = () => {
|
onModalClose = () => {
|
||||||
this.props.dispatchClearPendingChanges({ section: 'indexers' });
|
this.props.dispatchClearPendingChanges();
|
||||||
this.props.dispatchCancelTestIndexer({ section: 'indexers' });
|
this.props.dispatchCancelTestIndexer();
|
||||||
this.props.dispatchCancelSaveIndexer({ section: 'indexers' });
|
this.props.dispatchCancelSaveIndexer();
|
||||||
this.props.onModalClose();
|
this.props.onModalClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,15 @@ import { connect } from 'react-redux';
|
||||||
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
||||||
import EditMetadataModal from './EditMetadataModal';
|
import EditMetadataModal from './EditMetadataModal';
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
function createMapDispatchToProps(dispatch, props) {
|
||||||
clearPendingChanges
|
const section = 'metadata';
|
||||||
};
|
|
||||||
|
return {
|
||||||
|
dispatchClearPendingChanges() {
|
||||||
|
dispatch(clearPendingChanges)({ section });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class EditMetadataModalConnector extends Component {
|
class EditMetadataModalConnector extends Component {
|
||||||
|
|
||||||
|
@ -36,4 +42,4 @@ EditMetadataModalConnector.propTypes = {
|
||||||
clearPendingChanges: PropTypes.func.isRequired
|
clearPendingChanges: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(EditMetadataModalConnector);
|
export default connect(null, createMapDispatchToProps)(EditMetadataModalConnector);
|
||||||
|
|
|
@ -2,11 +2,26 @@ import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
||||||
|
import { cancelTestNotification, cancelSaveNotification } from 'Store/Actions/settingsActions';
|
||||||
import EditNotificationModal from './EditNotificationModal';
|
import EditNotificationModal from './EditNotificationModal';
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
function createMapDispatchToProps(dispatch, props) {
|
||||||
clearPendingChanges
|
const section = 'notifications';
|
||||||
};
|
|
||||||
|
return {
|
||||||
|
dispatchClearPendingChanges() {
|
||||||
|
dispatch(clearPendingChanges({ section }));
|
||||||
|
},
|
||||||
|
|
||||||
|
dispatchCancelTestNotification() {
|
||||||
|
dispatch(cancelTestNotification({ section }));
|
||||||
|
},
|
||||||
|
|
||||||
|
dispatchCancelSaveNotification() {
|
||||||
|
dispatch(cancelSaveNotification({ section }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
class EditNotificationModalConnector extends Component {
|
class EditNotificationModalConnector extends Component {
|
||||||
|
|
||||||
|
@ -14,7 +29,9 @@ class EditNotificationModalConnector extends Component {
|
||||||
// Listeners
|
// Listeners
|
||||||
|
|
||||||
onModalClose = () => {
|
onModalClose = () => {
|
||||||
this.props.clearPendingChanges({ section: 'notifications' });
|
this.props.dispatchClearPendingChanges();
|
||||||
|
this.props.dispatchCancelTestNotification();
|
||||||
|
this.props.dispatchCancelSaveNotification();
|
||||||
this.props.onModalClose();
|
this.props.onModalClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,9 +39,16 @@ class EditNotificationModalConnector extends Component {
|
||||||
// Render
|
// Render
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {
|
||||||
|
dispatchClearPendingChanges,
|
||||||
|
dispatchCancelTestNotification,
|
||||||
|
dispatchCancelSaveNotification,
|
||||||
|
...otherProps
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EditNotificationModal
|
<EditNotificationModal
|
||||||
{...this.props}
|
{...otherProps}
|
||||||
onModalClose={this.onModalClose}
|
onModalClose={this.onModalClose}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -33,7 +57,9 @@ class EditNotificationModalConnector extends Component {
|
||||||
|
|
||||||
EditNotificationModalConnector.propTypes = {
|
EditNotificationModalConnector.propTypes = {
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
clearPendingChanges: PropTypes.func.isRequired
|
dispatchClearPendingChanges: PropTypes.func.isRequired,
|
||||||
|
dispatchCancelTestNotification: PropTypes.func.isRequired,
|
||||||
|
dispatchCancelSaveNotification: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(EditNotificationModalConnector);
|
export default connect(null, createMapDispatchToProps)(EditNotificationModalConnector);
|
||||||
|
|
|
@ -7,10 +7,12 @@ const abortCurrentRequests = {};
|
||||||
|
|
||||||
export function createCancelSaveProviderHandler(section) {
|
export function createCancelSaveProviderHandler(section) {
|
||||||
return function(payload) {
|
return function(payload) {
|
||||||
if (abortCurrentRequests[section]) {
|
return function(dispatch, getState) {
|
||||||
abortCurrentRequests[section]();
|
if (abortCurrentRequests[section]) {
|
||||||
abortCurrentRequests[section] = null;
|
abortCurrentRequests[section]();
|
||||||
}
|
abortCurrentRequests[section] = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,12 @@ const abortCurrentRequests = {};
|
||||||
|
|
||||||
export function createCancelTestProviderHandler(section) {
|
export function createCancelTestProviderHandler(section) {
|
||||||
return function(payload) {
|
return function(payload) {
|
||||||
if (abortCurrentRequests[section]) {
|
return function(dispatch, getState) {
|
||||||
abortCurrentRequests[section]();
|
if (abortCurrentRequests[section]) {
|
||||||
abortCurrentRequests[section] = null;
|
abortCurrentRequests[section]();
|
||||||
}
|
abortCurrentRequests[section] = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue