Details page redesign (#3946)

* mobile improvements to performer page
* updated remaining details pages
* fixes tag page on mobile
* implemented show hide for performer details
* fixes card width cutoff on mobile(not related to redesign)
* added background image option plus more improvements
* add tooltip for age field
* translate encoding message string
This commit is contained in:
CJ
2023-07-31 01:10:42 -05:00
committed by GitHub
parent a665a56ef0
commit b8e2f2a0fa
30 changed files with 2023 additions and 1022 deletions

View File

@@ -1,119 +1,100 @@
import React from "react";
import { Badge } from "react-bootstrap";
import { FormattedMessage, useIntl } from "react-intl";
import * as GQL from "src/core/generated-graphql";
import TextUtils from "src/utils/text";
import { RatingSystem } from "src/components/Shared/Rating/RatingSystem";
import { TextField, URLField } from "src/utils/field";
import { DetailItem } from "src/components/Shared/DetailItem";
interface IStudioDetailsPanel {
studio: GQL.StudioDataFragment;
collapsed?: boolean;
fullWidth?: boolean;
}
export const StudioDetailsPanel: React.FC<IStudioDetailsPanel> = ({
studio,
collapsed,
fullWidth,
}) => {
const intl = useIntl();
function renderRatingField() {
if (!studio.rating100) {
return;
}
return (
<>
<dt>{intl.formatMessage({ id: "rating" })}</dt>
<dd>
<RatingSystem value={studio.rating100} disabled />
</dd>
</>
);
}
function renderTagsList() {
if (!studio.aliases?.length) {
return;
}
return (
<>
<dt>
<FormattedMessage id="aliases" />
</dt>
<dd>
{studio.aliases.map((a) => (
<Badge className="tag-item" variant="secondary" key={a}>
{a}
</Badge>
))}
</dd>
</>
);
}
function renderStashIDs() {
if (!studio.stash_ids?.length) {
return;
}
return (
<>
<dt>
<FormattedMessage id="stash_ids" />
</dt>
<dd>
<ul className="pl-0">
{studio.stash_ids.map((stashID) => {
const base = stashID.endpoint.match(/https?:\/\/.*?\//)?.[0];
const link = base ? (
<a
href={`${base}studios/${stashID.stash_id}`}
target="_blank"
rel="noopener noreferrer"
>
{stashID.stash_id}
</a>
) : (
stashID.stash_id
);
return (
<li key={stashID.stash_id} className="row no-gutters">
{link}
</li>
);
})}
</ul>
</dd>
</>
<ul className="pl-0">
{studio.stash_ids.map((stashID) => {
const base = stashID.endpoint.match(/https?:\/\/.*?\//)?.[0];
const link = base ? (
<a
href={`${base}studios/${stashID.stash_id}`}
target="_blank"
rel="noopener noreferrer"
>
{stashID.stash_id}
</a>
) : (
stashID.stash_id
);
return (
<li key={stashID.stash_id} className="row no-gutters">
{link}
</li>
);
})}
</ul>
);
}
function maybeRenderExtraDetails() {
if (!collapsed) {
return (
<DetailItem
id="StashIDs"
value={renderStashIDs()}
fullWidth={fullWidth}
/>
);
}
}
return (
<div className="studio-details">
<div>
<h2>{studio.name}</h2>
</div>
<dl className="details-list">
<URLField
id="url"
value={studio.url}
url={TextUtils.sanitiseURL(studio.url ?? "")}
/>
<TextField id="details" value={studio.details} />
<URLField
id="parent_studios"
value={studio.parent_studio?.name}
url={`/studios/${studio.parent_studio?.id}`}
trusted
target="_self"
/>
{renderRatingField()}
{renderTagsList()}
{renderStashIDs()}
</dl>
<div className="detail-group">
<DetailItem id="details" value={studio.details} fullWidth={fullWidth} />
<DetailItem
id="parent_studios"
value={
studio.parent_studio?.name ? (
<a href={`/studios/${studio.parent_studio?.id}`} target="_self">
{studio.parent_studio.name}
</a>
) : (
""
)
}
fullWidth={fullWidth}
/>
{maybeRenderExtraDetails()}
</div>
);
};
export const CompressedStudioDetailsPanel: React.FC<IStudioDetailsPanel> = ({
studio,
}) => {
function scrollToTop() {
window.scrollTo({ top: 0, behavior: "smooth" });
}
return (
<div className="sticky detail-header">
<div className="sticky detail-header-group">
<a className="studio-name" onClick={() => scrollToTop()}>
{studio.name}
</a>
{studio?.parent_studio?.name ? (
<span className="studio-parent">{studio?.parent_studio?.name}</span>
) : (
""
)}
</div>
</div>
);
};