mirror of
https://github.com/stashapp/stash.git
synced 2026-04-27 01:10:55 +02:00
Add Gender Icons to Performers (#2179)
This commit is contained in:
parent
34aea876e8
commit
1714efc92f
11 changed files with 88 additions and 9 deletions
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
36
ui/v2.5/src/components/Performers/GenderIcon.tsx
Normal file
36
ui/v2.5/src/components/Performers/GenderIcon.tsx
Normal 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;
|
||||
|
|
@ -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={
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -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()}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue