Prep for tauri

This commit is contained in:
Igor Katson 2023-12-01 18:08:41 +00:00
parent ab7d0f68d9
commit 950ed816d1
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
6 changed files with 158 additions and 136 deletions

View file

@ -0,0 +1,109 @@
// Interface for the Torrent API response
export interface TorrentId {
id: number;
info_hash: string;
}
export interface TorrentFile {
name: string;
length: number;
included: boolean;
}
// Interface for the Torrent Details API response
export interface TorrentDetails {
info_hash: string,
files: Array<TorrentFile>;
}
export interface AddTorrentResponse {
id: number | null;
details: TorrentDetails;
seen_peers?: Array<string>;
}
export interface ListTorrentsResponse {
torrents: Array<TorrentId>;
}
// Interface for the Torrent Stats API response
export interface LiveTorrentStats {
snapshot: {
have_bytes: number;
downloaded_and_checked_bytes: number;
downloaded_and_checked_pieces: number;
fetched_bytes: number;
uploaded_bytes: number;
initially_needed_bytes: number;
remaining_bytes: number;
total_bytes: number;
total_piece_download_ms: number;
peer_stats: {
queued: number;
connecting: number;
live: number;
seen: number;
dead: number;
not_needed: number;
};
};
average_piece_download_time: {
secs: number;
nanos: number;
};
download_speed: {
mbps: number;
human_readable: string;
};
all_time_download_speed: {
mbps: number;
human_readable: string;
};
time_remaining: {
human_readable: string;
duration?: {
secs: number,
}
} | null;
}
export const STATE_INITIALIZING = 'initializing';
export const STATE_PAUSED = 'paused';
export const STATE_LIVE = 'live';
export const STATE_ERROR = 'error';
export interface TorrentStats {
state: 'initializing' | 'paused' | 'live' | 'error',
error: string | null,
progress_bytes: number,
finished: boolean,
total_bytes: number,
live: LiveTorrentStats | null;
}
export interface ErrorDetails {
id?: number,
method?: string,
path?: string,
status?: number,
statusText?: string,
text: string,
};
export interface RqbitAPI {
listTorrents: () => Promise<ListTorrentsResponse>,
getTorrentDetails: (index: number) => Promise<TorrentDetails>,
getTorrentStats: (index: number) => Promise<TorrentStats>;
uploadTorrent: (data: string | File, opts?: {
listOnly?: boolean,
selectedFiles?: Array<number>,
unpopularTorrent?: boolean,
initialPeers?: Array<string>,
}) => Promise<AddTorrentResponse>;
pause: (index: number) => Promise<void>;
start: (index: number) => Promise<void>;
forget: (index: number) => Promise<void>;
delete: (index: number) => Promise<void>;
}

View file

@ -1,100 +1,8 @@
import { AddTorrentResponse, ErrorDetails, ListTorrentsResponse, RqbitAPI, TorrentDetails, TorrentStats } from "./api-types";
// Define API URL and base path
const apiUrl = (window.origin === 'null' || window.origin === 'http://localhost:3031') ? 'http://localhost:3030' : '';
// Interface for the Torrent API response
export interface TorrentId {
id: number;
info_hash: string;
}
export interface TorrentFile {
name: string;
length: number;
included: boolean;
}
// Interface for the Torrent Details API response
export interface TorrentDetails {
info_hash: string,
files: Array<TorrentFile>;
}
export interface AddTorrentResponse {
id: number | null;
details: TorrentDetails;
seen_peers?: Array<string>;
}
export interface ListTorrentsResponse {
torrents: Array<TorrentId>;
}
// Interface for the Torrent Stats API response
export interface LiveTorrentStats {
snapshot: {
have_bytes: number;
downloaded_and_checked_bytes: number;
downloaded_and_checked_pieces: number;
fetched_bytes: number;
uploaded_bytes: number;
initially_needed_bytes: number;
remaining_bytes: number;
total_bytes: number;
total_piece_download_ms: number;
peer_stats: {
queued: number;
connecting: number;
live: number;
seen: number;
dead: number;
not_needed: number;
};
};
average_piece_download_time: {
secs: number;
nanos: number;
};
download_speed: {
mbps: number;
human_readable: string;
};
all_time_download_speed: {
mbps: number;
human_readable: string;
};
time_remaining: {
human_readable: string;
duration?: {
secs: number,
}
} | null;
}
export const STATE_INITIALIZING = 'initializing';
export const STATE_PAUSED = 'paused';
export const STATE_LIVE = 'live';
export const STATE_ERROR = 'error';
export interface TorrentStats {
state: 'initializing' | 'paused' | 'live' | 'error',
error: string | null,
progress_bytes: number,
finished: boolean,
total_bytes: number,
live: LiveTorrentStats | null;
}
export interface ErrorDetails {
id?: number,
method?: string,
path?: string,
status?: number,
statusText?: string,
text: string,
};
const makeRequest = async (method: string, path: string, data?: any): Promise<any> => {
console.log(method, path);
const url = apiUrl + path;
@ -138,7 +46,7 @@ const makeRequest = async (method: string, path: string, data?: any): Promise<an
return result;
}
export const API = {
export const API: RqbitAPI = {
listTorrents: (): Promise<ListTorrentsResponse> => makeRequest('GET', '/torrents'),
getTorrentDetails: (index: number): Promise<TorrentDetails> => {
return makeRequest('GET', `/torrents/${index}`);

View file

@ -0,0 +1,9 @@
import { StrictMode } from "react";
import ReactDOM from 'react-dom/client';
import { RqbitWebUI } from "./rqbit-web";
import { API } from "./api";
globalThis.API = API;
const torrentsContainer = document.getElementById('app');
ReactDOM.createRoot(torrentsContainer).render(<StrictMode><RqbitWebUI /></StrictMode >);

View file

@ -1,7 +1,9 @@
import { MouseEventHandler, StrictMode, createContext, useContext, useEffect, useRef, useState } from 'react';
import { StrictMode, createContext, useContext, useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom/client';
import { ProgressBar, Button, Container, Row, Col, Alert, Modal, Form, Spinner, Table } from 'react-bootstrap';
import { AddTorrentResponse, TorrentDetails, TorrentFile, TorrentId, TorrentStats, ErrorDetails, API, STATE_INITIALIZING, STATE_LIVE, STATE_PAUSED, STATE_ERROR } from './api';
import { ProgressBar, Button, Container, Row, Col, Alert, Modal, Form, Spinner } from 'react-bootstrap';
import { AddTorrentResponse, TorrentDetails, TorrentId, TorrentStats, ErrorDetails, STATE_INITIALIZING, STATE_LIVE, STATE_PAUSED, STATE_ERROR, RqbitAPI } from './api-types';
declare const API: RqbitAPI;
interface Error {
text: string,
@ -308,7 +310,7 @@ const TorrentsList = (props: { torrents: Array<TorrentId>, loading: boolean }) =
</>;
};
const Root = () => {
export const RqbitWebUI = () => {
const [closeableError, setCloseableError] = useState<Error>(null);
const [otherError, setOtherError] = useState<Error>(null);
@ -693,13 +695,4 @@ function loopUntilSuccess<T>(callback: () => Promise<T>, interval: number): () =
scheduleNext(0);
return () => clearTimeout(timeoutId);
}
// List all torrents on page load and set up auto-refresh
async function init(): Promise<void> {
const torrentsContainer = document.getElementById('app');
ReactDOM.createRoot(torrentsContainer).render(<StrictMode><Root /></StrictMode>);
}
// Call init function on page load
document.addEventListener('DOMContentLoaded', init);
}