Add tracker filter an abstract components along the way

This commit is contained in:
John Furrow
2016-02-07 18:06:40 -08:00
parent 591eeed698
commit dc423ac6e9
26 changed files with 450 additions and 93 deletions
@@ -9,7 +9,7 @@ const METHODS_TO_BIND = [
'handleClick'
];
export default class StatusFilter extends React.Component {
export default class SidebarFilter extends React.Component {
constructor() {
super();
@@ -23,18 +23,22 @@ export default class StatusFilter extends React.Component {
}
render() {
let itemClass = 'status-filter__item--' + this.props.slug;
let itemClass = 'sidebar-filter__item--' + this.props.slug;
let classNames = classnames({
'status-filter__item': true,
itemClass: true,
'sidebar-filter__item': true,
[itemClass]: true,
'is-active': this.props.isActive
});
let name = this.props.name;
if (this.props.name === 'all') {
name = 'All';
}
return (
<li className={classNames} onClick={this.handleClick}>
{this.props.icon}
{this.props.name}
{name}
<Badge>
{this.props.count}
</Badge>
@@ -8,7 +8,8 @@ import DownloadSmall from '../../components/icons/DownloadSmall';
import Error from '../../components/icons/Error';
import EventTypes from '../../constants/EventTypes';
import Inactive from '../../components/icons/Inactive';
import StatusFilter from './StatusFilter';
import propsMap from '../../../../../shared/constants/propsMap';
import SidebarFilter from './SidebarFilter';
import TorrentFilterStore from '../../stores/TorrentFilterStore';
import TorrentStore from '../../stores/TorrentStore';
import UIActions from '../../actions/UIActions';
@@ -17,7 +18,9 @@ const METHODS_TO_BIND = [
'getFilters',
'handleClick',
'onStatusFilterChange',
'onTorrentStatusCountChange'
'onTorrentStatusCountChange',
'onTrackerFilterChange',
'updateStatusCount'
];
export default class StatusFilters extends React.Component {
@@ -26,7 +29,8 @@ export default class StatusFilters extends React.Component {
this.state = {
statusCount: {},
statusFilter: TorrentFilterStore.getStatusFilter()
statusFilter: TorrentFilterStore.getStatusFilter(),
trackerFilter: TorrentFilterStore.getTrackerFilter()
};
METHODS_TO_BIND.forEach((method) => {
@@ -38,11 +42,13 @@ export default class StatusFilters extends React.Component {
TorrentStore.listen(EventTypes.CLIENT_TORRENTS_REQUEST_SUCCESS, this.onTorrentRequestSuccess);
TorrentFilterStore.listen(EventTypes.CLIENT_TORRENT_STATUS_COUNT_CHANGE, this.onTorrentStatusCountChange);
TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, this.onStatusFilterChange);
TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, this.onTrackerFilterChange);
}
componentWillUnmount() {
TorrentFilterStore.unlisten(EventTypes.CLIENT_TORRENT_STATUS_COUNT_CHANGE, this.onTorrentStatusCountChange);
TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, this.onStatusFilterChange);
TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, this.onTrackerFilterChange);
}
handleClick(filter) {
@@ -60,9 +66,11 @@ export default class StatusFilters extends React.Component {
}
onTorrentStatusCountChange() {
this.setState({
statusCount: TorrentFilterStore.getTorrentStatusCount()
});
this.updateStatusCount();
}
onTrackerFilterChange() {
this.updateStatusCount();
}
getFilters() {
@@ -101,7 +109,7 @@ export default class StatusFilters extends React.Component {
let filterElements = filters.map((filter) => {
return (
<StatusFilter handleClick={this.handleClick}
<SidebarFilter handleClick={this.handleClick}
count={this.state.statusCount[filter.slug] || 0}
key={filter.slug}
icon={filter.icon}
@@ -114,12 +122,41 @@ export default class StatusFilters extends React.Component {
return filterElements;
}
updateStatusCount() {
let statusCount = TorrentFilterStore.getTorrentStatusCount();
let trackerFilter = TorrentFilterStore.getTrackerFilter();
if (TorrentFilterStore.getTrackerFilter() !== 'all') {
let totalStatusCount = 0;
let torrents = TorrentStore.getAllTorrents();
Object.keys(statusCount).forEach(function(key) {
statusCount[key] = 0;
});
Object.keys(torrents).forEach(function(hash) {
let torrent = torrents[hash];
if (torrent.trackers.indexOf(trackerFilter) > -1) {
totalStatusCount++;
torrent.status.forEach(function (status) {
statusCount[propsMap.serverStatus[status]]++;
});
}
});
statusCount.all = totalStatusCount;
}
this.setState({statusCount});
}
render() {
let filters = this.getFilters();
return (
<ul className="status-filter sidebar__item">
<li className="status-filter__item status-filter__item--heading">
<ul className="sidebar-filter sidebar__item">
<li className="sidebar-filter__item sidebar-filter__item--heading">
Filter by Status
</li>
{filters}
@@ -0,0 +1,131 @@
import classnames from 'classnames';
import React from 'react';
import Active from '../../components/icons/Active';
import All from '../../components/icons/All';
import Completed from '../../components/icons/Completed';
import DownloadSmall from '../../components/icons/DownloadSmall';
import Error from '../../components/icons/Error';
import EventTypes from '../../constants/EventTypes';
import Inactive from '../../components/icons/Inactive';
import propsMap from '../../../../../shared/constants/propsMap';
import SidebarFilter from './SidebarFilter';
import TorrentFilterStore from '../../stores/TorrentFilterStore';
import TorrentStore from '../../stores/TorrentStore';
import UIActions from '../../actions/UIActions';
const METHODS_TO_BIND = [
'getFilters',
'handleClick',
'onStatusFilterChange',
'onTrackerFilterChange',
'onTorrentTrackerCountChange',
'updateTrackerCount'
];
export default class TrackerFilters extends React.Component {
constructor() {
super();
this.state = {
trackerCount: {},
trackerFilter: TorrentFilterStore.getTrackerFilter()
};
METHODS_TO_BIND.forEach((method) => {
this[method] = this[method].bind(this);
});
}
componentDidMount() {
TorrentStore.listen(EventTypes.CLIENT_TORRENTS_REQUEST_SUCCESS, this.onTorrentRequestSuccess);
TorrentFilterStore.listen(EventTypes.CLIENT_TORRENT_TRACKER_COUNT_CHANGE, this.onTorrentTrackerCountChange);
TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, this.onTrackerFilterChange);
TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, this.onStatusFilterChange);
}
componentWillUnmount() {
TorrentFilterStore.unlisten(EventTypes.CLIENT_TORRENT_TRACKER_COUNT_CHANGE, this.onTorrentTrackerCountChange);
TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, this.onTrackerFilterChange);
TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, this.onStatusFilterChange);
}
handleClick(filter) {
UIActions.setTorrentTrackerFilter(filter);
}
onStatusFilterChange() {
this.updateTrackerCount();
}
onTrackerFilterChange() {
this.setState({trackerFilter: TorrentFilterStore.getTrackerFilter()});
}
onTorrentRequestSuccess() {
TorrentFilterStore.fetchTorrentTrackerCount();
}
onTorrentTrackerCountChange() {
this.updateTrackerCount();
}
getFilters() {
let filterItems = Object.keys(this.state.trackerCount);
let filterElements = filterItems.map((filter, index) => {
return (
<SidebarFilter handleClick={this.handleClick}
count={this.state.trackerCount[filter] || 0}
key={filter}
isActive={filter === this.state.trackerFilter}
name={filter}
slug={filter} />
);
});
return filterElements;
}
updateTrackerCount() {
let trackerCount = TorrentFilterStore.getTorrentTrackerCount();
let statusFilter = TorrentFilterStore.getStatusFilter();
if (statusFilter !== 'all') {
let torrentCount = 0;
let torrents = TorrentStore.getAllTorrents();
Object.keys(trackerCount).forEach(function(key) {
trackerCount[key] = 0;
});
Object.keys(torrents).forEach(function(hash) {
let torrent = torrents[hash];
if (torrent.status.indexOf(propsMap.clientStatus[statusFilter]) > -1) {
torrentCount++;
torrent.trackers.forEach(function (tracker) {
trackerCount[tracker]++;
});
}
});
trackerCount.all = torrentCount;
}
this.setState({trackerCount});
}
render() {
let filters = this.getFilters();
return (
<ul className="sidebar-filter sidebar__item">
<li className="sidebar-filter__item sidebar-filter__item--heading">
Filter by Tracker
</li>
{filters}
</ul>
);
}
}