Implement select all/none

master
Drew DeVault 2017-08-25 19:59:53 -04:00
parent f1e798a498
commit cc414c9b57
4 changed files with 28 additions and 19 deletions

View File

@ -5,12 +5,11 @@ import { push } from 'react-router-redux';
export const UNION = 'UNION'; export const UNION = 'UNION';
export const SUBTRACT = 'SUBTRACT'; export const SUBTRACT = 'SUBTRACT';
export const EXCLUSIVE = 'EXCLUSIVE'; export const EXCLUSIVE = 'EXCLUSIVE';
export const NONE = 'NONE';
export default function selectTorrent(id, action) { export default function selectTorrent(ids, action) {
return (dispatch, getState) => { return (dispatch, getState) => {
const previous = new Set(getState().selection); const previous = new Set(getState().selection);
dispatch({ type: action, id }); dispatch({ type: action, ids });
const state = getState(); const state = getState();
const next = new Set(state.selection); const next = new Set(state.selection);
@ -23,7 +22,7 @@ export default function selectTorrent(id, action) {
added.forEach(t => { added.forEach(t => {
const criteria = [ const criteria = [
{ field: "torrent_id", op: "==", value: id } { field: "torrent_id", op: "==", value: t }
]; ];
dispatch(filter_subscribe("peer", criteria)); dispatch(filter_subscribe("peer", criteria));
dispatch(filter_subscribe("file", criteria)); dispatch(filter_subscribe("file", criteria));
@ -38,7 +37,7 @@ export default function selectTorrent(id, action) {
.map(sub => sub.serial); .map(sub => sub.serial);
serials.forEach(serial => dispatch(filter_unsubscribe(serial))); serials.forEach(serial => dispatch(filter_unsubscribe(serial)));
/* Remove resource subscriptions */ /* Remove resource subscriptions */
const ids = [ const _ids = [
...Object.values(files) ...Object.values(files)
.filter(file => file.torrent_id === t) .filter(file => file.torrent_id === t)
.map(file => file.id) .map(file => file.id)
@ -52,8 +51,8 @@ export default function selectTorrent(id, action) {
// .filter(piece => piece.torrent_id === t) // .filter(piece => piece.torrent_id === t)
// .map(piece => piece.id), // .map(piece => piece.id),
]; ];
if (ids.length > 0) { if (_ids.length > 0) {
dispatch(unsubscribe(...ids)); dispatch(unsubscribe(..._ids));
} }
}); });

View File

@ -1,16 +1,14 @@
import { UNION, SUBTRACT, EXCLUSIVE, NONE } from '../actions/selection'; import { UNION, SUBTRACT, EXCLUSIVE, NONE } from '../actions/selection';
export default function selection(state = [], action) { export default function selection(state = [], action) {
const { id } = action; const { ids } = action;
switch (action.type) { switch (action.type) {
case UNION: case UNION:
return [id, ...state.filter(t => t !== id)]; return [...ids, ...state.filter(id => ids.indexOf(id) === -1)];
case SUBTRACT: case SUBTRACT:
return state.filter(t => t !== id); return state.filter(id => ids.indexOf(id) === -1);
case EXCLUSIVE: case EXCLUSIVE:
return [id]; return [...ids];
case NONE:
return [];
} }
return state; return state;
} }

View File

@ -13,7 +13,7 @@ import {
Progress Progress
} from 'reactstrap'; } from 'reactstrap';
import ws_send from '../socket'; import ws_send from '../socket';
import selectTorrent, { UNION, NONE } from '../actions/selection'; import selectTorrent, { EXCLUSIVE, UNION, NONE } from '../actions/selection';
function File({ file }) { function File({ file }) {
// TODO: show progress bar // TODO: show progress bar
@ -153,12 +153,12 @@ class TorrentDetails extends Component {
const { dispatch } = this.props; const { dispatch } = this.props;
const { ids } = this.props.match.params; const { ids } = this.props.match.params;
const _ids = ids.split(","); const _ids = ids.split(",");
_ids.forEach(id => dispatch(selectTorrent(id, UNION))); dispatch(selectTorrent(_ids, UNION));
} }
componentWillUnmount() { componentWillUnmount() {
const { dispatch } = this.props; const { dispatch } = this.props;
dispatch(selectTorrent(null, NONE)); dispatch(selectTorrent([], EXCLUSIVE));
} }
renderHeader(selection) { renderHeader(selection) {

View File

@ -10,7 +10,19 @@ class TorrentTable extends Component {
<table className="table"> <table className="table">
<thead> <thead>
<tr> <tr>
<th style={{width: "1px"}}></th> <th style={{width: "1px"}}>
<input
type="checkbox"
checked={selection.length === Object.values(torrents).length}
onChange={e => {
if (selection.length > 0) {
dispatch(selectTorrent([], EXCLUSIVE));
} else {
dispatch(selectTorrent(Object.keys(torrents), EXCLUSIVE));
}
}}
/>
</th>
<th>name</th> <th>name</th>
<th>up</th> <th>up</th>
<th>down</th> <th>down</th>
@ -35,7 +47,7 @@ class TorrentTable extends Component {
type="checkbox" type="checkbox"
checked={selection.indexOf(t.id) !== -1} checked={selection.indexOf(t.id) !== -1}
onChange={e => onChange={e =>
dispatch(selectTorrent(t.id, e.target.checked ? UNION : SUBTRACT)) dispatch(selectTorrent([t.id], e.target.checked ? UNION : SUBTRACT))
} }
/> />
</td> </td>
@ -44,7 +56,7 @@ class TorrentTable extends Component {
href={`/torrents/${t.id}`} href={`/torrents/${t.id}`}
onClick={e => { onClick={e => {
e.preventDefault(); e.preventDefault();
dispatch(selectTorrent(t.id, EXCLUSIVE)); dispatch(selectTorrent([t.id], EXCLUSIVE));
}} }}
>{t.name}</a> >{t.name}</a>
</td> </td>