Change show male performers option into list of gender checkboxes (#6321)

This commit is contained in:
WithoutPants 2025-11-28 13:51:20 +11:00 committed by GitHub
parent e052a431d1
commit d1ee64d36f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 53 additions and 25 deletions

View file

@ -1,4 +1,4 @@
import { ScraperSourceInput } from "src/core/generated-graphql";
import { GenderEnum, ScraperSourceInput } from "src/core/generated-graphql";
export const STASH_BOX_PREFIX = "stashbox:";
export const SCRAPER_PREFIX = "scraper:";
@ -27,7 +27,6 @@ export const DEFAULT_EXCLUDED_STUDIO_FIELDS = ["name"];
export const initialConfig: ITaggerConfig = {
blacklist: DEFAULT_BLACKLIST,
showMales: true,
mode: "auto",
setCoverImage: true,
setTags: true,
@ -43,7 +42,7 @@ export type ParseMode = "auto" | "filename" | "dir" | "path" | "metadata";
export type TagOperation = "merge" | "overwrite";
export interface ITaggerConfig {
blacklist: string[];
showMales: boolean;
performerGenders?: GenderEnum[];
mode: ParseMode;
setCoverImage: boolean;
setTags: boolean;

View file

@ -13,6 +13,8 @@ import { FormattedMessage, useIntl } from "react-intl";
import { Icon } from "src/components/Shared/Icon";
import { ParseMode, TagOperation } from "../constants";
import { TaggerStateContext } from "../context";
import { GenderEnum } from "src/core/generated-graphql";
import { genderList } from "src/utils/gender";
const Blacklist: React.FC<{
list: string[];
@ -118,6 +120,26 @@ const Config: React.FC<IConfigProps> = ({ show }) => {
const { config, setConfig } = useContext(TaggerStateContext);
const intl = useIntl();
function renderGenderCheckbox(gender: GenderEnum) {
const performerGenders = config.performerGenders || genderList.slice();
return (
<Form.Check
key={gender}
label={<FormattedMessage id={`gender_types.${gender}`} />}
checked={performerGenders.includes(gender)}
onChange={(e) => {
const isChecked = e.currentTarget.checked;
setConfig({
...config,
performerGenders: isChecked
? [...performerGenders, gender]
: performerGenders.filter((g) => g !== gender),
});
}}
/>
);
}
return (
<Collapse in={show}>
<Card>
@ -127,18 +149,16 @@ const Config: React.FC<IConfigProps> = ({ show }) => {
</h4>
<hr className="w-100" />
<Form className="col-md-6">
<Form.Group controlId="tag-males" className="align-items-center">
<Form.Check
label={
<FormattedMessage id="component_tagger.config.show_male_label" />
}
checked={config.showMales}
onChange={(e) =>
setConfig({ ...config, showMales: e.currentTarget.checked })
}
/>
<Form.Group
controlId="performer-genders"
className="align-items-center"
>
<Form.Label>
<FormattedMessage id="component_tagger.config.performer_genders.heading" />
</Form.Label>
{genderList.map(renderGenderCheckbox)}
<Form.Text>
<FormattedMessage id="component_tagger.config.show_male_desc" />
<FormattedMessage id="component_tagger.config.performer_genders.description" />
</Form.Text>
</Form.Group>
<Form.Group controlId="set-cover" className="align-items-center">

View file

@ -21,7 +21,7 @@ import { TagSelect } from "src/components/Shared/Select";
import { TruncatedText } from "src/components/Shared/TruncatedText";
import { OperationButton } from "src/components/Shared/OperationButton";
import * as FormUtils from "src/utils/form";
import { stringToGender } from "src/utils/gender";
import { genderList, stringToGender } from "src/utils/gender";
import { IScrapedScene, TaggerStateContext } from "../context";
import { OptionalField } from "../IncludeButton";
import { SceneTaggerModalsState } from "./sceneTaggerModals";
@ -237,17 +237,15 @@ const StashSearchResult: React.FC<IStashSearchResultProps> = ({
saveScene,
} = React.useContext(TaggerStateContext);
const performerGenders = config.performerGenders || genderList;
const performers = useMemo(
() =>
scene.performers?.filter((p) => {
if (!config.showMales) {
return (
!p.gender || stringToGender(p.gender, true) !== GQL.GenderEnum.Male
);
}
return true;
const gender = p.gender ? stringToGender(p.gender, true) : undefined;
return !gender || performerGenders.includes(gender);
}) ?? [],
[config, scene]
[scene, performerGenders]
);
const { createPerformerModal, createStudioModal } = React.useContext(

View file

@ -190,6 +190,10 @@
},
"mark_organized_desc": "Immediately mark the scene as Organized after the Save button is clicked.",
"mark_organized_label": "Mark as Organized on save",
"performer_genders": {
"heading": "Performer genders",
"description": "Performers with these genders will be shown when tagging scenes."
},
"query_mode_auto": "Auto",
"query_mode_auto_desc": "Uses metadata if present, or filename",
"query_mode_dir": "Dir",
@ -205,8 +209,6 @@
"set_cover_label": "Set scene cover image",
"set_tag_desc": "Attach tags to scene, either by overwriting or merging with existing tags on scene.",
"set_tag_label": "Set tags",
"show_male_desc": "Toggle whether male performers will be available to tag.",
"show_male_label": "Show male performers",
"source": "Source"
},
"noun_query": "Query",

View file

@ -1,14 +1,23 @@
import * as GQL from "../core/generated-graphql";
export const stringGenderMap = new Map<string, GQL.GenderEnum>([
["Male", GQL.GenderEnum.Male],
["Female", GQL.GenderEnum.Female],
["Male", GQL.GenderEnum.Male],
["Transgender Male", GQL.GenderEnum.TransgenderMale],
["Transgender Female", GQL.GenderEnum.TransgenderFemale],
["Intersex", GQL.GenderEnum.Intersex],
["Non-Binary", GQL.GenderEnum.NonBinary],
]);
export const genderList = [
GQL.GenderEnum.Female,
GQL.GenderEnum.Male,
GQL.GenderEnum.TransgenderFemale,
GQL.GenderEnum.TransgenderMale,
GQL.GenderEnum.Intersex,
GQL.GenderEnum.NonBinary,
];
export const genderToString = (value?: GQL.GenderEnum | string | null) => {
if (!value) {
return undefined;