Lots of tiny adjustments

This commit is contained in:
Lim Chee Aun 2023-01-07 14:45:04 +08:00
parent aab9a475e8
commit ee9bfe6331
4 changed files with 52 additions and 20 deletions

View file

@ -280,7 +280,8 @@
display: none; display: none;
} }
.status .content p { .status .content p {
margin-block: 0.75em; /* 12px = 75% of 16px */
margin-block: min(0.75em, 12px);
} }
.status .content p:first-child { .status .content p:first-child {
margin-block-start: 0; margin-block-start: 0;
@ -320,7 +321,7 @@
.status.large :is(.media-container, .media-container.media-gt2) { .status.large :is(.media-container, .media-container.media-gt2) {
height: auto; height: auto;
min-height: 160px; min-height: 160px;
max-height: 50vh; max-height: 60vh;
} }
.status .media { .status .media {
border-radius: 8px; border-radius: 8px;
@ -331,6 +332,15 @@
.status .media:only-child { .status .media:only-child {
grid-area: span 2 / span 2; grid-area: span 2 / span 2;
} }
.status:not(.large) .media:only-child {
max-width: 480px;
}
.status.large .media:only-child {
display: inline-block;
min-width: 160px;
min-height: 160px;
width: fit-content;
}
.status .media:first-child:nth-last-child(3) { .status .media:first-child:nth-last-child(3) {
grid-area: span 2; grid-area: span 2;
} }
@ -355,6 +365,8 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
}
.status .media:not(.media-audio) {
cursor: pointer; cursor: pointer;
} }
@keyframes position-object { @keyframes position-object {
@ -371,7 +383,7 @@
object-position: 50% 50%; object-position: 50% 50%;
} }
} }
.status:not(.large) .media img:hover { .status .media img:hover {
animation: position-object 5s ease-in-out 1s 5; animation: position-object 5s ease-in-out 1s 5;
} }
.status .media video { .status .media video {
@ -437,6 +449,10 @@
object-fit: cover; object-fit: cover;
pointer-events: none; pointer-events: none;
} }
.status .media-contain {
min-width: 160px;
width: fit-content;
}
.status .media-contain video { .status .media-contain video {
object-fit: contain !important; object-fit: contain !important;
} }
@ -474,10 +490,13 @@
object-fit: cover; object-fit: cover;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
} }
.status.large .card.link.large .image { .status.large .card.link {
max-width: 480px;
}
.status.large .card.link .image {
aspect-ratio: 1.91 / 1; aspect-ratio: 1.91 / 1;
width: 100%; width: 100%;
max-height: 50vh; max-height: 40vh;
border-inline-end: 0; border-inline-end: 0;
border-block-end: 1px solid var(--outline-color); border-block-end: 1px solid var(--outline-color);
} }
@ -493,7 +512,7 @@
flex-grow: 1; flex-grow: 1;
align-self: center; align-self: center;
} }
.status.large .card.link.large .meta-container { .status.large .card.link .meta-container {
align-self: flex-start; align-self: flex-start;
} }
.card .title { .card .title {

View file

@ -749,20 +749,20 @@ function Media({ media, showOriginal, autoAnimate, onClick = () => {} }) {
</div> </div>
); );
} else if (type === 'gifv' || type === 'video') { } else if (type === 'gifv' || type === 'video') {
// 20 seconds, treat as a gif const shortDuration = original.duration < 31;
const shortDuration = original.duration <= 20; const isGIF = type === 'gifv' && shortDuration;
const isGIFV = type === 'gifv'; // If GIF is too long, treat it as a video
const isGIF = isGIFV || shortDuration; const loopable = original.duration < 61;
const loopable = original.duration <= 60;
const formattedDuration = formatDuration(original.duration); const formattedDuration = formatDuration(original.duration);
const hoverAnimate = !showOriginal && !autoAnimate && isGIF; const hoverAnimate = !showOriginal && !autoAnimate && isGIF;
const autoGIFAnimate = !showOriginal && autoAnimate && isGIF;
return ( return (
<div <div
class={`media media-${isGIF ? 'gif' : 'video'} ${ class={`media media-${isGIF ? 'gif' : 'video'} ${
autoAnimate ? 'media-contain' : '' autoGIFAnimate ? 'media-contain' : ''
}`} }`}
data-formatted-duration={formattedDuration} data-formatted-duration={formattedDuration}
data-label={isGIF && !showOriginal && !autoAnimate ? 'GIF' : ''} data-label={isGIF && !showOriginal && !autoGIFAnimate ? 'GIF' : ''}
style={{ style={{
backgroundColor: backgroundColor:
rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`, rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`,
@ -790,7 +790,7 @@ function Media({ media, showOriginal, autoAnimate, onClick = () => {} }) {
} }
}} }}
> >
{showOriginal || autoAnimate ? ( {showOriginal || autoGIFAnimate ? (
<div <div
style={{ style={{
width: '100%', width: '100%',
@ -806,7 +806,7 @@ function Media({ media, showOriginal, autoAnimate, onClick = () => {} }) {
preload="auto" preload="auto"
autoplay autoplay
muted="${isGIF}" muted="${isGIF}"
${isGIFV ? '' : 'controls'} ${isGIF ? '' : 'controls'}
playsinline playsinline
loop="${loopable}" loop="${loopable}"
></video> ></video>

View file

@ -1,7 +1,7 @@
import { Link } from 'preact-router/match'; import { Link } from 'preact-router/match';
import { memo } from 'preact/compat';
import { useEffect, useRef, useState } from 'preact/hooks'; import { useEffect, useRef, useState } from 'preact/hooks';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { InView } from 'react-intersection-observer';
import { useSnapshot } from 'valtio'; import { useSnapshot } from 'valtio';
import Icon from '../components/icon'; import Icon from '../components/icon';
@ -167,6 +167,7 @@ function Home({ hidden }) {
scrollableElement: scrollableRef.current, scrollableElement: scrollableRef.current,
distanceFromTop: 0.1, distanceFromTop: 0.1,
distanceFromBottom: 0.15, distanceFromBottom: 0.15,
scrollThresholdUp: 44,
}); });
useEffect(() => { useEffect(() => {
@ -352,4 +353,4 @@ function Home({ hidden }) {
); );
} }
export default Home; export default memo(Home);

View file

@ -4,7 +4,8 @@ export default function useScroll({
scrollableElement = window, scrollableElement = window,
distanceFromTop = 0, distanceFromTop = 0,
distanceFromBottom = 0, distanceFromBottom = 0,
scrollThreshold = 10, scrollThresholdUp = 10,
scrollThresholdDown = 10,
} = {}) { } = {}) {
const [scrollDirection, setScrollDirection] = useState(null); const [scrollDirection, setScrollDirection] = useState(null);
const [reachTop, setReachTop] = useState(false); const [reachTop, setReachTop] = useState(false);
@ -22,7 +23,12 @@ export default function useScroll({
const distanceFromBottomPx = const distanceFromBottomPx =
scrollHeight * Math.min(1, Math.max(0, distanceFromBottom)); scrollHeight * Math.min(1, Math.max(0, distanceFromBottom));
if (scrollDistance >= scrollThreshold) { if (
scrollDistance >=
(previousScrollTop < scrollTop
? scrollThresholdDown
: scrollThresholdUp)
) {
setScrollDirection(previousScrollTop < scrollTop ? 'down' : 'up'); setScrollDirection(previousScrollTop < scrollTop ? 'down' : 'up');
previousScrollTop = scrollTop; previousScrollTop = scrollTop;
} }
@ -37,7 +43,13 @@ export default function useScroll({
scrollableElement.addEventListener('scroll', onScroll, { passive: true }); scrollableElement.addEventListener('scroll', onScroll, { passive: true });
return () => scrollableElement.removeEventListener('scroll', onScroll); return () => scrollableElement.removeEventListener('scroll', onScroll);
}, [scrollableElement, distanceFromTop, distanceFromBottom, scrollThreshold]); }, [
scrollableElement,
distanceFromTop,
distanceFromBottom,
scrollThresholdUp,
scrollThresholdDown,
]);
return { scrollDirection, reachTop, nearReachTop, nearReachBottom }; return { scrollDirection, reachTop, nearReachTop, nearReachBottom };
} }