mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 12:54:38 +03:00
Add Studio Code and Photographer to Galleries. (#4195)
* Added Studio Code and Photographer to Galleries * Fix gallery display on mobile * Fixed potential panic when scraping with a bad configuration --------- Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
@@ -24,7 +24,7 @@ export const GalleryDetailPanel: React.FC<IGalleryDetailProps> = ({
|
||||
return (
|
||||
<>
|
||||
<h6>
|
||||
<FormattedMessage id="details" />
|
||||
<FormattedMessage id="details" />:{" "}
|
||||
</h6>
|
||||
<p className="pre">{gallery.details}</p>
|
||||
</>
|
||||
@@ -111,6 +111,16 @@ export const GalleryDetailPanel: React.FC<IGalleryDetailProps> = ({
|
||||
<FormattedMessage id="updated_at" />:{" "}
|
||||
{TextUtils.formatDateTime(intl, gallery.updated_at)}{" "}
|
||||
</h6>
|
||||
{gallery.code && (
|
||||
<h6>
|
||||
<FormattedMessage id="scene_code" />: {gallery.code}{" "}
|
||||
</h6>
|
||||
)}
|
||||
{gallery.photographer && (
|
||||
<h6>
|
||||
<FormattedMessage id="photographer" />: {gallery.photographer}{" "}
|
||||
</h6>
|
||||
)}
|
||||
</div>
|
||||
{gallery.studio && (
|
||||
<div className="col-3 d-xl-none">
|
||||
|
||||
@@ -86,8 +86,10 @@ export const GalleryEditPanel: React.FC<IProps> = ({
|
||||
|
||||
const schema = yup.object({
|
||||
title: titleRequired ? yup.string().required() : yup.string().ensure(),
|
||||
code: yup.string().ensure(),
|
||||
urls: yupUniqueStringList("urls"),
|
||||
date: yupDateString(intl),
|
||||
photographer: yup.string().ensure(),
|
||||
rating100: yup.number().integer().nullable().defined(),
|
||||
studio_id: yup.string().required().nullable(),
|
||||
performer_ids: yup.array(yup.string().required()).defined(),
|
||||
@@ -98,8 +100,10 @@ export const GalleryEditPanel: React.FC<IProps> = ({
|
||||
|
||||
const initialValues = {
|
||||
title: gallery?.title ?? "",
|
||||
code: gallery?.code ?? "",
|
||||
urls: gallery?.urls ?? [],
|
||||
date: gallery?.date ?? "",
|
||||
photographer: gallery?.photographer ?? "",
|
||||
rating100: gallery?.rating100 ?? null,
|
||||
studio_id: gallery?.studio?.id ?? null,
|
||||
performer_ids: (gallery?.performers ?? []).map((p) => p.id),
|
||||
@@ -288,10 +292,18 @@ export const GalleryEditPanel: React.FC<IProps> = ({
|
||||
formik.setFieldValue("title", galleryData.title);
|
||||
}
|
||||
|
||||
if (galleryData.code) {
|
||||
formik.setFieldValue("code", galleryData.code);
|
||||
}
|
||||
|
||||
if (galleryData.details) {
|
||||
formik.setFieldValue("details", galleryData.details);
|
||||
}
|
||||
|
||||
if (galleryData.photographer) {
|
||||
formik.setFieldValue("photographer", galleryData.photographer);
|
||||
}
|
||||
|
||||
if (galleryData.date) {
|
||||
formik.setFieldValue("date", galleryData.date);
|
||||
}
|
||||
@@ -490,6 +502,7 @@ export const GalleryEditPanel: React.FC<IProps> = ({
|
||||
<Row className="form-container px-3">
|
||||
<Col lg={7} xl={12}>
|
||||
{renderInputField("title")}
|
||||
{renderInputField("code", "text", "scene_code")}
|
||||
|
||||
{renderURLListField(
|
||||
"urls",
|
||||
@@ -499,6 +512,7 @@ export const GalleryEditPanel: React.FC<IProps> = ({
|
||||
)}
|
||||
|
||||
{renderDateField("date")}
|
||||
{renderInputField("photographer")}
|
||||
{renderRatingField("rating100", "rating")}
|
||||
|
||||
{renderScenesField()}
|
||||
|
||||
@@ -48,6 +48,9 @@ export const GalleryScrapeDialog: React.FC<IGalleryScrapeDialogProps> = ({
|
||||
const [title, setTitle] = useState<ScrapeResult<string>>(
|
||||
new ScrapeResult<string>(gallery.title, scraped.title)
|
||||
);
|
||||
const [code, setCode] = useState<ScrapeResult<string>>(
|
||||
new ScrapeResult<string>(gallery.code, scraped.code)
|
||||
);
|
||||
const [urls, setURLs] = useState<ScrapeResult<string[]>>(
|
||||
new ScrapeResult<string[]>(
|
||||
gallery.urls,
|
||||
@@ -59,6 +62,9 @@ export const GalleryScrapeDialog: React.FC<IGalleryScrapeDialogProps> = ({
|
||||
const [date, setDate] = useState<ScrapeResult<string>>(
|
||||
new ScrapeResult<string>(gallery.date, scraped.date)
|
||||
);
|
||||
const [photographer, setPhotographer] = useState<ScrapeResult<string>>(
|
||||
new ScrapeResult<string>(gallery.photographer, scraped.photographer)
|
||||
);
|
||||
const [studio, setStudio] = useState<ScrapeResult<string>>(
|
||||
new ScrapeResult<string>(gallery.studio_id, scraped.studio?.stored_id)
|
||||
);
|
||||
@@ -157,9 +163,17 @@ export const GalleryScrapeDialog: React.FC<IGalleryScrapeDialogProps> = ({
|
||||
|
||||
// don't show the dialog if nothing was scraped
|
||||
if (
|
||||
[title, urls, date, studio, performers, tags, details].every(
|
||||
(r) => !r.scraped
|
||||
) &&
|
||||
[
|
||||
title,
|
||||
code,
|
||||
urls,
|
||||
date,
|
||||
photographer,
|
||||
studio,
|
||||
performers,
|
||||
tags,
|
||||
details,
|
||||
].every((r) => !r.scraped) &&
|
||||
!newStudio &&
|
||||
newPerformers.length === 0 &&
|
||||
newTags.length === 0
|
||||
@@ -173,8 +187,10 @@ export const GalleryScrapeDialog: React.FC<IGalleryScrapeDialogProps> = ({
|
||||
|
||||
return {
|
||||
title: title.getNewValue(),
|
||||
code: code.getNewValue(),
|
||||
urls: urls.getNewValue(),
|
||||
date: date.getNewValue(),
|
||||
photographer: photographer.getNewValue(),
|
||||
studio: newStudioValue
|
||||
? {
|
||||
stored_id: newStudioValue,
|
||||
@@ -200,6 +216,11 @@ export const GalleryScrapeDialog: React.FC<IGalleryScrapeDialogProps> = ({
|
||||
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}
|
||||
@@ -211,6 +232,11 @@ export const GalleryScrapeDialog: React.FC<IGalleryScrapeDialogProps> = ({
|
||||
result={date}
|
||||
onChange={(value) => setDate(value)}
|
||||
/>
|
||||
<ScrapedInputGroupRow
|
||||
title={intl.formatMessage({ id: "photographer" })}
|
||||
result={photographer}
|
||||
onChange={(value) => setPhotographer(value)}
|
||||
/>
|
||||
<ScrapedStudioRow
|
||||
title={intl.formatMessage({ id: "studios" })}
|
||||
result={studio}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
.gallery-tabs {
|
||||
max-height: calc(100vh - 4rem);
|
||||
|
||||
overflow: auto;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
@@ -62,7 +63,6 @@ $galleryTabWidth: 450px;
|
||||
.gallery-tabs {
|
||||
flex: 0 0 $galleryTabWidth;
|
||||
max-width: $galleryTabWidth;
|
||||
overflow: auto;
|
||||
|
||||
&.collapsed {
|
||||
display: none;
|
||||
@@ -285,3 +285,7 @@ $galleryTabWidth: 450px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.col-form-label {
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user