"use client";
import useEvents from "@/lib/hooks/useEvents";
import {
type NDKEvent,
type NDKKind,
type NDKFilter,
} from "@nostr-dev-kit/ndk";
import { getTagValues } from "@/lib/nostr/utils";
import { fromUnix, daysOffset } from "@/lib/utils/dates";
import Spinner from "@/components/spinner";
import CalendarSection, { CalendarSectionLoading } from "./CalendarSection";
import { uniqBy } from "ramda";
type EventsTimelineProps = {
filter?: NDKFilter;
loader?: () => JSX.Element;
empty?: () => JSX.Element;
};
export default function EventsTimeline({
filter,
loader: Loader,
empty: Empty,
}: EventsTimelineProps) {
const { events, isLoading } = useEvents({
filter: { kinds: [31923 as NDKKind], ...filter },
});
const eventsByDay = groupEventsByDay(
uniqBy((e) => getTagValues("d", e.tags), events),
);
if (isLoading) {
if (Loader) {
return ;
}
return ;
}
if (Empty && eventsByDay.length === 0) {
return ;
}
return (
<>
{eventsByDay.map((e) => (
))}
>
);
}
export function groupEventsByDay(events: NDKEvent[]) {
const eventDays: Record = {};
for (const event of events) {
const eventStartTime = getTagValues("start", event.tags);
if (!eventStartTime) continue;
const startDate = fromUnix(parseInt(eventStartTime));
const daysAway = daysOffset(startDate);
if (daysAway < 1) {
if (eventDays[`0`]) {
eventDays[`0`]!.push(event);
} else {
eventDays[`0`] = [event];
}
} else if (eventDays[`${daysAway}`]) {
eventDays[`${daysAway}`]!.push(event);
} else {
eventDays[`${daysAway}`] = [event];
}
}
const groupedArray = Object.entries(eventDays)
.sort(([aKey], [bKey]) => {
const aDay = parseInt(aKey);
const bDay = parseInt(bKey);
if (aDay > bDay) {
return 1;
} else if (aDay < bDay) {
return -1;
}
return 0;
})
.map(([_, events]) =>
events.sort((a, b) => {
const aStart = parseInt(getTagValues("start", a.tags) ?? "0");
const bStart = parseInt(getTagValues("start", b.tags) ?? "0");
if (aStart > bStart) {
return 1;
} else if (aStart < bStart) {
return -1;
}
return 0;
}),
);
return groupedArray;
}