Little adjustments, show more captions

This commit is contained in:
Lim Chee Aun 2023-10-01 13:18:31 +08:00
parent 6a16b25722
commit 359fd92ae0
3 changed files with 163 additions and 133 deletions

View file

@ -59,6 +59,7 @@ function Media({
lang, lang,
showOriginal, showOriginal,
autoAnimate, autoAnimate,
showCaption,
onClick = () => {}, onClick = () => {},
}) { }) {
const { const {
@ -169,6 +170,48 @@ function Media({
aspectRatio: `${width} / ${height}`, aspectRatio: `${width} / ${height}`,
}; };
const multilineDesc =
!!description && description.trim().split('\n').length > 2;
const longDesc = description?.length > MEDIA_CAPTION_LIMIT || multilineDesc;
const showInlineDesc =
!!showCaption &&
!showOriginal &&
!!description &&
!longDesc &&
!multilineDesc;
const Figure = !showInlineDesc
? Fragment
: (props) => {
const { children, ...restProps } = props;
return (
<figure {...restProps}>
{children}
<figcaption
class={`media-caption media-caption-${
longDesc ? 'long' : 'short'
}`}
lang={lang}
dir="auto"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
states.showMediaAlt = {
alt: description,
lang,
};
}}
title={
description.length > MEDIA_CAPTION_LIMIT
? description
: undefined
}
>
{description}
</figcaption>
</figure>
);
};
if (isImage) { if (isImage) {
// Note: type: unknown might not have width/height // Note: type: unknown might not have width/height
quickPinchZoomProps.containerProps.style.display = 'inherit'; quickPinchZoomProps.containerProps.style.display = 'inherit';
@ -187,83 +230,85 @@ function Media({
}, [mediaURL]); }, [mediaURL]);
return ( return (
<Parent <Figure>
ref={parentRef} <Parent
class={`media media-image`} ref={parentRef}
onClick={onClick} class={`media media-image`}
data-orientation={orientation} onClick={onClick}
data-has-alt={!!description || undefined} data-orientation={orientation}
style={ data-has-alt={!showInlineDesc}
showOriginal style={
? { showOriginal
backgroundImage: `url(${previewUrl})`, ? {
backgroundSize: imageSmallerThanParent backgroundImage: `url(${previewUrl})`,
? `${width}px ${height}px` backgroundSize: imageSmallerThanParent
: undefined, ? `${width}px ${height}px`
} : undefined,
: mediaStyles
}
>
{showOriginal ? (
<QuickPinchZoom {...quickPinchZoomProps}>
<img
ref={mediaRef}
src={mediaURL}
alt={description}
width={width}
height={height}
data-orientation={orientation}
loading="eager"
decoding="sync"
onLoad={(e) => {
e.target.closest('.media-image').style.backgroundImage = '';
e.target.closest('.media-zoom').style.display = '';
setPinchZoomEnabled(true);
}}
onError={(e) => {
const { src } = e.target;
if (src === mediaURL) {
e.target.src = remoteMediaURL;
} }
}} : mediaStyles
/> }
</QuickPinchZoom> >
) : ( {showOriginal ? (
<> <QuickPinchZoom {...quickPinchZoomProps}>
<img <img
src={mediaURL} ref={mediaRef}
alt={description} src={mediaURL}
width={width} alt={description}
height={height} width={width}
data-orientation={orientation} height={height}
loading="lazy" data-orientation={orientation}
style={{ loading="eager"
backgroundColor: decoding="sync"
rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`, onLoad={(e) => {
backgroundPosition: focalBackgroundPosition || 'center', e.target.closest('.media-image').style.backgroundImage = '';
// Duration based on width or height in pixels e.target.closest('.media-zoom').style.display = '';
// 100px per second (rough estimate) setPinchZoomEnabled(true);
// Clamp between 5s and 120s }}
'--anim-duration': `${Math.min( onError={(e) => {
Math.max(Math.max(width, height) / 100, 5), const { src } = e.target;
120, if (src === mediaURL) {
)}s`, e.target.src = remoteMediaURL;
}} }
onLoad={(e) => { }}
e.target.closest('.media-image').style.backgroundImage = ''; />
e.target.dataset.loaded = true; </QuickPinchZoom>
}} ) : (
onError={(e) => { <>
const { src } = e.target; <img
if (src === mediaURL) { src={mediaURL}
e.target.src = remoteMediaURL; alt={showInlineDesc ? '' : description}
} width={width}
}} height={height}
/> data-orientation={orientation}
<AltBadge alt={description} lang={lang} /> loading="lazy"
</> style={{
)} backgroundColor:
</Parent> rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`,
backgroundPosition: focalBackgroundPosition || 'center',
// Duration based on width or height in pixels
// 100px per second (rough estimate)
// Clamp between 5s and 120s
'--anim-duration': `${Math.min(
Math.max(Math.max(width, height) / 100, 5),
120,
)}s`,
}}
onLoad={(e) => {
e.target.closest('.media-image').style.backgroundImage = '';
e.target.dataset.loaded = true;
}}
onError={(e) => {
const { src } = e.target;
if (src === mediaURL) {
e.target.src = remoteMediaURL;
}
}}
/>
{!showInlineDesc && <AltBadge alt={description} lang={lang} />}
</>
)}
</Parent>
</Figure>
); );
} else if (type === 'gifv' || type === 'video' || isVideoMaybe) { } else if (type === 'gifv' || type === 'video' || isVideoMaybe) {
const shortDuration = original.duration < 31; const shortDuration = original.duration < 31;
@ -291,11 +336,8 @@ function Media({
></video> ></video>
`; `;
const showInlineDesc = !showOriginal && !isGIF && !!description;
const Container = showInlineDesc ? 'figure' : Fragment;
return ( return (
<Container> <Figure>
<Parent <Parent
class={`media media-${isGIF ? 'gif' : 'video'} ${ class={`media media-${isGIF ? 'gif' : 'video'} ${
autoGIFAnimate ? 'media-contain' : '' autoGIFAnimate ? 'media-contain' : ''
@ -303,7 +345,7 @@ function Media({
data-orientation={orientation} data-orientation={orientation}
data-formatted-duration={formattedDuration} data-formatted-duration={formattedDuration}
data-label={isGIF && !showOriginal && !autoGIFAnimate ? 'GIF' : ''} data-label={isGIF && !showOriginal && !autoGIFAnimate ? 'GIF' : ''}
data-has-alt={!!description || undefined} data-has-alt={!showInlineDesc}
// style={{ // style={{
// backgroundColor: // backgroundColor:
// rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`, // rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`,
@ -391,67 +433,48 @@ 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} />}
</> </>
)} )}
{!showOriginal && !showInlineDesc && ( {!showOriginal && !showInlineDesc && (
<AltBadge alt={description} lang={lang} /> <AltBadge alt={description} lang={lang} />
)} )}
</Parent> </Parent>
{showInlineDesc && ( </Figure>
<figcaption
class={`media-caption media-caption-${
description.length <= MEDIA_CAPTION_LIMIT ? 'short' : 'long'
}`}
lang={lang}
dir="auto"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
states.showMediaAlt = {
alt: description,
lang,
};
}}
title={
description.length > MEDIA_CAPTION_LIMIT ? description : undefined
}
>
{description}
</figcaption>
)}
</Container>
); );
} else if (type === 'audio') { } else if (type === 'audio') {
const formattedDuration = formatDuration(original.duration); const formattedDuration = formatDuration(original.duration);
return ( return (
<Parent <Figure>
class="media media-audio" <Parent
data-formatted-duration={formattedDuration} class="media media-audio"
data-has-alt={!!description || undefined} data-formatted-duration={formattedDuration}
onClick={onClick} data-has-alt={!showInlineDesc}
style={!showOriginal && mediaStyles} onClick={onClick}
> style={!showOriginal && mediaStyles}
{showOriginal ? ( >
<audio src={remoteUrl || url} preload="none" controls autoplay /> {showOriginal ? (
) : previewUrl ? ( <audio src={remoteUrl || url} preload="none" controls autoplay />
<img ) : previewUrl ? (
src={previewUrl} <img
alt={description} src={previewUrl}
width={width} alt={showInlineDesc ? '' : description}
height={height} width={width}
data-orientation={orientation} height={height}
loading="lazy" data-orientation={orientation}
/> loading="lazy"
) : null} />
{!showOriginal && ( ) : null}
<> {!showOriginal && (
<div class="media-play"> <>
<Icon icon="play" size="xl" /> <div class="media-play">
</div> <Icon icon="play" size="xl" />
<AltBadge alt={description} lang={lang} /> </div>
</> {!showInlineDesc && <AltBadge alt={description} lang={lang} />}
)} </>
</Parent> )}
</Parent>
</Figure>
); );
} }
} }

View file

@ -719,6 +719,7 @@
color: var(--text-insignificant-color); color: var(--text-insignificant-color);
line-height: 1.2; line-height: 1.2;
cursor: pointer; cursor: pointer;
white-space: pre-line;
&.media-caption-long { &.media-caption-long {
overflow: hidden; overflow: hidden;
@ -1027,6 +1028,11 @@ body:has(#modal-container .carousel) .status .media img:hover {
z-index: 1; z-index: 1;
text-shadow: 0 var(--hairline-width) var(--bg-color); text-shadow: 0 var(--hairline-width) var(--bg-color);
mix-blend-mode: luminosity; mix-blend-mode: luminosity;
white-space: pre-line;
&:is(:hover, :focus) {
mix-blend-mode: normal;
}
} }
.carousel-item button.media-alt .media-alt-desc { .carousel-item button.media-alt .media-alt-desc {
overflow: hidden; overflow: hidden;
@ -1684,7 +1690,7 @@ a.card:is(:hover, :focus):visited {
transition: 0.15s ease-out; transition: 0.15s ease-out;
transition-property: transform, opacity, mix-blend-mode; transition-property: transform, opacity, mix-blend-mode;
transform: scale(1.15); transform: scale(1.15);
opacity: 0.8; opacity: 0.9;
mix-blend-mode: normal; mix-blend-mode: normal;
} }
} }

View file

@ -1269,6 +1269,7 @@ function Status({
key={media.id} key={media.id}
media={media} media={media}
autoAnimate={isSizeLarge} autoAnimate={isSizeLarge}
showCaption={mediaAttachments.length === 1}
lang={language} lang={language}
to={`/${instance}/s/${id}?${ to={`/${instance}/s/${id}?${
withinContext ? 'media' : 'media-only' withinContext ? 'media' : 'media-only'