mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 21:04:37 +03:00
Fix scene edit state resetting when scene is updated (#1112)
* Fix organized click resetting scene form state * Fix state resetting for images/galleries * Fix favoriting a performer resetting edit state
This commit is contained in:
@@ -29,10 +29,11 @@
|
||||
* Support configurable number of threads for scanning and generation.
|
||||
|
||||
### 🐛 Bug fixes
|
||||
* Fix edit data being lost when clicking the O-Counter, Organized or Favorite buttons.
|
||||
* Exclude media in `generated` directory from the library.
|
||||
* Prevent cover image from being incorrectly regenerated when a scene file's hash changes.
|
||||
* Fix version check sometimes giving incorrect results.
|
||||
* Fixed stash potentially deleting `downloads` directory when first run.
|
||||
* Fix stash potentially deleting `downloads` directory when first run.
|
||||
* Fix sprite generation when generated path has special characters.
|
||||
* Prevent studio from being set as its own parent
|
||||
* Fixed performer scraper select overlapping search results
|
||||
|
||||
@@ -39,18 +39,29 @@ interface IExistingProps {
|
||||
|
||||
export const GalleryEditPanel: React.FC<
|
||||
IProps & (INewProps | IExistingProps)
|
||||
> = (props) => {
|
||||
> = ({ gallery, isNew, isVisible, onDelete }) => {
|
||||
const Toast = useToast();
|
||||
const history = useHistory();
|
||||
const [title, setTitle] = useState<string>();
|
||||
const [details, setDetails] = useState<string>();
|
||||
const [url, setUrl] = useState<string>();
|
||||
const [date, setDate] = useState<string>();
|
||||
const [rating, setRating] = useState<number>();
|
||||
const [studioId, setStudioId] = useState<string>();
|
||||
const [performerIds, setPerformerIds] = useState<string[]>();
|
||||
const [tagIds, setTagIds] = useState<string[]>();
|
||||
const [scenes, setScenes] = useState<{ id: string; title: string }[]>([]);
|
||||
const [title, setTitle] = useState<string>(gallery?.title ?? "");
|
||||
const [details, setDetails] = useState<string>(gallery?.details ?? "");
|
||||
const [url, setUrl] = useState<string>(gallery?.url ?? "");
|
||||
const [date, setDate] = useState<string>(gallery?.date ?? "");
|
||||
const [rating, setRating] = useState<number>(gallery?.rating ?? NaN);
|
||||
const [studioId, setStudioId] = useState<string | undefined>(
|
||||
gallery?.studio?.id ?? undefined
|
||||
);
|
||||
const [performerIds, setPerformerIds] = useState<string[]>(
|
||||
gallery?.performers.map((p) => p.id) ?? []
|
||||
);
|
||||
const [tagIds, setTagIds] = useState<string[]>(
|
||||
gallery?.tags.map((t) => t.id) ?? []
|
||||
);
|
||||
const [scenes, setScenes] = useState<{ id: string; title: string }[]>(
|
||||
gallery?.scenes.map((s) => ({
|
||||
id: s.id,
|
||||
title: s.title ?? TextUtils.fileNameFromPath(s.path ?? ""),
|
||||
})) ?? []
|
||||
);
|
||||
|
||||
const Scrapers = useListGalleryScrapers();
|
||||
|
||||
@@ -60,18 +71,18 @@ export const GalleryEditPanel: React.FC<
|
||||
] = useState<GQL.ScrapedGallery | null>();
|
||||
|
||||
// Network state
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const [createGallery] = useGalleryCreate();
|
||||
const [updateGallery] = useGalleryUpdate();
|
||||
|
||||
useEffect(() => {
|
||||
if (props.isVisible) {
|
||||
if (isVisible) {
|
||||
Mousetrap.bind("s s", () => {
|
||||
onSave();
|
||||
});
|
||||
Mousetrap.bind("d d", () => {
|
||||
props.onDelete();
|
||||
onDelete();
|
||||
});
|
||||
|
||||
// numeric keypresses get caught by jwplayer, so blur the element
|
||||
@@ -107,34 +118,9 @@ export const GalleryEditPanel: React.FC<
|
||||
}
|
||||
});
|
||||
|
||||
function updateGalleryEditState(state?: GQL.GalleryDataFragment) {
|
||||
const perfIds = state?.performers?.map((performer) => performer.id);
|
||||
const tIds = state?.tags ? state?.tags.map((tag) => tag.id) : undefined;
|
||||
|
||||
setTitle(state?.title ?? undefined);
|
||||
setDetails(state?.details ?? undefined);
|
||||
setUrl(state?.url ?? undefined);
|
||||
setDate(state?.date ?? undefined);
|
||||
setRating(state?.rating === null ? NaN : state?.rating);
|
||||
setStudioId(state?.studio?.id ?? undefined);
|
||||
setPerformerIds(perfIds);
|
||||
setTagIds(tIds);
|
||||
setScenes(
|
||||
(state?.scenes ?? []).map((s) => ({
|
||||
id: s.id,
|
||||
title: s.title ?? TextUtils.fileNameFromPath(s.path ?? ""),
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateGalleryEditState(props.gallery);
|
||||
setIsLoading(false);
|
||||
}, [props.gallery]);
|
||||
|
||||
function getGalleryInput() {
|
||||
return {
|
||||
id: props.isNew ? undefined : props.gallery.id,
|
||||
id: isNew ? undefined : gallery?.id ?? "",
|
||||
title: title ?? "",
|
||||
details,
|
||||
url,
|
||||
@@ -150,7 +136,7 @@ export const GalleryEditPanel: React.FC<
|
||||
async function onSave() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
if (props.isNew) {
|
||||
if (isNew) {
|
||||
const result = await createGallery({
|
||||
variables: {
|
||||
input: getGalleryInput(),
|
||||
@@ -176,9 +162,9 @@ export const GalleryEditPanel: React.FC<
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
function onScrapeDialogClosed(gallery?: GQL.ScrapedGalleryDataFragment) {
|
||||
if (gallery) {
|
||||
updateGalleryFromScrapedGallery(gallery);
|
||||
function onScrapeDialogClosed(data?: GQL.ScrapedGalleryDataFragment) {
|
||||
if (data) {
|
||||
updateGalleryFromScrapedGallery(data);
|
||||
}
|
||||
setScrapedGallery(undefined);
|
||||
}
|
||||
@@ -194,8 +180,8 @@ export const GalleryEditPanel: React.FC<
|
||||
<GalleryScrapeDialog
|
||||
gallery={currentGallery}
|
||||
scraped={scrapedGallery}
|
||||
onClose={(gallery) => {
|
||||
onScrapeDialogClosed(gallery);
|
||||
onClose={(data) => {
|
||||
onScrapeDialogClosed(data);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -208,30 +194,30 @@ export const GalleryEditPanel: React.FC<
|
||||
}
|
||||
|
||||
function updateGalleryFromScrapedGallery(
|
||||
gallery: GQL.ScrapedGalleryDataFragment
|
||||
galleryData: GQL.ScrapedGalleryDataFragment
|
||||
) {
|
||||
if (gallery.title) {
|
||||
setTitle(gallery.title);
|
||||
if (galleryData.title) {
|
||||
setTitle(galleryData.title);
|
||||
}
|
||||
|
||||
if (gallery.details) {
|
||||
setDetails(gallery.details);
|
||||
if (galleryData.details) {
|
||||
setDetails(galleryData.details);
|
||||
}
|
||||
|
||||
if (gallery.date) {
|
||||
setDate(gallery.date);
|
||||
if (galleryData.date) {
|
||||
setDate(galleryData.date);
|
||||
}
|
||||
|
||||
if (gallery.url) {
|
||||
setUrl(gallery.url);
|
||||
if (galleryData.url) {
|
||||
setUrl(galleryData.url);
|
||||
}
|
||||
|
||||
if (gallery.studio && gallery.studio.stored_id) {
|
||||
setStudioId(gallery.studio.stored_id);
|
||||
if (galleryData.studio?.stored_id) {
|
||||
setStudioId(galleryData.studio.stored_id);
|
||||
}
|
||||
|
||||
if (gallery.performers && gallery.performers.length > 0) {
|
||||
const idPerfs = gallery.performers.filter((p) => {
|
||||
if (galleryData.performers?.length) {
|
||||
const idPerfs = galleryData.performers.filter((p) => {
|
||||
return p.stored_id !== undefined && p.stored_id !== null;
|
||||
});
|
||||
|
||||
@@ -241,13 +227,13 @@ export const GalleryEditPanel: React.FC<
|
||||
}
|
||||
}
|
||||
|
||||
if (gallery?.tags?.length) {
|
||||
const idTags = gallery.tags.filter((p) => {
|
||||
return p.stored_id !== undefined && p.stored_id !== null;
|
||||
if (galleryData?.tags?.length) {
|
||||
const idTags = galleryData.tags.filter((t) => {
|
||||
return t.stored_id !== undefined && t.stored_id !== null;
|
||||
});
|
||||
|
||||
if (idTags.length > 0) {
|
||||
const newIds = idTags.map((p) => p.stored_id);
|
||||
const newIds = idTags.map((t) => t.stored_id);
|
||||
setTagIds(newIds as string[]);
|
||||
}
|
||||
}
|
||||
@@ -299,7 +285,7 @@ export const GalleryEditPanel: React.FC<
|
||||
<Button
|
||||
className="edit-button"
|
||||
variant="danger"
|
||||
onClick={() => props.onDelete()}
|
||||
onClick={() => onDelete()}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
@@ -343,7 +329,7 @@ export const GalleryEditPanel: React.FC<
|
||||
<Col xs={9}>
|
||||
<RatingStars
|
||||
value={rating}
|
||||
onSetRating={(value) => setRating(value)}
|
||||
onSetRating={(value) => setRating(value ?? NaN)}
|
||||
/>
|
||||
</Col>
|
||||
</Form.Group>
|
||||
|
||||
@@ -19,26 +19,32 @@ interface IProps {
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
export const ImageEditPanel: React.FC<IProps> = ({
|
||||
image,
|
||||
isVisible,
|
||||
onDelete,
|
||||
}) => {
|
||||
const Toast = useToast();
|
||||
const [title, setTitle] = useState<string>();
|
||||
const [rating, setRating] = useState<number>();
|
||||
const [studioId, setStudioId] = useState<string>();
|
||||
const [performerIds, setPerformerIds] = useState<string[]>();
|
||||
const [tagIds, setTagIds] = useState<string[]>();
|
||||
const [title, setTitle] = useState<string>(image?.title ?? "");
|
||||
const [rating, setRating] = useState<number>(image.rating ?? NaN);
|
||||
const [studioId, setStudioId] = useState<string>(image.studio?.id ?? "");
|
||||
const [performerIds, setPerformerIds] = useState<string[]>(
|
||||
image.performers.map((p) => p.id)
|
||||
);
|
||||
const [tagIds, setTagIds] = useState<string[]>(image.tags.map((t) => t.id));
|
||||
|
||||
// Network state
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const [updateImage] = useImageUpdate();
|
||||
|
||||
useEffect(() => {
|
||||
if (props.isVisible) {
|
||||
if (isVisible) {
|
||||
Mousetrap.bind("s s", () => {
|
||||
onSave();
|
||||
});
|
||||
Mousetrap.bind("d d", () => {
|
||||
props.onDelete();
|
||||
onDelete();
|
||||
});
|
||||
|
||||
// numeric keypresses get caught by jwplayer, so blur the element
|
||||
@@ -74,26 +80,9 @@ export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
}
|
||||
});
|
||||
|
||||
function updateImageEditState(state: Partial<GQL.ImageDataFragment>) {
|
||||
const perfIds = state.performers?.map((performer) => performer.id);
|
||||
const tIds = state.tags ? state.tags.map((tag) => tag.id) : undefined;
|
||||
|
||||
setTitle(state.title ?? undefined);
|
||||
setRating(state.rating === null ? NaN : state.rating);
|
||||
// setGalleryId(state?.gallery?.id ?? undefined);
|
||||
setStudioId(state?.studio?.id ?? undefined);
|
||||
setPerformerIds(perfIds);
|
||||
setTagIds(tIds);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateImageEditState(props.image);
|
||||
setIsLoading(false);
|
||||
}, [props.image]);
|
||||
|
||||
function getImageInput(): GQL.ImageUpdateInput {
|
||||
return {
|
||||
id: props.image.id,
|
||||
id: image.id,
|
||||
title,
|
||||
rating: rating ?? null,
|
||||
studio_id: studioId ?? null,
|
||||
@@ -131,7 +120,7 @@ export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
<Button
|
||||
className="edit-button"
|
||||
variant="danger"
|
||||
onClick={() => props.onDelete()}
|
||||
onClick={() => onDelete()}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
@@ -152,7 +141,7 @@ export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
<Col xs={9}>
|
||||
<RatingStars
|
||||
value={rating}
|
||||
onSetRating={(value) => setRating(value)}
|
||||
onSetRating={(value) => setRating(value ?? NaN)}
|
||||
/>
|
||||
</Col>
|
||||
</Form.Group>
|
||||
@@ -164,7 +153,7 @@ export const ImageEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
<Col xs={9}>
|
||||
<StudioSelect
|
||||
onSelect={(items) =>
|
||||
setStudioId(items.length > 0 ? items[0]?.id : undefined)
|
||||
setStudioId(items.length > 0 ? items[0]?.id : "")
|
||||
}
|
||||
ids={studioId ? [studioId] : []}
|
||||
/>
|
||||
|
||||
@@ -223,11 +223,17 @@ export const Performer: React.FC = () => {
|
||||
}
|
||||
|
||||
function setFavorite(v: boolean) {
|
||||
onSave({
|
||||
if (performer.id) {
|
||||
updatePerformer({
|
||||
variables: {
|
||||
input: {
|
||||
id: performer.id,
|
||||
favorite: v,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const renderIcons = () => (
|
||||
<span className="name-icons">
|
||||
|
||||
@@ -68,24 +68,32 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
||||
|
||||
// Editing performer state
|
||||
const [image, setImage] = useState<string | null>();
|
||||
const [name, setName] = useState<string>();
|
||||
const [aliases, setAliases] = useState<string>();
|
||||
const [favorite, setFavorite] = useState<boolean>();
|
||||
const [birthdate, setBirthdate] = useState<string>();
|
||||
const [ethnicity, setEthnicity] = useState<string>();
|
||||
const [country, setCountry] = useState<string>();
|
||||
const [eyeColor, setEyeColor] = useState<string>();
|
||||
const [height, setHeight] = useState<string>();
|
||||
const [measurements, setMeasurements] = useState<string>();
|
||||
const [fakeTits, setFakeTits] = useState<string>();
|
||||
const [careerLength, setCareerLength] = useState<string>();
|
||||
const [tattoos, setTattoos] = useState<string>();
|
||||
const [piercings, setPiercings] = useState<string>();
|
||||
const [url, setUrl] = useState<string>();
|
||||
const [twitter, setTwitter] = useState<string>();
|
||||
const [instagram, setInstagram] = useState<string>();
|
||||
const [gender, setGender] = useState<string | undefined>(undefined);
|
||||
const [stashIDs, setStashIDs] = useState<GQL.StashIdInput[]>([]);
|
||||
const [name, setName] = useState<string>(performer?.name ?? "");
|
||||
const [aliases, setAliases] = useState<string>(performer.aliases ?? "");
|
||||
const [birthdate, setBirthdate] = useState<string>(performer.birthdate ?? "");
|
||||
const [ethnicity, setEthnicity] = useState<string>(performer.ethnicity ?? "");
|
||||
const [country, setCountry] = useState<string>(performer.country ?? "");
|
||||
const [eyeColor, setEyeColor] = useState<string>(performer.eye_color ?? "");
|
||||
const [height, setHeight] = useState<string>(performer.height ?? "");
|
||||
const [measurements, setMeasurements] = useState<string>(
|
||||
performer.measurements ?? ""
|
||||
);
|
||||
const [fakeTits, setFakeTits] = useState<string>(performer.fake_tits ?? "");
|
||||
const [careerLength, setCareerLength] = useState<string>(
|
||||
performer.career_length ?? ""
|
||||
);
|
||||
const [tattoos, setTattoos] = useState<string>(performer.tattoos ?? "");
|
||||
const [piercings, setPiercings] = useState<string>(performer.piercings ?? "");
|
||||
const [url, setUrl] = useState<string>(performer.url ?? "");
|
||||
const [twitter, setTwitter] = useState<string>(performer.twitter ?? "");
|
||||
const [instagram, setInstagram] = useState<string>(performer.instagram ?? "");
|
||||
const [gender, setGender] = useState<string | undefined>(
|
||||
performer.gender ?? undefined
|
||||
);
|
||||
const [stashIDs, setStashIDs] = useState<GQL.StashIdInput[]>(
|
||||
performer.stash_ids ?? []
|
||||
);
|
||||
const favorite = performer.favorite ?? false;
|
||||
|
||||
// Network state
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
@@ -101,35 +109,6 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
||||
|
||||
const imageEncoding = ImageUtils.usePasteImage(onImageLoad, isEditing);
|
||||
|
||||
function updatePerformerEditState(
|
||||
state: Partial<GQL.PerformerDataFragment | GQL.ScrapedPerformerDataFragment>
|
||||
) {
|
||||
if ((state as GQL.PerformerDataFragment).favorite !== undefined) {
|
||||
setFavorite((state as GQL.PerformerDataFragment).favorite);
|
||||
}
|
||||
setName(state.name ?? undefined);
|
||||
setAliases(state.aliases ?? undefined);
|
||||
setBirthdate(state.birthdate ?? undefined);
|
||||
setEthnicity(state.ethnicity ?? undefined);
|
||||
setCountry(state.country ?? undefined);
|
||||
setEyeColor(state.eye_color ?? undefined);
|
||||
setHeight(state.height ?? undefined);
|
||||
setMeasurements(state.measurements ?? undefined);
|
||||
setFakeTits(state.fake_tits ?? undefined);
|
||||
setCareerLength(state.career_length ?? undefined);
|
||||
setTattoos(state.tattoos ?? undefined);
|
||||
setPiercings(state.piercings ?? undefined);
|
||||
setUrl(state.url ?? undefined);
|
||||
setTwitter(state.twitter ?? undefined);
|
||||
setInstagram(state.instagram ?? undefined);
|
||||
setGender(
|
||||
genderToString((state as GQL.PerformerDataFragment).gender ?? undefined)
|
||||
);
|
||||
if ((state as GQL.PerformerDataFragment).stash_ids !== undefined) {
|
||||
setStashIDs((state as GQL.PerformerDataFragment).stash_ids);
|
||||
}
|
||||
}
|
||||
|
||||
function translateScrapedGender(scrapedGender?: string) {
|
||||
if (!scrapedGender) {
|
||||
return;
|
||||
@@ -245,10 +224,6 @@ export const PerformerDetailsPanel: React.FC<IPerformerDetails> = ({
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!isNew) updatePerformerEditState(performer);
|
||||
}, [isNew, performer]);
|
||||
|
||||
useEffect(() => {
|
||||
if (onImageChange) {
|
||||
onImageChange(image);
|
||||
|
||||
@@ -40,26 +40,43 @@ interface IProps {
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
export const SceneEditPanel: React.FC<IProps> = ({
|
||||
scene,
|
||||
isVisible,
|
||||
onDelete,
|
||||
}) => {
|
||||
const Toast = useToast();
|
||||
const [title, setTitle] = useState<string>();
|
||||
const [details, setDetails] = useState<string>();
|
||||
const [url, setUrl] = useState<string>();
|
||||
const [date, setDate] = useState<string>();
|
||||
const [rating, setRating] = useState<number>();
|
||||
const [galleries, setGalleries] = useState<{ id: string; title: string }[]>(
|
||||
[]
|
||||
const [title, setTitle] = useState<string>(scene.title ?? "");
|
||||
const [details, setDetails] = useState<string>(scene.details ?? "");
|
||||
const [url, setUrl] = useState<string>(scene.url ?? "");
|
||||
const [date, setDate] = useState<string>(scene.date ?? "");
|
||||
const [rating, setRating] = useState<number | undefined>(
|
||||
scene.rating ?? undefined
|
||||
);
|
||||
const [galleries, setGalleries] = useState<{ id: string; title: string }[]>(
|
||||
scene.galleries.map((g) => ({
|
||||
id: g.id,
|
||||
title: g.title ?? TextUtils.fileNameFromPath(g.path ?? ""),
|
||||
}))
|
||||
);
|
||||
const [studioId, setStudioId] = useState<string | undefined>(
|
||||
scene.studio?.id
|
||||
);
|
||||
const [performerIds, setPerformerIds] = useState<string[]>(
|
||||
scene.performers.map((p) => p.id)
|
||||
);
|
||||
const [movieIds, setMovieIds] = useState<string[]>(
|
||||
scene.movies.map((m) => m.movie.id)
|
||||
);
|
||||
const [studioId, setStudioId] = useState<string>();
|
||||
const [performerIds, setPerformerIds] = useState<string[]>();
|
||||
const [movieIds, setMovieIds] = useState<string[] | undefined>(undefined);
|
||||
const [
|
||||
movieSceneIndexes,
|
||||
setMovieSceneIndexes,
|
||||
] = useState<MovieSceneIndexMap>(new Map());
|
||||
const [tagIds, setTagIds] = useState<string[]>();
|
||||
] = useState<MovieSceneIndexMap>(
|
||||
new Map(scene.movies.map((m) => [m.movie.id, m.scene_index ?? undefined]))
|
||||
);
|
||||
const [tagIds, setTagIds] = useState<string[]>(scene.tags.map((t) => t.id));
|
||||
const [coverImage, setCoverImage] = useState<string>();
|
||||
const [stashIDs, setStashIDs] = useState<GQL.StashIdInput[]>([]);
|
||||
const [stashIDs, setStashIDs] = useState<GQL.StashIdInput[]>(scene.stash_ids);
|
||||
|
||||
const Scrapers = useListSceneScrapers();
|
||||
const [queryableScrapers, setQueryableScrapers] = useState<GQL.Scraper[]>([]);
|
||||
@@ -71,17 +88,17 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
const stashConfig = useConfiguration();
|
||||
|
||||
// Network state
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const [updateScene] = useSceneUpdate();
|
||||
|
||||
useEffect(() => {
|
||||
if (props.isVisible) {
|
||||
if (isVisible) {
|
||||
Mousetrap.bind("s s", () => {
|
||||
onSave();
|
||||
});
|
||||
Mousetrap.bind("d d", () => {
|
||||
props.onDelete();
|
||||
onDelete();
|
||||
});
|
||||
|
||||
// numeric keypresses get caught by jwplayer, so blur the element
|
||||
@@ -141,7 +158,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
});
|
||||
|
||||
if (!changed) {
|
||||
movieSceneIndexes.forEach((v, id) => {
|
||||
movieSceneIndexes.forEach((_v, id) => {
|
||||
if (!newMap.has(id)) {
|
||||
// id was removed
|
||||
changed = true;
|
||||
@@ -155,49 +172,11 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
}
|
||||
}, [movieIds, movieSceneIndexes]);
|
||||
|
||||
function updateSceneEditState(state: Partial<GQL.SceneDataFragment>) {
|
||||
const perfIds = state.performers?.map((performer) => performer.id);
|
||||
const tIds = state.tags ? state.tags.map((tag) => tag.id) : undefined;
|
||||
const moviIds = state.movies
|
||||
? state.movies.map((sceneMovie) => sceneMovie.movie.id)
|
||||
: undefined;
|
||||
const movieSceneIdx: MovieSceneIndexMap = new Map();
|
||||
if (state.movies) {
|
||||
state.movies.forEach((m) => {
|
||||
movieSceneIdx.set(m.movie.id, m.scene_index ?? undefined);
|
||||
});
|
||||
}
|
||||
|
||||
setTitle(state.title ?? undefined);
|
||||
setDetails(state.details ?? undefined);
|
||||
setUrl(state.url ?? undefined);
|
||||
setDate(state.date ?? undefined);
|
||||
setRating(state.rating === null ? NaN : state.rating);
|
||||
setGalleries(
|
||||
(state?.galleries ?? []).map((g) => ({
|
||||
id: g.id,
|
||||
title: g.title ?? TextUtils.fileNameFromPath(g.path ?? ""),
|
||||
}))
|
||||
);
|
||||
setStudioId(state?.studio?.id ?? undefined);
|
||||
setMovieIds(moviIds);
|
||||
setMovieSceneIndexes(movieSceneIdx);
|
||||
setPerformerIds(perfIds);
|
||||
setTagIds(tIds);
|
||||
setStashIDs(state?.stash_ids ?? []);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateSceneEditState(props.scene);
|
||||
setCoverImagePreview(props.scene?.paths?.screenshot ?? undefined);
|
||||
setIsLoading(false);
|
||||
}, [props.scene]);
|
||||
|
||||
const imageEncoding = ImageUtils.usePasteImage(onImageLoad, true);
|
||||
|
||||
function getSceneInput(): GQL.SceneUpdateInput {
|
||||
return {
|
||||
id: props.scene.id,
|
||||
id: scene.id,
|
||||
title,
|
||||
details,
|
||||
url,
|
||||
@@ -284,7 +263,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
async function onScrapeStashBoxClicked(stashBoxIndex: number) {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const result = await queryStashBoxScene(stashBoxIndex, props.scene.id);
|
||||
const result = await queryStashBoxScene(stashBoxIndex, scene.id);
|
||||
if (!result.data || !result.data.queryStashBoxScene) {
|
||||
return;
|
||||
}
|
||||
@@ -339,9 +318,9 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
function onScrapeDialogClosed(scene?: GQL.ScrapedSceneDataFragment) {
|
||||
if (scene) {
|
||||
updateSceneFromScrapedScene(scene);
|
||||
function onScrapeDialogClosed(sceneData?: GQL.ScrapedSceneDataFragment) {
|
||||
if (sceneData) {
|
||||
updateSceneFromScrapedScene(sceneData);
|
||||
}
|
||||
setScrapedScene(undefined);
|
||||
}
|
||||
@@ -353,16 +332,14 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
|
||||
const currentScene = getSceneInput();
|
||||
if (!currentScene.cover_image) {
|
||||
currentScene.cover_image = props.scene.paths.screenshot;
|
||||
currentScene.cover_image = scene.paths.screenshot;
|
||||
}
|
||||
|
||||
return (
|
||||
<SceneScrapeDialog
|
||||
scene={currentScene}
|
||||
scraped={scrapedScene}
|
||||
onClose={(scene) => {
|
||||
onScrapeDialogClosed(scene);
|
||||
}}
|
||||
onClose={(s) => onScrapeDialogClosed(s)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -444,29 +421,31 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
);
|
||||
}
|
||||
|
||||
function updateSceneFromScrapedScene(scene: GQL.ScrapedSceneDataFragment) {
|
||||
if (scene.title) {
|
||||
setTitle(scene.title);
|
||||
function updateSceneFromScrapedScene(
|
||||
updatedScene: GQL.ScrapedSceneDataFragment
|
||||
) {
|
||||
if (updatedScene.title) {
|
||||
setTitle(updatedScene.title);
|
||||
}
|
||||
|
||||
if (scene.details) {
|
||||
setDetails(scene.details);
|
||||
if (updatedScene.details) {
|
||||
setDetails(updatedScene.details);
|
||||
}
|
||||
|
||||
if (scene.date) {
|
||||
setDate(scene.date);
|
||||
if (updatedScene.date) {
|
||||
setDate(updatedScene.date);
|
||||
}
|
||||
|
||||
if (scene.url) {
|
||||
setUrl(scene.url);
|
||||
if (updatedScene.url) {
|
||||
setUrl(updatedScene.url);
|
||||
}
|
||||
|
||||
if (scene.studio && scene.studio.stored_id) {
|
||||
setStudioId(scene.studio.stored_id);
|
||||
if (updatedScene.studio && updatedScene.studio.stored_id) {
|
||||
setStudioId(updatedScene.studio.stored_id);
|
||||
}
|
||||
|
||||
if (scene.performers && scene.performers.length > 0) {
|
||||
const idPerfs = scene.performers.filter((p) => {
|
||||
if (updatedScene.performers && updatedScene.performers.length > 0) {
|
||||
const idPerfs = updatedScene.performers.filter((p) => {
|
||||
return p.stored_id !== undefined && p.stored_id !== null;
|
||||
});
|
||||
|
||||
@@ -476,8 +455,8 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (scene.movies && scene.movies.length > 0) {
|
||||
const idMovis = scene.movies.filter((p) => {
|
||||
if (updatedScene.movies && updatedScene.movies.length > 0) {
|
||||
const idMovis = updatedScene.movies.filter((p) => {
|
||||
return p.stored_id !== undefined && p.stored_id !== null;
|
||||
});
|
||||
|
||||
@@ -487,8 +466,8 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (scene?.tags?.length) {
|
||||
const idTags = scene.tags.filter((p) => {
|
||||
if (updatedScene?.tags?.length) {
|
||||
const idTags = updatedScene.tags.filter((p) => {
|
||||
return p.stored_id !== undefined && p.stored_id !== null;
|
||||
});
|
||||
|
||||
@@ -498,10 +477,10 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (scene.image) {
|
||||
if (updatedScene.image) {
|
||||
// image is a base64 string
|
||||
setCoverImage(scene.image);
|
||||
setCoverImagePreview(scene.image);
|
||||
setCoverImage(updatedScene.image);
|
||||
setCoverImagePreview(updatedScene.image);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +530,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
|
||||
<Button
|
||||
className="edit-button"
|
||||
variant="danger"
|
||||
onClick={() => props.onDelete()}
|
||||
onClick={() => onDelete()}
|
||||
>
|
||||
Delete
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user