Support deleting multiple scenes (#630)

* Improve layout and add buttons
* Move functionality into ListFilter
* Make modal style dark
* Convert scene options into edit scenes dialog
* Add delete scenes dialog
* Clear selected ids on delete
* Refetch after update/delete
* Use DeleteScenesDialog in Scene page
* Show scene check boxes in small screens
* Change default multi-set mode to set
This commit is contained in:
WithoutPants
2020-06-23 10:40:11 +10:00
committed by GitHub
parent 83f8bc0832
commit 455e16ece9
20 changed files with 613 additions and 366 deletions

View File

@@ -1,4 +1,4 @@
import { Tab, Nav, Dropdown, Form } from "react-bootstrap";
import { Tab, Nav, Dropdown } from "react-bootstrap";
import queryString from "query-string";
import React, { useEffect, useState } from "react";
import { useParams, useLocation, useHistory, Link } from "react-router-dom";
@@ -9,10 +9,9 @@ import {
useSceneDecrementO,
useSceneResetO,
useSceneGenerateScreenshot,
useSceneDestroy,
} from "src/core/StashService";
import { GalleryViewer } from "src/components/Galleries/GalleryViewer";
import { LoadingIndicator, Icon, Modal } from "src/components/Shared";
import { LoadingIndicator, Icon } from "src/components/Shared";
import { useToast } from "src/hooks";
import { ScenePlayer } from "src/components/ScenePlayer";
import { TextUtils, JWUtils } from "src/utils";
@@ -22,6 +21,7 @@ import { SceneEditPanel } from "./SceneEditPanel";
import { SceneDetailPanel } from "./SceneDetailPanel";
import { OCounterButton } from "./OCounterButton";
import { SceneMoviePanel } from "./SceneMoviePanel";
import { DeleteScenesDialog } from "../DeleteScenesDialog";
export const Scene: React.FC = () => {
const { id = "new" } = useParams();
@@ -39,10 +39,6 @@ export const Scene: React.FC = () => {
const [resetO] = useSceneResetO(scene?.id ?? "0");
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
const [deleteFile, setDeleteFile] = useState<boolean>(false);
const [deleteGenerated, setDeleteGenerated] = useState<boolean>(true);
const [deleteLoading, setDeleteLoading] = useState(false);
const [deleteScene] = useSceneDestroy(getSceneDeleteInput());
const queryParams = queryString.parse(location.search);
const autoplay = queryParams?.autoplay === "true";
@@ -120,54 +116,19 @@ export const Scene: React.FC = () => {
Toast.success({ content: "Generating screenshot" });
}
function getSceneDeleteInput(): GQL.SceneDestroyInput {
return {
id: scene?.id ?? "0",
delete_file: deleteFile,
delete_generated: deleteGenerated,
};
}
async function onDelete() {
function onDeleteDialogClosed(deleted: boolean) {
setIsDeleteAlertOpen(false);
setDeleteLoading(true);
try {
await deleteScene();
Toast.success({ content: "Deleted scene" });
} catch (e) {
Toast.error(e);
if (deleted) {
history.push("/scenes");
}
setDeleteLoading(false);
history.push("/scenes");
}
function renderDeleteAlert() {
return (
<Modal
show={isDeleteAlertOpen}
icon="trash-alt"
header="Delete Scene?"
accept={{ variant: "danger", onClick: onDelete, text: "Delete" }}
cancel={{ onClick: () => setIsDeleteAlertOpen(false), text: "Cancel" }}
>
<p>
Are you sure you want to delete this scene? Unless the file is also
deleted, this scene will be re-added when scan is performed.
</p>
<Form>
<Form.Check
checked={deleteFile}
label="Delete file"
onChange={() => setDeleteFile(!deleteFile)}
/>
<Form.Check
checked={deleteGenerated}
label="Delete generated supporting files"
onChange={() => setDeleteGenerated(!deleteGenerated)}
/>
</Form>
</Modal>
);
function maybeRenderDeleteDialog() {
if (isDeleteAlertOpen && scene) {
return (
<DeleteScenesDialog selected={[scene]} onClose={onDeleteDialogClosed} />
);
}
}
function renderOperations() {
@@ -294,7 +255,7 @@ export const Scene: React.FC = () => {
);
}
if (deleteLoading || loading || !scene || !data?.findScene) {
if (loading || !scene || !data?.findScene) {
return <LoadingIndicator />;
}
@@ -302,7 +263,7 @@ export const Scene: React.FC = () => {
return (
<div className="row">
{renderDeleteAlert()}
{maybeRenderDeleteDialog()}
<div className="scene-tabs order-xl-first order-last">
<div className="d-none d-xl-block">
{scene.studio && (