Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions frontend/src/components/editCard/ModifyEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import ImageChangeRow from "src/components/imageChangeRow";
import URLChangeRow, { type URL } from "src/components/urlChangeRow";
import {
BreastTypes,
CircumcisedTypes,
EthnicityTypes,
EyeColorTypes,
GenderTypes,
HairColorTypes,
} from "src/constants";
import type {
BreastTypeEnum,
CircumcisedEnum,
EditFragment,
EthnicityEnum,
EyeColorEnum,
Expand Down Expand Up @@ -124,6 +126,8 @@ export interface PerformerDetails {
waist_size?: number | null;
hip_size?: number | null;
breast_type?: BreastTypeEnum | null;
circumcised?: CircumcisedEnum | null;
penis_length?: number | null;
country?: string | null;
ethnicity?: EthnicityEnum | null;
eye_color?: string | null;
Expand Down Expand Up @@ -255,6 +259,28 @@ export const renderPerformerDetails = (
}
showDiff={showDiff}
/>
<ChangeRow
name="Circumcised"
newValue={
performerDetails.circumcised &&
CircumcisedTypes[
performerDetails.circumcised as keyof typeof CircumcisedEnum
]
}
oldValue={
oldPerformerDetails?.circumcised &&
CircumcisedTypes[
oldPerformerDetails.circumcised as keyof typeof CircumcisedEnum
]
}
showDiff={showDiff}
/>
<ChangeRow
name="Penis Length"
newValue={performerDetails.penis_length}
oldValue={oldPerformerDetails?.penis_length}
showDiff={showDiff}
/>
<ChangeRow
name="Bra Size"
newValue={`${performerDetails.band_size || ""}${
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/constants/enums.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
BreastTypeEnum,
CircumcisedEnum,
EthnicityEnum,
EthnicityFilterEnum,
EyeColorEnum,
Expand All @@ -23,6 +24,11 @@ export const BreastTypes: EnumDictionary<BreastTypeEnum, string> = {
[BreastTypeEnum.NATURAL]: "Natural",
};

export const CircumcisedTypes: EnumDictionary<CircumcisedEnum, string> = {
[CircumcisedEnum.CUT]: "Cut",
[CircumcisedEnum.UNCUT]: "Uncut",
};

export const EthnicityTypes: EnumDictionary<EthnicityEnum, string> = {
[EthnicityEnum.ASIAN]: "Asian",
[EthnicityEnum.BLACK]: "Black",
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/graphql/fragments/EditFragment.gql
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ fragment EditFragment on Edit {
waist_size
hip_size
breast_type
circumcised
penis_length
career_start_year
career_end_year
added_tattoos {
Expand Down Expand Up @@ -207,6 +209,8 @@ fragment EditFragment on Edit {
waist_size
hip_size
breast_type
circumcised
penis_length
career_start_year
career_end_year
}
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/graphql/fragments/PerformerFragment.gql
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ fragment PerformerFragment on Performer {
career_end_year
career_start_year
breast_type
circumcised
penis_length
waist_size
hip_size
band_size
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/graphql/queries/Draft.gql
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ query Draft($id: ID!) {
height
measurements
breast_type
circumcised
penis_length
tattoos
piercings
career_start_year
Expand Down
269 changes: 144 additions & 125 deletions frontend/src/graphql/types.ts

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions frontend/src/pages/drafts/parse.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { uniqBy } from "lodash-es";
import {
BreastTypeEnum,
CircumcisedEnum,
type DraftQuery,
EthnicityEnum,
EyeColorEnum,
Expand Down Expand Up @@ -189,6 +190,17 @@ const parseBreastType = (value: string | null | undefined) => {
}
};

const parseCircumcised = (value: string | null | undefined) => {
switch (value?.toLocaleUpperCase()) {
case "CUT":
return CircumcisedEnum.CUT;
case "UNCUT":
return CircumcisedEnum.UNCUT;
default:
return null;
}
};

const parseHairColor = (value: string | null | undefined) => {
switch (value?.toLocaleUpperCase()) {
case "BROWN":
Expand Down Expand Up @@ -256,6 +268,9 @@ export const parsePerformerDraft = (
draft?.career_end_year ?? existingPerformer?.career_end_year,
breast_type:
parseBreastType(draft?.breast_type) ?? existingPerformer?.breast_type,
circumcised:
parseCircumcised(draft?.circumcised) ?? existingPerformer?.circumcised,
penis_length: draft?.penis_length ?? existingPerformer?.penis_length,
band_size: measurements?.band ?? existingPerformer?.band_size,
waist_size: measurements?.waist ?? existingPerformer?.waist_size,
hip_size: measurements?.hip ?? existingPerformer?.hip_size,
Expand All @@ -276,6 +291,10 @@ export const parsePerformerDraft = (
draft?.breast_type && !parseBreastType(draft?.breast_type)
? draft.breast_type
: null,
Circumcised:
draft?.circumcised && !parseCircumcised(draft?.circumcised)
? draft.circumcised
: null,
Piercings: draft?.piercings ?? null,
Tattoos: draft?.tattoos ?? null,
};
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/pages/performers/components/performerInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import Image from "src/components/image";
import {
BreastTypes,
CircumcisedTypes,
EthnicityTypes,
EyeColorTypes,
HairColorTypes,
Expand Down Expand Up @@ -177,6 +178,25 @@ export const PerformerInfo: FC<Props> = ({ performer }) => {
</tr>
</>
)}
{performer.gender !== GenderEnum.FEMALE &&
performer.gender !== GenderEnum.TRANSGENDER_MALE && (
<>
<tr>
<td>Circumcised</td>
<td>
{performer.circumcised &&
CircumcisedTypes[performer.circumcised]}
</td>
</tr>
<tr>
<td>Penis length</td>
<td>
{(performer?.penis_length ?? 0) > 0 &&
`${performer.penis_length}cm`}
</td>
</tr>
</>
)}
<tr>
<td>Nationality</td>
<td>{getCountryByISO(performer.country)}</td>
Expand Down
69 changes: 69 additions & 0 deletions frontend/src/pages/performers/performerForm/PerformerForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import URLInput from "src/components/urlInput";
import { GenderTypes } from "src/constants";
import {
BreastTypeEnum,
CircumcisedEnum,
EthnicityEnum,
EyeColorEnum,
GenderEnum,
Expand Down Expand Up @@ -83,6 +84,12 @@ const BREAST: OptionEnum[] = [
{ value: "NA", label: "N/A" },
];

const CIRCUMCISED: OptionEnum[] = [
{ value: "null", label: "Unknown" },
{ value: "CUT", label: "Cut" },
{ value: "UNCUT", label: "Uncut" },
];

const EYE: OptionEnum[] = [
{ value: "null", label: "Unknown" },
{ value: "BLUE", label: "Blue" },
Expand Down Expand Up @@ -171,6 +178,11 @@ const PerformerForm: FC<PerformerProps> = ({
BREAST,
initial?.breast_type ?? performer?.breast_type ?? null,
),
circumcised: getEnumValue(
CIRCUMCISED,
initial?.circumcised ?? performer?.circumcised ?? null,
),
penisLength: initial?.penis_length ?? performer?.penis_length,
bandSize: initial?.band_size ?? performer?.band_size,
cupSize: initial?.cup_size ?? performer?.cup_size,
waistSize: initial?.waist_size ?? performer?.waist_size,
Expand Down Expand Up @@ -223,6 +235,20 @@ const PerformerForm: FC<PerformerProps> = ({
if (!showBreastType) setValue("breastType", BreastTypeEnum.NA);
}, [showBreastType, setValue]);

const showPenisFields =
fieldData.gender !== GenderEnum.FEMALE &&
fieldData.gender !== GenderEnum.TRANSGENDER_MALE;
// Clear penis-related fields when they're not applicable.
// Transfeminine performers can have both breast and penis attributes;
// transmasculine performers get neither penis attributes nor (per
// showBreastType above) breast attributes.
useEffect(() => {
if (!showPenisFields) {
setValue("circumcised", "null");
setValue("penisLength", null);
}
}, [showPenisFields, setValue]);

const enumOptions = (enums: OptionEnum[]) =>
enums.map((obj) => (
<option key={obj.value} value={obj.value} disabled={!!obj.disabled}>
Expand Down Expand Up @@ -254,6 +280,10 @@ const PerformerForm: FC<PerformerProps> = ({
tattoos: data.tattoos ?? [],
breast_type:
BreastTypeEnum[data.breastType as keyof typeof BreastTypeEnum] || null,
circumcised:
CircumcisedEnum[data.circumcised as keyof typeof CircumcisedEnum] ||
null,
penis_length: data.penisLength,
image_ids: data.images.map((i) => i.id),
urls: data.urls?.map((u) => ({
url: u.url,
Expand All @@ -270,6 +300,14 @@ const PerformerForm: FC<PerformerProps> = ({
)
performerData.breast_type = BreastTypeEnum.NA;

if (
data.gender === GenderEnum.FEMALE ||
data.gender === GenderEnum.TRANSGENDER_MALE
) {
performerData.circumcised = null;
performerData.penis_length = null;
}

callback(performerData, data.note, updateAliases, data.id);
};

Expand Down Expand Up @@ -571,6 +609,37 @@ const PerformerForm: FC<PerformerProps> = ({
</Row>
)}

{showPenisFields && (
<Row>
<Form.Group controlId="circumcised" className="col-6 mb-3">
<Form.Label>Circumcised</Form.Label>
<Form.Select
className={cx({ "is-invalid": errors.circumcised })}
{...register("circumcised")}
>
{enumOptions(CIRCUMCISED)}
</Form.Select>
<Form.Control.Feedback type="invalid">
{errors?.circumcised?.message}
</Form.Control.Feedback>
</Form.Group>

<Form.Group controlId="penisLength" className="col-6 mb-3">
<Form.Label>Penis length</Form.Label>
<Form.Control
className={cx({ "is-invalid": errors.penisLength })}
type="number"
onWheel={handleNumberInputWheel}
{...register("penisLength")}
/>
<Form.Control.Feedback type="invalid">
{errors?.penisLength?.message}
</Form.Control.Feedback>
<Form.Text>Length in centimeters</Form.Text>
</Form.Group>
</Row>
)}

<Row>
<Form.Group controlId="country" className="col-6 mb-3">
<Form.Label>Nationality</Form.Label>
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/pages/performers/performerForm/diff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
import type { PerformerFragment } from "src/graphql";
import {
breastType,
circumcised,
diffArray,
diffImages,
diffURLs,
Expand Down Expand Up @@ -87,6 +88,11 @@ const selectPerformerDetails = (
original?.breast_type,
breastType(data.breastType),
),
circumcised: diffValue(
original?.circumcised,
circumcised(data.circumcised),
),
penis_length: diffValue(original?.penis_length, data.penisLength),
country: diffValue(original?.country, data.country),
ethnicity: diffValue(original?.ethnicity, ethnicityEnum(data.ethnicity)),
eye_color: diffValue(original?.eye_color, data.eye_color),
Expand Down Expand Up @@ -115,6 +121,11 @@ const selectPerformerDetails = (
breastType(data.breastType),
original?.breast_type,
),
circumcised: diffValue(
circumcised(data.circumcised),
original?.circumcised,
),
penis_length: diffValue(data.penisLength, original?.penis_length),
country: diffValue(data.country, original?.country),
ethnicity: diffValue(ethnicityEnum(data.ethnicity), original?.ethnicity),
eye_color: diffValue(data.eye_color, original?.eye_color),
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/pages/performers/performerForm/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { uniq, uniqBy } from "lodash-es";
import type { MergeConflict } from "src/components/mergeConflicts";
import {
BreastTypes,
CircumcisedTypes,
EthnicityTypes,
EyeColorTypes,
GenderTypes,
Expand Down Expand Up @@ -93,6 +94,21 @@ const SCALAR_FIELDS: ScalarField[] = [
get: (p) => p.breast_type,
display: (v) => BreastTypes[v as keyof typeof BreastTypes] ?? asString(v),
},
{
field: "circumcised",
initialKey: "circumcised",
label: "Circumcised",
get: (p) => p.circumcised,
display: (v) =>
CircumcisedTypes[v as keyof typeof CircumcisedTypes] ?? asString(v),
},
{
field: "penisLength",
initialKey: "penis_length",
label: "Penis Length",
get: (p) => p.penis_length,
display: (v) => `${v} cm`,
},
{
field: "bandSize",
initialKey: "band_size",
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/pages/performers/performerForm/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
BreastTypeEnum,
CircumcisedEnum,
EthnicityEnum,
EyeColorEnum,
GenderEnum,
Expand Down Expand Up @@ -98,6 +99,20 @@ export const PerformerSchema = yup.object({
.transform(nullCheck)
.nullable()
.oneOf([...Object.keys(BreastTypeEnum), null], "Invalid breast type"),
circumcised: yup
.string()
.transform(nullCheck)
.nullable()
.oneOf(
[...Object.keys(CircumcisedEnum), null],
"Invalid circumcised value",
),
penisLength: yup
.number()
.transform(zeroCheck)
.min(1, "Invalid length, length must be in centimeters.")
.max(50, "Invalid length")
.nullable(),
country: yup.string().trim().transform(nullCheck).nullable().defined(),
ethnicity: yup
.string()
Expand Down
Loading