Compare commits

...

6 Commits

Author SHA1 Message Date
Hendrik Luup d5bcf77c8b
Merge 2ec40cea02 into 821a6816ef 2024-04-26 00:22:33 +08:00
Pooyan Khanjankhani 821a6816ef
doc: fix typo (#6790) 2024-04-21 18:21:17 -05:00
Dzmitry Neviadomski ef18816b7f
Fix code style script path in CONTRIBUTING.md (#6787)
Signed-off-by: Dzmitry Neviadomski <nevack.d@gmail.com>
2024-04-21 07:36:13 -05:00
Dzmitry Neviadomski 0e25584e78
Make std::hash specialization for tr_socket_address a struct (#6788)
To be in line with std::hash declaration

See https://en.cppreference.com/w/cpp/utility/hash

Signed-off-by: Dzmitry Neviadomski <nevack.d@gmail.com>
2024-04-20 21:01:47 -05:00
Hendrik Luup 2ec40cea02 feat(web): add context menu items for sequential downloading 2024-03-10 14:51:38 +02:00
Hendrik Luup d19b534c1d feat(web): show sequential download status in inspector 2024-03-10 14:51:38 +02:00
9 changed files with 56 additions and 3 deletions

View File

@ -41,7 +41,7 @@ On macOS, Transmission is usually built with Xcode. Everywhere else, it's CMake
- Prefer `enum class` over `enum` - Prefer `enum class` over `enum`
- Prefer new-style headers, e.g. `<cstring>` over `<string.h>` - Prefer new-style headers, e.g. `<cstring>` over `<string.h>`
- Fix any warnings in new code before merging - Fix any warnings in new code before merging
- Run `./code-style.sh` on your code to ensure the whole codebase has consistent indentation. - Run `./code_style.sh` on your code to ensure the whole codebase has consistent indentation.
Note that Transmission existed in C for over a decade and those idioms don't change overnight. "Follow the C++ core guidelines" can be difficult when working with older code, and the maintainers will understand that when reviewing your PRs. :smiley: Note that Transmission existed in C for over a decade and those idioms don't change overnight. "Follow the C++ core guidelines" can be difficult when working with older code, and the maintainers will understand that when reviewing your PRs. :smiley:

View File

@ -404,7 +404,7 @@ struct tr_socket_address
}; };
template<> template<>
class std::hash<tr_socket_address> struct std::hash<tr_socket_address>
{ {
public: public:
std::size_t operator()(tr_socket_address const& socket_address) const noexcept std::size_t operator()(tr_socket_address const& socket_address) const noexcept

View File

@ -150,7 +150,7 @@ Get a file list for the current torrent(s)
.It Fl g Fl -get Ar all | file-index | files .It Fl g Fl -get Ar all | file-index | files
Mark file(s) for download. Mark file(s) for download.
.Ar all .Ar all
marks all all of the torrent's files for downloading, marks all of the torrent's files for downloading,
.Ar file-index .Ar file-index
adds a single file to the download list, and adds a single file to the download list, and
.Ar files .Ar files

View File

@ -12,6 +12,14 @@ export class ActionManager extends EventTarget {
shortcut: 'D', shortcut: 'D',
text: 'Deselect all', text: 'Deselect all',
}, },
'disable-sequential-downloading': {
enabled: true,
text: 'Disable sequential downloading',
},
'enable-sequential-downloading': {
enabled: true,
text: 'Enable sequential downloading',
},
'move-bottom': { enabled: false, text: 'Move to the back of the queue' }, 'move-bottom': { enabled: false, text: 'Move to the back of the queue' },
'move-down': { enabled: false, text: 'Move down in the queue' }, 'move-down': { enabled: false, text: 'Move down in the queue' },
'move-top': { enabled: false, text: 'Move to the front of the queue' }, 'move-top': { enabled: false, text: 'Move to the front of the queue' },

View File

@ -94,6 +94,9 @@ export class ContextMenu extends EventTarget {
add_item('remove-selected-torrents', true); add_item('remove-selected-torrents', true);
add_item('trash-selected-torrents', true); add_item('trash-selected-torrents', true);
add_separator(); add_separator();
add_item('enable-sequential-downloading');
add_item('disable-sequential-downloading');
add_separator();
add_item('verify-selected-torrents'); add_item('verify-selected-torrents');
add_item('show-move-dialog'); add_item('show-move-dialog');
add_item('show-rename-dialog'); add_item('show-rename-dialog');

View File

@ -91,6 +91,7 @@ export class Inspector extends EventTarget {
['availability', 'Availability:'], ['availability', 'Availability:'],
['uploaded', 'Uploaded:'], ['uploaded', 'Uploaded:'],
['downloaded', 'Downloaded:'], ['downloaded', 'Downloaded:'],
['sequential_download', 'Sequential download:'],
['state', 'State:'], ['state', 'State:'],
['running_time', 'Running time:'], ['running_time', 'Running time:'],
['remaining_time', 'Remaining:'], ['remaining_time', 'Remaining:'],
@ -563,6 +564,14 @@ export class Inspector extends EventTarget {
const link = torrents[0].getMagnetLink(); const link = torrents[0].getMagnetLink();
e.info.magnetLink.innerHTML = `<a class="inspector-info-magnet" href="${link}"><button></button></a>`; e.info.magnetLink.innerHTML = `<a class="inspector-info-magnet" href="${link}"><button></button></a>`;
} }
// Sequential Download
const isSequential = torrents.reduce((acc, cur) => {
cur = cur.isSequentialDownload() ? 'Yes' : 'No';
return acc !== none && acc !== cur ? mixed : cur;
}, none);
setTextContent(e.info.sequential_download, isSequential);
} }
/// PEERS PAGE /// PEERS PAGE

View File

@ -281,6 +281,21 @@ export class Remote {
}); });
} }
_setSequentialDownload(torrentIds, state, callback) {
const args = {
ids: torrentIds,
sequentialDownload: state,
};
this.sendRequest({ arguments: args, method: 'torrent-set' }, callback);
}
disableSequentialDownload(torrentIds, callback) {
this._setSequentialDownload(torrentIds, false, callback);
}
enableSequentialDownload(torrentIds, callback) {
this._setSequentialDownload(torrentIds, true, callback);
}
// Added queue calls // Added queue calls
moveTorrentsToTop(torrent_ids, callback, context) { moveTorrentsToTop(torrent_ids, callback, context) {
this.sendTorrentActionRequests( this.sendTorrentActionRequests(

View File

@ -255,6 +255,9 @@ export class Torrent extends EventTarget {
isSeeding() { isSeeding() {
return this.getStatus() === Torrent._StatusSeed; return this.getStatus() === Torrent._StatusSeed;
} }
isSequentialDownload() {
return this.fields.sequentialDownload;
}
isStopped() { isStopped() {
return this.getStatus() === Torrent._StatusStopped; return this.getStatus() === Torrent._StatusStopped;
} }
@ -607,6 +610,7 @@ Torrent.Fields.Stats = [
'rateUpload', 'rateUpload',
'recheckProgress', 'recheckProgress',
'seedRatioMode', 'seedRatioMode',
'sequentialDownload',
'seedRatioLimit', 'seedRatioLimit',
'sizeWhenDone', 'sizeWhenDone',
'status', 'status',

View File

@ -170,6 +170,12 @@ export class Transmission extends EventTarget {
? Prefs.DisplayFull ? Prefs.DisplayFull
: Prefs.DisplayCompact; : Prefs.DisplayCompact;
break; break;
case 'enable-sequential-downloading':
this._enableSequentialDownload(this.getSelectedTorrents());
break;
case 'disable-sequential-downloading':
this._disableSequentialDownload(this.getSelectedTorrents());
break;
case 'trash-selected-torrents': case 'trash-selected-torrents':
this._removeSelectedTorrents(true); this._removeSelectedTorrents(true);
break; break;
@ -853,6 +859,14 @@ TODO: fix this when notifications get fixed
this, this,
); );
} }
_enableSequentialDownload(torrents) {
this.remote.enableSequentialDownload(Transmission._getTorrentIds(torrents));
}
_disableSequentialDownload(torrents) {
this.remote.disableSequentialDownload(
Transmission._getTorrentIds(torrents),
);
}
_verifyTorrents(torrents) { _verifyTorrents(torrents) {
this.remote.verifyTorrents( this.remote.verifyTorrents(
Transmission._getTorrentIds(torrents), Transmission._getTorrentIds(torrents),