Add Gender Icons to Performers (#2179)

This commit is contained in:
kermieisinthehouse 2022-01-03 20:09:03 -08:00 committed by GitHub
parent 34aea876e8
commit 1714efc92f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 88 additions and 9 deletions

View file

@ -1,4 +1,5 @@
### 🎨 Improvements
* Add gender icons to performers. ([#2179](https://github.com/stashapp/stash/pull/2179))
* Add button to test credentials when adding/editing stash-box endpoints. ([#2173](https://github.com/stashapp/stash/pull/2173))
* Show counts on list tabs in Performer, Studio and Tag pages. ([#2169](https://github.com/stashapp/stash/pull/2169))

View file

@ -0,0 +1,36 @@
import React from "react";
import {
faVenus,
faTransgenderAlt,
faMars,
} from "@fortawesome/free-solid-svg-icons";
import * as GQL from "src/core/generated-graphql";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useIntl } from "react-intl";
interface IIconProps {
gender?: GQL.Maybe<GQL.GenderEnum>;
className?: string;
}
const GenderIcon: React.FC<IIconProps> = ({ gender, className }) => {
const intl = useIntl();
if (gender) {
const icon =
gender === GQL.GenderEnum.Male
? faMars
: gender === GQL.GenderEnum.Female
? faVenus
: faTransgenderAlt;
return (
<FontAwesomeIcon
title={intl.formatMessage({ id: "gender." + gender })}
className={className}
icon={icon}
/>
);
}
return null;
};
export default GenderIcon;

View file

@ -16,6 +16,7 @@ import {
CriterionValue,
} from "src/models/list-filter/criteria/criterion";
import { PopoverCountButton } from "../Shared/PopoverCountButton";
import GenderIcon from "./GenderIcon";
export interface IPerformerCardExtraCriteria {
scenes: Criterion<CriterionValue>[];
@ -183,6 +184,9 @@ export const PerformerCard: React.FC<IPerformerCardProps> = ({
<GridCard
className="performer-card"
url={`/performers/${performer.id}`}
pretitleIcon={
<GenderIcon className="gender-icon" gender={performer.gender} />
}
title={performer.name ?? ""}
image={
<>

View file

@ -27,6 +27,7 @@ import { PerformerGalleriesPanel } from "./PerformerGalleriesPanel";
import { PerformerMoviesPanel } from "./PerformerMoviesPanel";
import { PerformerImagesPanel } from "./PerformerImagesPanel";
import { PerformerEditPanel } from "./PerformerEditPanel";
import GenderIcon from "../GenderIcon";
interface IProps {
performer: GQL.PerformerDataFragment;
@ -357,6 +358,10 @@ const PerformerPage: React.FC<IProps> = ({ performer }) => {
<div className="row">
<div className="performer-head col">
<h2>
<GenderIcon
gender={performer.gender}
className="gender-icon mr-2"
/>
<CountryFlag country={performer.country} className="mr-2" />
{performer.name}
{renderIcons()}

View file

@ -4,7 +4,6 @@ import { TagLink } from "src/components/Shared";
import * as GQL from "src/core/generated-graphql";
import { TextUtils } from "src/utils";
import { TextField, URLField } from "src/utils/field";
import { genderToString } from "src/utils/gender";
interface IPerformerDetails {
performer: GQL.PerformerDataFragment;
@ -97,8 +96,12 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
return (
<dl className="details-list">
<TextField
id="gender"
value={genderToString(performer.gender ?? undefined)}
id="gender.gender"
value={
performer.gender
? intl.formatMessage({ id: "gender." + performer.gender })
: undefined
}
/>
<TextField
id="birthdate"

View file

@ -880,7 +880,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
<Form.Group as={Row}>
<Form.Label column xs={labelXS} xl={labelXL}>
<FormattedMessage id="gender" />
<FormattedMessage id="gender.gender" />
</Form.Label>
<Col xs="auto">
<Form.Control

View file

@ -429,7 +429,7 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
onChange={(value) => setAliases(value)}
/>
{renderScrapedGenderRow(
intl.formatMessage({ id: "gender" }),
intl.formatMessage({ id: "gender.gender" }),
gender,
(value) => setGender(value)
)}

View file

@ -114,3 +114,21 @@
}
}
}
.flex-aligned {
align-items: center;
column-gap: 0.5rem;
display: flex;
}
.fa-mars {
color: #89cff0;
}
.fa-venus {
color: #f38cac;
}
.fa-transgender-alt {
color: #c8a2c8;
}

View file

@ -9,6 +9,7 @@ interface ICardProps {
linkClassName?: string;
thumbnailSectionClassName?: string;
url: string;
pretitleIcon?: JSX.Element;
title: string;
image: JSX.Element;
details?: JSX.Element;
@ -106,7 +107,8 @@ export const GridCard: React.FC<ICardProps> = (props: ICardProps) => {
{maybeRenderInteractiveHeatmap()}
<div className="card-section">
<Link to={props.url} onClick={handleImageClick}>
<h5 className="card-section-title">
<h5 className="card-section-title flex-aligned">
{props.pretitleIcon}
<TruncatedText text={props.title} lineCount={2} />
</h5>
</Link>

View file

@ -11,7 +11,7 @@ import {
TruncatedText,
} from "src/components/Shared";
import * as GQL from "src/core/generated-graphql";
import { genderToString, stringToGender } from "src/utils/gender";
import { stringToGender } from "src/utils/gender";
interface IPerformerModalProps {
performer: GQL.ScrapedScenePerformerDataFragment;
@ -191,7 +191,9 @@ const PerformerModal: React.FC<IPerformerModalProps> = ({
{renderField("aliases", performer.aliases)}
{renderField(
"gender",
performer.gender ? genderToString(performer.gender) : ""
performer.gender
? intl.formatMessage({ id: "gender." + performer.gender })
: ""
)}
{renderField("birthdate", performer.birthdate)}
{renderField("death_date", performer.death_date)}

View file

@ -691,7 +691,15 @@
"galleries": "Galleries",
"gallery": "Gallery",
"gallery_count": "Gallery Count",
"gender": "Gender",
"gender": {
"gender": "Gender",
"MALE": "Male",
"FEMALE": "Female",
"TRANSGENDER_MALE": "Transgender Male",
"TRANSGENDER_FEMALE": "Transgender Female",
"INTERSEX": "Intersex",
"NON_BINARY": "Non-Binary"
},
"hair_color": "Hair Colour",
"hasMarkers": "Has Markers",
"height": "Height",