-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Colorful progress bars #82
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,21 +17,46 @@ | |
*/ | ||
|
||
import "../css/progressbar.css"; | ||
import React from "react"; | ||
import React, { useContext } from "react"; | ||
import { ConfigContext } from "../config"; | ||
import { Status } from "../rpc/transmission"; | ||
|
||
interface ProgressBarProps { | ||
now: number, | ||
max?: number, | ||
label?: string, | ||
animate?: boolean, | ||
status?: number, | ||
className?: string, | ||
} | ||
|
||
export function ProgressBar(props: ProgressBarProps) { | ||
const max = props.max ?? 100; | ||
const percent = Math.floor(1000 * props.now / max) / 10; | ||
const label = props.label ?? `${percent}%`; | ||
const className = `progressbar ${props.animate === true ? "animate" : ""} ${props.className ?? ""}`; | ||
const label = props.label || `${percent}%`; | ||
Check failure on line 36 in src/components/progressbar.tsx GitHub Actions / eslint
Check failure on line 36 in src/components/progressbar.tsx GitHub Actions / eslint
|
||
const animate = (props.animate && props.status !== Status.queuedToVerify && | ||
Check failure on line 37 in src/components/progressbar.tsx GitHub Actions / eslint
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Animate prop should also be taken as is. Determine whether progress bar should be animated in the parent. |
||
props.status !== Status.queuedToDownload && props.status !== Status.queuedToSeed) || | ||
Check failure on line 38 in src/components/progressbar.tsx GitHub Actions / eslint
|
||
props.status == Status.magnetizing || props.status == Status.verifying; | ||
Check failure on line 39 in src/components/progressbar.tsx GitHub Actions / eslint
Check failure on line 39 in src/components/progressbar.tsx GitHub Actions / eslint
|
||
let color = "blue"; | ||
|
||
const config = useContext(ConfigContext); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move the config checks outside as well. Basically this should be a dumb generic reusable component that just draws what it's told. |
||
const colorize = config.values.interface.colorfulProgressBars; | ||
if (colorize) { | ||
if (props.status == Status.error) { | ||
Check failure on line 45 in src/components/progressbar.tsx GitHub Actions / eslint
|
||
color = "dark-red"; | ||
} else if (props.status == Status.magnetizing) { | ||
Check failure on line 47 in src/components/progressbar.tsx GitHub Actions / eslint
|
||
color = "red"; | ||
} else if (props.status == Status.stopped) { | ||
Check failure on line 49 in src/components/progressbar.tsx GitHub Actions / eslint
|
||
color = "dark-green"; | ||
} else if (props.status == Status.seeding || props.status == Status.downloading && percent == 100) { | ||
color = "green"; | ||
} else if (props.status == Status.queuedToVerify || props.status == Status.queuedToDownload || | ||
props.status == Status.queuedToSeed) { | ||
color = "dark-blue"; | ||
} // Waiting and Downloading @ <=99% will default to plain blue | ||
} | ||
|
||
const className = `progressbar ${animate === true ? "animate" : ""} ${color} ${props.className ?? ""}`; | ||
return ( | ||
<div className={className}> | ||
<div>{label}</div> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ import type { Row, ColumnDef, CellContext } from "@tanstack/react-table"; | |
import type { CachedFileTree, FileDirEntry } from "../../cachedfiletree"; | ||
import { isDirEntry } from "../../cachedfiletree"; | ||
import { ConfigContext, ServerConfigContext } from "../../config"; | ||
import { PriorityColors, PriorityStrings } from "../../rpc/transmission"; | ||
import { Status, PriorityColors, PriorityStrings } from "../../rpc/transmission"; | ||
import { bytesToHumanReadableStr, pathMapFromServer } from "../../trutil"; | ||
import { ProgressBar } from "../progressbar"; | ||
import * as Icon from "react-bootstrap-icons"; | ||
|
@@ -136,7 +136,7 @@ function ByteSizeField(props: TableFieldProps) { | |
function PercentBarField(props: TableFieldProps) { | ||
const now = props.entry.percent ?? 0; | ||
|
||
return <ProgressBar now={now} className="white-outline" />; | ||
return <ProgressBar now={now} status={Status.downloading} className="white-outline" />; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep this blue. |
||
} | ||
|
||
function PriorityField(props: TableFieldProps) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
import type { AccessorFn, CellContext, ColumnDef } from "@tanstack/react-table"; | ||
import React, { useMemo, useCallback } from "react"; | ||
import type { Torrent, PeerStats } from "rpc/torrent"; | ||
import { Status } from "../../rpc/transmission"; | ||
import { bytesToHumanReadableStr } from "trutil"; | ||
import { TrguiTable, useStandardSelect } from "./common"; | ||
import { ProgressBar } from "components/progressbar"; | ||
|
@@ -80,7 +81,8 @@ function PercentField(props: TableFieldProps) { | |
return <ProgressBar | ||
now={now} | ||
className="white-outline" | ||
animate={active} />; | ||
animate={active} | ||
status={Status.downloading} />; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, either keep this unchanged or keep consistent logic. |
||
} | ||
|
||
const Columns = AllFields.map((field): ColumnDef<PeerStats> => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -299,13 +299,24 @@ function ByteRateField(props: TableFieldProps) { | |
} | ||
|
||
function PercentBarField(props: TableFieldProps) { | ||
const now = props.torrent[props.fieldName] * 100; | ||
let now: number = props.torrent[props.fieldName] * 100; | ||
let label: string = ''; | ||
let status: number = props.torrent.status; | ||
if ((props.torrent.error !== undefined && props.torrent.error > 0) || props.torrent.cachedError !== "") { | ||
status = Status.error; | ||
} else if (props.torrent.status === Status.downloading && props.torrent.pieceCount === 0) { | ||
now = 100; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this is leftover from testing or you intend to always show full progress bar. I'm inclined to not show it, even if it makes the color of the progress bar rarely visible because it usually goes from 0 to downloading in a single update. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem with the Magnetizing one is that I think you said the Magnetization progress is not grabbed at the full table level, only at the per-torrent level. So the Magnetization process will never be shown, and so the colors will never be shown. I felt it's better to have the bar be full all the time to at least show that this torrent is being Magnetized. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense, showing full animated bar with no percentage text will be fine. |
||
label = "🧲"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No emojis and no custom labels here, the icon in name field is enough indication. |
||
status = Status.magnetizing; | ||
} | ||
const active = props.torrent.rateDownload > 0 || props.torrent.rateUpload > 0; | ||
|
||
return <ProgressBar | ||
now={now} | ||
className="white-outline" | ||
animate={active} />; | ||
label={label} | ||
animate={active} | ||
status={status} />; | ||
} | ||
|
||
const Columns = AllFields.map((f): ColumnDef<Torrent> => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,27 @@ | |
transition: clip-path 0.5s ease; | ||
} | ||
|
||
.progressbar.dark-blue>:first-child { | ||
background: #0054ae; | ||
} | ||
|
||
.progressbar.green>:first-child { | ||
background: #36B24D; | ||
} | ||
|
||
.progressbar.dark-green>:first-child { | ||
background: #1d8931; | ||
} | ||
|
||
.progressbar.red>:first-child { | ||
background: #FA5352; | ||
} | ||
|
||
.progressbar.dark-red>:first-child { | ||
background: #C92B2A; | ||
} | ||
Comment on lines
+36
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The colors are fine but they are not from the default palette and stand out. |
||
|
||
|
||
.progressbar.animate>:first-child { | ||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); | ||
background-size: 1rem 1rem; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,8 @@ export const Status = { | |
downloading: 4, | ||
queuedToSeed: 5, | ||
seeding: 6, | ||
magnetizing: -1, | ||
error: -2, | ||
Comment on lines
+32
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file should not be changed at all. It is meant to directly map to transmission API. Once you move the status out of ProgressBar you will likely find that you don't need these fake statuses here. |
||
} as const; | ||
|
||
export const StatusStrings = [ | ||
|
@@ -39,6 +41,8 @@ export const StatusStrings = [ | |
"Downloading", | ||
"Waiting", | ||
"Seeding", | ||
"Magnetizing", | ||
"Error", | ||
] as const; | ||
|
||
const PriorityNumbers = [-1, 0, 1] as const; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Status logic should not be in ProgressBar component because it is generic. It should have an enum variant prop that gives it correct color, determine the variant in parent component that knows what status means, let progressbar handle the color based on variant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of confused on this one. Do you mean the ProgressBar component should have an enum for the possible colors, and everything that calls ProgressBar should manually convert e.g. the torrent status into a ProgressBarColor? Which would mean repeating the code between torrenttable.tsx and details.tsx?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to repeat the code, extract it into a helper function, you can put it in
torrent.ts
.