Allow customisation of preview generation (#673)

* Add generate-specific options
* Include no-cache in preview response
This commit is contained in:
WithoutPants
2020-07-23 12:51:35 +10:00
committed by GitHub
parent 37be146a9d
commit a2341f0819
18 changed files with 509 additions and 53 deletions

View File

@@ -1,8 +1,12 @@
import React, { useState } from "react";
import { Form } from "react-bootstrap";
import { mutateMetadataGenerate } from "src/core/StashService";
import { Modal } from "src/components/Shared";
import React, { useState, useEffect } from "react";
import { Form, Button, Collapse } from "react-bootstrap";
import {
mutateMetadataGenerate,
useConfiguration,
} from "src/core/StashService";
import { Modal, Icon } from "src/components/Shared";
import { useToast } from "src/hooks";
import * as GQL from "src/core/generated-graphql";
interface ISceneGenerateDialogProps {
selectedIds: string[];
@@ -12,6 +16,8 @@ interface ISceneGenerateDialogProps {
export const SceneGenerateDialog: React.FC<ISceneGenerateDialogProps> = (
props: ISceneGenerateDialogProps
) => {
const { data, error, loading } = useConfiguration();
const [sprites, setSprites] = useState(true);
const [previews, setPreviews] = useState(true);
const [markers, setMarkers] = useState(true);
@@ -19,8 +25,37 @@ export const SceneGenerateDialog: React.FC<ISceneGenerateDialogProps> = (
const [overwrite, setOverwrite] = useState(true);
const [imagePreviews, setImagePreviews] = useState(false);
const [previewSegments, setPreviewSegments] = useState<number>(0);
const [previewSegmentDuration, setPreviewSegmentDuration] = useState<number>(
0
);
const [previewExcludeStart, setPreviewExcludeStart] = useState<
string | undefined
>(undefined);
const [previewExcludeEnd, setPreviewExcludeEnd] = useState<
string | undefined
>(undefined);
const [previewPreset, setPreviewPreset] = useState<string>(
GQL.PreviewPreset.Slow
);
const [previewOptionsOpen, setPreviewOptionsOpen] = useState(false);
const Toast = useToast();
useEffect(() => {
if (!data?.configuration) return;
const conf = data.configuration;
if (conf.general) {
setPreviewSegments(conf.general.previewSegments);
setPreviewSegmentDuration(conf.general.previewSegmentDuration);
setPreviewExcludeStart(conf.general.previewExcludeStart);
setPreviewExcludeEnd(conf.general.previewExcludeEnd);
setPreviewPreset(conf.general.previewPreset);
}
}, [data]);
async function onGenerate() {
try {
await mutateMetadataGenerate({
@@ -32,6 +67,13 @@ export const SceneGenerateDialog: React.FC<ISceneGenerateDialogProps> = (
thumbnails: false,
overwrite,
sceneIDs: props.selectedIds,
previewOptions: {
previewPreset: (previewPreset as GQL.PreviewPreset) ?? undefined,
previewSegments,
previewSegmentDuration,
previewExcludeStart,
previewExcludeEnd,
},
});
Toast.success({ content: "Started generating" });
} catch (e) {
@@ -41,6 +83,15 @@ export const SceneGenerateDialog: React.FC<ISceneGenerateDialogProps> = (
}
}
if (error) {
Toast.error(error);
props.onClose();
}
if (loading) {
return <></>;
}
return (
<Modal
show
@@ -72,6 +123,109 @@ export const SceneGenerateDialog: React.FC<ISceneGenerateDialogProps> = (
className="ml-2 flex-grow"
/>
</div>
<div className="my-2">
<Button
onClick={() => setPreviewOptionsOpen(!previewOptionsOpen)}
className="minimal pl-0 no-focus"
>
<Icon
icon={previewOptionsOpen ? "chevron-down" : "chevron-right"}
/>
<span>Preview Options</span>
</Button>
<Collapse in={previewOptionsOpen}>
<div>
<Form.Group id="transcode-size">
<h6>Preview encoding preset</h6>
<Form.Control
className="w-auto input-control"
as="select"
value={previewPreset}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
setPreviewPreset(e.currentTarget.value)
}
>
{Object.keys(GQL.PreviewPreset).map((p) => (
<option value={p.toLowerCase()} key={p}>
{p}
</option>
))}
</Form.Control>
<Form.Text className="text-muted">
The preset regulates size, quality and encoding time of
preview generation. Presets beyond slow have diminishing
returns and are not recommended.
</Form.Text>
</Form.Group>
<Form.Group id="preview-segments">
<h6>Number of segments in preview</h6>
<Form.Control
className="col col-sm-6 text-input"
type="number"
value={previewSegments.toString()}
onInput={(e: React.FormEvent<HTMLInputElement>) =>
setPreviewSegments(
Number.parseInt(e.currentTarget.value, 10)
)
}
/>
<Form.Text className="text-muted">
Number of segments in preview files.
</Form.Text>
</Form.Group>
<Form.Group id="preview-segment-duration">
<h6>Preview segment duration</h6>
<Form.Control
className="col col-sm-6 text-input"
type="number"
value={previewSegmentDuration.toString()}
onInput={(e: React.FormEvent<HTMLInputElement>) =>
setPreviewSegmentDuration(
Number.parseFloat(e.currentTarget.value)
)
}
/>
<Form.Text className="text-muted">
Duration of each preview segment, in seconds.
</Form.Text>
</Form.Group>
<Form.Group id="preview-exclude-start">
<h6>Exclude start time</h6>
<Form.Control
className="col col-sm-6 text-input"
defaultValue={previewExcludeStart}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPreviewExcludeStart(e.currentTarget.value)
}
/>
<Form.Text className="text-muted">
Exclude the first x seconds from scene previews. This can be
a value in seconds, or a percentage (eg 2%) of the total
scene duration.
</Form.Text>
</Form.Group>
<Form.Group id="preview-exclude-start">
<h6>Exclude end time</h6>
<Form.Control
className="col col-sm-6 text-input"
defaultValue={previewExcludeEnd}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPreviewExcludeEnd(e.currentTarget.value)
}
/>
<Form.Text className="text-muted">
Exclude the last x seconds from scene previews. This can be
a value in seconds, or a percentage (eg 2%) of the total
scene duration.
</Form.Text>
</Form.Group>
</div>
</Collapse>
</div>
<Form.Check
id="sprite-task"
checked={sprites}