mirror of
https://github.com/zoriya/flood.git
synced 2026-06-03 03:12:14 +00:00
feature: display total size by tag or tracker of torrents on sidebar (#369)
Bug: #244
This commit is contained in:
@@ -3,6 +3,7 @@ import {FC, ReactNode} from 'react';
|
||||
import {useLingui} from '@lingui/react';
|
||||
|
||||
import Badge from '../general/Badge';
|
||||
import Size from '../general/Size';
|
||||
|
||||
interface SidebarFilterProps {
|
||||
name: string;
|
||||
@@ -10,18 +11,26 @@ interface SidebarFilterProps {
|
||||
isActive: boolean;
|
||||
slug: string;
|
||||
count: number;
|
||||
size?: number;
|
||||
handleClick: (slug: string) => void;
|
||||
}
|
||||
|
||||
const SidebarFilter: FC<SidebarFilterProps> = (props: SidebarFilterProps) => {
|
||||
const {isActive, count, slug, icon, handleClick} = props;
|
||||
const SidebarFilter: FC<SidebarFilterProps> = ({
|
||||
name: _name,
|
||||
icon,
|
||||
isActive,
|
||||
slug,
|
||||
count,
|
||||
size,
|
||||
handleClick,
|
||||
}: SidebarFilterProps) => {
|
||||
const {i18n} = useLingui();
|
||||
|
||||
const classNames = classnames('sidebar-filter__item', {
|
||||
'is-active': isActive,
|
||||
});
|
||||
let {name} = props;
|
||||
|
||||
let name = _name;
|
||||
if (name === '') {
|
||||
name = i18n._('filter.all');
|
||||
} else if (name === 'untagged') {
|
||||
@@ -51,8 +60,9 @@ const SidebarFilter: FC<SidebarFilterProps> = (props: SidebarFilterProps) => {
|
||||
onClick={() => handleClick(slug)}
|
||||
role="menuitem">
|
||||
{icon}
|
||||
{name}
|
||||
<span className="name">{name}</span>
|
||||
<Badge>{count}</Badge>
|
||||
{size && <Size value={size} className="size" />}
|
||||
</button>
|
||||
</li>
|
||||
);
|
||||
@@ -60,6 +70,7 @@ const SidebarFilter: FC<SidebarFilterProps> = (props: SidebarFilterProps) => {
|
||||
|
||||
SidebarFilter.defaultProps = {
|
||||
icon: undefined,
|
||||
size: undefined,
|
||||
};
|
||||
|
||||
export default SidebarFilter;
|
||||
|
||||
@@ -35,6 +35,7 @@ const TagFilters: FC = observer(() => {
|
||||
isActive={filter === TorrentFilterStore.filters.tagFilter}
|
||||
name={filter}
|
||||
slug={filter}
|
||||
size={TorrentFilterStore.taxonomy.tagSizes[filter]}
|
||||
/>
|
||||
));
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ const TrackerFilters: FC = observer(() => {
|
||||
isActive={filter === TorrentFilterStore.filters.trackerFilter}
|
||||
name={filter}
|
||||
slug={filter}
|
||||
size={TorrentFilterStore.taxonomy.trackerSizes[filter]}
|
||||
/>
|
||||
));
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ class TorrentFilterStore {
|
||||
taxonomy: Taxonomy = {
|
||||
statusCounts: {},
|
||||
tagCounts: {},
|
||||
tagSizes: {},
|
||||
trackerCounts: {},
|
||||
trackerSizes: {},
|
||||
};
|
||||
|
||||
@computed get isFilterActive() {
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
padding: 3px 20px;
|
||||
text-align: start;
|
||||
transition: color 0.25s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
&:focus-visible,
|
||||
&:hover {
|
||||
@@ -53,6 +56,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
@include themes.theme('fill', 'sidebar-filter--foreground');
|
||||
@@ -62,6 +72,10 @@
|
||||
vertical-align: middle;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.size {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.badge {
|
||||
|
||||
@@ -15,7 +15,9 @@ class TaxonomyService extends BaseService<TaxonomyServiceEvents> {
|
||||
taxonomy: Taxonomy = {
|
||||
statusCounts: {'': 0},
|
||||
tagCounts: {'': 0, untagged: 0},
|
||||
tagSizes: {},
|
||||
trackerCounts: {'': 0},
|
||||
trackerSizes: {},
|
||||
};
|
||||
|
||||
lastTaxonomy: Taxonomy = this.taxonomy;
|
||||
@@ -61,7 +63,9 @@ class TaxonomyService extends BaseService<TaxonomyServiceEvents> {
|
||||
this.lastTaxonomy = {
|
||||
statusCounts: {...this.taxonomy.statusCounts},
|
||||
tagCounts: {...this.taxonomy.tagCounts},
|
||||
tagSizes: {...this.taxonomy.tagSizes},
|
||||
trackerCounts: {...this.taxonomy.trackerCounts},
|
||||
trackerSizes: {...this.taxonomy.trackerSizes},
|
||||
};
|
||||
|
||||
torrentStatusMap.forEach((status) => {
|
||||
@@ -70,7 +74,9 @@ class TaxonomyService extends BaseService<TaxonomyServiceEvents> {
|
||||
|
||||
this.taxonomy.statusCounts[''] = 0;
|
||||
this.taxonomy.tagCounts = {'': 0, untagged: 0};
|
||||
this.taxonomy.tagSizes = {};
|
||||
this.taxonomy.trackerCounts = {'': 0};
|
||||
this.taxonomy.trackerSizes = {};
|
||||
};
|
||||
|
||||
handleProcessTorrentListEnd = ({torrents}: {torrents: TorrentList}) => {
|
||||
@@ -93,7 +99,9 @@ class TaxonomyService extends BaseService<TaxonomyServiceEvents> {
|
||||
handleProcessTorrent = (torrentProperties: TorrentProperties) => {
|
||||
this.incrementStatusCounts(torrentProperties.status);
|
||||
this.incrementTagCounts(torrentProperties.tags);
|
||||
this.incrementTagSizes(torrentProperties.tags, torrentProperties.sizeBytes);
|
||||
this.incrementTrackerCounts(torrentProperties.trackerURIs);
|
||||
this.incrementTrackerSizes(torrentProperties.trackerURIs, torrentProperties.sizeBytes);
|
||||
};
|
||||
|
||||
incrementStatusCounts(statuses: Array<TorrentStatus>) {
|
||||
@@ -116,6 +124,16 @@ class TaxonomyService extends BaseService<TaxonomyServiceEvents> {
|
||||
});
|
||||
}
|
||||
|
||||
incrementTagSizes(tags: TorrentProperties['tags'], sizeBytes: TorrentProperties['sizeBytes']) {
|
||||
tags.forEach((tag) => {
|
||||
if (this.taxonomy.tagSizes[tag] != null) {
|
||||
this.taxonomy.tagSizes[tag] += sizeBytes;
|
||||
} else {
|
||||
this.taxonomy.tagSizes[tag] = sizeBytes;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
incrementTrackerCounts(trackers: TorrentProperties['trackerURIs']) {
|
||||
trackers.forEach((tracker) => {
|
||||
if (this.taxonomy.trackerCounts[tracker] != null) {
|
||||
@@ -125,6 +143,16 @@ class TaxonomyService extends BaseService<TaxonomyServiceEvents> {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
incrementTrackerSizes(trackers: TorrentProperties['trackerURIs'], sizeBytes: TorrentProperties['sizeBytes']) {
|
||||
trackers.forEach((tracker) => {
|
||||
if (this.taxonomy.trackerSizes[tracker] != null) {
|
||||
this.taxonomy.trackerSizes[tracker] += sizeBytes;
|
||||
} else {
|
||||
this.taxonomy.trackerSizes[tracker] = sizeBytes;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default TaxonomyService;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export interface Taxonomy {
|
||||
statusCounts: Record<string, number>;
|
||||
tagCounts: Record<string, number>;
|
||||
tagSizes: Record<string, number>;
|
||||
trackerCounts: Record<string, number>;
|
||||
trackerSizes: Record<string, number>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user