Experiment figcaption for *multiple* media's

This commit is contained in:
Lim Chee Aun 2023-10-02 12:21:26 +08:00
parent 9f6236762d
commit 348efe0069
3 changed files with 132 additions and 35 deletions

View file

@ -29,7 +29,7 @@ audio = Audio track
const dataAltLabel = 'ALT'; const dataAltLabel = 'ALT';
const AltBadge = (props) => { const AltBadge = (props) => {
const { alt, lang, ...rest } = props; const { alt, lang, index, ...rest } = props;
if (!alt || !alt.trim()) return null; if (!alt || !alt.trim()) return null;
return ( return (
<button <button
@ -47,6 +47,7 @@ const AltBadge = (props) => {
title="Media description" title="Media description"
> >
{dataAltLabel} {dataAltLabel}
{!!index && <sup>{index}</sup>}
</button> </button>
); );
}; };
@ -60,6 +61,7 @@ function Media({
showOriginal, showOriginal,
autoAnimate, autoAnimate,
showCaption, showCaption,
altIndex,
onClick = () => {}, onClick = () => {},
}) { }) {
const { const {
@ -304,7 +306,9 @@ function Media({
} }
}} }}
/> />
{!showInlineDesc && <AltBadge alt={description} lang={lang} />} {!showInlineDesc && (
<AltBadge alt={description} lang={lang} index={altIndex} />
)}
</> </>
)} )}
</Parent> </Parent>
@ -433,11 +437,13 @@ function Media({
<div class="media-play"> <div class="media-play">
<Icon icon="play" size="xl" /> <Icon icon="play" size="xl" />
</div> </div>
{!showInlineDesc && <AltBadge alt={description} lang={lang} />} {!showInlineDesc && (
<AltBadge alt={description} lang={lang} index={altIndex} />
)}
</> </>
)} )}
{!showOriginal && !showInlineDesc && ( {!showOriginal && !showInlineDesc && (
<AltBadge alt={description} lang={lang} /> <AltBadge alt={description} lang={lang} index={altIndex} />
)} )}
</Parent> </Parent>
</Figure> </Figure>
@ -470,7 +476,9 @@ function Media({
<div class="media-play"> <div class="media-play">
<Icon icon="play" size="xl" /> <Icon icon="play" size="xl" />
</div> </div>
{!showInlineDesc && <AltBadge alt={description} lang={lang} />} {!showInlineDesc && (
<AltBadge alt={description} lang={lang} index={altIndex} />
)}
</> </>
)} )}
</Parent> </Parent>

View file

@ -460,7 +460,7 @@
.status .status
.content-container.has-spoiler:not(.show-spoiler) .content-container.has-spoiler:not(.show-spoiler)
.spoiler .spoiler
~ *:not(.media-container, .card), ~ *:not(.media-container, .card, .media-figure-multiple),
.status .status
.content-container.has-spoiler:not(.show-spoiler) .content-container.has-spoiler:not(.show-spoiler)
.spoiler .spoiler
@ -469,7 +469,7 @@
.status .status
.content-container.has-spoiler:not(.show-spoiler) .content-container.has-spoiler:not(.show-spoiler)
.spoiler .spoiler
~ .media-container ~ :is(.media-container, .media-figure-multiple)
figcaption { figcaption {
filter: blur(5px) invert(0.5); filter: blur(5px) invert(0.5);
image-rendering: crisp-edges; image-rendering: crisp-edges;
@ -483,7 +483,7 @@
.status .status
.content-container.has-spoiler:not(.show-spoiler) .content-container.has-spoiler:not(.show-spoiler)
.spoiler .spoiler
~ .media-container ~ :is(.media-container, .media-figure-multiple)
.media .media
> *, > *,
.status .status
@ -1008,6 +1008,37 @@ body:has(#modal-container .carousel) .status .media img:hover {
white-space: normal; white-space: normal;
} }
.media-figure-multiple {
margin: 0;
padding: 0;
figcaption {
padding: 4px;
font-size: 90%;
color: var(--text-insignificant-color);
line-height: 1.2;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
& > * {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&:hover {
color: var(--text-color);
cursor: pointer;
}
}
sup {
opacity: 0.75;
font-variant-numeric: tabular-nums;
}
}
}
.carousel-item { .carousel-item {
position: relative; position: relative;
} }
@ -1687,6 +1718,13 @@ a.card:is(:hover, :focus):visited {
padding: 4px; padding: 4px;
opacity: 0.65; opacity: 0.65;
sup {
vertical-align: super;
font-weight: normal;
line-height: 0;
padding-left: 2px;
}
&.clickable { &.clickable {
opacity: 0.75; opacity: 0.75;
border-width: 2px; border-width: 2px;

View file

@ -1265,34 +1265,72 @@ function Status({
</button> </button>
)} )}
{!!mediaAttachments.length && ( {!!mediaAttachments.length && (
<div <MultipleMediaFigure
ref={mediaContainerRef} lang={language}
class={`media-container media-eq${mediaAttachments.length} ${ enabled={
mediaAttachments.length > 2 ? 'media-gt2' : '' mediaAttachments.length > 1 &&
} ${mediaAttachments.length > 4 ? 'media-gt4' : ''}`} mediaAttachments.some((media) => !!media.description)
}
captionChildren={() => {
return mediaAttachments.map(
(media, i) =>
!!media.description && (
<div
key={media.id}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
states.showMediaAlt = {
alt: media.description,
lang: language,
};
}}
title={
media.description
? `Media ${i + 1}: ${media.description}`
: undefined
}
>
<sup>{i + 1}</sup> {media.description}
</div>
),
);
}}
> >
{mediaAttachments <div
.slice(0, isSizeLarge ? undefined : 4) ref={mediaContainerRef}
.map((media, i) => ( class={`media-container media-eq${mediaAttachments.length} ${
<Media mediaAttachments.length > 2 ? 'media-gt2' : ''
key={media.id} } ${mediaAttachments.length > 4 ? 'media-gt4' : ''}`}
media={media} >
autoAnimate={isSizeLarge} {mediaAttachments
showCaption={mediaAttachments.length === 1} .slice(0, isSizeLarge ? undefined : 4)
lang={language} .map((media, i) => (
to={`/${instance}/s/${id}?${ <Media
withinContext ? 'media' : 'media-only' key={media.id}
}=${i + 1}`} media={media}
onClick={ autoAnimate={isSizeLarge}
onMediaClick showCaption={mediaAttachments.length === 1}
? (e) => { lang={language}
onMediaClick(e, i, media, status); altIndex={
} mediaAttachments.length > 1 &&
: undefined !!media.description &&
} i + 1
/> }
))} to={`/${instance}/s/${id}?${
</div> withinContext ? 'media' : 'media-only'
}=${i + 1}`}
onClick={
onMediaClick
? (e) => {
onMediaClick(e, i, media, status);
}
: undefined
}
/>
))}
</div>
</MultipleMediaFigure>
)} )}
{!!card && {!!card &&
card?.url !== status.url && card?.url !== status.url &&
@ -1489,6 +1527,19 @@ function Status({
); );
} }
function MultipleMediaFigure(props) {
const { enabled, children, lang, captionChildren } = props;
if (!enabled || !captionChildren) return children;
return (
<figure class="media-figure-multiple">
{children}
<figcaption lang={lang} dir="auto">
{captionChildren?.()}
</figcaption>
</figure>
);
}
function Card({ card, instance }) { function Card({ card, instance }) {
const snapStates = useSnapshot(states); const snapStates = useSnapshot(states);
const { const {