diff --git a/ui/v2.5/src/components/Performers/PerformerDetails/PerformerScrapeDialog.tsx b/ui/v2.5/src/components/Performers/PerformerDetails/PerformerScrapeDialog.tsx index 9ccbdf04a..897bd17dd 100644 --- a/ui/v2.5/src/components/Performers/PerformerDetails/PerformerScrapeDialog.tsx +++ b/ui/v2.5/src/components/Performers/PerformerDetails/PerformerScrapeDialog.tsx @@ -5,7 +5,7 @@ import { ScrapeDialog, ScrapeResult, ScrapedInputGroupRow, - ScrapedImageRow, + ScrapedImagesRow, ScrapeDialogRow, ScrapedTextAreaRow, ScrapedCountryRow, @@ -414,6 +414,11 @@ export const PerformerScrapeDialog: React.FC = ( ) ); + const images = + props.scraped.images && props.scraped.images.length > 0 + ? props.scraped.images + : []; + const allFields = [ name, disambiguation, @@ -646,10 +651,11 @@ export const PerformerScrapeDialog: React.FC = ( newTags, createNewTag )} - setImage(value)} /> = (props) => { ); }; +interface IScrapedImageDialogRowProps< + T extends ScrapeResult, + V extends IHasName +> extends IScrapedFieldProps { + title: string; + renderOriginalField: () => JSX.Element | undefined; + renderNewField: () => JSX.Element | undefined; + onChange: (value: T) => void; + newValues?: V[]; + images: string[]; + onCreateNew?: (index: number) => void; +} + +export const ScrapeImageDialogRow = < + T extends ScrapeResult, + V extends IHasName +>( + props: IScrapedImageDialogRowProps +) => { + const [imageIndex, setImageIndex] = useState(0); + + function hasNewValues() { + return props.newValues && props.newValues.length > 0 && props.onCreateNew; + } + + function setPrev() { + let newIdx = imageIndex - 1; + if (newIdx < 0) { + newIdx = props.images.length - 1; + } + const ret = props.result.cloneWithValue(props.images[newIdx]); + props.onChange(ret as T); + setImageIndex(newIdx); + } + + function setNext() { + let newIdx = imageIndex + 1; + if (newIdx >= props.images.length) { + newIdx = 0; + } + const ret = props.result.cloneWithValue(props.images[newIdx]); + props.onChange(ret as T); + setImageIndex(newIdx); + } + + if (!props.result.scraped && !hasNewValues()) { + return <>; + } + + function renderSelector() { + return ( + props.images.length > 1 && ( +
+ +
+ Select performer image +
+ {imageIndex + 1} of {props.images.length} +
+ +
+ ) + ); + } + + function renderNewValues() { + if (!hasNewValues()) { + return; + } + + const ret = ( + <> + {props.newValues!.map((t, i) => ( + props.onCreateNew!(i)} + > + {t.name} + + + ))} + + ); + + const minCollapseLength = 10; + + if (props.newValues!.length >= minCollapseLength) { + return ( + + {ret} + + ); + } + + return ret; + } + + return ( + + + {props.title} + + + + + + {props.renderOriginalField()} + + + + {props.renderNewField()} + {renderSelector()} + + {renderNewValues()} + + + + + ); +}; + +interface IScrapedImagesRowProps { + title: string; + className?: string; + result: ScrapeResult; + images: string[]; + onChange: (value: ScrapeResult) => void; +} + +export const ScrapedImagesRow: React.FC = (props) => { + return ( + ( + + )} + renderNewField={() => ( + + )} + onChange={props.onChange} + /> + ); +}; + interface IScrapeDialogProps { title: string; existingLabel?: string;