diff --git a/src/components/media.jsx b/src/components/media.jsx
index d7d67f63..d58b0d59 100644
--- a/src/components/media.jsx
+++ b/src/components/media.jsx
@@ -29,7 +29,7 @@ audio = Audio track
const dataAltLabel = 'ALT';
const AltBadge = (props) => {
- const { alt, lang, ...rest } = props;
+ const { alt, lang, index, ...rest } = props;
if (!alt || !alt.trim()) return null;
return (
);
};
@@ -60,6 +61,7 @@ function Media({
showOriginal,
autoAnimate,
showCaption,
+ altIndex,
onClick = () => {},
}) {
const {
@@ -304,7 +306,9 @@ function Media({
}
}}
/>
- {!showInlineDesc && }
+ {!showInlineDesc && (
+
+ )}
>
)}
@@ -433,11 +437,13 @@ function Media({
- {!showInlineDesc && }
+ {!showInlineDesc && (
+
+ )}
>
)}
{!showOriginal && !showInlineDesc && (
-
+
)}
@@ -470,7 +476,9 @@ function Media({
- {!showInlineDesc && }
+ {!showInlineDesc && (
+
+ )}
>
)}
diff --git a/src/components/status.css b/src/components/status.css
index 5cc0ec84..fc59d46d 100644
--- a/src/components/status.css
+++ b/src/components/status.css
@@ -460,7 +460,7 @@
.status
.content-container.has-spoiler:not(.show-spoiler)
.spoiler
- ~ *:not(.media-container, .card),
+ ~ *:not(.media-container, .card, .media-figure-multiple),
.status
.content-container.has-spoiler:not(.show-spoiler)
.spoiler
@@ -469,7 +469,7 @@
.status
.content-container.has-spoiler:not(.show-spoiler)
.spoiler
- ~ .media-container
+ ~ :is(.media-container, .media-figure-multiple)
figcaption {
filter: blur(5px) invert(0.5);
image-rendering: crisp-edges;
@@ -483,7 +483,7 @@
.status
.content-container.has-spoiler:not(.show-spoiler)
.spoiler
- ~ .media-container
+ ~ :is(.media-container, .media-figure-multiple)
.media
> *,
.status
@@ -1008,6 +1008,37 @@ body:has(#modal-container .carousel) .status .media img:hover {
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 {
position: relative;
}
@@ -1687,6 +1718,13 @@ a.card:is(:hover, :focus):visited {
padding: 4px;
opacity: 0.65;
+ sup {
+ vertical-align: super;
+ font-weight: normal;
+ line-height: 0;
+ padding-left: 2px;
+ }
+
&.clickable {
opacity: 0.75;
border-width: 2px;
diff --git a/src/components/status.jsx b/src/components/status.jsx
index 4a7d6ebe..bcb1f122 100644
--- a/src/components/status.jsx
+++ b/src/components/status.jsx
@@ -1265,34 +1265,72 @@ function Status({
)}
{!!mediaAttachments.length && (
-
+ 2 ? 'media-gt2' : ''
+ } ${mediaAttachments.length > 4 ? 'media-gt4' : ''}`}
+ >
+ {mediaAttachments
+ .slice(0, isSizeLarge ? undefined : 4)
+ .map((media, i) => (
+ 1 &&
+ !!media.description &&
+ i + 1
+ }
+ to={`/${instance}/s/${id}?${
+ withinContext ? 'media' : 'media-only'
+ }=${i + 1}`}
+ onClick={
+ onMediaClick
+ ? (e) => {
+ onMediaClick(e, i, media, status);
+ }
+ : undefined
+ }
+ />
+ ))}
+
+
)}
{!!card &&
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 (
+
+ );
+}
+
function Card({ card, instance }) {
const snapStates = useSnapshot(states);
const {