import React, { useEffect, useState } from "react"; import { Button, Form, Col, Row } from "react-bootstrap"; import * as GQL from "src/core/generated-graphql"; import { useImageUpdate } from "src/core/StashService"; import { PerformerSelect, TagSelect, StudioSelect, LoadingIndicator, } from "src/components/Shared"; import { useToast } from "src/hooks"; import { FormUtils } from "src/utils"; import { RatingStars } from "src/components/Scenes/SceneDetails/RatingStars"; interface IProps { image: GQL.ImageDataFragment; isVisible: boolean; onUpdate: (image: GQL.ImageDataFragment) => void; onDelete: () => void; } export const ImageEditPanel: React.FC = (props: IProps) => { const Toast = useToast(); const [title, setTitle] = useState(); const [rating, setRating] = useState(); const [studioId, setStudioId] = useState(); const [performerIds, setPerformerIds] = useState(); const [tagIds, setTagIds] = useState(); // Network state const [isLoading, setIsLoading] = useState(true); const [updateImage] = useImageUpdate(getImageInput()); useEffect(() => { if (props.isVisible) { Mousetrap.bind("s s", () => { onSave(); }); Mousetrap.bind("d d", () => { props.onDelete(); }); // numeric keypresses get caught by jwplayer, so blur the element // if the rating sequence is started Mousetrap.bind("r", () => { if (document.activeElement instanceof HTMLElement) { document.activeElement.blur(); } Mousetrap.bind("0", () => setRating(NaN)); Mousetrap.bind("1", () => setRating(1)); Mousetrap.bind("2", () => setRating(2)); Mousetrap.bind("3", () => setRating(3)); Mousetrap.bind("4", () => setRating(4)); Mousetrap.bind("5", () => setRating(5)); setTimeout(() => { Mousetrap.unbind("0"); Mousetrap.unbind("1"); Mousetrap.unbind("2"); Mousetrap.unbind("3"); Mousetrap.unbind("4"); Mousetrap.unbind("5"); }, 1000); }); return () => { Mousetrap.unbind("s s"); Mousetrap.unbind("d d"); Mousetrap.unbind("r"); }; } }); function updateImageEditState(state: Partial) { 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, title, rating, studio_id: studioId, performer_ids: performerIds, tag_ids: tagIds, }; } async function onSave() { setIsLoading(true); try { const result = await updateImage(); if (result.data?.imageUpdate) { props.onUpdate(result.data.imageUpdate); Toast.success({ content: "Updated image" }); } } catch (e) { Toast.error(e); } setIsLoading(false); } if (isLoading) return ; return (
{FormUtils.renderInputGroup({ title: "Title", value: title, onChange: setTitle, isEditing: true, })} {FormUtils.renderLabel({ title: "Rating", })} setRating(value)} /> {FormUtils.renderLabel({ title: "Studio", })} setStudioId(items.length > 0 ? items[0]?.id : undefined) } ids={studioId ? [studioId] : []} /> {FormUtils.renderLabel({ title: "Performers", labelProps: { column: true, sm: 3, xl: 12, }, })} setPerformerIds(items.map((item) => item.id)) } ids={performerIds} /> {FormUtils.renderLabel({ title: "Tags", labelProps: { column: true, sm: 3, xl: 12, }, })} setTagIds(items.map((item) => item.id))} ids={tagIds} />
); };