Fix a bug that made it impossible to add torrents in desktop

This commit is contained in:
Igor Katson 2023-12-08 09:41:54 +00:00
parent 2b9129221d
commit 0751dbc5fc
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
4 changed files with 26 additions and 18 deletions

11
TODO.md
View file

@ -19,7 +19,6 @@
- [x] for torrents with a few seeds might be cool to re-query DHT once in a while. - [x] for torrents with a few seeds might be cool to re-query DHT once in a while.
- [x] don't leak memory when deleting torrents (i.e. remove torrent information (seen peers etc) once the torrent is deleted) - [x] don't leak memory when deleting torrents (i.e. remove torrent information (seen peers etc) once the torrent is deleted)
- [x] Routing table - is it balanced properly? - [x] Routing table - is it balanced properly?
- [ ]
- [x] Don't query Bad nodes - [x] Don't query Bad nodes
- [-] Buckets that have not been changed in 15 minutes should be "refreshed." (per RFC) - [-] Buckets that have not been changed in 15 minutes should be "refreshed." (per RFC)
- [x] Did it, but it's flawed: starts repeating the same queries again as neighboring refreshes - [x] Did it, but it's flawed: starts repeating the same queries again as neighboring refreshes
@ -33,25 +32,31 @@
- [x] Ensure that if we query the "returned" nodes, they are even closer to our request than the responding node id was. - [x] Ensure that if we query the "returned" nodes, they are even closer to our request than the responding node id was.
incoming peers: incoming peers:
- [x] error managing peer: expected extended handshake, but got Bitfield(<94 bytes>) - [x] error managing peer: expected extended handshake, but got Bitfield(<94 bytes>)
- [x] do not announce when merely listing the torrent - [x] do not announce when merely listing the torrent
someday: someday:
- [x] cancellation from the client-side for the lib (i.e. stop the torrent manager) - [x] cancellation from the client-side for the lib (i.e. stop the torrent manager)
- [x] favicons for Web UI - [x] favicons for Web UI
desktop: desktop:
- [ ] on first run show options
- [ ] allow to change options later (even with a session restart) - [x] on first run show options
- [x] allow to change options later (even with a session restart)
- [ ] look at logs - allow writing them to files? Set RUST_LOG through API - [ ] look at logs - allow writing them to files? Set RUST_LOG through API
persistence: persistence:
- [ ] store total uploaded bytes, so that on restart it comes back up - [ ] store total uploaded bytes, so that on restart it comes back up
efficiency: efficiency:
- [ ] once the torrent is completed, we don't need to remember old peers - [ ] once the torrent is completed, we don't need to remember old peers
refactor: refactor:
- [x] session persistence: should add torrents even if we haven't resolved it yet - [x] session persistence: should add torrents even if we haven't resolved it yet
- [x] where are peers stored - [x] where are peers stored
- [x] http api pause/unpause etc - [x] http api pause/unpause etc

View file

@ -203,9 +203,9 @@ fn compute_only_files<ByteBuf: AsRef<[u8]>>(
/// Options for adding new torrents to the session. /// Options for adding new torrents to the session.
#[serde_as] #[serde_as]
#[derive(Default, Clone, Serialize, Deserialize)] #[derive(Default, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct AddTorrentOptions { pub struct AddTorrentOptions {
/// Start in paused state. /// Start in paused state.
#[serde(default)]
pub paused: bool, pub paused: bool,
/// A regex to only download files matching it. /// A regex to only download files matching it.
pub only_files_regex: Option<String>, pub only_files_regex: Option<String>,
@ -214,10 +214,8 @@ pub struct AddTorrentOptions {
pub only_files: Option<Vec<usize>>, pub only_files: Option<Vec<usize>>,
/// Allow writing on top of existing files, including when resuming a torrent. /// Allow writing on top of existing files, including when resuming a torrent.
/// You probably want to set it, however for safety it's not default. /// You probably want to set it, however for safety it's not default.
#[serde(default)]
pub overwrite: bool, pub overwrite: bool,
/// Only list the files in the torrent without starting it. /// Only list the files in the torrent without starting it.
#[serde(default)]
pub list_only: bool, pub list_only: bool,
/// The output folder for the torrent. If not set, the session's default one will be used. /// The output folder for the torrent. If not set, the session's default one will be used.
pub output_folder: Option<String>, pub output_folder: Option<String>,

View file

@ -3,9 +3,12 @@ import { MouseEventHandler } from "react";
export const IconButton: React.FC<{ export const IconButton: React.FC<{
onClick: () => void; onClick: () => void;
disabled?: boolean; disabled?: boolean;
className?: string;
color?: string; color?: string;
children: any; children: any;
}> = ({ onClick, disabled, color, children }) => { }> = (props) => {
const { onClick, disabled, color, children, className, ...otherProps } =
props;
const onClickStopPropagation: MouseEventHandler<HTMLAnchorElement> = (e) => { const onClickStopPropagation: MouseEventHandler<HTMLAnchorElement> = (e) => {
e.stopPropagation(); e.stopPropagation();
if (disabled) { if (disabled) {
@ -16,9 +19,10 @@ export const IconButton: React.FC<{
const colorClassName = color ? `text-${color}` : ""; const colorClassName = color ? `text-${color}` : "";
return ( return (
<a <a
className={`p-1 ${colorClassName}`} className={`p-1 ${colorClassName} ${className}`}
onClick={onClickStopPropagation} onClick={onClickStopPropagation}
href="#" href="#"
{...otherProps}
> >
{children} {children}
</a> </a>

View file

@ -2,6 +2,8 @@ import { useState } from "react";
import { RqbitWebUI } from "./rqbit-webui-src/rqbit-web"; import { RqbitWebUI } from "./rqbit-webui-src/rqbit-web";
import { CurrentDesktopState, RqbitDesktopConfig } from "./configuration"; import { CurrentDesktopState, RqbitDesktopConfig } from "./configuration";
import { ConfigModal } from "./configure"; import { ConfigModal } from "./configure";
import { IconButton } from "./rqbit-webui-src/components/IconButton";
import { BsSliders2 } from "react-icons/bs";
export const RqbitDesktop: React.FC<{ export const RqbitDesktop: React.FC<{
version: string; version: string;
@ -20,15 +22,14 @@ export const RqbitDesktop: React.FC<{
<RqbitWebUI title={`Rqbit Desktop v${version}`}></RqbitWebUI> <RqbitWebUI title={`Rqbit Desktop v${version}`}></RqbitWebUI>
)} )}
{configured && ( {configured && (
<a <IconButton
className="bi bi-sliders2 position-absolute top-0 start-0 p-3 text-primary" className="position-absolute top-0 start-0 p-3 text-primary"
onClick={(e) => { onClick={() => {
e.stopPropagation();
setConfigurationOpened(true); setConfigurationOpened(true);
}} }}
href="#" >
aria-label="Settings" <BsSliders2 />
/> </IconButton>
)} )}
<ConfigModal <ConfigModal
show={!configured || configurationOpened} show={!configured || configurationOpened}