farjs-app
Version:
FAR.js - Cross-platform File and Archive Manager app in your terminal
181 lines (163 loc) • 4.35 kB
JavaScript
import React from "react";
import Theme from "@farjs/ui/theme/Theme.mjs";
import TextAlign from "@farjs/ui/TextAlign.mjs";
import TextLine from "@farjs/ui/TextLine.mjs";
import ProgressBar from "@farjs/ui/ProgressBar.mjs";
import HorizontalLine from "@farjs/ui/border/HorizontalLine.mjs";
import SingleChars from "@farjs/ui/border/SingleChars.mjs";
import ModalContent from "@farjs/ui/popup/ModalContent.mjs";
import Modal from "@farjs/ui/popup/Modal.mjs";
import { formatSize } from "@farjs/filelist/utils.mjs";
const h = React.createElement;
/**
* @typedef {{
* readonly move: boolean;
* readonly item: string;
* readonly to: string;
* readonly itemPercent: number;
* readonly total: number;
* readonly totalPercent: number;
* readonly timeSeconds: number;
* readonly leftSeconds: number;
* readonly bytesPerSecond: number;
* onCancel(): void;
* }} CopyProgressPopupProps
*/
/**
* @param {CopyProgressPopupProps} props
*/
const CopyProgressPopup = (props) => {
const {
modalComp,
textLineComp,
horizontalLineComp,
progressBarComp,
_toTime,
_toSpeed,
} = CopyProgressPopup;
const [width, height] = [50, 13];
const contentWidth = width - (ModalContent.paddingHorizontal + 2) * 2;
const contentLeft = 2;
const theme = Theme.useTheme().popup.regular;
return h(
modalComp,
{
title: props.move ? "Move" : "Copy",
width,
height,
style: theme,
onCancel: props.onCancel,
},
h("text", {
left: contentLeft,
top: 1,
style: theme,
content: `${props.move ? "Moving" : "Copying"} the file
to
`,
}),
h(textLineComp, {
align: TextAlign.left,
left: contentLeft,
top: 2,
width: contentWidth,
text: props.item,
style: theme,
padding: 0,
}),
h(textLineComp, {
align: TextAlign.left,
left: contentLeft,
top: 4,
width: contentWidth,
text: props.to,
style: theme,
padding: 0,
}),
h(progressBarComp, {
percent: props.itemPercent,
left: contentLeft,
top: 5,
length: contentWidth,
style: theme,
}),
h(horizontalLineComp, {
left: contentLeft,
top: 6,
length: contentWidth,
lineCh: SingleChars.horizontal,
style: theme,
}),
h(textLineComp, {
align: TextAlign.center,
left: contentLeft,
top: 6,
width: contentWidth,
text: `Total: ${formatSize(props.total)}`,
style: theme,
}),
h(progressBarComp, {
percent: props.totalPercent,
left: contentLeft,
top: 7,
length: contentWidth,
style: theme,
}),
h(horizontalLineComp, {
left: contentLeft,
top: 8,
length: contentWidth,
lineCh: SingleChars.horizontal,
style: theme,
}),
h("text", {
left: contentLeft,
top: 9,
style: theme,
content: `Time: ${_toTime(props.timeSeconds)} Left: ${_toTime(
props.leftSeconds
)}`,
}),
h(textLineComp, {
align: TextAlign.right,
left: contentLeft + 30,
top: 9,
width: contentWidth - 30,
text: `${_toSpeed(props.bytesPerSecond * 8)}/s`,
style: theme,
padding: 0,
}),
//for capturing inputs
h("button", { width: 0, height: 0 })
);
};
CopyProgressPopup.displayName = "CopyProgressPopup";
CopyProgressPopup.modalComp = Modal;
CopyProgressPopup.textLineComp = TextLine;
CopyProgressPopup.horizontalLineComp = HorizontalLine;
CopyProgressPopup.progressBarComp = ProgressBar;
/** @type {(seconds: number) => string} */
CopyProgressPopup._toTime = (seconds) => {
const hrs = Math.round(seconds / 3600);
const min = Math.round((seconds - hrs * 3600) / 60);
const sec = Math.round(seconds - hrs * 3600 - min * 60);
return `${pad(hrs)}:${pad(min)}:${pad(sec)}`;
};
/** @type {(n: number) => string} */
function pad(n) {
return formatSize(n).padStart(2, "0");
}
/** @type {(bits: number) => string} */
CopyProgressPopup._toSpeed = (bits) => {
const [speed, mod] = (() => {
return bits >= 100000000000
? [bits / 1000000000, "Gb"]
: bits >= 100000000
? [bits / 1000000, "Mb"]
: bits >= 100000
? [bits / 1000, "Kb"]
: [bits, "b"];
})();
return `${formatSize(speed)}${mod}`;
};
export default CopyProgressPopup;