mirror of
https://github.com/stashapp/stash.git
synced 2025-12-07 00:43:12 +01:00
Add date & details to gallery card (#1763)
* Add date & details to gallery card Make the gallery card visually consistent with the scenes card. So move the "X images" to a button at the bottom (where tags, performers and scenes are shown as well) and add the date & details to the card.
This commit is contained in:
parent
ba2a79700a
commit
f977d0e18a
3 changed files with 46 additions and 13 deletions
|
|
@ -13,6 +13,7 @@
|
||||||
* Support filtering Movies by Performers. ([#1675](https://github.com/stashapp/stash/pull/1675))
|
* Support filtering Movies by Performers. ([#1675](https://github.com/stashapp/stash/pull/1675))
|
||||||
|
|
||||||
### 🎨 Improvements
|
### 🎨 Improvements
|
||||||
|
* Added date and details to Gallery card, and move image count to icon. ([#1763](https://github.com/stashapp/stash/pull/1763))
|
||||||
* Optimised image thumbnail generation (optionally using `libvips`) and made optional. ([#1655](https://github.com/stashapp/stash/pull/1655))
|
* Optimised image thumbnail generation (optionally using `libvips`) and made optional. ([#1655](https://github.com/stashapp/stash/pull/1655))
|
||||||
* Added missing image table indexes, resulting in a significant performance improvement. ([#1740](https://github.com/stashapp/stash/pull/1740))
|
* Added missing image table indexes, resulting in a significant performance improvement. ([#1740](https://github.com/stashapp/stash/pull/1740))
|
||||||
* Support scraper script logging to specific log levels. ([#1648](https://github.com/stashapp/stash/pull/1648))
|
* Support scraper script logging to specific log levels. ([#1648](https://github.com/stashapp/stash/pull/1648))
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,16 @@ import { Button, ButtonGroup } from "react-bootstrap";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
import { FormattedPlural } from "react-intl";
|
|
||||||
import { useConfiguration } from "src/core/StashService";
|
import { useConfiguration } from "src/core/StashService";
|
||||||
import { GridCard, HoverPopover, Icon, TagLink } from "src/components/Shared";
|
import {
|
||||||
import { TextUtils } from "src/utils";
|
GridCard,
|
||||||
|
HoverPopover,
|
||||||
|
Icon,
|
||||||
|
TagLink,
|
||||||
|
TruncatedText,
|
||||||
|
} from "src/components/Shared";
|
||||||
|
import { PopoverCountButton } from "src/components/Shared/PopoverCountButton";
|
||||||
|
import { NavUtils, TextUtils } from "src/utils";
|
||||||
import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton";
|
import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton";
|
||||||
import { RatingBanner } from "../Shared/RatingBanner";
|
import { RatingBanner } from "../Shared/RatingBanner";
|
||||||
|
|
||||||
|
|
@ -62,6 +68,18 @@ export const GalleryCard: React.FC<IProps> = (props) => {
|
||||||
return <PerformerPopoverButton performers={props.gallery.performers} />;
|
return <PerformerPopoverButton performers={props.gallery.performers} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function maybeRenderImagesPopoverButton() {
|
||||||
|
if (!props.gallery.image_count) return;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PopoverCountButton
|
||||||
|
type="image"
|
||||||
|
count={props.gallery.image_count}
|
||||||
|
url={NavUtils.makeGalleryImagesUrl(props.gallery)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function maybeRenderSceneStudioOverlay() {
|
function maybeRenderSceneStudioOverlay() {
|
||||||
if (!props.gallery.studio) return;
|
if (!props.gallery.studio) return;
|
||||||
|
|
||||||
|
|
@ -99,12 +117,14 @@ export const GalleryCard: React.FC<IProps> = (props) => {
|
||||||
props.gallery.scenes.length > 0 ||
|
props.gallery.scenes.length > 0 ||
|
||||||
props.gallery.performers.length > 0 ||
|
props.gallery.performers.length > 0 ||
|
||||||
props.gallery.tags.length > 0 ||
|
props.gallery.tags.length > 0 ||
|
||||||
props.gallery.organized
|
props.gallery.organized ||
|
||||||
|
props.gallery.image_count > 0
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<hr />
|
<hr />
|
||||||
<ButtonGroup className="card-popovers">
|
<ButtonGroup className="card-popovers">
|
||||||
|
{maybeRenderImagesPopoverButton()}
|
||||||
{maybeRenderTagPopoverButton()}
|
{maybeRenderTagPopoverButton()}
|
||||||
{maybeRenderPerformerPopoverButton()}
|
{maybeRenderPerformerPopoverButton()}
|
||||||
{maybeRenderScenePopoverButton()}
|
{maybeRenderScenePopoverButton()}
|
||||||
|
|
@ -140,15 +160,10 @@ export const GalleryCard: React.FC<IProps> = (props) => {
|
||||||
overlays={maybeRenderSceneStudioOverlay()}
|
overlays={maybeRenderSceneStudioOverlay()}
|
||||||
details={
|
details={
|
||||||
<>
|
<>
|
||||||
<span>
|
<span>{props.gallery.date}</span>
|
||||||
{props.gallery.image_count}
|
<p>
|
||||||
<FormattedPlural
|
<TruncatedText text={props.gallery.details} lineCount={3} />
|
||||||
value={props.gallery.image_count}
|
</p>
|
||||||
one="image"
|
|
||||||
other="images"
|
|
||||||
/>
|
|
||||||
.
|
|
||||||
</span>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
popovers={maybeRenderPopoverButtonGroup()}
|
popovers={maybeRenderPopoverButtonGroup()}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import {
|
||||||
Criterion,
|
Criterion,
|
||||||
CriterionValue,
|
CriterionValue,
|
||||||
} from "src/models/list-filter/criteria/criterion";
|
} from "src/models/list-filter/criteria/criterion";
|
||||||
|
import { GalleriesCriterion } from "src/models/list-filter/criteria/galleries";
|
||||||
|
|
||||||
function addExtraCriteria(
|
function addExtraCriteria(
|
||||||
dest: Criterion<CriterionValue>[],
|
dest: Criterion<CriterionValue>[],
|
||||||
|
|
@ -206,6 +207,21 @@ const makeSceneMarkerUrl = (
|
||||||
return `/scenes/${sceneMarker.scene.id}?t=${sceneMarker.seconds}`;
|
return `/scenes/${sceneMarker.scene.id}?t=${sceneMarker.seconds}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const makeGalleryImagesUrl = (
|
||||||
|
gallery: Partial<GQL.GalleryDataFragment | GQL.SlimGalleryDataFragment>,
|
||||||
|
extraCriteria?: Criterion<CriterionValue>[]
|
||||||
|
) => {
|
||||||
|
if (!gallery.id) return "#";
|
||||||
|
const filter = new ListFilterModel(GQL.FilterMode.Images);
|
||||||
|
const criterion = new GalleriesCriterion();
|
||||||
|
criterion.value = [
|
||||||
|
{ id: gallery.id, label: gallery.title || `Gallery ${gallery.id}` },
|
||||||
|
];
|
||||||
|
filter.criteria.push(criterion);
|
||||||
|
addExtraCriteria(filter.criteria, extraCriteria);
|
||||||
|
return `/images?${filter.makeQueryParameters()}`;
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
makePerformerScenesUrl,
|
makePerformerScenesUrl,
|
||||||
makePerformerImagesUrl,
|
makePerformerImagesUrl,
|
||||||
|
|
@ -222,4 +238,5 @@ export default {
|
||||||
makeSceneMarkerUrl,
|
makeSceneMarkerUrl,
|
||||||
makeMovieScenesUrl,
|
makeMovieScenesUrl,
|
||||||
makeChildStudiosUrl,
|
makeChildStudiosUrl,
|
||||||
|
makeGalleryImagesUrl,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue