mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: Download Clients for Manual Grabs
This commit is contained in:
@@ -3,6 +3,7 @@ import React, { Component } from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import Link from 'Components/Link/Link';
|
||||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
@@ -15,8 +16,59 @@ import Peers from './Peers';
|
||||
import ProtocolLabel from './ProtocolLabel';
|
||||
import styles from './SearchIndexRow.css';
|
||||
|
||||
function getDownloadIcon(isGrabbing, isGrabbed, grabError) {
|
||||
if (isGrabbing) {
|
||||
return icons.SPINNER;
|
||||
} else if (isGrabbed) {
|
||||
return icons.DOWNLOADING;
|
||||
} else if (grabError) {
|
||||
return icons.DOWNLOADING;
|
||||
}
|
||||
|
||||
return icons.DOWNLOAD;
|
||||
}
|
||||
|
||||
function getDownloadTooltip(isGrabbing, isGrabbed, grabError) {
|
||||
if (isGrabbing) {
|
||||
return '';
|
||||
} else if (isGrabbed) {
|
||||
return translate('AddedToDownloadClient');
|
||||
} else if (grabError) {
|
||||
return grabError;
|
||||
}
|
||||
|
||||
return translate('AddToDownloadClient');
|
||||
}
|
||||
|
||||
class SearchIndexRow extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
isConfirmGrabModalOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onGrabPress = () => {
|
||||
const {
|
||||
guid,
|
||||
indexerId,
|
||||
onGrabPress
|
||||
} = this.props;
|
||||
|
||||
onGrabPress({
|
||||
guid,
|
||||
indexerId
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
@@ -39,6 +91,9 @@ class SearchIndexRow extends Component {
|
||||
leechers,
|
||||
indexerFlags,
|
||||
columns,
|
||||
isGrabbing,
|
||||
isGrabbed,
|
||||
grabError,
|
||||
longDateFormat,
|
||||
timeFormat
|
||||
} = this.props;
|
||||
@@ -214,11 +269,13 @@ class SearchIndexRow extends Component {
|
||||
key={column.name}
|
||||
className={styles[column.name]}
|
||||
>
|
||||
<IconButton
|
||||
className={styles.downloadLink}
|
||||
name={icons.DOWNLOAD}
|
||||
title={'Grab'}
|
||||
to={downloadUrl}
|
||||
<SpinnerIconButton
|
||||
name={getDownloadIcon(isGrabbing, isGrabbed, grabError)}
|
||||
kind={grabError ? kinds.DANGER : kinds.DEFAULT}
|
||||
title={getDownloadTooltip(isGrabbing, isGrabbed, grabError)}
|
||||
isDisabled={isGrabbed}
|
||||
isSpinning={isGrabbing}
|
||||
onPress={this.onGrabPress}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
@@ -259,8 +316,17 @@ SearchIndexRow.propTypes = {
|
||||
leechers: PropTypes.number,
|
||||
indexerFlags: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onGrabPress: PropTypes.func.isRequired,
|
||||
isGrabbing: PropTypes.bool.isRequired,
|
||||
isGrabbed: PropTypes.bool.isRequired,
|
||||
grabError: PropTypes.string,
|
||||
longDateFormat: PropTypes.string.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
SearchIndexRow.defaultProps = {
|
||||
isGrabbing: false,
|
||||
isGrabbed: false
|
||||
};
|
||||
|
||||
export default SearchIndexRow;
|
||||
|
@@ -48,7 +48,8 @@ class SearchIndexTable extends Component {
|
||||
items,
|
||||
columns,
|
||||
longDateFormat,
|
||||
timeFormat
|
||||
timeFormat,
|
||||
onGrabPress
|
||||
} = this.props;
|
||||
|
||||
const release = items[rowIndex];
|
||||
@@ -65,6 +66,7 @@ class SearchIndexTable extends Component {
|
||||
guid={release.guid}
|
||||
longDateFormat={longDateFormat}
|
||||
timeFormat={timeFormat}
|
||||
onGrabPress={onGrabPress}
|
||||
/>
|
||||
</VirtualTableRow>
|
||||
);
|
||||
@@ -118,7 +120,8 @@ SearchIndexTable.propTypes = {
|
||||
scroller: PropTypes.instanceOf(Element).isRequired,
|
||||
longDateFormat: PropTypes.string.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired,
|
||||
onSortPress: PropTypes.func.isRequired
|
||||
onSortPress: PropTypes.func.isRequired,
|
||||
onGrabPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default SearchIndexTable;
|
||||
|
@@ -1,20 +1,20 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { setReleasesSort } from 'Store/Actions/releaseActions';
|
||||
import { grabRelease, setReleasesSort } from 'Store/Actions/releaseActions';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import SearchIndexTable from './SearchIndexTable';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.app.dimensions,
|
||||
(state) => state.releases.columns,
|
||||
(state) => state.releases,
|
||||
createUISettingsSelector(),
|
||||
(dimensions, columns, uiSettings) => {
|
||||
(dimensions, releases, uiSettings) => {
|
||||
return {
|
||||
isSmallScreen: dimensions.isSmallScreen,
|
||||
columns,
|
||||
longDateFormat: uiSettings.longDateFormat,
|
||||
timeFormat: uiSettings.timeFormat
|
||||
timeFormat: uiSettings.timeFormat,
|
||||
...releases
|
||||
};
|
||||
}
|
||||
);
|
||||
@@ -24,6 +24,9 @@ function createMapDispatchToProps(dispatch, props) {
|
||||
return {
|
||||
onSortPress(sortKey) {
|
||||
dispatch(setReleasesSort({ sortKey }));
|
||||
},
|
||||
onGrabPress(payload) {
|
||||
dispatch(grabRelease(payload));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user