Add scrolling to share urls

This commit is contained in:
Sam Becker 2025-04-29 21:47:45 -05:00
parent ec890777b9
commit eef47699b7
6 changed files with 30 additions and 15 deletions

View File

@ -4,7 +4,7 @@ import useMaskedScroll, { MaskedScrollExternalProps } from './useMaskedScroll';
export default function MaskedScroll({ export default function MaskedScroll({
direction = 'vertical', direction = 'vertical',
fadeHeight, fadeSize,
hideScrollbar, hideScrollbar,
className, className,
style, style,
@ -16,7 +16,7 @@ MaskedScrollExternalProps & {
}) { }) {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
const { maskImage } = useMaskedScroll({ ref, direction, fadeHeight }); const { maskImage } = useMaskedScroll({ ref, direction, fadeSize });
return <div return <div
{...props} {...props}

View File

@ -2,13 +2,13 @@ import { RefObject, useCallback, useEffect, useMemo, useState } from 'react';
export interface MaskedScrollExternalProps { export interface MaskedScrollExternalProps {
direction?: 'vertical' | 'horizontal' direction?: 'vertical' | 'horizontal'
fadeHeight?: number fadeSize?: number
} }
export default function useMaskedScroll({ export default function useMaskedScroll({
ref: containerRef, ref: containerRef,
direction = 'vertical', direction = 'vertical',
fadeHeight = 24, fadeSize = 24,
// Disable when calling 'updateMask' explicitly // Disable when calling 'updateMask' explicitly
updateMaskOnEvents = true, updateMaskOnEvents = true,
}: MaskedScrollExternalProps & { }: MaskedScrollExternalProps & {
@ -26,8 +26,8 @@ export default function useMaskedScroll({
? ref.scrollTop === 0 ? ref.scrollTop === 0
: ref.scrollLeft === 0; : ref.scrollLeft === 0;
const end = isVertical const end = isVertical
? ref.scrollHeight - ref.scrollTop === ref.clientHeight ? Math.abs((ref.scrollHeight - ref.scrollTop) - ref.clientHeight) < 1
: ref.scrollWidth - ref.scrollLeft === ref.clientWidth; : Math.abs((ref.scrollWidth - ref.scrollLeft) - ref.clientWidth) < 1;
setPosition({ start, end }); setPosition({ start, end });
} }
}, [containerRef, isVertical]); }, [containerRef, isVertical]);
@ -47,13 +47,21 @@ export default function useMaskedScroll({
} }
}, [containerRef, updateMask, updateMaskOnEvents]); }, [containerRef, updateMask, updateMaskOnEvents]);
useEffect(() => {
const ref = containerRef?.current;
const rect = ref?.getClientRects()[0];
if (ref && rect) {
ref.scrollTo({ left: rect.right });
}
}, [containerRef]);
const maskImage = useMemo(() => { const maskImage = useMemo(() => {
let mask = `linear-gradient(to ${isVertical ? 'bottom' : 'right'}, `; let mask = `linear-gradient(to ${isVertical ? 'bottom' : 'right'}, `;
mask += 'transparent, black '; mask += 'transparent, black ';
mask += `${!position.start ? fadeHeight : 0}px, black calc(100% - `; mask += `${!position.start ? fadeSize : 0}px, black calc(100% - `;
mask += `${!position.end ? fadeHeight : 0}px), transparent)`; mask += `${!position.end ? fadeSize : 0}px), transparent)`;
return mask; return mask;
}, [fadeHeight, isVertical, position]); }, [fadeSize, isVertical, position]);
return { maskImage, updateMask }; return { maskImage, updateMask };
} }

View File

@ -40,7 +40,7 @@ export default function PhotoGridPageClient({
'sticky top-0 -mb-5 -mt-5', 'sticky top-0 -mb-5 -mt-5',
'max-h-screen py-4', 'max-h-screen py-4',
)} )}
fadeHeight={36} fadeSize={36}
hideScrollbar hideScrollbar
> >
<PhotoGridSidebar {...{ <PhotoGridSidebar {...{

View File

@ -289,7 +289,7 @@ export default function PhotoLarge({
<div className="md:absolute inset-0 -mt-1"> <div className="md:absolute inset-0 -mt-1">
<MaskedScroll <MaskedScroll
className="sticky top-4 self-start" className="sticky top-4 self-start"
fadeHeight={36} fadeSize={36}
hideScrollbar hideScrollbar
> >
<DivDebugBaselineGrid className={clsx( <DivDebugBaselineGrid className={clsx(

View File

@ -13,6 +13,7 @@ import { generateXPostText } from '@/utility/social';
import { useAppState } from '@/state/AppState'; import { useAppState } from '@/state/AppState';
import useOnPathChange from '@/utility/useOnPathChange'; import useOnPathChange from '@/utility/useOnPathChange';
import { IoArrowUp } from 'react-icons/io5'; import { IoArrowUp } from 'react-icons/io5';
import MaskedScroll from '@/components/MaskedScroll';
export default function ShareModal({ export default function ShareModal({
title, title,
@ -81,9 +82,16 @@ export default function ShareModal({
'flex items-center justify-stretch', 'flex items-center justify-stretch',
'border border-gray-200 dark:border-gray-800', 'border border-gray-200 dark:border-gray-800',
)}> )}>
<div className="truncate p-2 w-full [direction:rtl] text-left"> <MaskedScroll
{shortenUrl(pathShare)} className="flex grow"
</div> direction="horizontal"
fadeSize={100}
hideScrollbar
>
<div className="whitespace-nowrap px-2">
{shortenUrl(pathShare)}
</div>
</MaskedScroll>
{renderIcon( {renderIcon(
<BiCopy size={18} />, <BiCopy size={18} />,
() => { () => {

View File

@ -8,7 +8,6 @@ export const storeCookie = (
sameSite = 'Lax', sameSite = 'Lax',
) => { ) => {
if (typeof document !== 'undefined') { if (typeof document !== 'undefined') {
console.log('storeCookie', name, value);
document.cookie = document.cookie =
`${name}=${value};Path=${path};Max-Age=${maxAge};SameSite=${sameSite}`; `${name}=${value};Path=${path};Max-Age=${maxAge};SameSite=${sameSite}`;
} }