diff --git a/ui/v2.5/src/components/Changelog/versions/v0110.md b/ui/v2.5/src/components/Changelog/versions/v0110.md index 7e6bfd2b6..7e160b76f 100644 --- a/ui/v2.5/src/components/Changelog/versions/v0110.md +++ b/ui/v2.5/src/components/Changelog/versions/v0110.md @@ -8,6 +8,7 @@ * Added interface options to disable creating performers/studios/tags from dropdown selectors. ([#1814](https://github.com/stashapp/stash/pull/1814)) ### 🎨 Improvements +* Added stash-id to scene scrape dialog. ([#1955](https://github.com/stashapp/stash/pull/1955)) * Reworked main navbar and positioned at bottom for mobile devices. ([#1769](https://github.com/stashapp/stash/pull/1769)) * Show files being deleted in the Delete dialogs. ([#1852](https://github.com/stashapp/stash/pull/1852)) * Added specific page titles. ([#1831](https://github.com/stashapp/stash/pull/1831)) diff --git a/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx b/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx index 37ac8cbf1..892859129 100644 --- a/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx +++ b/ui/v2.5/src/components/Scenes/SceneDetails/SceneEditPanel.tsx @@ -73,6 +73,7 @@ export const SceneEditPanel: React.FC = ({ setIsScraperQueryModalOpen, ] = useState(false); const [scrapedScene, setScrapedScene] = useState(); + const [endpoint, setEndpoint] = useState(); const [coverImagePreview, setCoverImagePreview] = useState< string | undefined @@ -299,6 +300,7 @@ export const SceneEditPanel: React.FC = ({ } // assume one returned scene setScrapedScene(result.data.scrapeSingleScene[0]); + setEndpoint(s.stash_box_endpoint ?? undefined); } catch (e) { Toast.error(e); } finally { @@ -338,6 +340,7 @@ export const SceneEditPanel: React.FC = ({ function onScrapeQueryClicked(s: GQL.ScraperSourceInput) { setScraper(s); + setEndpoint(s.stash_box_endpoint ?? undefined); setIsScraperQueryModalOpen(true); } @@ -376,6 +379,7 @@ export const SceneEditPanel: React.FC = ({ onScrapeDialogClosed(s)} /> ); @@ -396,7 +400,12 @@ export const SceneEditPanel: React.FC = ({ {stashBoxes.map((s, index) => ( onScrapeQueryClicked({ stash_box_index: index })} + onClick={() => + onScrapeQueryClicked({ + stash_box_index: index, + stash_box_endpoint: s.endpoint, + }) + } > {stashboxDisplayName(s.name, index)} @@ -463,7 +472,12 @@ export const SceneEditPanel: React.FC = ({ {stashBoxes.map((s, index) => ( onScrapeClicked({ stash_box_index: index })} + onClick={() => + onScrapeClicked({ + stash_box_index: index, + stash_box_endpoint: s.endpoint, + }) + } > {stashboxDisplayName(s.name, index)} @@ -555,6 +569,34 @@ export const SceneEditPanel: React.FC = ({ formik.setFieldValue("cover_image", updatedScene.image); setCoverImagePreview(updatedScene.image); } + + if (updatedScene.remote_site_id && endpoint) { + let found = false; + formik.setFieldValue( + "stash_ids", + formik.values.stash_ids.map((s) => { + if (s.endpoint === endpoint) { + found = true; + return { + endpoint, + stash_id: updatedScene.remote_site_id, + }; + } + + return s; + }) + ); + + if (!found) { + formik.setFieldValue( + "stash_ids", + formik.values.stash_ids.concat({ + endpoint, + stash_id: updatedScene.remote_site_id, + }) + ); + } + } } async function onScrapeSceneURL() { @@ -771,41 +813,51 @@ export const SceneEditPanel: React.FC = ({ /> - - StashIDs -
    - {formik.values.stash_ids.map((stashID) => { - const base = stashID.endpoint.match(/https?:\/\/.*?\//)?.[0]; - const link = base ? ( - - {stashID.stash_id} - - ) : ( - stashID.stash_id - ); - return ( -
  • - - {link} -
  • - ); - })} -
-
+ {stashID.stash_id} + + ) : ( + stashID.stash_id + ); + return ( +
  • + + {link} +
  • + ); + })} + + + ) : undefined}
    diff --git a/ui/v2.5/src/components/Scenes/SceneDetails/SceneScrapeDialog.tsx b/ui/v2.5/src/components/Scenes/SceneDetails/SceneScrapeDialog.tsx index 3248beccc..510479aea 100644 --- a/ui/v2.5/src/components/Scenes/SceneDetails/SceneScrapeDialog.tsx +++ b/ui/v2.5/src/components/Scenes/SceneDetails/SceneScrapeDialog.tsx @@ -230,6 +230,7 @@ function renderScrapedTagsRow( interface ISceneScrapeDialogProps { scene: Partial; scraped: GQL.ScrapedScene; + endpoint?: string; onClose: (scrapedScene?: GQL.ScrapedScene) => void; } @@ -238,28 +239,33 @@ interface IHasStoredID { stored_id?: string | null; } -export const SceneScrapeDialog: React.FC = ( - props: ISceneScrapeDialogProps -) => { +export const SceneScrapeDialog: React.FC = ({ + scene, + scraped, + onClose, + endpoint, +}) => { const [title, setTitle] = useState>( - new ScrapeResult(props.scene.title, props.scraped.title) + new ScrapeResult(scene.title, scraped.title) ); const [url, setURL] = useState>( - new ScrapeResult(props.scene.url, props.scraped.url) + new ScrapeResult(scene.url, scraped.url) ); const [date, setDate] = useState>( - new ScrapeResult(props.scene.date, props.scraped.date) + new ScrapeResult(scene.date, scraped.date) ); const [studio, setStudio] = useState>( - new ScrapeResult( - props.scene.studio_id, - props.scraped.studio?.stored_id - ) + new ScrapeResult(scene.studio_id, scraped.studio?.stored_id) ); const [newStudio, setNewStudio] = useState( - props.scraped.studio && !props.scraped.studio.stored_id - ? props.scraped.studio - : undefined + scraped.studio && !scraped.studio.stored_id ? scraped.studio : undefined + ); + + const [stashID, setStashID] = useState( + new ScrapeResult( + scene.stash_ids?.find((s) => s.endpoint === endpoint)?.stash_id, + scraped.remote_site_id + ) ); function mapStoredIdObjects( @@ -302,39 +308,39 @@ export const SceneScrapeDialog: React.FC = ( const [performers, setPerformers] = useState>( new ScrapeResult( - sortIdList(props.scene.performer_ids), - mapStoredIdObjects(props.scraped.performers ?? undefined) + sortIdList(scene.performer_ids), + mapStoredIdObjects(scraped.performers ?? undefined) ) ); const [newPerformers, setNewPerformers] = useState( - props.scraped.performers?.filter((t) => !t.stored_id) ?? [] + scraped.performers?.filter((t) => !t.stored_id) ?? [] ); const [movies, setMovies] = useState>( new ScrapeResult( - sortIdList(props.scene.movies?.map((p) => p.movie_id)), - mapStoredIdObjects(props.scraped.movies ?? undefined) + sortIdList(scene.movies?.map((p) => p.movie_id)), + mapStoredIdObjects(scraped.movies ?? undefined) ) ); const [newMovies, setNewMovies] = useState( - props.scraped.movies?.filter((t) => !t.stored_id) ?? [] + scraped.movies?.filter((t) => !t.stored_id) ?? [] ); const [tags, setTags] = useState>( new ScrapeResult( - sortIdList(props.scene.tag_ids), - mapStoredIdObjects(props.scraped.tags ?? undefined) + sortIdList(scene.tag_ids), + mapStoredIdObjects(scraped.tags ?? undefined) ) ); const [newTags, setNewTags] = useState( - props.scraped.tags?.filter((t) => !t.stored_id) ?? [] + scraped.tags?.filter((t) => !t.stored_id) ?? [] ); const [details, setDetails] = useState>( - new ScrapeResult(props.scene.details, props.scraped.details) + new ScrapeResult(scene.details, scraped.details) ); const [image, setImage] = useState>( - new ScrapeResult(props.scene.cover_image, props.scraped.image) + new ScrapeResult(scene.cover_image, scraped.image) ); const [createStudio] = useStudioCreate(); @@ -347,11 +353,20 @@ export const SceneScrapeDialog: React.FC = ( // don't show the dialog if nothing was scraped if ( - [title, url, date, studio, performers, movies, tags, details, image].every( - (r) => !r.scraped - ) + [ + title, + url, + date, + studio, + performers, + movies, + tags, + details, + image, + stashID, + ].every((r) => !r.scraped) ) { - props.onClose(); + onClose(); return <>; } @@ -535,6 +550,7 @@ export const SceneScrapeDialog: React.FC = ( }), details: details.getNewValue(), image: image.getNewValue(), + remote_site_id: stashID.getNewValue(), }; } @@ -590,6 +606,12 @@ export const SceneScrapeDialog: React.FC = ( result={details} onChange={(value) => setDetails(value)} /> + setStashID(value)} + /> = ( )} renderScrapeRows={renderScrapeRows} onClose={(apply) => { - props.onClose(apply ? makeNewScrapedItem() : undefined); + onClose(apply ? makeNewScrapedItem() : undefined); }} /> );