mirror of https://github.com/stashapp/stash.git
Fix tag display issue in performer scrape dialog (#4943)
This commit is contained in:
parent
4b8af18fab
commit
dbfa450ace
|
@ -597,6 +597,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
|||
return (
|
||||
<PerformerScrapeDialog
|
||||
performer={currentPerformer}
|
||||
performerTags={tags}
|
||||
scraped={scrapedPerformer}
|
||||
scraper={scraper}
|
||||
onClose={(p) => {
|
||||
|
|
|
@ -9,11 +9,7 @@ import {
|
|||
ScrapedTextAreaRow,
|
||||
ScrapedCountryRow,
|
||||
} from "src/components/Shared/ScrapeDialog/ScrapeDialog";
|
||||
import { useTagCreate } from "src/core/StashService";
|
||||
import { Form } from "react-bootstrap";
|
||||
import { TagSelect } from "src/components/Shared/Select";
|
||||
import { useToast } from "src/hooks/Toast";
|
||||
import clone from "lodash-es/clone";
|
||||
import {
|
||||
genderStrings,
|
||||
genderToString,
|
||||
|
@ -25,7 +21,14 @@ import {
|
|||
stringToCircumcised,
|
||||
} from "src/utils/circumcised";
|
||||
import { IStashBox } from "./PerformerStashBoxModal";
|
||||
import { ScrapeResult } from "src/components/Shared/ScrapeDialog/scrapeResult";
|
||||
import {
|
||||
ObjectListScrapeResult,
|
||||
ScrapeResult,
|
||||
} from "src/components/Shared/ScrapeDialog/scrapeResult";
|
||||
import { ScrapedTagsRow } from "src/components/Shared/ScrapeDialog/ScrapedObjectsRow";
|
||||
import { sortStoredIdObjects } from "src/utils/data";
|
||||
import { Tag } from "src/components/Tags/TagSelect";
|
||||
import { useCreateScrapedTag } from "src/components/Shared/ScrapeDialog/createObjects";
|
||||
|
||||
function renderScrapedGender(
|
||||
result: ScrapeResult<string>,
|
||||
|
@ -76,55 +79,6 @@ function renderScrapedGenderRow(
|
|||
);
|
||||
}
|
||||
|
||||
function renderScrapedTags(
|
||||
result: ScrapeResult<string[]>,
|
||||
isNew?: boolean,
|
||||
onChange?: (value: string[]) => void
|
||||
) {
|
||||
const resultValue = isNew ? result.newValue : result.originalValue;
|
||||
const value = resultValue ?? [];
|
||||
|
||||
return (
|
||||
<TagSelect
|
||||
isMulti
|
||||
className="form-control react-select"
|
||||
isDisabled={!isNew}
|
||||
onSelect={(items) => {
|
||||
if (onChange) {
|
||||
onChange(items.map((i) => i.id));
|
||||
}
|
||||
}}
|
||||
ids={value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function renderScrapedTagsRow(
|
||||
title: string,
|
||||
result: ScrapeResult<string[]>,
|
||||
onChange: (value: ScrapeResult<string[]>) => void,
|
||||
newTags: GQL.ScrapedTag[],
|
||||
onCreateNew?: (value: GQL.ScrapedTag) => void
|
||||
) {
|
||||
return (
|
||||
<ScrapeDialogRow
|
||||
title={title}
|
||||
result={result}
|
||||
renderOriginalField={() => renderScrapedTags(result)}
|
||||
renderNewField={() =>
|
||||
renderScrapedTags(result, true, (value) =>
|
||||
onChange(result.cloneWithValue(value))
|
||||
)
|
||||
}
|
||||
newValues={newTags}
|
||||
onChange={onChange}
|
||||
onCreateNew={(i) => {
|
||||
if (onCreateNew) onCreateNew(newTags[i]);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function renderScrapedCircumcised(
|
||||
result: ScrapeResult<string>,
|
||||
isNew?: boolean,
|
||||
|
@ -176,6 +130,7 @@ function renderScrapedCircumcisedRow(
|
|||
|
||||
interface IPerformerScrapeDialogProps {
|
||||
performer: Partial<GQL.PerformerUpdateInput>;
|
||||
performerTags: Tag[];
|
||||
scraped: GQL.ScrapedPerformer;
|
||||
scraper?: GQL.Scraper | IStashBox;
|
||||
|
||||
|
@ -349,55 +304,15 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
|
|||
)
|
||||
);
|
||||
|
||||
const [createTag] = useTagCreate();
|
||||
const Toast = useToast();
|
||||
|
||||
interface IHasStoredID {
|
||||
stored_id?: string | null;
|
||||
}
|
||||
|
||||
function mapStoredIdObjects(
|
||||
scrapedObjects?: IHasStoredID[]
|
||||
): string[] | undefined {
|
||||
if (!scrapedObjects) {
|
||||
return undefined;
|
||||
}
|
||||
const ret = scrapedObjects
|
||||
.map((p) => p.stored_id)
|
||||
.filter((p) => {
|
||||
return p !== undefined && p !== null;
|
||||
}) as string[];
|
||||
|
||||
if (ret.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// sort by id numerically
|
||||
ret.sort((a, b) => {
|
||||
return parseInt(a, 10) - parseInt(b, 10);
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function sortIdList(idList?: string[] | null) {
|
||||
if (!idList) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ret = clone(idList);
|
||||
// sort by id numerically
|
||||
ret.sort((a, b) => {
|
||||
return parseInt(a, 10) - parseInt(b, 10);
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const [tags, setTags] = useState<ScrapeResult<string[]>>(
|
||||
new ScrapeResult<string[]>(
|
||||
sortIdList(props.performer.tag_ids ?? undefined),
|
||||
mapStoredIdObjects(props.scraped.tags ?? undefined)
|
||||
const [tags, setTags] = useState<ObjectListScrapeResult<GQL.ScrapedTag>>(
|
||||
new ObjectListScrapeResult<GQL.ScrapedTag>(
|
||||
sortStoredIdObjects(
|
||||
props.performerTags.map((t) => ({
|
||||
stored_id: t.id,
|
||||
name: t.name,
|
||||
}))
|
||||
),
|
||||
sortStoredIdObjects(props.scraped.tags ?? undefined)
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -405,6 +320,13 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
|
|||
props.scraped.tags?.filter((t) => !t.stored_id) ?? []
|
||||
);
|
||||
|
||||
const createNewTag = useCreateScrapedTag({
|
||||
scrapeResult: tags,
|
||||
setScrapeResult: setTags,
|
||||
newObjects: newTags,
|
||||
setNewObjects: setNewTags,
|
||||
});
|
||||
|
||||
const [image, setImage] = useState<ScrapeResult<string>>(
|
||||
new ScrapeResult<string>(
|
||||
props.performer.image,
|
||||
|
@ -453,40 +375,6 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
|
|||
return <></>;
|
||||
}
|
||||
|
||||
async function createNewTag(toCreate: GQL.ScrapedTag) {
|
||||
const tagInput: GQL.TagCreateInput = { name: toCreate.name ?? "" };
|
||||
try {
|
||||
const result = await createTag({
|
||||
variables: {
|
||||
input: tagInput,
|
||||
},
|
||||
});
|
||||
|
||||
// add the new tag to the new tags value
|
||||
const tagClone = tags.cloneWithValue(tags.newValue);
|
||||
if (!tagClone.newValue) {
|
||||
tagClone.newValue = [];
|
||||
}
|
||||
tagClone.newValue.push(result.data!.tagCreate!.id);
|
||||
setTags(tagClone);
|
||||
|
||||
// remove the tag from the list
|
||||
const newTagsClone = newTags.concat();
|
||||
const pIndex = newTagsClone.indexOf(toCreate);
|
||||
newTagsClone.splice(pIndex, 1);
|
||||
|
||||
setNewTags(newTagsClone);
|
||||
|
||||
Toast.success(
|
||||
<span>
|
||||
Created tag: <b>{toCreate.name}</b>
|
||||
</span>
|
||||
);
|
||||
} catch (e) {
|
||||
Toast.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
function makeNewScrapedItem(): GQL.ScrapedPerformer {
|
||||
const newImage = image.getNewValue();
|
||||
return {
|
||||
|
@ -507,12 +395,7 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
|
|||
twitter: twitter.getNewValue(),
|
||||
instagram: instagram.getNewValue(),
|
||||
gender: gender.getNewValue(),
|
||||
tags: tags.getNewValue()?.map((m) => {
|
||||
return {
|
||||
stored_id: m,
|
||||
name: "",
|
||||
};
|
||||
}),
|
||||
tags: tags.getNewValue(),
|
||||
images: newImage ? [newImage] : undefined,
|
||||
details: details.getNewValue(),
|
||||
death_date: deathDate.getNewValue(),
|
||||
|
@ -642,13 +525,13 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
|
|||
result={details}
|
||||
onChange={(value) => setDetails(value)}
|
||||
/>
|
||||
{renderScrapedTagsRow(
|
||||
intl.formatMessage({ id: "tags" }),
|
||||
tags,
|
||||
(value) => setTags(value),
|
||||
newTags,
|
||||
createNewTag
|
||||
)}
|
||||
<ScrapedTagsRow
|
||||
title={intl.formatMessage({ id: "tags" })}
|
||||
result={tags}
|
||||
onChange={(value) => setTags(value)}
|
||||
newObjects={newTags}
|
||||
onCreateNew={createNewTag}
|
||||
/>
|
||||
<ScrapedImagesRow
|
||||
title={intl.formatMessage({ id: "performer_image" })}
|
||||
className="performer-image"
|
||||
|
|
Loading…
Reference in New Issue