FR: Add Delete Button For Scene Covers (#6444)

This commit is contained in:
Gykes 2026-01-13 19:13:41 -08:00 committed by GitHub
parent 77d0008c6d
commit 0fa132cf60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 9 deletions

View file

@ -297,6 +297,7 @@ func (r *mutationResolver) sceneUpdate(ctx context.Context, input models.SceneUp
} }
var coverImageData []byte var coverImageData []byte
coverImageIncluded := translator.hasField("cover_image")
if input.CoverImage != nil { if input.CoverImage != nil {
var err error var err error
coverImageData, err = utils.ProcessImageInput(ctx, *input.CoverImage) coverImageData, err = utils.ProcessImageInput(ctx, *input.CoverImage)
@ -310,21 +311,21 @@ func (r *mutationResolver) sceneUpdate(ctx context.Context, input models.SceneUp
return nil, err return nil, err
} }
if err := r.sceneUpdateCoverImage(ctx, scene, coverImageData); err != nil { if coverImageIncluded {
return nil, err if err := r.sceneUpdateCoverImage(ctx, scene, coverImageData); err != nil {
return nil, err
}
} }
return scene, nil return scene, nil
} }
func (r *mutationResolver) sceneUpdateCoverImage(ctx context.Context, s *models.Scene, coverImageData []byte) error { func (r *mutationResolver) sceneUpdateCoverImage(ctx context.Context, s *models.Scene, coverImageData []byte) error {
if len(coverImageData) > 0 { qb := r.repository.Scene
qb := r.repository.Scene
// update cover table // update cover table - empty data will clear the cover
if err := qb.UpdateCover(ctx, s.ID, coverImageData); err != nil { if err := qb.UpdateCover(ctx, s.ID, coverImageData); err != nil {
return err return err
}
} }
return nil return nil

View file

@ -12,6 +12,7 @@ import (
"github.com/stashapp/stash/internal/manager" "github.com/stashapp/stash/internal/manager"
"github.com/stashapp/stash/internal/manager/config" "github.com/stashapp/stash/internal/manager/config"
"github.com/stashapp/stash/internal/static"
"github.com/stashapp/stash/pkg/ffmpeg" "github.com/stashapp/stash/pkg/ffmpeg"
"github.com/stashapp/stash/pkg/file/video" "github.com/stashapp/stash/pkg/file/video"
"github.com/stashapp/stash/pkg/fsutil" "github.com/stashapp/stash/pkg/fsutil"
@ -243,6 +244,12 @@ func (rs sceneRoutes) streamSegment(w http.ResponseWriter, r *http.Request, stre
} }
func (rs sceneRoutes) Screenshot(w http.ResponseWriter, r *http.Request) { func (rs sceneRoutes) Screenshot(w http.ResponseWriter, r *http.Request) {
// if default flag is set, return the default image
if r.URL.Query().Get("default") == "true" {
utils.ServeImage(w, r, static.ReadAll(static.DefaultSceneImage))
return
}
scene := r.Context().Value(sceneKey).(*models.Scene) scene := r.Context().Value(sceneKey).(*models.Scene)
ss := manager.SceneServer{ ss := manager.SceneServer{

View file

@ -302,6 +302,10 @@ export const SceneEditPanel: React.FC<IProps> = ({
ImageUtils.onImageChange(event, onImageLoad); ImageUtils.onImageChange(event, onImageLoad);
} }
function onResetCover() {
formik.setFieldValue("cover_image", null);
}
async function onScrapeClicked(s: GQL.ScraperSourceInput) { async function onScrapeClicked(s: GQL.ScraperSourceInput) {
setIsLoading(true); setIsLoading(true);
try { try {
@ -856,6 +860,7 @@ export const SceneEditPanel: React.FC<IProps> = ({
isEditing isEditing
onImageChange={onCoverImageChange} onImageChange={onCoverImageChange}
onImageURL={onImageLoad} onImageURL={onImageLoad}
onReset={scene.id ? onResetCover : undefined}
/> />
</Form.Group> </Form.Group>
</Col> </Col>

View file

@ -18,6 +18,7 @@ interface IImageInput {
text?: string; text?: string;
onImageChange: (event: React.ChangeEvent<HTMLInputElement>) => void; onImageChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
onImageURL?: (url: string) => void; onImageURL?: (url: string) => void;
onReset?: () => void;
acceptSVG?: boolean; acceptSVG?: boolean;
} }
@ -27,7 +28,14 @@ function acceptExtensions(acceptSVG: boolean = false) {
export const ImageInput: React.FC<IImageInput> = PatchComponent( export const ImageInput: React.FC<IImageInput> = PatchComponent(
"ImageInput", "ImageInput",
({ isEditing, text, onImageChange, onImageURL, acceptSVG = false }) => { ({
isEditing,
text,
onImageChange,
onImageURL,
onReset,
acceptSVG = false,
}) => {
const [isShowDialog, setIsShowDialog] = useState(false); const [isShowDialog, setIsShowDialog] = useState(false);
const [url, setURL] = useState(""); const [url, setURL] = useState("");
const intl = useIntl(); const intl = useIntl();
@ -137,6 +145,11 @@ export const ImageInput: React.FC<IImageInput> = PatchComponent(
{text ?? intl.formatMessage({ id: "actions.set_image" })} {text ?? intl.formatMessage({ id: "actions.set_image" })}
</Button> </Button>
</OverlayTrigger> </OverlayTrigger>
{onReset && (
<Button variant="danger" className="mr-2" onClick={onReset}>
{intl.formatMessage({ id: "actions.clear_image" })}
</Button>
)}
</> </>
); );
} }