mirror of
https://github.com/stashapp/stash.git
synced 2025-12-07 17:02:38 +01:00
Add FileSize component and refactor file size rendering in various components (#5695)
This commit is contained in:
parent
a391fa4345
commit
ce2d779dbc
9 changed files with 53 additions and 125 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Accordion, Button, Card } from "react-bootstrap";
|
import { Accordion, Button, Card } from "react-bootstrap";
|
||||||
import { FormattedMessage, FormattedNumber, FormattedTime } from "react-intl";
|
import { FormattedMessage, FormattedTime } from "react-intl";
|
||||||
import { TruncatedText } from "src/components/Shared/TruncatedText";
|
import { TruncatedText } from "src/components/Shared/TruncatedText";
|
||||||
import { DeleteFilesDialog } from "src/components/Shared/DeleteFilesDialog";
|
import { DeleteFilesDialog } from "src/components/Shared/DeleteFilesDialog";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
|
|
@ -8,6 +8,7 @@ import { mutateImageSetPrimaryFile } from "src/core/StashService";
|
||||||
import { useToast } from "src/hooks/Toast";
|
import { useToast } from "src/hooks/Toast";
|
||||||
import TextUtils from "src/utils/text";
|
import TextUtils from "src/utils/text";
|
||||||
import { TextField, URLField, URLsField } from "src/utils/field";
|
import { TextField, URLField, URLsField } from "src/utils/field";
|
||||||
|
import { FileSize } from "src/components/Shared/FileSize";
|
||||||
|
|
||||||
interface IFileInfoPanelProps {
|
interface IFileInfoPanelProps {
|
||||||
file: GQL.ImageFileDataFragment | GQL.VideoFileDataFragment;
|
file: GQL.ImageFileDataFragment | GQL.VideoFileDataFragment;
|
||||||
|
|
@ -21,29 +22,6 @@ interface IFileInfoPanelProps {
|
||||||
const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
||||||
props: IFileInfoPanelProps
|
props: IFileInfoPanelProps
|
||||||
) => {
|
) => {
|
||||||
function renderFileSize() {
|
|
||||||
if (props.file.size === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { size, unit } = TextUtils.fileSize(props.file.size ?? 0);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TextField id="filesize">
|
|
||||||
<span className="text-truncate">
|
|
||||||
<FormattedNumber
|
|
||||||
value={size}
|
|
||||||
// eslint-disable-next-line react/style-prop-object
|
|
||||||
style="unit"
|
|
||||||
unit={unit}
|
|
||||||
unitDisplay="narrow"
|
|
||||||
maximumFractionDigits={2}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</TextField>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const checksum = props.file.fingerprints.find((f) => f.type === "md5");
|
const checksum = props.file.fingerprints.find((f) => f.type === "md5");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -64,7 +42,11 @@ const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
||||||
value={`file://${props.file.path}`}
|
value={`file://${props.file.path}`}
|
||||||
truncate
|
truncate
|
||||||
/>
|
/>
|
||||||
{renderFileSize()}
|
<TextField id="filesize">
|
||||||
|
<span className="text-truncate">
|
||||||
|
<FileSize size={props.file.size} />
|
||||||
|
</span>
|
||||||
|
</TextField>
|
||||||
<TextField id="file_mod_time">
|
<TextField id="file_mod_time">
|
||||||
<FormattedTime
|
<FormattedTime
|
||||||
dateStyle="medium"
|
dateStyle="medium"
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ import "flexbin/flexbin.css";
|
||||||
import Gallery from "react-photo-gallery";
|
import Gallery from "react-photo-gallery";
|
||||||
import { ExportDialog } from "../Shared/ExportDialog";
|
import { ExportDialog } from "../Shared/ExportDialog";
|
||||||
import { objectTitle } from "src/core/files";
|
import { objectTitle } from "src/core/files";
|
||||||
import TextUtils from "src/utils/text";
|
|
||||||
import { ConfigurationContext } from "src/hooks/Config";
|
import { ConfigurationContext } from "src/hooks/Config";
|
||||||
import { ImageGridCard } from "./ImageGridCard";
|
import { ImageGridCard } from "./ImageGridCard";
|
||||||
import { View } from "../List/views";
|
import { View } from "../List/views";
|
||||||
import { IItemListOperation } from "../List/FilteredListToolbar";
|
import { IItemListOperation } from "../List/FilteredListToolbar";
|
||||||
|
import { FileSize } from "../Shared/FileSize";
|
||||||
|
|
||||||
interface IImageWallProps {
|
interface IImageWallProps {
|
||||||
images: GQL.SlimImageDataFragment[];
|
images: GQL.SlimImageDataFragment[];
|
||||||
|
|
@ -230,7 +230,6 @@ function getCount(result: GQL.FindImagesQueryResult) {
|
||||||
function renderMetadataByline(result: GQL.FindImagesQueryResult) {
|
function renderMetadataByline(result: GQL.FindImagesQueryResult) {
|
||||||
const megapixels = result?.data?.findImages?.megapixels;
|
const megapixels = result?.data?.findImages?.megapixels;
|
||||||
const size = result?.data?.findImages?.filesize;
|
const size = result?.data?.findImages?.filesize;
|
||||||
const filesize = size ? TextUtils.fileSize(size) : undefined;
|
|
||||||
|
|
||||||
if (!megapixels && !size) {
|
if (!megapixels && !size) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -247,15 +246,9 @@ function renderMetadataByline(result: GQL.FindImagesQueryResult) {
|
||||||
</span>
|
</span>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{separator}
|
{separator}
|
||||||
{size && filesize ? (
|
{size ? (
|
||||||
<span className="images-size">
|
<span className="images-size">
|
||||||
<FormattedNumber
|
<FileSize size={size} />
|
||||||
value={filesize.size}
|
|
||||||
maximumFractionDigits={TextUtils.fileSizeFractionalDigits(
|
|
||||||
filesize.unit
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{` ${TextUtils.formatFileSizeUnit(filesize.unit)}`}
|
|
||||||
</span>
|
</span>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ import {
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { SceneMergeModal } from "../Scenes/SceneMergeDialog";
|
import { SceneMergeModal } from "../Scenes/SceneMergeDialog";
|
||||||
import { objectTitle } from "src/core/files";
|
import { objectTitle } from "src/core/files";
|
||||||
|
import { FileSize } from "../Shared/FileSize";
|
||||||
|
|
||||||
const CLASSNAME = "duplicate-checker";
|
const CLASSNAME = "duplicate-checker";
|
||||||
|
|
||||||
|
|
@ -326,19 +327,6 @@ export const SceneDuplicateChecker: React.FC = () => {
|
||||||
resetCheckboxSelection();
|
resetCheckboxSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderFilesize = (filesize: number | null | undefined) => {
|
|
||||||
const { size: parsedSize, unit } = TextUtils.fileSize(filesize ?? 0);
|
|
||||||
return (
|
|
||||||
<FormattedNumber
|
|
||||||
value={parsedSize}
|
|
||||||
style="unit"
|
|
||||||
unit={unit}
|
|
||||||
unitDisplay="narrow"
|
|
||||||
maximumFractionDigits={2}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function maybeRenderMissingPhashWarning() {
|
function maybeRenderMissingPhashWarning() {
|
||||||
const missingPhashes = missingPhash?.findScenes.count ?? 0;
|
const missingPhashes = missingPhash?.findScenes.count ?? 0;
|
||||||
if (missingPhashes > 0) {
|
if (missingPhashes > 0) {
|
||||||
|
|
@ -917,7 +905,9 @@ export const SceneDuplicateChecker: React.FC = () => {
|
||||||
{file?.duration &&
|
{file?.duration &&
|
||||||
TextUtils.secondsToTimestamp(file.duration)}
|
TextUtils.secondsToTimestamp(file.duration)}
|
||||||
</td>
|
</td>
|
||||||
<td>{renderFilesize(file?.size ?? 0)}</td>
|
<td>
|
||||||
|
<FileSize size={file?.size ?? 0} />
|
||||||
|
</td>
|
||||||
<td>{`${file?.width ?? 0}x${file?.height ?? 0}`}</td>
|
<td>{`${file?.width ?? 0}x${file?.height ?? 0}`}</td>
|
||||||
<td>
|
<td>
|
||||||
<FormattedNumber
|
<FormattedNumber
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import { ConfigurationContext } from "src/hooks/Config";
|
||||||
import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton";
|
import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton";
|
||||||
import { GridCard, calculateCardWidth } from "../Shared/GridCard/GridCard";
|
import { GridCard, calculateCardWidth } from "../Shared/GridCard/GridCard";
|
||||||
import { RatingBanner } from "../Shared/RatingBanner";
|
import { RatingBanner } from "../Shared/RatingBanner";
|
||||||
import { FormattedMessage, FormattedNumber } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import {
|
import {
|
||||||
faBox,
|
faBox,
|
||||||
faCopy,
|
faCopy,
|
||||||
|
|
@ -30,6 +30,7 @@ import { PatchComponent } from "src/patch";
|
||||||
import ScreenUtils from "src/utils/screen";
|
import ScreenUtils from "src/utils/screen";
|
||||||
import { StudioOverlay } from "../Shared/GridCard/StudioOverlay";
|
import { StudioOverlay } from "../Shared/GridCard/StudioOverlay";
|
||||||
import { GroupTag } from "../Groups/GroupTag";
|
import { GroupTag } from "../Groups/GroupTag";
|
||||||
|
import { FileSize } from "../Shared/FileSize";
|
||||||
|
|
||||||
interface IScenePreviewProps {
|
interface IScenePreviewProps {
|
||||||
isPortrait: boolean;
|
isPortrait: boolean;
|
||||||
|
|
@ -362,21 +363,11 @@ const SceneCardImage = PatchComponent(
|
||||||
);
|
);
|
||||||
|
|
||||||
function maybeRenderSceneSpecsOverlay() {
|
function maybeRenderSceneSpecsOverlay() {
|
||||||
let sizeObj = null;
|
|
||||||
if (file?.size) {
|
|
||||||
sizeObj = TextUtils.fileSize(file.size);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div className="scene-specs-overlay">
|
<div className="scene-specs-overlay">
|
||||||
{sizeObj != null ? (
|
{file?.size !== undefined ? (
|
||||||
<span className="overlay-filesize extra-scene-info">
|
<span className="overlay-filesize extra-scene-info">
|
||||||
<FormattedNumber
|
<FileSize size={file.size} />
|
||||||
value={sizeObj.size}
|
|
||||||
maximumFractionDigits={TextUtils.fileSizeFractionalDigits(
|
|
||||||
sizeObj.unit
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{TextUtils.formatFileSizeUnit(sizeObj.unit)}
|
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import TextUtils from "src/utils/text";
|
||||||
import { TextField, URLField, URLsField } from "src/utils/field";
|
import { TextField, URLField, URLsField } from "src/utils/field";
|
||||||
import { StashIDPill } from "src/components/Shared/StashID";
|
import { StashIDPill } from "src/components/Shared/StashID";
|
||||||
import { PatchComponent } from "../../../patch";
|
import { PatchComponent } from "../../../patch";
|
||||||
|
import { FileSize } from "src/components/Shared/FileSize";
|
||||||
|
|
||||||
interface IFileInfoPanelProps {
|
interface IFileInfoPanelProps {
|
||||||
sceneID: string;
|
sceneID: string;
|
||||||
|
|
@ -36,25 +37,6 @@ const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
function renderFileSize() {
|
|
||||||
const { size, unit } = TextUtils.fileSize(props.file.size);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TextField id="filesize">
|
|
||||||
<span className="text-truncate">
|
|
||||||
<FormattedNumber
|
|
||||||
value={size}
|
|
||||||
// eslint-disable-next-line react/style-prop-object
|
|
||||||
style="unit"
|
|
||||||
unit={unit}
|
|
||||||
unitDisplay="narrow"
|
|
||||||
maximumFractionDigits={2}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</TextField>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO - generalise fingerprints
|
// TODO - generalise fingerprints
|
||||||
const oshash = props.file.fingerprints.find((f) => f.type === "oshash");
|
const oshash = props.file.fingerprints.find((f) => f.type === "oshash");
|
||||||
const phash = props.file.fingerprints.find((f) => f.type === "phash");
|
const phash = props.file.fingerprints.find((f) => f.type === "phash");
|
||||||
|
|
@ -94,7 +76,11 @@ const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
||||||
value={`file://${props.file.path}`}
|
value={`file://${props.file.path}`}
|
||||||
truncate
|
truncate
|
||||||
/>
|
/>
|
||||||
{renderFileSize()}
|
<TextField id="filesize">
|
||||||
|
<span className="text-truncate">
|
||||||
|
<FileSize size={props.file.size} />
|
||||||
|
</span>
|
||||||
|
</TextField>
|
||||||
<TextField id="file_mod_time">
|
<TextField id="file_mod_time">
|
||||||
<FormattedTime
|
<FormattedTime
|
||||||
dateStyle="medium"
|
dateStyle="medium"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import cloneDeep from "lodash-es/cloneDeep";
|
import cloneDeep from "lodash-es/cloneDeep";
|
||||||
import { FormattedNumber, useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import Mousetrap from "mousetrap";
|
import Mousetrap from "mousetrap";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
|
|
@ -25,6 +25,7 @@ import { SceneMergeModal } from "./SceneMergeDialog";
|
||||||
import { objectTitle } from "src/core/files";
|
import { objectTitle } from "src/core/files";
|
||||||
import TextUtils from "src/utils/text";
|
import TextUtils from "src/utils/text";
|
||||||
import { View } from "../List/views";
|
import { View } from "../List/views";
|
||||||
|
import { FileSize } from "../Shared/FileSize";
|
||||||
|
|
||||||
function getItems(result: GQL.FindScenesQueryResult) {
|
function getItems(result: GQL.FindScenesQueryResult) {
|
||||||
return result?.data?.findScenes?.scenes ?? [];
|
return result?.data?.findScenes?.scenes ?? [];
|
||||||
|
|
@ -37,7 +38,6 @@ function getCount(result: GQL.FindScenesQueryResult) {
|
||||||
function renderMetadataByline(result: GQL.FindScenesQueryResult) {
|
function renderMetadataByline(result: GQL.FindScenesQueryResult) {
|
||||||
const duration = result?.data?.findScenes?.duration;
|
const duration = result?.data?.findScenes?.duration;
|
||||||
const size = result?.data?.findScenes?.filesize;
|
const size = result?.data?.findScenes?.filesize;
|
||||||
const filesize = size ? TextUtils.fileSize(size) : undefined;
|
|
||||||
|
|
||||||
if (!duration && !size) {
|
if (!duration && !size) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -54,15 +54,9 @@ function renderMetadataByline(result: GQL.FindScenesQueryResult) {
|
||||||
</span>
|
</span>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{separator}
|
{separator}
|
||||||
{size && filesize ? (
|
{size ? (
|
||||||
<span className="scenes-size">
|
<span className="scenes-size">
|
||||||
<FormattedNumber
|
<FileSize size={size} />
|
||||||
value={filesize.size}
|
|
||||||
maximumFractionDigits={TextUtils.fileSizeFractionalDigits(
|
|
||||||
filesize.unit
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{` ${TextUtils.formatFileSizeUnit(filesize.unit)}`}
|
|
||||||
</span>
|
</span>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
import NavUtils from "src/utils/navigation";
|
import NavUtils from "src/utils/navigation";
|
||||||
import TextUtils from "src/utils/text";
|
import TextUtils from "src/utils/text";
|
||||||
import { FormattedMessage, FormattedNumber, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import { objectTitle } from "src/core/files";
|
import { objectTitle } from "src/core/files";
|
||||||
import { galleryTitle } from "src/core/galleries";
|
import { galleryTitle } from "src/core/galleries";
|
||||||
import SceneQueue from "src/models/sceneQueue";
|
import SceneQueue from "src/models/sceneQueue";
|
||||||
|
|
@ -11,6 +11,7 @@ import { RatingSystem } from "../Shared/Rating/RatingSystem";
|
||||||
import { useSceneUpdate } from "src/core/StashService";
|
import { useSceneUpdate } from "src/core/StashService";
|
||||||
import { IColumn, ListTable } from "../List/ListTable";
|
import { IColumn, ListTable } from "../List/ListTable";
|
||||||
import { useTableColumns } from "src/hooks/useTableColumns";
|
import { useTableColumns } from "src/hooks/useTableColumns";
|
||||||
|
import { FileSize } from "../Shared/FileSize";
|
||||||
|
|
||||||
interface ISceneListTableProps {
|
interface ISceneListTableProps {
|
||||||
scenes: GQL.SlimSceneDataFragment[];
|
scenes: GQL.SlimSceneDataFragment[];
|
||||||
|
|
@ -169,24 +170,12 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
|
|
||||||
function renderFileSize(file: { size: number | undefined }) {
|
|
||||||
const { size, unit } = TextUtils.fileSize(file.size);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormattedNumber
|
|
||||||
value={size}
|
|
||||||
style="unit"
|
|
||||||
unit={unit}
|
|
||||||
unitDisplay="narrow"
|
|
||||||
maximumFractionDigits={2}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const FileSizeCell = (scene: GQL.SlimSceneDataFragment) => (
|
const FileSizeCell = (scene: GQL.SlimSceneDataFragment) => (
|
||||||
<ul className="comma-list">
|
<ul className="comma-list">
|
||||||
{scene.files.map((file) => (
|
{scene.files.map((file) => (
|
||||||
<li key={file.id}>{renderFileSize(file)}</li>
|
<li key={file.id}>
|
||||||
|
<FileSize size={file.size} />
|
||||||
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
17
ui/v2.5/src/components/Shared/FileSize.tsx
Normal file
17
ui/v2.5/src/components/Shared/FileSize.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedNumber } from "react-intl";
|
||||||
|
import TextUtils from "src/utils/text";
|
||||||
|
|
||||||
|
export const FileSize: React.FC<{ size: number }> = ({ size: fileSize }) => {
|
||||||
|
const { size, unit } = TextUtils.fileSize(fileSize);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FormattedNumber
|
||||||
|
value={size}
|
||||||
|
maximumFractionDigits={TextUtils.fileSizeFractionalDigits(unit)}
|
||||||
|
/>
|
||||||
|
{` ${TextUtils.formatFileSizeUnit(unit)}`}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -3,6 +3,7 @@ import { useStats } from "src/core/StashService";
|
||||||
import { FormattedMessage, FormattedNumber } from "react-intl";
|
import { FormattedMessage, FormattedNumber } from "react-intl";
|
||||||
import { LoadingIndicator } from "src/components/Shared/LoadingIndicator";
|
import { LoadingIndicator } from "src/components/Shared/LoadingIndicator";
|
||||||
import TextUtils from "src/utils/text";
|
import TextUtils from "src/utils/text";
|
||||||
|
import { FileSize } from "./Shared/FileSize";
|
||||||
|
|
||||||
export const Stats: React.FC = () => {
|
export const Stats: React.FC = () => {
|
||||||
const { data, error, loading } = useStats();
|
const { data, error, loading } = useStats();
|
||||||
|
|
@ -10,9 +11,6 @@ export const Stats: React.FC = () => {
|
||||||
if (error) return <span>{error.message}</span>;
|
if (error) return <span>{error.message}</span>;
|
||||||
if (loading || !data) return <LoadingIndicator />;
|
if (loading || !data) return <LoadingIndicator />;
|
||||||
|
|
||||||
const scenesSize = TextUtils.fileSize(data.stats.scenes_size);
|
|
||||||
const imagesSize = TextUtils.fileSize(data.stats.images_size);
|
|
||||||
|
|
||||||
const scenesDuration = TextUtils.secondsAsTimeString(
|
const scenesDuration = TextUtils.secondsAsTimeString(
|
||||||
data.stats.scenes_duration,
|
data.stats.scenes_duration,
|
||||||
3
|
3
|
||||||
|
|
@ -28,13 +26,7 @@ export const Stats: React.FC = () => {
|
||||||
<div className="col col-sm-8 m-sm-auto row stats">
|
<div className="col col-sm-8 m-sm-auto row stats">
|
||||||
<div className="stats-element">
|
<div className="stats-element">
|
||||||
<p className="title">
|
<p className="title">
|
||||||
<FormattedNumber
|
<FileSize size={data.stats.scenes_size} />
|
||||||
value={scenesSize.size}
|
|
||||||
maximumFractionDigits={TextUtils.fileSizeFractionalDigits(
|
|
||||||
scenesSize.unit
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{` ${TextUtils.formatFileSizeUnit(scenesSize.unit)}`}
|
|
||||||
</p>
|
</p>
|
||||||
<p className="heading">
|
<p className="heading">
|
||||||
<FormattedMessage id="stats.scenes_size" />
|
<FormattedMessage id="stats.scenes_size" />
|
||||||
|
|
@ -74,13 +66,7 @@ export const Stats: React.FC = () => {
|
||||||
<div className="col col-sm-8 m-sm-auto row stats">
|
<div className="col col-sm-8 m-sm-auto row stats">
|
||||||
<div className="stats-element">
|
<div className="stats-element">
|
||||||
<p className="title">
|
<p className="title">
|
||||||
<FormattedNumber
|
<FileSize size={data.stats.images_size} />
|
||||||
value={imagesSize.size}
|
|
||||||
maximumFractionDigits={TextUtils.fileSizeFractionalDigits(
|
|
||||||
imagesSize.unit
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
{` ${TextUtils.formatFileSizeUnit(imagesSize.unit)}`}
|
|
||||||
</p>
|
</p>
|
||||||
<p className="heading">
|
<p className="heading">
|
||||||
<FormattedMessage id="stats.image_size" />
|
<FormattedMessage id="stats.image_size" />
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue