mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
Display tag and performer image on hover. on the scene edit page (#5739)
* add component for PerformerPopover * show PerformerPopover for performer select values * show TagPopover for tag select values
This commit is contained in:
parent
1d3bc40a6b
commit
3489dca83a
3 changed files with 99 additions and 8 deletions
71
ui/v2.5/src/components/Performers/PerformerPopover.tsx
Normal file
71
ui/v2.5/src/components/Performers/PerformerPopover.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import React from "react";
|
||||
import { ErrorMessage } from "../Shared/ErrorMessage";
|
||||
import { LoadingIndicator } from "../Shared/LoadingIndicator";
|
||||
import { HoverPopover } from "../Shared/HoverPopover";
|
||||
import { useFindPerformer } from "../../core/StashService";
|
||||
import { PerformerCard } from "./PerformerCard";
|
||||
import { ConfigurationContext } from "../../hooks/Config";
|
||||
import { Placement } from "react-bootstrap/esm/Overlay";
|
||||
|
||||
interface IPeromerPopoverCardProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export const PerformerPopoverCard: React.FC<IPeromerPopoverCardProps> = ({
|
||||
id,
|
||||
}) => {
|
||||
const { data, loading, error } = useFindPerformer(id);
|
||||
|
||||
if (loading)
|
||||
return (
|
||||
<div className="tag-popover-card-placeholder">
|
||||
<LoadingIndicator card={true} message={""} />
|
||||
</div>
|
||||
);
|
||||
if (error) return <ErrorMessage error={error.message} />;
|
||||
if (!data?.findPerformer)
|
||||
return <ErrorMessage error={`No tag found with id ${id}.`} />;
|
||||
|
||||
const performer = data.findPerformer;
|
||||
|
||||
return (
|
||||
<div className="tag-popover-card">
|
||||
<PerformerCard performer={performer} zoomIndex={0} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface IPeroformerPopoverProps {
|
||||
id: string;
|
||||
hide?: boolean;
|
||||
placement?: Placement;
|
||||
target?: React.RefObject<HTMLElement>;
|
||||
}
|
||||
|
||||
export const PerformerPopover: React.FC<IPeroformerPopoverProps> = ({
|
||||
id,
|
||||
hide,
|
||||
children,
|
||||
placement = "top",
|
||||
target,
|
||||
}) => {
|
||||
const { configuration: config } = React.useContext(ConfigurationContext);
|
||||
|
||||
const showPerformerCardOnHover = config?.ui.showTagCardOnHover ?? true;
|
||||
|
||||
if (hide || !showPerformerCardOnHover) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<HoverPopover
|
||||
target={target}
|
||||
placement={placement}
|
||||
enterDelay={500}
|
||||
leaveDelay={100}
|
||||
content={<PerformerPopoverCard id={id} />}
|
||||
>
|
||||
{children}
|
||||
</HoverPopover>
|
||||
);
|
||||
};
|
||||
|
|
@ -30,6 +30,8 @@ import { sortByRelevance } from "src/utils/query";
|
|||
import { PatchComponent, PatchFunction } from "src/patch";
|
||||
import { TruncatedText } from "../Shared/TruncatedText";
|
||||
import TextUtils from "src/utils/text";
|
||||
import { PerformerPopover } from "./PerformerPopover";
|
||||
import { Placement } from "react-bootstrap/esm/Overlay";
|
||||
|
||||
export type SelectObject = {
|
||||
id: string;
|
||||
|
|
@ -71,7 +73,12 @@ const performerSelectSort = PatchFunction(
|
|||
);
|
||||
|
||||
const _PerformerSelect: React.FC<
|
||||
IFilterProps & IFilterValueProps<Performer> & { ageFromDate?: string | null }
|
||||
IFilterProps &
|
||||
IFilterValueProps<Performer> & {
|
||||
ageFromDate?: string | null;
|
||||
hoverPlacementLabel?: Placement;
|
||||
hoverPlacementOptions?: Placement;
|
||||
}
|
||||
> = (props) => {
|
||||
const [createPerformer] = usePerformerCreate();
|
||||
|
||||
|
|
@ -201,12 +208,17 @@ const _PerformerSelect: React.FC<
|
|||
thisOptionProps = {
|
||||
...optionProps,
|
||||
children: (
|
||||
<span className="performer-select-value">
|
||||
<span>{object.name}</span>
|
||||
{object.disambiguation && (
|
||||
<span className="performer-disambiguation">{` (${object.disambiguation})`}</span>
|
||||
)}
|
||||
</span>
|
||||
<PerformerPopover
|
||||
id={object.id}
|
||||
placement={props.hoverPlacementLabel ?? "top"}
|
||||
>
|
||||
<span className="performer-select-value">
|
||||
<span>{object.name}</span>
|
||||
{object.disambiguation && (
|
||||
<span className="performer-disambiguation">{` (${object.disambiguation})`}</span>
|
||||
)}
|
||||
</span>
|
||||
</PerformerPopover>
|
||||
),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ const tagSelectSort = PatchFunction("TagSelect.sort", sortTagsByRelevance);
|
|||
export type TagSelectProps = IFilterProps &
|
||||
IFilterValueProps<Tag> & {
|
||||
hoverPlacement?: Placement;
|
||||
hoverPlacementLabel?: Placement;
|
||||
excludeIds?: string[];
|
||||
};
|
||||
|
||||
|
|
@ -151,7 +152,14 @@ const _TagSelect: React.FC<TagSelectProps> = (props) => {
|
|||
|
||||
thisOptionProps = {
|
||||
...optionProps,
|
||||
children: object.name,
|
||||
children: (
|
||||
<TagPopover
|
||||
id={object.id}
|
||||
placement={props.hoverPlacementLabel ?? "top"}
|
||||
>
|
||||
<span>{object.name}</span>
|
||||
</TagPopover>
|
||||
),
|
||||
};
|
||||
|
||||
return <reactSelectComponents.MultiValueLabel {...thisOptionProps} />;
|
||||
|
|
|
|||
Loading…
Reference in a new issue