Fix carousel actually not working properly

- Need intersection observer to tell JS that scroll snap happened
- Fix carousel dots not working
- Add fancy background overlay based on image average color
- Disable fade out if open in carousel
This commit is contained in:
Lim Chee Aun 2022-12-11 14:35:57 +08:00
parent be5a5cbd7c
commit aeceb94219
3 changed files with 50 additions and 14 deletions

View file

@ -349,7 +349,8 @@ a.hashtag {
pointer-events: none;
}
button.carousel-button {
button.carousel-button,
button.carousel-dot {
pointer-events: auto;
font-weight: bold;
}
@ -360,7 +361,12 @@ button.carousel-button[hidden] {
}
.carousel-dots {
border-radius: 999px;
backdrop-filter: blur(12px);
backdrop-filter: blur(12px) invert(.25) brightness(1.5);
}
@media (prefers-color-scheme: dark) {
.carousel-dots {
backdrop-filter: blur(12px) brightness(.5);
}
}
button.carousel-dot {
color: var(--text-insignificant-color) !important;
@ -392,6 +398,12 @@ button.carousel-dot.active {
transform: translateY(0);
}
}
@media (prefers-color-scheme: dark) {
.carousel :is(img, video) {
/* No need fade out if inside carousel */
filter: none;
}
}
/* COMPOSE BUTTON */

View file

@ -3,6 +3,7 @@ import './status.css';
import { getBlurHashAverageColor } from 'fast-blurhash';
import mem from 'mem';
import { useEffect, useRef, useState } from 'preact/hooks';
import { InView } from 'react-intersection-observer';
import { useSnapshot } from 'valtio';
import Modal from '../components/modal';
@ -477,7 +478,7 @@ function Status({ statusID, status, withinContext, size = 'm', skeleton }) {
const prevShowMediaModal = useRef(showMediaModal);
useEffect(() => {
if (showMediaModal !== false) {
carouselFocusItem.current?.scrollIntoView({
carouselFocusItem.current?.node?.scrollIntoView({
behavior: prevShowMediaModal.current === false ? 'auto' : 'smooth',
});
}
@ -498,6 +499,8 @@ function Status({ statusID, status, withinContext, size = 'm', skeleton }) {
const [actionsUIState, setActionsUIState] = useState(null); // boost-loading, favourite-loading, bookmark-loading
const carouselRef = useRef(null);
return (
<div
class={`status ${
@ -802,6 +805,7 @@ function Status({ statusID, status, withinContext, size = 'm', skeleton }) {
{showMediaModal !== false && (
<Modal>
<div
ref={carouselRef}
class="carousel"
onClick={(e) => {
if (
@ -813,16 +817,33 @@ function Status({ statusID, status, withinContext, size = 'm', skeleton }) {
}}
tabindex="0"
>
{mediaAttachments?.map((media, i) => (
<div
class="carousel-item"
tabindex="0"
key={media.id}
ref={i === showMediaModal ? carouselFocusItem : null}
>
<Media media={media} showOriginal />
</div>
))}
{mediaAttachments?.map((media, i) => {
const { blurhash } = media;
const rgbAverageColor = blurhash
? getBlurHashAverageColor(blurhash)
: null;
return (
<InView
class="carousel-item"
style={{
backgroundColor: `rgba(${rgbAverageColor.join(',')}, .5)`,
}}
tabindex="0"
key={media.id}
ref={i === showMediaModal ? carouselFocusItem : null}
// InView options
root={carouselRef.current}
threshold={1}
onChange={(inView) => {
if (inView) {
setShowMediaModal(i);
}
}}
>
<Media media={media} showOriginal />
</InView>
);
})}
</div>
<div class="carousel-top-controls">
<span />

View file

@ -123,7 +123,7 @@ button > * {
:is(button, .button).plain {
background-color: transparent;
color: var(--link-color);
backdrop-filter: blur(12px);
backdrop-filter: blur(12px) invert(.25) brightness(1.5);
}
:is(button, .button).light {
background-color: var(--bg-faded-color);
@ -170,6 +170,9 @@ select.plain {
img:hover, video:hover {
filter: brightness(1);
}
:is(button, .button).plain {
backdrop-filter: blur(12px) brightness(.5);
}
}
/* UTILS */