diff --git a/public/locales/en/modules/torrents-status.json b/public/locales/en/modules/torrents-status.json index 3f83a6396..f83493b9d 100644 --- a/public/locales/en/modules/torrents-status.json +++ b/public/locales/en/modules/torrents-status.json @@ -10,6 +10,12 @@ "displayCompletedTorrents": { "label": "Display completed torrents" }, + "displayActiveTorrents": { + "label": "Display active torrents" + }, + "speedLimitOfActiveTorrents": { + "label": "Upload speed to consider a torrent as active (kB/s)" + }, "displayStaleTorrents": { "label": "Display stale torrents" }, diff --git a/src/widgets/torrent/TorrentTile.spec.ts b/src/widgets/torrent/TorrentTile.spec.ts index f3a4148fd..71fb178ff 100644 --- a/src/widgets/torrent/TorrentTile.spec.ts +++ b/src/widgets/torrent/TorrentTile.spec.ts @@ -20,13 +20,15 @@ describe('TorrentTile', () => { labelFilter: [], labelFilterIsWhitelist: false, displayCompletedTorrents: true, + displayActiveTorrents: true, + speedLimitOfActiveTorrents: 10, displayStaleTorrents: false, }, }; const torrents: NormalizedTorrent[] = [ - constructTorrent('ABC', 'Nice Torrent', false, 672), - constructTorrent('HH', 'I am completed', true, 0), - constructTorrent('HH', 'I am stale', false, 0), + constructTorrent('ABC', 'Nice Torrent', false, 672, 672), + constructTorrent('HH', 'I am completed', true, 0, 0), + constructTorrent('HH', 'I am stale', false, 0, 0), ]; // act @@ -55,13 +57,15 @@ describe('TorrentTile', () => { labelFilter: [], labelFilterIsWhitelist: false, displayCompletedTorrents: true, + displayActiveTorrents: true, + speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, }, }; const torrents: NormalizedTorrent[] = [ - constructTorrent('ABC', 'Nice Torrent', false, 672), - constructTorrent('HH', 'I am completed', true, 0), - constructTorrent('HH', 'I am stale', false, 0), + constructTorrent('ABC', 'Nice Torrent', false, 672, 672), + constructTorrent('HH', 'I am completed', true, 0, 0), + constructTorrent('HH', 'I am stale', false, 0, 0), ]; // act @@ -74,7 +78,7 @@ describe('TorrentTile', () => { expect(filtered.includes(torrents[2])).toBe(true); }); - it('filter when completed', () => { + it('filter when completed without active torrent', () => { // arrange const widget: ITorrent = { id: 'abc', @@ -90,13 +94,15 @@ describe('TorrentTile', () => { labelFilter: [], labelFilterIsWhitelist: false, displayCompletedTorrents: false, + displayActiveTorrents: false, + speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, }, }; const torrents: NormalizedTorrent[] = [ - constructTorrent('ABC', 'Nice Torrent', false, 672), - constructTorrent('HH', 'I am completed', true, 0), - constructTorrent('HH', 'I am stale', false, 0), + constructTorrent('ABC', 'Nice Torrent', false, 672, 672), + constructTorrent('HH', 'I am completed', true, 0, 672), + constructTorrent('HH', 'I am stale', false, 0, 0), ]; // act @@ -109,6 +115,47 @@ describe('TorrentTile', () => { expect(filtered.at(1)).toBe(torrents[2]); }); + it('filter when completed with active torrent', () => { + // arrange + const widget: ITorrent = { + id: 'abc', + area: { + type: 'sidebar', + properties: { + location: 'left', + }, + }, + shape: {}, + type: 'torrents-status', + properties: { + labelFilter: [], + labelFilterIsWhitelist: false, + displayCompletedTorrents: false, + displayActiveTorrents: true, + speedLimitOfActiveTorrents: 10, + displayStaleTorrents: true, + }, + }; + const torrents: NormalizedTorrent[] = [ + constructTorrent('ABC', 'Nice Torrent', false, 672, 672), + constructTorrent('HH', 'I am completed and uploading less than 10 ko/s (10239 ≈ 9.99ko/s)', true, 0, 10239), + constructTorrent('HH', 'I am completed and uploading more than 10 ko/s (10241 ≈ 10.01ko/s)', true, 0, 10241), + constructTorrent('HH', 'I am completed', true, 0, 0), + constructTorrent('HH', 'I am stale', false, 0, 0), + ]; + + // act + const filtered = filterTorrents(widget, torrents); + + // assert + expect(filtered.length).toBe(3); + expect(filtered.at(0)).toBe(torrents[0]); + expect(filtered.includes(torrents[1])).toBe(false); + expect(filtered.at(1)).toBe(torrents[2]); + expect(filtered.includes(torrents[3])).toBe(false); + expect(filtered.at(2)).toBe(torrents[4]); + }); + it('filter by label when whitelist', () => { // arrange const widget: ITorrent = { @@ -125,13 +172,15 @@ describe('TorrentTile', () => { labelFilter: ['music', 'movie'], labelFilterIsWhitelist: true, displayCompletedTorrents: true, + displayActiveTorrents: true, + speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, }, }; const torrents: NormalizedTorrent[] = [ - constructTorrent('1', 'A sick drop', false, 672, 'music'), - constructTorrent('2', 'I cried', true, 0, 'movie'), - constructTorrent('3', 'Great Animations', false, 0, 'anime'), + constructTorrent('1', 'A sick drop', false, 672, 672, 'music'), + constructTorrent('2', 'I cried', true, 0, 0, 'movie'), + constructTorrent('3', 'Great Animations', false, 0, 0, 'anime'), ]; // act @@ -160,13 +209,15 @@ describe('TorrentTile', () => { labelFilter: ['music', 'movie'], labelFilterIsWhitelist: false, displayCompletedTorrents: false, + displayActiveTorrents: false, + speedLimitOfActiveTorrents: 10, displayStaleTorrents: true, }, }; const torrents: NormalizedTorrent[] = [ - constructTorrent('ABC', 'Nice Torrent', false, 672, 'anime'), - constructTorrent('HH', 'I am completed', true, 0, 'movie'), - constructTorrent('HH', 'I am stale', false, 0, 'tv'), + constructTorrent('ABC', 'Nice Torrent', false, 672, 672, 'anime'), + constructTorrent('HH', 'I am completed', true, 0, 0, 'movie'), + constructTorrent('HH', 'I am stale', false, 0, 0, 'tv'), ]; // act @@ -184,7 +235,8 @@ const constructTorrent = ( id: string, name: string, isCompleted: boolean, - downloadSpeed: number, + downloadSpeed: number, // Bytes per second in @ctrl/shared-torrent + uploadSpeed: number, // Bytes per second in @ctrl/shared-torrent label?: string ): NormalizedTorrent => ({ id, @@ -208,6 +260,6 @@ const constructTorrent = ( totalSize: 839539535, totalSelected: 0, totalUploaded: 378535535, - uploadSpeed: 8349, + uploadSpeed, label, }); diff --git a/src/widgets/torrent/TorrentTile.tsx b/src/widgets/torrent/TorrentTile.tsx index 79c52b28d..5d02d8bb6 100644 --- a/src/widgets/torrent/TorrentTile.tsx +++ b/src/widgets/torrent/TorrentTile.tsx @@ -40,6 +40,14 @@ const definition = defineWidget({ type: 'switch', defaultValue: true, }, + displayActiveTorrents: { + type: 'switch', + defaultValue: true, + }, + speedLimitOfActiveTorrents: { // Unit : kB/s + type: 'number', + defaultValue: 10, + }, displayStaleTorrents: { type: 'switch', defaultValue: true, @@ -194,7 +202,7 @@ function TorrentTile({ widget }: TorrentTileProps) { export const filterTorrents = (widget: ITorrent, torrents: NormalizedTorrent[]) => { let result = torrents; if (!widget.properties.displayCompletedTorrents) { - result = result.filter((torrent) => !torrent.isCompleted); + result = result.filter((torrent) => !torrent.isCompleted || (widget.properties.displayActiveTorrents && torrent.uploadSpeed > widget.properties.speedLimitOfActiveTorrents * 1024)); } if (widget.properties.labelFilter.length > 0) {