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 new-style headers, e.g. `<cstring>` over `<string.h>`
- 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:

View File

@ -404,7 +404,7 @@ struct tr_socket_address
};
template<>
class std::hash<tr_socket_address>
struct std::hash<tr_socket_address>
{
public:
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
Mark file(s) for download.
.Ar all
marks all all of the torrent's files for downloading,
marks all of the torrent's files for downloading,
.Ar file-index
adds a single file to the download list, and
.Ar files

View File

@ -12,6 +12,14 @@ export class ActionManager extends EventTarget {
shortcut: 'D',
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-down': { enabled: false, text: 'Move down in 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('trash-selected-torrents', true);
add_separator();
add_item('enable-sequential-downloading');
add_item('disable-sequential-downloading');
add_separator();
add_item('verify-selected-torrents');
add_item('show-move-dialog');
add_item('show-rename-dialog');

View File

@ -91,6 +91,7 @@ export class Inspector extends EventTarget {
['availability', 'Availability:'],
['uploaded', 'Uploaded:'],
['downloaded', 'Downloaded:'],
['sequential_download', 'Sequential download:'],
['state', 'State:'],
['running_time', 'Running time:'],
['remaining_time', 'Remaining:'],
@ -563,6 +564,14 @@ export class Inspector extends EventTarget {
const link = torrents[0].getMagnetLink();
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

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
moveTorrentsToTop(torrent_ids, callback, context) {
this.sendTorrentActionRequests(

View File

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

View File

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