mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-12 13:49:33 +02:00
cleanup image gallery props
This commit is contained in:
parent
ed0408de76
commit
6325e16cc2
@ -17,6 +17,7 @@ import { getMatchLink } from "../../helpers/regexp";
|
||||
import { useRegisterSlide } from "../lightbox-provider";
|
||||
import { isImageURL } from "../../helpers/url";
|
||||
import PhotoGallery, { PhotoWithoutSize } from "../photo-gallery";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
|
||||
function useElementBlur(initBlur = false): { style: CSSProperties; onClick: MouseEventHandler } {
|
||||
const [blur, setBlur] = useState(initBlur);
|
||||
@ -37,7 +38,9 @@ function useElementBlur(initBlur = false): { style: CSSProperties; onClick: Mous
|
||||
return { onClick, style };
|
||||
}
|
||||
|
||||
export const TrustImage = forwardRef<HTMLImageElement, ImageProps>((props, ref) => {
|
||||
export type TrustImageProps = ImageProps;
|
||||
|
||||
export const TrustImage = forwardRef<HTMLImageElement, TrustImageProps>((props, ref) => {
|
||||
const trusted = useTrusted();
|
||||
const { onClick, style } = useElementBlur(!trusted);
|
||||
|
||||
@ -54,7 +57,11 @@ export const TrustImage = forwardRef<HTMLImageElement, ImageProps>((props, ref)
|
||||
return <Image {...props} onClick={handleClick} style={{ ...style, ...props.style }} ref={ref} />;
|
||||
});
|
||||
|
||||
export const EmbeddedImage = forwardRef<HTMLImageElement, ImageProps>(({ src, ...props }, ref) => {
|
||||
export type EmbeddedImageProps = TrustImageProps & {
|
||||
event?: NostrEvent;
|
||||
};
|
||||
|
||||
export const EmbeddedImage = forwardRef<HTMLImageElement, EmbeddedImageProps>(({ src, event, ...props }, ref) => {
|
||||
const thumbnail = appSettings.value.imageProxy
|
||||
? new URL(`/256,fit/${src}`, appSettings.value.imageProxy).toString()
|
||||
: src;
|
||||
@ -62,13 +69,13 @@ export const EmbeddedImage = forwardRef<HTMLImageElement, ImageProps>(({ src, ..
|
||||
ref = ref || useRef<HTMLImageElement | null>(null);
|
||||
const { show } = useRegisterSlide(
|
||||
ref as MutableRefObject<HTMLImageElement | null>,
|
||||
src ? { type: "image", src } : undefined,
|
||||
src ? { type: "image", src, event } : undefined,
|
||||
);
|
||||
|
||||
return <TrustImage {...props} src={thumbnail} cursor="pointer" ref={ref} onClick={show} />;
|
||||
});
|
||||
|
||||
export function ImageGallery({ images }: { images: string[] }) {
|
||||
export function ImageGallery({ images, event }: { images: string[]; event?: NostrEvent }) {
|
||||
const photos = useMemo(() => {
|
||||
return images.map((img) => {
|
||||
const photo: PhotoWithoutSize = { src: img };
|
||||
@ -89,7 +96,7 @@ export function ImageGallery({ images }: { images: string[] }) {
|
||||
}
|
||||
|
||||
// nevent1qqs8397rp8tt60f3lm8zldt8uqljuqw9axp8z79w0qsmj3r96lmg4tgpz3mhxue69uhhyetvv9ujuerpd46hxtnfduq3zamnwvaz7tmwdaehgun4v5hxxmmd0mkwa9
|
||||
export function embedImageGallery(content: EmbedableContent): EmbedableContent {
|
||||
export function embedImageGallery(content: EmbedableContent, event?: NostrEvent): EmbedableContent {
|
||||
return content
|
||||
.map((subContent, i) => {
|
||||
if (typeof subContent === "string") {
|
||||
@ -104,7 +111,7 @@ export function embedImageGallery(content: EmbedableContent): EmbedableContent {
|
||||
// render previous batch
|
||||
const lastMatchPosition = defaultGetLocation(batch[batch.length - 1]);
|
||||
const before = subContent.substring(lastBatchEnd, defaultGetLocation(batch[0]).start);
|
||||
const render = <ImageGallery images={batch.map((m) => m[0])} />;
|
||||
const render = <ImageGallery images={batch.map((m) => m[0])} event={event} />;
|
||||
|
||||
newContent.push(before, render);
|
||||
lastBatchEnd = lastMatchPosition.end;
|
||||
|
@ -21,6 +21,15 @@ import Download from "yet-another-react-lightbox/plugins/download";
|
||||
import "yet-another-react-lightbox/styles.css";
|
||||
import "yet-another-react-lightbox/plugins/counter.css";
|
||||
|
||||
// extend slide type to include eventId
|
||||
declare module "yet-another-react-lightbox" {
|
||||
interface GenericSlide {
|
||||
event?: NostrEvent;
|
||||
}
|
||||
}
|
||||
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
|
||||
type RefType = MutableRefObject<HTMLElement | null>;
|
||||
|
||||
function getElementPath(element: HTMLElement): HTMLElement[] {
|
||||
@ -85,6 +94,20 @@ function getRefPath(ref: RefType) {
|
||||
return path;
|
||||
}
|
||||
|
||||
// function EventSlideHeader({ event }: { event: NostrEvent }) {
|
||||
// return (
|
||||
// <Flex gap="2" alignItems="center" w="full">
|
||||
// <UserAvatarLink pubkey={event.pubkey} size={["xs", "sm"]} />
|
||||
// <UserLink pubkey={event.pubkey} isTruncated fontWeight="bold" fontSize="lg" />
|
||||
// <UserDnsIdentityIcon pubkey={event.pubkey} onlyIcon />
|
||||
// <Flex grow={1} />
|
||||
// <NoteLink noteId={event.id} whiteSpace="nowrap" color="current">
|
||||
// {dayjs.unix(event.created_at).fromNow()}
|
||||
// </NoteLink>
|
||||
// </Flex>
|
||||
// );
|
||||
// }
|
||||
|
||||
export function LightboxProvider({ children }: PropsWithChildren) {
|
||||
const lightbox = useDisclosure();
|
||||
const [index, setIndex] = useState(0);
|
||||
|
@ -26,7 +26,7 @@ function buildContents(event: NostrEvent | DraftNostrEvent) {
|
||||
let content: EmbedableContent = [event.content.trim()];
|
||||
|
||||
// image gallery
|
||||
content = embedImageGallery(content);
|
||||
content = embedImageGallery(content, event as NostrEvent);
|
||||
|
||||
// common
|
||||
content = embedUrls(content, [
|
||||
|
@ -1,33 +1,34 @@
|
||||
import { useMemo, useRef } from "react";
|
||||
import { ImageProps, useBreakpointValue } from "@chakra-ui/react";
|
||||
import { useBreakpointValue } from "@chakra-ui/react";
|
||||
|
||||
import { TimelineLoader } from "../../../classes/timeline-loader";
|
||||
import useSubject from "../../../hooks/use-subject";
|
||||
import { getMatchLink } from "../../../helpers/regexp";
|
||||
import { LightboxProvider } from "../../lightbox-provider";
|
||||
import { isImageURL } from "../../../helpers/url";
|
||||
import { EmbeddedImage } from "../../embed-types";
|
||||
import { EmbeddedImage, EmbeddedImageProps } from "../../embed-types";
|
||||
import { TrustProvider } from "../../../providers/trust";
|
||||
import PhotoGallery, { PhotoWithoutSize } from "../../photo-gallery";
|
||||
import { useRegisterIntersectionEntity } from "../../../providers/intersection-observer";
|
||||
import { Photo } from "react-photo-album";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
|
||||
function GalleryImage({ eventId, ...props }: ImageProps & { eventId: string }) {
|
||||
function GalleryImage({ event, ...props }: EmbeddedImageProps & { event: NostrEvent }) {
|
||||
const ref = useRef<HTMLImageElement | null>(null);
|
||||
useRegisterIntersectionEntity(ref, eventId);
|
||||
useRegisterIntersectionEntity(ref, event.id);
|
||||
|
||||
return <EmbeddedImage {...props} ref={ref} />;
|
||||
return <EmbeddedImage {...props} event={event} ref={ref} />;
|
||||
}
|
||||
|
||||
type PhotoWithEventId = PhotoWithoutSize & { eventId: string };
|
||||
function ImageGallery({ images }: { images: PhotoWithEventId[] }) {
|
||||
type PhotoWithEvent = PhotoWithoutSize & { event: NostrEvent };
|
||||
function ImageGallery({ images }: { images: PhotoWithEvent[] }) {
|
||||
const rowMultiplier = useBreakpointValue({ base: 2, sm: 3, md: 3, lg: 4, xl: 5 }) ?? 2;
|
||||
|
||||
return (
|
||||
<PhotoGallery<Photo & { eventId: string }>
|
||||
<PhotoGallery<Photo & { event: NostrEvent }>
|
||||
layout="masonry"
|
||||
photos={images}
|
||||
renderPhoto={({ photo, imageProps }) => <GalleryImage eventId={photo.eventId} {...imageProps} />}
|
||||
renderPhoto={({ photo, imageProps }) => <GalleryImage event={photo.event} {...imageProps} />}
|
||||
columns={rowMultiplier}
|
||||
/>
|
||||
);
|
||||
@ -37,14 +38,14 @@ export default function MediaTimeline({ timeline }: { timeline: TimelineLoader }
|
||||
const events = useSubject(timeline.timeline);
|
||||
|
||||
const images = useMemo(() => {
|
||||
var images: { eventId: string; src: string; index: number }[] = [];
|
||||
var images: PhotoWithEvent[] = [];
|
||||
|
||||
for (const event of events) {
|
||||
const urls = event.content.matchAll(getMatchLink());
|
||||
|
||||
let i = 0;
|
||||
for (const match of urls) {
|
||||
if (isImageURL(match[0])) images.push({ eventId: event.id, src: match[0], index: i++ });
|
||||
if (isImageURL(match[0])) images.push({ event, src: match[0] });
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user