import React from "react"; import { Link } from "react-router-dom"; import { useIntl } from "react-intl"; import * as GQL from "src/core/generated-graphql"; import NavUtils from "src/utils/navigation"; import TextUtils from "src/utils/text"; import { GridCard } from "../Shared/GridCard/GridCard"; import { CountryFlag } from "../Shared/CountryFlag"; import { HoverPopover } from "../Shared/HoverPopover"; import { Icon } from "../Shared/Icon"; import { TagLink } from "../Shared/TagLink"; import { Button, ButtonGroup } from "react-bootstrap"; import { ModifierCriterion, CriterionValue, } from "src/models/list-filter/criteria/criterion"; import { PopoverCountButton } from "../Shared/PopoverCountButton"; import GenderIcon from "./GenderIcon"; import { faLink, faTag } from "@fortawesome/free-solid-svg-icons"; import { faInstagram, faTwitter } from "@fortawesome/free-brands-svg-icons"; import { RatingBanner } from "../Shared/RatingBanner"; import { usePerformerUpdate } from "src/core/StashService"; import { ILabeledId } from "src/models/list-filter/types"; import { FavoriteIcon } from "../Shared/FavoriteIcon"; import { PatchComponent } from "src/patch"; import { ExternalLinksButton } from "../Shared/ExternalLinksButton"; import { useConfigurationContext } from "src/hooks/Config"; import { OCounterButton } from "../Shared/CountButton"; export interface IPerformerCardExtraCriteria { scenes?: ModifierCriterion[]; images?: ModifierCriterion[]; galleries?: ModifierCriterion[]; groups?: ModifierCriterion[]; performer?: ILabeledId; } interface IPerformerCardProps { performer: GQL.PerformerDataFragment; cardWidth?: number; ageFromDate?: string; selecting?: boolean; selected?: boolean; zoomIndex?: number; onSelectedChanged?: (selected: boolean, shiftKey: boolean) => void; extraCriteria?: IPerformerCardExtraCriteria; } const PerformerCardPopovers: React.FC = PatchComponent( "PerformerCard.Popovers", ({ performer, extraCriteria }) => { function maybeRenderScenesPopoverButton() { if (!performer.scene_count) return; return ( ); } function maybeRenderImagesPopoverButton() { if (!performer.image_count) return; return ( ); } function maybeRenderGalleriesPopoverButton() { if (!performer.gallery_count) return; return ( ); } function maybeRenderOCounter() { if (!performer.o_counter) return; return ; } function maybeRenderTagPopoverButton() { if (performer.tags.length <= 0) return; const popoverContent = performer.tags.map((tag) => ( )); return ( ); } function maybeRenderGroupsPopoverButton() { if (!performer.group_count) return; return ( ); } if ( performer.scene_count || performer.image_count || performer.gallery_count || performer.tags.length > 0 || performer.o_counter || performer.group_count ) { return ( <>
{maybeRenderScenesPopoverButton()} {maybeRenderGroupsPopoverButton()} {maybeRenderImagesPopoverButton()} {maybeRenderGalleriesPopoverButton()} {maybeRenderTagPopoverButton()} {maybeRenderOCounter()} ); } return null; } ); const PerformerCardOverlays: React.FC = PatchComponent( "PerformerCard.Overlays", ({ performer }) => { const { configuration } = useConfigurationContext(); const uiConfig = configuration?.ui; const [updatePerformer] = usePerformerUpdate(); function onToggleFavorite(v: boolean) { if (performer.id) { updatePerformer({ variables: { input: { id: performer.id, favorite: v, }, }, }); } } function maybeRenderRatingBanner() { if (!performer.rating100) { return; } return ; } function maybeRenderFlag() { if (performer.country) { return ( {performer.country} ); } } function maybeRenderLinks() { if (!uiConfig?.showLinksOnPerformerCard) { return; } if (performer.urls && performer.urls.length > 0) { const twitter = performer.urls.filter((u) => u.match(/https?:\/\/(?:www\.)?(?:twitter|x).com\//) ); const instagram = performer.urls.filter((u) => u.match(/https?:\/\/(?:www\.)?instagram.com\//) ); const others = performer.urls.filter( (u) => !twitter.includes(u) && !instagram.includes(u) ); return (
{twitter.length > 0 && ( )} {instagram.length > 0 && ( )} {others.length > 0 && ( )}
); } } return ( <> {maybeRenderRatingBanner()} {maybeRenderLinks()} {maybeRenderFlag()} ); } ); const PerformerCardDetails: React.FC = PatchComponent( "PerformerCard.Details", ({ performer, ageFromDate }) => { const intl = useIntl(); const age = TextUtils.age( performer.birthdate, ageFromDate ?? performer.death_date ); const ageL10nId = ageFromDate ? "media_info.performer_card.age_context" : "media_info.performer_card.age"; const ageL10String = intl.formatMessage({ id: "years_old", defaultMessage: "years old", }); const ageString = intl.formatMessage( { id: ageL10nId }, { age, years_old: ageL10String } ); return ( <> {age !== 0 ? (
{ageString}
) : ( "" )} ); } ); const PerformerCardImage: React.FC = PatchComponent( "PerformerCard.Image", ({ performer }) => { return ( <> {performer.name ); } ); const PerformerCardTitle: React.FC = PatchComponent( "PerformerCard.Title", ({ performer }) => { return (
{performer.name} {performer.disambiguation && ( {` (${performer.disambiguation})`} )}
); } ); export const PerformerCard: React.FC = PatchComponent( "PerformerCard", (props) => { const { performer, cardWidth, selecting, selected, onSelectedChanged, zoomIndex, } = props; return ( } title={} image={} overlays={} details={} popovers={} selected={selected} selecting={selecting} onSelectedChanged={onSelectedChanged} /> ); } );