UI supporting multiple states

This commit is contained in:
Igor Katson 2023-11-24 15:47:51 +00:00
parent 66d2f224ed
commit c2dd367794
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5

View file

@ -19,15 +19,16 @@ const TorrentRow: React.FC<{
id: number, detailsResponse: TorrentDetails, statsResponse: TorrentStats
}> = ({ id, detailsResponse, statsResponse }) => {
const state = statsResponse?.state ?? "";
const error = statsResponse?.error;
const totalBytes = statsResponse?.total_bytes ?? 1;
const progressBytes = statsResponse?.progress_bytes ?? 0;
const finished = statsResponse?.finished || false;
const progressPercentage = state == 'error' ? 100 : (progressBytes / totalBytes) * 100;
const progressPercentage = error ? 100 : (progressBytes / totalBytes) * 100;
const isAnimated = (state == "initializing" || state == "live") && !finished;
const progressLabel = state == 'error' ? 'Error' : `${progressPercentage.toFixed(2)}%`;
const progressLabel = error ? 'Error' : `${progressPercentage.toFixed(2)}%`;
const progressBarVariant = error ? 'danger' : finished ? 'success' : 'info';
const getPeersString = (statsResponse: TorrentStats) => {
const formatPeersString = () => {
let peer_stats = statsResponse?.live?.snapshot.peer_stats;
if (!peer_stats) {
return '';
@ -35,37 +36,47 @@ const TorrentRow: React.FC<{
return `${peer_stats.live} / ${peer_stats.seen}`;
}
let classNames = [];
if (id % 2 == 0) {
classNames.push('bg-light');
const formatDownloadSped = () => {
if (finished) {
return 'Completed';
}
if (state == 'initializing') {
return 'Checking files';
}
return statsResponse.live?.download_speed.human_readable ?? "N/A";
}
if (statsResponse?.error) {
let classNames = [];
if (error) {
classNames.push('bg-warning');
} else {
if (id % 2 == 0) {
classNames.push('bg-light');
}
}
return (
<Row className={classNames.join(' ')}>
<Column size={4} label="Name">
{detailsResponse ?
<div className='text-truncate'>
{getLargestFileName(detailsResponse)}
</div>
<>
<div className='text-truncate'>
{getLargestFileName(detailsResponse)}
</div>
{error && <p className='text-danger'><strong>Error:</strong> {error}</p>}
</>
: <Spinner />}
</Column>
{statsResponse ?
<>
<Column label="Size">{`${formatBytes(totalBytes)} `}</Column>
<Column size={2} label="Progress">
<ProgressBar now={progressPercentage} label={progressLabel} animated={isAnimated} className={state == 'error' ? 'bg-danger' : ''} />
{
statsResponse.error && (
<p>{statsResponse.error}</p>
)
}
<ProgressBar now={progressPercentage} label={progressLabel} animated={isAnimated} variant={progressBarVariant} />
</Column>
<Column size={2} label="Down Speed">{statsResponse.live?.download_speed.human_readable ?? "N/A"}</Column>
<Column size={2} label="Down Speed">{formatDownloadSped()}</Column>
<Column label="ETA">{getCompletionETA(statsResponse)}</Column>
<Column size={2} label="Peers">{getPeersString(statsResponse)}</Column >
<Column size={2} label="Peers">{formatPeersString()}</Column >
</>
: <Column label="Loading stats" size={8}><Spinner /></Column>
}