mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
* Add ids to findMovies input * Use ids for other find interfaces * Update client side * Fix gallery select function * Replace movie select * Re-add creatable * Overhaul movie table * Remove and deprecated unused code
324 lines
9.0 KiB
TypeScript
324 lines
9.0 KiB
TypeScript
import React, { useState } from "react";
|
|
import * as GQL from "src/core/generated-graphql";
|
|
import {
|
|
ScrapeDialog,
|
|
ScrapedInputGroupRow,
|
|
ScrapedTextAreaRow,
|
|
ScrapedImageRow,
|
|
ScrapedStringListRow,
|
|
} from "src/components/Shared/ScrapeDialog/ScrapeDialog";
|
|
import { useIntl } from "react-intl";
|
|
import { uniq } from "lodash-es";
|
|
import { Performer } from "src/components/Performers/PerformerSelect";
|
|
import { sortStoredIdObjects } from "src/utils/data";
|
|
import {
|
|
ObjectListScrapeResult,
|
|
ObjectScrapeResult,
|
|
ScrapeResult,
|
|
} from "src/components/Shared/ScrapeDialog/scrapeResult";
|
|
import {
|
|
ScrapedMoviesRow,
|
|
ScrapedPerformersRow,
|
|
ScrapedStudioRow,
|
|
ScrapedTagsRow,
|
|
} from "src/components/Shared/ScrapeDialog/ScrapedObjectsRow";
|
|
import {
|
|
useCreateScrapedMovie,
|
|
useCreateScrapedPerformer,
|
|
useCreateScrapedStudio,
|
|
useCreateScrapedTag,
|
|
} from "src/components/Shared/ScrapeDialog/createObjects";
|
|
import { Tag } from "src/components/Tags/TagSelect";
|
|
import { Studio } from "src/components/Studios/StudioSelect";
|
|
import { Movie } from "src/components/Movies/MovieSelect";
|
|
|
|
interface ISceneScrapeDialogProps {
|
|
scene: Partial<GQL.SceneUpdateInput>;
|
|
sceneStudio: Studio | null;
|
|
scenePerformers: Performer[];
|
|
sceneTags: Tag[];
|
|
sceneMovies: Movie[];
|
|
scraped: GQL.ScrapedScene;
|
|
endpoint?: string;
|
|
|
|
onClose: (scrapedScene?: GQL.ScrapedScene) => void;
|
|
}
|
|
|
|
export const SceneScrapeDialog: React.FC<ISceneScrapeDialogProps> = ({
|
|
scene,
|
|
sceneStudio,
|
|
scenePerformers,
|
|
sceneTags,
|
|
sceneMovies,
|
|
scraped,
|
|
onClose,
|
|
endpoint,
|
|
}) => {
|
|
const [title, setTitle] = useState<ScrapeResult<string>>(
|
|
new ScrapeResult<string>(scene.title, scraped.title)
|
|
);
|
|
const [code, setCode] = useState<ScrapeResult<string>>(
|
|
new ScrapeResult<string>(scene.code, scraped.code)
|
|
);
|
|
|
|
const [urls, setURLs] = useState<ScrapeResult<string[]>>(
|
|
new ScrapeResult<string[]>(
|
|
scene.urls,
|
|
scraped.urls
|
|
? uniq((scene.urls ?? []).concat(scraped.urls ?? []))
|
|
: undefined
|
|
)
|
|
);
|
|
|
|
const [date, setDate] = useState<ScrapeResult<string>>(
|
|
new ScrapeResult<string>(scene.date, scraped.date)
|
|
);
|
|
const [director, setDirector] = useState<ScrapeResult<string>>(
|
|
new ScrapeResult<string>(scene.director, scraped.director)
|
|
);
|
|
const [studio, setStudio] = useState<ObjectScrapeResult<GQL.ScrapedStudio>>(
|
|
new ObjectScrapeResult<GQL.ScrapedStudio>(
|
|
sceneStudio
|
|
? {
|
|
stored_id: sceneStudio.id,
|
|
name: sceneStudio.name,
|
|
}
|
|
: undefined,
|
|
scraped.studio?.stored_id ? scraped.studio : undefined
|
|
)
|
|
);
|
|
const [newStudio, setNewStudio] = useState<GQL.ScrapedStudio | undefined>(
|
|
scraped.studio && !scraped.studio.stored_id ? scraped.studio : undefined
|
|
);
|
|
|
|
const [stashID, setStashID] = useState(
|
|
new ScrapeResult<string>(
|
|
scene.stash_ids?.find((s) => s.endpoint === endpoint)?.stash_id,
|
|
scraped.remote_site_id
|
|
)
|
|
);
|
|
|
|
const [performers, setPerformers] = useState<
|
|
ObjectListScrapeResult<GQL.ScrapedPerformer>
|
|
>(
|
|
new ObjectListScrapeResult<GQL.ScrapedPerformer>(
|
|
sortStoredIdObjects(
|
|
scenePerformers.map((p) => ({
|
|
stored_id: p.id,
|
|
name: p.name,
|
|
}))
|
|
),
|
|
sortStoredIdObjects(scraped.performers ?? undefined)
|
|
)
|
|
);
|
|
const [newPerformers, setNewPerformers] = useState<GQL.ScrapedPerformer[]>(
|
|
scraped.performers?.filter((t) => !t.stored_id) ?? []
|
|
);
|
|
|
|
const [movies, setMovies] = useState<
|
|
ObjectListScrapeResult<GQL.ScrapedMovie>
|
|
>(
|
|
new ObjectListScrapeResult<GQL.ScrapedMovie>(
|
|
sortStoredIdObjects(
|
|
sceneMovies.map((p) => ({
|
|
stored_id: p.id,
|
|
name: p.name,
|
|
}))
|
|
),
|
|
sortStoredIdObjects(scraped.movies ?? undefined)
|
|
)
|
|
);
|
|
const [newMovies, setNewMovies] = useState<GQL.ScrapedMovie[]>(
|
|
scraped.movies?.filter((t) => !t.stored_id) ?? []
|
|
);
|
|
|
|
const [tags, setTags] = useState<ObjectListScrapeResult<GQL.ScrapedTag>>(
|
|
new ObjectListScrapeResult<GQL.ScrapedTag>(
|
|
sortStoredIdObjects(
|
|
sceneTags.map((t) => ({
|
|
stored_id: t.id,
|
|
name: t.name,
|
|
}))
|
|
),
|
|
sortStoredIdObjects(scraped.tags ?? undefined)
|
|
)
|
|
);
|
|
const [newTags, setNewTags] = useState<GQL.ScrapedTag[]>(
|
|
scraped.tags?.filter((t) => !t.stored_id) ?? []
|
|
);
|
|
|
|
const [details, setDetails] = useState<ScrapeResult<string>>(
|
|
new ScrapeResult<string>(scene.details, scraped.details)
|
|
);
|
|
|
|
const [image, setImage] = useState<ScrapeResult<string>>(
|
|
new ScrapeResult<string>(scene.cover_image, scraped.image)
|
|
);
|
|
|
|
const createNewStudio = useCreateScrapedStudio({
|
|
scrapeResult: studio,
|
|
setScrapeResult: setStudio,
|
|
setNewObject: setNewStudio,
|
|
});
|
|
|
|
const createNewPerformer = useCreateScrapedPerformer({
|
|
scrapeResult: performers,
|
|
setScrapeResult: setPerformers,
|
|
newObjects: newPerformers,
|
|
setNewObjects: setNewPerformers,
|
|
});
|
|
|
|
const createNewMovie = useCreateScrapedMovie({
|
|
scrapeResult: movies,
|
|
setScrapeResult: setMovies,
|
|
newObjects: newMovies,
|
|
setNewObjects: setNewMovies,
|
|
});
|
|
|
|
const createNewTag = useCreateScrapedTag({
|
|
scrapeResult: tags,
|
|
setScrapeResult: setTags,
|
|
newObjects: newTags,
|
|
setNewObjects: setNewTags,
|
|
});
|
|
|
|
const intl = useIntl();
|
|
|
|
// don't show the dialog if nothing was scraped
|
|
if (
|
|
[
|
|
title,
|
|
code,
|
|
urls,
|
|
date,
|
|
director,
|
|
studio,
|
|
performers,
|
|
movies,
|
|
tags,
|
|
details,
|
|
image,
|
|
stashID,
|
|
].every((r) => !r.scraped) &&
|
|
newTags.length === 0 &&
|
|
newPerformers.length === 0 &&
|
|
newMovies.length === 0 &&
|
|
!newStudio
|
|
) {
|
|
onClose();
|
|
return <></>;
|
|
}
|
|
|
|
function makeNewScrapedItem(): GQL.ScrapedSceneDataFragment {
|
|
const newStudioValue = studio.getNewValue();
|
|
|
|
return {
|
|
title: title.getNewValue(),
|
|
code: code.getNewValue(),
|
|
urls: urls.getNewValue(),
|
|
date: date.getNewValue(),
|
|
director: director.getNewValue(),
|
|
studio: newStudioValue,
|
|
performers: performers.getNewValue(),
|
|
movies: movies.getNewValue(),
|
|
tags: tags.getNewValue(),
|
|
details: details.getNewValue(),
|
|
image: image.getNewValue(),
|
|
remote_site_id: stashID.getNewValue(),
|
|
};
|
|
}
|
|
|
|
function renderScrapeRows() {
|
|
return (
|
|
<>
|
|
<ScrapedInputGroupRow
|
|
title={intl.formatMessage({ id: "title" })}
|
|
result={title}
|
|
onChange={(value) => setTitle(value)}
|
|
/>
|
|
<ScrapedInputGroupRow
|
|
title={intl.formatMessage({ id: "scene_code" })}
|
|
result={code}
|
|
onChange={(value) => setCode(value)}
|
|
/>
|
|
<ScrapedStringListRow
|
|
title={intl.formatMessage({ id: "urls" })}
|
|
result={urls}
|
|
onChange={(value) => setURLs(value)}
|
|
/>
|
|
<ScrapedInputGroupRow
|
|
title={intl.formatMessage({ id: "date" })}
|
|
placeholder="YYYY-MM-DD"
|
|
result={date}
|
|
onChange={(value) => setDate(value)}
|
|
/>
|
|
<ScrapedInputGroupRow
|
|
title={intl.formatMessage({ id: "director" })}
|
|
result={director}
|
|
onChange={(value) => setDirector(value)}
|
|
/>
|
|
<ScrapedStudioRow
|
|
title={intl.formatMessage({ id: "studios" })}
|
|
result={studio}
|
|
onChange={(value) => setStudio(value)}
|
|
newStudio={newStudio}
|
|
onCreateNew={createNewStudio}
|
|
/>
|
|
<ScrapedPerformersRow
|
|
title={intl.formatMessage({ id: "performers" })}
|
|
result={performers}
|
|
onChange={(value) => setPerformers(value)}
|
|
newObjects={newPerformers}
|
|
onCreateNew={createNewPerformer}
|
|
/>
|
|
<ScrapedMoviesRow
|
|
title={intl.formatMessage({ id: "movies" })}
|
|
result={movies}
|
|
onChange={(value) => setMovies(value)}
|
|
newObjects={newMovies}
|
|
onCreateNew={createNewMovie}
|
|
/>
|
|
<ScrapedTagsRow
|
|
title={intl.formatMessage({ id: "tags" })}
|
|
result={tags}
|
|
onChange={(value) => setTags(value)}
|
|
newObjects={newTags}
|
|
onCreateNew={createNewTag}
|
|
/>
|
|
<ScrapedTextAreaRow
|
|
title={intl.formatMessage({ id: "details" })}
|
|
result={details}
|
|
onChange={(value) => setDetails(value)}
|
|
/>
|
|
<ScrapedInputGroupRow
|
|
title={intl.formatMessage({ id: "stash_id" })}
|
|
result={stashID}
|
|
locked
|
|
onChange={(value) => setStashID(value)}
|
|
/>
|
|
<ScrapedImageRow
|
|
title={intl.formatMessage({ id: "cover_image" })}
|
|
className="scene-cover"
|
|
result={image}
|
|
onChange={(value) => setImage(value)}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<ScrapeDialog
|
|
title={intl.formatMessage(
|
|
{ id: "dialogs.scrape_entity_title" },
|
|
{ entity_type: intl.formatMessage({ id: "scene" }) }
|
|
)}
|
|
renderScrapeRows={renderScrapeRows}
|
|
onClose={(apply) => {
|
|
onClose(apply ? makeNewScrapedItem() : undefined);
|
|
}}
|
|
/>
|
|
);
|
|
};
|
|
|
|
export default SceneScrapeDialog;
|