mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-01-23 09:06:23 +01:00
New feature: ALT badge in image carousel
Adjusted the layout and fix some styles as well
This commit is contained in:
parent
2a44f3a670
commit
1439b22963
3 changed files with 132 additions and 42 deletions
21
src/app.css
21
src/app.css
|
@ -625,10 +625,6 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
|
|||
top: 0;
|
||||
top: env(safe-area-inset-top, 0);
|
||||
}
|
||||
.carousel-controls {
|
||||
bottom: 0;
|
||||
bottom: env(safe-area-inset-bottom, 0);
|
||||
}
|
||||
:is(.carousel-top-controls, .carousel-controls) {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
|
@ -670,14 +666,15 @@ button.carousel-dot {
|
|||
font-weight: bold;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
button.carousel-dot:is(:hover, :focus) button.carousel-dot.active,
|
||||
button.carousel-dot[disabled].active {
|
||||
button.carousel-dot[disabled] {
|
||||
pointer-events: none;
|
||||
}
|
||||
button.carousel-dot:is(:hover, :focus, .active, [disabled].active) {
|
||||
color: var(--link-color) !important;
|
||||
}
|
||||
button.carousel-dot.active,
|
||||
button.carousel-dot[disabled].active {
|
||||
button.carousel-dot:is(.active, [disabled].active) {
|
||||
opacity: 1;
|
||||
transform: scale(2) translateY(-0.5px);
|
||||
transform: scale(2.2) translateY(-0.5px);
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.carousel-top-controls {
|
||||
|
@ -685,7 +682,7 @@ button.carousel-dot[disabled].active {
|
|||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
.carousel-controls {
|
||||
transform: translateY(100%);
|
||||
transform: scaleX(200%);
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
:is(.carousel-top-controls, .carousel-controls)[hidden] {
|
||||
|
@ -1061,9 +1058,9 @@ meter.donut:is(.danger, .explode):after {
|
|||
.box {
|
||||
padding: 32px;
|
||||
}
|
||||
:is(.carousel-top-controls, .carousel-controls) {
|
||||
/* :is(.carousel-top-controls, .carousel-controls) {
|
||||
padding: 32px;
|
||||
}
|
||||
} */
|
||||
li:has(.boost-carousel) {
|
||||
width: 95vw;
|
||||
max-width: calc(320px * 3.3);
|
||||
|
|
|
@ -488,6 +488,60 @@
|
|||
background-blend-mode: multiply;
|
||||
}
|
||||
|
||||
.carousel-item {
|
||||
position: relative;
|
||||
}
|
||||
.carousel-item button.media-alt {
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
bottom: calc(16px + env(safe-area-inset-bottom));
|
||||
left: 16px;
|
||||
left: calc(16px + env(safe-area-inset-left));
|
||||
text-align: left;
|
||||
border-radius: 8px;
|
||||
color: var(--text-color);
|
||||
padding: 4px 8px 4px 4px;
|
||||
border: 1px solid var(--outline-color);
|
||||
box-shadow: 0 4px 16px var(--outline-color);
|
||||
max-width: min(40em, calc(100% - 32px));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 90%;
|
||||
}
|
||||
.carousel-item button.media-alt .media-alt-desc {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@media (min-width: 40em) {
|
||||
.carousel-item button.media-alt .media-alt-desc {
|
||||
white-space: normal;
|
||||
display: -webkit-box;
|
||||
display: box;
|
||||
-webkit-box-orient: vertical;
|
||||
box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
.carousel-item button.media-alt[hidden] {
|
||||
opacity: 0;
|
||||
}
|
||||
@media (hover: hover) {
|
||||
.carousel-item button.media-alt {
|
||||
transform: translateY(200%);
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
.carousel-item:hover button.media-alt {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.carousel-item button.media-alt[hidden] {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* CARD */
|
||||
|
||||
.card {
|
||||
|
|
|
@ -1320,6 +1320,8 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
|
||||
useHotkeys('esc', onClose, [onClose]);
|
||||
|
||||
const [showMediaAlt, setShowMediaAlt] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
|
@ -1362,25 +1364,26 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
}
|
||||
}}
|
||||
>
|
||||
{!!media.description && (
|
||||
<button
|
||||
type="button"
|
||||
class="plain2 media-alt"
|
||||
hidden={!showControls}
|
||||
onClick={() => {
|
||||
setShowMediaAlt(media.description);
|
||||
}}
|
||||
>
|
||||
<span class="tag">ALT</span>{' '}
|
||||
<span class="media-alt-desc">{media.description}</span>
|
||||
</button>
|
||||
)}
|
||||
<Media media={media} showOriginal />
|
||||
</InView>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div class="carousel-top-controls" hidden={!showControls}>
|
||||
<span />
|
||||
<span>
|
||||
<a
|
||||
href={
|
||||
mediaAttachments[currentIndex]?.remoteUrl ||
|
||||
mediaAttachments[currentIndex]?.url
|
||||
}
|
||||
target="_blank"
|
||||
class="button carousel-button plain2"
|
||||
title="Open original media in new window"
|
||||
>
|
||||
<Icon icon="popout" alt="Open original media in new window" />
|
||||
</a>{' '}
|
||||
<button
|
||||
type="button"
|
||||
class="carousel-button plain2"
|
||||
|
@ -1389,24 +1392,7 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
<Icon icon="x" />
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
{mediaAttachments?.length > 1 && (
|
||||
<div class="carousel-controls" hidden={!showControls}>
|
||||
<button
|
||||
type="button"
|
||||
class="carousel-button plain2"
|
||||
hidden={currentIndex === 0}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setCurrentIndex(
|
||||
(currentIndex - 1 + mediaAttachments.length) %
|
||||
mediaAttachments.length,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Icon icon="arrow-left" />
|
||||
</button>
|
||||
{mediaAttachments?.length > 1 ? (
|
||||
<span class="carousel-dots">
|
||||
{mediaAttachments?.map((media, i) => (
|
||||
<button
|
||||
|
@ -1426,6 +1412,40 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
</button>
|
||||
))}
|
||||
</span>
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
<span>
|
||||
<a
|
||||
href={
|
||||
mediaAttachments[currentIndex]?.remoteUrl ||
|
||||
mediaAttachments[currentIndex]?.url
|
||||
}
|
||||
target="_blank"
|
||||
class="button carousel-button plain2"
|
||||
title="Open original media in new window"
|
||||
>
|
||||
<Icon icon="popout" alt="Open original media in new window" />
|
||||
</a>{' '}
|
||||
</span>
|
||||
</div>
|
||||
{mediaAttachments?.length > 1 && (
|
||||
<div class="carousel-controls" hidden={!showControls}>
|
||||
<button
|
||||
type="button"
|
||||
class="carousel-button plain2"
|
||||
hidden={currentIndex === 0}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setCurrentIndex(
|
||||
(currentIndex - 1 + mediaAttachments.length) %
|
||||
mediaAttachments.length,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Icon icon="arrow-left" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="carousel-button plain2"
|
||||
|
@ -1440,6 +1460,25 @@ function Carousel({ mediaAttachments, index = 0, onClose = () => {} }) {
|
|||
</button>
|
||||
</div>
|
||||
)}
|
||||
{!!showMediaAlt && (
|
||||
<Modal
|
||||
class="light"
|
||||
onClick={(e) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
setShowMediaAlt(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div class="sheet">
|
||||
<header>
|
||||
<h2>Media description</h2>
|
||||
</header>
|
||||
<main>
|
||||
<p>{showMediaAlt}</p>
|
||||
</main>
|
||||
</div>
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue