1 import { c, msgid } from 'ttag';
3 import { BASE_SIZE } from '../constants';
5 export const sizeUnits = {
8 MB: BASE_SIZE * BASE_SIZE,
9 GB: BASE_SIZE * BASE_SIZE * BASE_SIZE,
10 TB: BASE_SIZE * BASE_SIZE * BASE_SIZE * BASE_SIZE,
13 export type SizeUnits = keyof typeof sizeUnits;
15 export const getSizeFormat = (key: SizeUnits, n: number) => {
17 return c('file size format').ngettext(msgid`byte`, `bytes`, n);
20 return c('file size format').t`KB`;
23 return c('file size format').t`MB`;
26 return c('file size format').t`GB`;
29 return c('file size format').t`TB`;
31 throw new Error('Unknown unit');
34 export const getLongSizeFormat = (key: SizeUnits, n: number) => {
36 return c('file size format, long').ngettext(msgid`Byte`, `Bytes`, n);
39 return c('file size format, long').ngettext(msgid`Kilobyte`, `Kilobytes`, n);
42 return c('file size format, long').ngettext(msgid`Megabyte`, `Megabytes`, n);
45 return c('file size format, long').ngettext(msgid`Gigabyte`, `Gigabytes`, n);
48 return c('file size format, long').ngettext(msgid`Terabyte`, `Terabytes`, n);
50 throw new Error('Unknown unit');
53 export const getUnit = (bytes: number): SizeUnits => {
54 if (bytes < sizeUnits.KB) {
58 if (bytes < sizeUnits.MB) {
62 if (bytes < sizeUnits.GB) {
69 const transformTo = ({
78 withoutUnit?: boolean;
79 fractionDigits?: number;
82 const completeValue = bytes / sizeUnits[unit];
84 if (fractionDigits === 0 && !truncate) {
85 value = `${Number(completeValue.toFixed(1))}`;
87 value = completeValue.toFixed(fractionDigits);
89 const suffix = withoutUnit ? '' : ` ${getSizeFormat(unit, Number(value))}`;
91 return value + suffix;
97 fraction: maybeFraction,
102 bytes: number | undefined;
104 withoutUnit?: boolean;
107 const unit = maybeUnit || getUnit(bytes);
108 const fractionDigits = maybeFraction === undefined && unit === 'B' ? 0 : maybeFraction;
109 return transformTo({ bytes, unit, withoutUnit, fractionDigits, truncate });
112 export default humanSize;
115 * shortHumanSize makes the compact size version to the bytes precision. It drops
116 * the fractional part for sizes smaller than gigabyte--only for bigger files
117 * it shows one fractional digit. Examples:
119 * 12 bytes -> 12 bytes
122 * 12.34 GB -> 12.3 GB
124 export const shortHumanSize = (bytes = 0) => {
125 if (bytes < sizeUnits.KB) {
126 return humanSize({ bytes, unit: 'B', truncate: true, fraction: 0 });
128 if (bytes < sizeUnits.GB) {
129 return humanSize({ bytes, truncate: true, fraction: 0 });
131 return humanSize({ bytes, fraction: 1 });
135 * Produces always readable version in bytes. Useful for titles where we
136 * might want to display the exact size.
138 export const bytesSize = (bytes = 0) => {
139 return `${bytes} ${getSizeFormat('B', bytes)}`;