mirror of https://github.com/stashapp/stash.git
Adding info about duplicate files in various places in the UI (#3054)
* Add counter to File Info where file count > 1 * Add file modification time to File Info panel * Remove duplicate intl keys * Add file count to duplicate checker Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
parent
821587b166
commit
3072333118
|
@ -7,6 +7,7 @@ fragment VideoFileData on VideoFile {
|
|||
id
|
||||
path
|
||||
size
|
||||
mod_time
|
||||
duration
|
||||
video_codec
|
||||
audio_codec
|
||||
|
@ -24,6 +25,7 @@ fragment ImageFileData on ImageFile {
|
|||
id
|
||||
path
|
||||
size
|
||||
mod_time
|
||||
width
|
||||
height
|
||||
fingerprints {
|
||||
|
@ -36,6 +38,7 @@ fragment GalleryFileData on GalleryFile {
|
|||
id
|
||||
path
|
||||
size
|
||||
mod_time
|
||||
fingerprints {
|
||||
type
|
||||
value
|
||||
|
|
|
@ -9,7 +9,12 @@ import {
|
|||
useFindGallery,
|
||||
useGalleryUpdate,
|
||||
} from "src/core/StashService";
|
||||
import { ErrorMessage, LoadingIndicator, Icon } from "src/components/Shared";
|
||||
import {
|
||||
ErrorMessage,
|
||||
LoadingIndicator,
|
||||
Icon,
|
||||
Counter,
|
||||
} from "src/components/Shared";
|
||||
import Mousetrap from "mousetrap";
|
||||
import { useToast } from "src/hooks";
|
||||
import { OrganizedButton } from "src/components/Scenes/SceneDetails/OrganizedButton";
|
||||
|
@ -174,6 +179,9 @@ export const GalleryPage: React.FC<IProps> = ({ gallery }) => {
|
|||
<Nav.Item>
|
||||
<Nav.Link eventKey="gallery-file-info-panel">
|
||||
<FormattedMessage id="file_info" />
|
||||
{gallery.files.length > 1 && (
|
||||
<Counter count={gallery.files.length ?? 0} />
|
||||
)}
|
||||
</Nav.Link>
|
||||
</Nav.Item>
|
||||
) : undefined}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useMemo, useState } from "react";
|
||||
import { Accordion, Button, Card } from "react-bootstrap";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { FormattedMessage, FormattedTime } from "react-intl";
|
||||
import { TruncatedText } from "src/components/Shared";
|
||||
import DeleteFilesDialog from "src/components/Shared/DeleteFilesDialog";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
|
@ -44,6 +44,15 @@ const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
|||
value={`file://${path}`}
|
||||
truncate
|
||||
/>
|
||||
{props.file && (
|
||||
<TextField id="file_mod_time">
|
||||
<FormattedTime
|
||||
dateStyle="medium"
|
||||
timeStyle="medium"
|
||||
value={props.file.mod_time ?? 0}
|
||||
/>
|
||||
</TextField>
|
||||
)}
|
||||
</dl>
|
||||
{props.ofMany && props.onSetPrimaryFile && !props.primary && (
|
||||
<div>
|
||||
|
|
|
@ -11,7 +11,12 @@ import {
|
|||
useImageUpdate,
|
||||
mutateMetadataScan,
|
||||
} from "src/core/StashService";
|
||||
import { ErrorMessage, LoadingIndicator, Icon } from "src/components/Shared";
|
||||
import {
|
||||
ErrorMessage,
|
||||
LoadingIndicator,
|
||||
Icon,
|
||||
Counter,
|
||||
} from "src/components/Shared";
|
||||
import { useToast } from "src/hooks";
|
||||
import * as Mousetrap from "mousetrap";
|
||||
import { OCounterButton } from "src/components/Scenes/SceneDetails/OCounterButton";
|
||||
|
@ -178,6 +183,9 @@ export const Image: React.FC = () => {
|
|||
<Nav.Item>
|
||||
<Nav.Link eventKey="image-file-info-panel">
|
||||
<FormattedMessage id="file_info" />
|
||||
{image.files.length > 1 && (
|
||||
<Counter count={image.files.length ?? 0} />
|
||||
)}
|
||||
</Nav.Link>
|
||||
</Nav.Item>
|
||||
<Nav.Item>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import { Accordion, Button, Card } from "react-bootstrap";
|
||||
import { FormattedMessage, FormattedNumber } from "react-intl";
|
||||
import { FormattedMessage, FormattedNumber, FormattedTime } from "react-intl";
|
||||
import { TruncatedText } from "src/components/Shared";
|
||||
import DeleteFilesDialog from "src/components/Shared/DeleteFilesDialog";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
|
@ -65,6 +65,13 @@ const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
|||
truncate
|
||||
/>
|
||||
{renderFileSize()}
|
||||
<TextField id="file_mod_time">
|
||||
<FormattedTime
|
||||
dateStyle="medium"
|
||||
timeStyle="medium"
|
||||
value={props.file.mod_time ?? 0}
|
||||
/>
|
||||
</TextField>
|
||||
<TextField
|
||||
id="dimensions"
|
||||
value={`${props.file.width} x ${props.file.height}`}
|
||||
|
|
|
@ -31,6 +31,7 @@ import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton";
|
|||
import {
|
||||
faBox,
|
||||
faExclamationTriangle,
|
||||
faFileAlt,
|
||||
faFilm,
|
||||
faImages,
|
||||
faMapMarkerAlt,
|
||||
|
@ -293,6 +294,26 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
);
|
||||
}
|
||||
|
||||
function maybeRenderFileCount(scene: GQL.SlimSceneDataFragment) {
|
||||
if (scene.files.length <= 1) return;
|
||||
|
||||
const popoverContent = (
|
||||
<FormattedMessage
|
||||
id="files_amount"
|
||||
values={{ value: intl.formatNumber(scene.files.length ?? 0) }}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<HoverPopover placement="bottom" content={popoverContent}>
|
||||
<Button className="minimal">
|
||||
<Icon icon={faFileAlt} />
|
||||
<span>{scene.files.length}</span>
|
||||
</Button>
|
||||
</HoverPopover>
|
||||
);
|
||||
}
|
||||
|
||||
function maybeRenderOrganized(scene: GQL.SlimSceneDataFragment) {
|
||||
if (scene.organized) {
|
||||
return (
|
||||
|
@ -313,6 +334,7 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
scene.scene_markers.length > 0 ||
|
||||
scene?.o_counter ||
|
||||
scene.galleries.length > 0 ||
|
||||
scene.files.length > 1 ||
|
||||
scene.organized
|
||||
) {
|
||||
return (
|
||||
|
@ -324,6 +346,7 @@ export const SceneDuplicateChecker: React.FC = () => {
|
|||
{maybeRenderSceneMarkerPopoverButton(scene)}
|
||||
{maybeRenderOCounter(scene)}
|
||||
{maybeRenderGallery(scene)}
|
||||
{maybeRenderFileCount(scene)}
|
||||
{maybeRenderOrganized(scene)}
|
||||
</ButtonGroup>
|
||||
</>
|
||||
|
|
|
@ -58,6 +58,7 @@ const DeleteScenesDialog = lazy(() => import("../DeleteScenesDialog"));
|
|||
const GenerateDialog = lazy(() => import("../../Dialogs/GenerateDialog"));
|
||||
const SceneVideoFilterPanel = lazy(() => import("./SceneVideoFilterPanel"));
|
||||
import { objectPath, objectTitle } from "src/core/files";
|
||||
import { Counter } from "src/components/Shared";
|
||||
|
||||
interface IProps {
|
||||
scene: GQL.SceneDataFragment;
|
||||
|
@ -367,6 +368,9 @@ const ScenePage: React.FC<IProps> = ({
|
|||
<Nav.Item>
|
||||
<Nav.Link eventKey="scene-file-info-panel">
|
||||
<FormattedMessage id="file_info" />
|
||||
{scene.files.length > 1 && (
|
||||
<Counter count={scene.files.length ?? 0} />
|
||||
)}
|
||||
</Nav.Link>
|
||||
</Nav.Item>
|
||||
<Nav.Item>
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import React, { useMemo, useState } from "react";
|
||||
import { Accordion, Button, Card } from "react-bootstrap";
|
||||
import { FormattedMessage, FormattedNumber, useIntl } from "react-intl";
|
||||
import {
|
||||
FormattedMessage,
|
||||
FormattedNumber,
|
||||
FormattedTime,
|
||||
useIntl,
|
||||
} from "react-intl";
|
||||
import { useHistory } from "react-router-dom";
|
||||
import { TruncatedText } from "src/components/Shared";
|
||||
import DeleteFilesDialog from "src/components/Shared/DeleteFilesDialog";
|
||||
|
@ -87,6 +92,13 @@ const FileInfoPanel: React.FC<IFileInfoPanelProps> = (
|
|||
truncate
|
||||
/>
|
||||
{renderFileSize()}
|
||||
<TextField id="file_mod_time">
|
||||
<FormattedTime
|
||||
dateStyle="medium"
|
||||
timeStyle="medium"
|
||||
value={props.file.mod_time ?? 0}
|
||||
/>
|
||||
</TextField>
|
||||
<TextField
|
||||
id="duration"
|
||||
value={TextUtils.secondsToTimestamp(props.file.duration ?? 0)}
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
* Added tag description filter criterion. ([#3011](https://github.com/stashapp/stash/pull/3011))
|
||||
|
||||
### 🎨 Improvements
|
||||
* Added File Modification Time to File Info panels. ([#3054](https://github.com/stashapp/stash/pull/3054))
|
||||
* Added counter to File Info tabs for objects with multiple files. ([#3054](https://github.com/stashapp/stash/pull/3054))
|
||||
* Added file count in Scene Duplicate Checker for scenes with multiple files. ([#3054](https://github.com/stashapp/stash/pull/3054))
|
||||
* Jump back/forward buttons on mobile have been replaced with double-tap gestures on mobile. ([#3120](https://github.com/stashapp/stash/pull/3120))
|
||||
* Added shift- and ctrl-keybinds for seeking for shorter and longer intervals, respectively. ([#3120](https://github.com/stashapp/stash/pull/3120))
|
||||
* Added Estonian and Russian Language translations. Added in-progress Languages for Persian, Ukrainian, Bengali, Thai, Romainian, Hungarian, and Czech.([#3024] (https://github.com/stashapp/stash/pull/3024))
|
||||
|
|
|
@ -535,10 +535,6 @@
|
|||
"description": "The percentage of time in which a scene must be played before its play count is incremented.",
|
||||
"heading": "Minumum Play Percent"
|
||||
},
|
||||
"show_tag_card_on_hover": {
|
||||
"description": "Show tag card when hovering tag badges",
|
||||
"heading": "Tag card tooltips"
|
||||
},
|
||||
"performers": {
|
||||
"options": {
|
||||
"image_location": {
|
||||
|
@ -817,6 +813,7 @@
|
|||
"file_info": "File Info",
|
||||
"file_mod_time": "File Modification Time",
|
||||
"files": "files",
|
||||
"files_amount": "{value} files",
|
||||
"filesize": "File Size",
|
||||
"filter": "Filter",
|
||||
"filter_name": "Filter name",
|
||||
|
@ -1104,7 +1101,6 @@
|
|||
"generating_screenshot": "Generating screenshot…",
|
||||
"merged_scenes": "Merged scenes",
|
||||
"merged_tags": "Merged tags",
|
||||
"rescanning_entity": "Rescanning {count, plural, one {{singularEntity}} other {{pluralEntity}}}…",
|
||||
"reassign_past_tense": "File reassigned",
|
||||
"removed_entity": "Removed {count, plural, one {{singularEntity}} other {{pluralEntity}}}",
|
||||
"rescanning_entity": "Rescanning {count, plural, one {{singularEntity}} other {{pluralEntity}}}…",
|
||||
|
|
Loading…
Reference in New Issue