mirror of
https://github.com/zoriya/flood.git
synced 2025-12-20 14:15:15 +00:00
Add icons for torrent overview details
This commit is contained in:
@@ -82,23 +82,33 @@ $progress-bar--fill--error: #e95779;
|
||||
position: relative;
|
||||
|
||||
&:after {
|
||||
background: $progress-bar--background;
|
||||
background: $progress-bar--fill;
|
||||
content: '';
|
||||
height: 1px;
|
||||
left: 0;
|
||||
opacity: 0.5;
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
transition: background 0.25s;
|
||||
transition: background 0.25s, opacity 0.25s;
|
||||
width: 100%;
|
||||
|
||||
.is-stopped & {
|
||||
background: $progress-bar--fill--stopped;
|
||||
}
|
||||
|
||||
.has-error & {
|
||||
background: $progress-bar--fill--error;
|
||||
}
|
||||
|
||||
.is-selected & {
|
||||
background: $progress-bar--background--selected;
|
||||
}
|
||||
|
||||
.is-selected.is-stopped & {
|
||||
background: $progress-bar--background--selected--stopped;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ $torrent-list--background: #fff;
|
||||
$torrent-list--border: rgba($background, 0.15);
|
||||
|
||||
$torrent--primary--foreground: #5b6d7c;
|
||||
$torrent--primary--foreground--error: #e95779;
|
||||
$torrent--primary--foreground--stopped: rgba(#333332, 0.5);
|
||||
$torrent--primary--foreground--selected: #fff;
|
||||
$torrent--primary--foreground--selected--stopped: rgba($torrent--primary--foreground--selected, 0.6);
|
||||
@@ -149,6 +150,10 @@ $torrent--background--error: #e95779;
|
||||
color: $torrent--primary--foreground--stopped;
|
||||
}
|
||||
|
||||
.has-error & {
|
||||
color: $torrent--primary--foreground--error;
|
||||
}
|
||||
|
||||
.is-selected & {
|
||||
color: $torrent--primary--foreground--selected;
|
||||
}
|
||||
@@ -161,16 +166,26 @@ $torrent--background--error: #e95779;
|
||||
&--secondary {
|
||||
align-items: flex-end;
|
||||
color: $torrent--secondary--foreground;
|
||||
flex: 1;
|
||||
flex: 0 0 245px;
|
||||
font-size: 0.75em;
|
||||
min-width: 200px;
|
||||
min-width: 255px;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
|
||||
li {
|
||||
flex: 1 1 auto;
|
||||
min-width: 15%;
|
||||
display: inline-block;
|
||||
font-weight: 500;
|
||||
margin-right: 5px;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
|
||||
&.torrent__details--ratio {
|
||||
max-width: 30px;
|
||||
.unit {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +210,8 @@ $torrent--background--error: #e95779;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
margin-right: 15px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
@@ -219,6 +235,74 @@ $torrent--background--error: #e95779;
|
||||
margin-right: 0.5em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
display: inline-block;
|
||||
padding-right: 5px;
|
||||
transform: translateY(1px);
|
||||
vertical-align: baseline;
|
||||
|
||||
.icon {
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
height: 12px;
|
||||
opacity: 0.66;
|
||||
width: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&--completed {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
&--uploaded {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
&--size {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
&--peers {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
&--seeds {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
&--added {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
&--eta {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
&--speed {
|
||||
width: 60px;
|
||||
|
||||
&--download,
|
||||
&--upload {
|
||||
transition: color 0.25s;
|
||||
|
||||
.is-selected & {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&--download {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
&--upload {
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
&--ratio {
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
14
client/source/scripts/components/icons/CalendarIcon.js
Normal file
14
client/source/scripts/components/icons/CalendarIcon.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class CalendarIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--calendar ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<path d="M51.9,9.39h-4V6.3a5.08,5.08,0,0,0-5-5.15h-2A5.08,5.08,0,0,0,36,6.3V9.39H24V6.3a5.08,5.08,0,0,0-5-5.15h-2a5.08,5.08,0,0,0-5,5.15V9.39h-4a4.08,4.08,0,0,0-4,4.12V54.74a4.08,4.08,0,0,0,4,4.12H51.9a4.08,4.08,0,0,0,4-4.12V13.51A4.08,4.08,0,0,0,51.9,9.39ZM40,6.3a1,1,0,0,1,1-1h2a1,1,0,0,1,1,1v9.28a1,1,0,0,1-1,1h-2a1,1,0,0,1-1-1V6.3Zm-23.89,0a1,1,0,0,1,1-1h2a1,1,0,0,1,1,1v9.28a1,1,0,0,1-1,1h-2a1,1,0,0,1-1-1V6.3ZM49.8,52.84H10.2V22.42H49.8V52.84Z"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
15
client/source/scripts/components/icons/ClockIcon.js
Normal file
15
client/source/scripts/components/icons/ClockIcon.js
Normal file
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class ClockIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--clock ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<path d="M30,6A24,24,0,0,1,47,47,24,24,0,0,1,13,13,23.85,23.85,0,0,1,30,6m0-6A30,30,0,1,0,51.21,8.79,29.91,29.91,0,0,0,30,0h0Z"/>
|
||||
<polygon points="26.85 46.91 21.18 44.09 28.58 29.21 17.93 22.93 21.14 17.48 36.88 26.75 26.85 46.91"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
24
client/source/scripts/components/icons/DiskIcon.js
Normal file
24
client/source/scripts/components/icons/DiskIcon.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class DiskIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--disk ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<polygon points="51.8,0 51.8,0 51.8,3.7 51.8,56.3 8.2,56.3 8.2,3.7 8.2,0 8.2,0 4.5,0 4.5,60.1 55.5,60.1 55.5,0 "/>
|
||||
<rect x="18.4" y="8.9" width="23.1" height="3.8"/>
|
||||
<path d="M30,51.8c3.4,0,6.8-1.1,9.6-3.3L29.4,38.4l3.1-3.1l10.2,10.1c4.3-6.1,3.8-14.5-1.7-20c-3-3-7-4.5-11-4.5
|
||||
s-7.9,1.5-11,4.5C13,31.4,13,41.2,19,47.3C22.1,50.3,26,51.8,30,51.8z"/>
|
||||
<rect x="40" y="0" width="3.5" height="3.8"/>
|
||||
<rect x="45.9" y="0" width="3.5" height="3.8"/>
|
||||
<rect x="34.1" y="0" width="3.5" height="3.8"/>
|
||||
<rect x="16.5" y="0" width="3.5" height="3.8"/>
|
||||
<rect x="10.6" y="0" width="3.5" height="3.8"/>
|
||||
<rect x="22.4" y="0" width="3.5" height="3.8"/>
|
||||
<rect x="28.2" y="0" width="3.5" height="3.8"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
14
client/source/scripts/components/icons/DownloadThickIcon.js
Normal file
14
client/source/scripts/components/icons/DownloadThickIcon.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class DownloadThickIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--download ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<polygon points="44.1,23 33,39.7 33,4.6 27,4.6 27,39.7 15.9,23 10.9,26.4 30,55 49.1,26.4 "/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
14
client/source/scripts/components/icons/PeersIcon.js
Normal file
14
client/source/scripts/components/icons/PeersIcon.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class PeersIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--peers ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<path d="M47.95,1.4a12.05,12.05,0,0,0-11.78,9.55H23.84A12,12,0,1,0,12.05,25.5a11.92,11.92,0,0,0,3.56-.6l6,13a12.51,12.51,0,1,0,4.28-2.66L20,22.45a12,12,0,0,0,3.85-6.5H36.16A12,12,0,1,0,47.95,1.4ZM37.05,46.55A7.05,7.05,0,1,1,30,39.5,7.06,7.06,0,0,1,37.05,46.55ZM5,13.45a7.05,7.05,0,1,1,7.05,7.05A7.06,7.06,0,0,1,5,13.45ZM47.95,20.5A7.05,7.05,0,1,1,55,13.45,7.06,7.06,0,0,1,47.95,20.5Z"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
14
client/source/scripts/components/icons/RatioIcon.js
Normal file
14
client/source/scripts/components/icons/RatioIcon.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class RatioIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--ratio ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<path d="M60,4.85L55.14,0l-7,6.94a29.17,29.17,0,0,0-5.24-3.3l-3,6.16a22.39,22.39,0,0,1,3.37,2L12,43c-0.31-.43-0.62-0.86-0.9-1.31L5.27,45.35a29.07,29.07,0,0,0,1.81,2.55l-7,6.93L5,59.68l7-6.94a29.32,29.32,0,0,0,38.81-2.28A29.08,29.08,0,0,0,53,11.78ZM45.89,45.61a22.39,22.39,0,0,1-29,2.22L48.12,16.69A22.2,22.2,0,0,1,45.89,45.61ZM32.7,7.68L33.5,0.87a29.72,29.72,0,0,0-6.57,0l0.73,6.81A22.35,22.35,0,0,1,32.7,7.68Zm-12.26,2-3-6.19A29.23,29.23,0,0,0,11.9,7l4.27,5.37A22.31,22.31,0,0,1,20.44,9.69ZM8.23,34.78a22.48,22.48,0,0,1-.55-5l-6.88,0a29.31,29.31,0,0,0,.72,6.45Zm2.91-16.87L5.33,14.24a29,29,0,0,0-2.87,5.89l6.49,2.28A22.15,22.15,0,0,1,11.14,17.91Z"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
14
client/source/scripts/components/icons/SeedsIcon.js
Normal file
14
client/source/scripts/components/icons/SeedsIcon.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class SeedsIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--seeds ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<path d="M47.95,1.4a12.05,12.05,0,0,0-11.78,9.55H23.84A12,12,0,1,0,12.05,25.5a11.92,11.92,0,0,0,3.56-.6l6,13a12.51,12.51,0,1,0,4.28-2.66L20,22.45a12,12,0,0,0,3.85-6.5H36.16A12,12,0,1,0,47.95,1.4ZM37.05,46.55A7.05,7.05,0,1,1,30,39.5,7.06,7.06,0,0,1,37.05,46.55Z"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
14
client/source/scripts/components/icons/UploadThickIcon.js
Normal file
14
client/source/scripts/components/icons/UploadThickIcon.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
|
||||
import BaseIcon from './BaseIcon';
|
||||
|
||||
export default class UploadThickIcon extends BaseIcon {
|
||||
render() {
|
||||
return (
|
||||
<svg className={`icon icon--upload ${this.props.className}`}
|
||||
xmlns={this.getXmlns()} viewBox={this.getViewBox()}>
|
||||
<polygon points="15.9,36.6 27,19.9 27,55 33,55 33,19.9 44.1,36.6 49.1,33.3 30,4.6 10.9,33.3 "/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
import CalendarIcon from '../icons/CalendarIcon';
|
||||
import ClockIcon from '../icons/ClockIcon';
|
||||
import DiskIcon from '../icons/DiskIcon';
|
||||
import DotsMini from '../icons/DotsMini';
|
||||
import DownloadThickIcon from '../icons/DownloadThickIcon';
|
||||
import EventTypes from '../../constants/EventTypes';
|
||||
import format from '../../util/formatData';
|
||||
import PeersIcon from '../icons/PeersIcon';
|
||||
import ProgressBar from '../ui/ProgressBar';
|
||||
import RatioIcon from '../icons/RatioIcon';
|
||||
import SeedsIcon from '../icons/SeedsIcon';
|
||||
import {torrentStatusIcons} from '../../util/torrentStatusIcons';
|
||||
import {torrentStatusClasses} from '../../util/torrentStatusClasses';
|
||||
import UploadThickIcon from '../icons/UploadThickIcon';
|
||||
|
||||
const METHODS_TO_BIND = [
|
||||
'handleClick',
|
||||
@@ -61,17 +69,21 @@ export default class Torrent extends React.Component {
|
||||
<li className="torrent__details--secondary">
|
||||
<ul className="torrent__details">
|
||||
<li className="torrent__details--eta">
|
||||
<span className="torrent__details__icon"><ClockIcon /></span>
|
||||
{eta}
|
||||
</li>
|
||||
<li className="torrent__details--speed">
|
||||
<li className="torrent__details--speed torrent__details--speed--download">
|
||||
<span className="torrent__details__icon"><DownloadThickIcon /></span>
|
||||
{downloadRate.value}
|
||||
<em className="unit">{downloadRate.unit}</em>
|
||||
</li>
|
||||
<li className="torrent__details--speed">
|
||||
<li className="torrent__details--speed torrent__details--speed--upload">
|
||||
<span className="torrent__details__icon"><UploadThickIcon /></span>
|
||||
{uploadRate.value}
|
||||
<em className="unit">{uploadRate.unit}</em>
|
||||
</li>
|
||||
<li className="torrent__details--ratio">
|
||||
<span className="torrent__details__icon"><RatioIcon /></span>
|
||||
{ratio}
|
||||
</li>
|
||||
</ul>
|
||||
@@ -79,7 +91,7 @@ export default class Torrent extends React.Component {
|
||||
</ul>
|
||||
<ul className="torrent__details torrent__details--tertiary">
|
||||
<li className="torrent__details--completed">
|
||||
<span className="torrent__details__label">Downloaded</span>
|
||||
<span className="torrent__details__icon"><DownloadThickIcon /></span>
|
||||
{torrent.percentComplete}
|
||||
<em className="unit">%</em>
|
||||
—
|
||||
@@ -87,17 +99,25 @@ export default class Torrent extends React.Component {
|
||||
<em className="unit">{completed.unit}</em>
|
||||
</li>
|
||||
<li className="torrent__details--uploaded">
|
||||
<span className="torrent__details__label">Uploaded</span>
|
||||
<span className="torrent__details__icon"><UploadThickIcon /></span>
|
||||
{uploadTotal.value}
|
||||
<em className="unit">{uploadTotal.unit}</em>
|
||||
</li>
|
||||
<li className="torrent__details--size">
|
||||
<span className="torrent__details__label">Size</span>
|
||||
<span className="torrent__details__icon"><DiskIcon /></span>
|
||||
{totalSize.value}
|
||||
<em className="unit">{totalSize.unit}</em>
|
||||
</li>
|
||||
<li className="torrent__details--peers">
|
||||
<span className="torrent__details__icon"><PeersIcon /></span>
|
||||
{torrent.connectedPeers} <em className="unit">of</em> {torrent.totalPeers}
|
||||
</li>
|
||||
<li className="torrent__details--seeds">
|
||||
<span className="torrent__details__icon"><SeedsIcon /></span>
|
||||
{torrent.connectedSeeds} <em className="unit">of</em> {torrent.totalSeeds}
|
||||
</li>
|
||||
<li className="torrent__details--added">
|
||||
<span className="torrent__details__label">Added</span>
|
||||
<span className="torrent__details__icon"><CalendarIcon /></span>
|
||||
{addedString}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -73,29 +73,38 @@ const format = {
|
||||
megabyte = kilobyte * 1024,
|
||||
gigabyte = megabyte * 1024,
|
||||
terabyte = gigabyte * 1024,
|
||||
value = '',
|
||||
value = 0,
|
||||
unit = '';
|
||||
|
||||
if ((bytes >= 0) && (bytes < kilobyte)) {
|
||||
value = bytes;
|
||||
unit = 'B';
|
||||
} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
|
||||
value = (bytes / kilobyte).toFixed(precision);
|
||||
value = (bytes / kilobyte);
|
||||
unit = 'KB';
|
||||
} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
|
||||
value = (bytes / megabyte).toFixed(precision);
|
||||
value = (bytes / megabyte);
|
||||
unit = 'MB';
|
||||
} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
|
||||
value = (bytes / gigabyte).toFixed(precision);
|
||||
value = (bytes / gigabyte);
|
||||
unit = 'GB';
|
||||
} else if (bytes >= terabyte) {
|
||||
value = (bytes / terabyte).toFixed(precision);
|
||||
value = (bytes / terabyte);
|
||||
unit = 'TB';
|
||||
} else {
|
||||
value = bytes;
|
||||
unit = 'B';
|
||||
}
|
||||
|
||||
value = Number(value);
|
||||
if (!!value && value < 10) {
|
||||
value = value.toFixed(precision);
|
||||
} else if (!!value && value > 10 && value < 100) {
|
||||
value = value.toFixed(precision - 1);
|
||||
} else if (!!value && value > 100) {
|
||||
value = Math.floor(value);
|
||||
}
|
||||
|
||||
if (extraUnits) {
|
||||
unit += extraUnits;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,15 @@ class Torrent {
|
||||
}
|
||||
|
||||
getCalculatedPercentComplete(clientData) {
|
||||
return (clientData.bytesDone / clientData.sizeBytes * 100).toFixed(2);
|
||||
let percentComplete = clientData.bytesDone / clientData.sizeBytes * 100;
|
||||
|
||||
if (percentComplete > 0 && percentComplete < 10) {
|
||||
return percentComplete.toFixed(2);
|
||||
} else if (percentComplete > 10 && percentComplete < 100) {
|
||||
return percentComplete.toFixed(1);
|
||||
} else {
|
||||
return percentComplete;
|
||||
}
|
||||
}
|
||||
|
||||
getCalculatedStatus(clientData) {
|
||||
|
||||
Reference in New Issue
Block a user