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:
bob123491234
2023-11-27 22:05:33 -06:00
committed by GitHub
parent b78771dbcd
commit d1018b4c5d
25 changed files with 243 additions and 102 deletions

View File

@@ -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">

View File

@@ -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()}

View File

@@ -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}

View File

@@ -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;
}