From e3156d7e21543c8a90281230aac000868daa5dbb Mon Sep 17 00:00:00 2001 From: zmeyer44 Date: Thu, 2 Nov 2023 09:48:06 -0400 Subject: [PATCH] auto select calendar and some other simple stuff --- .../[naddr]/_components/CreateEventButton.tsx | 10 +- .../calendar/[naddr]/_components/Header.tsx | 7 +- .../explore/_components/CalendarCard.tsx | 122 ++++++++---------- components/Modals/CreateCalendarEvent.tsx | 16 ++- .../EventsTimeline/EventsFromCalendar.tsx | 35 ----- lib/nostr/utils.ts | 18 +++ 6 files changed, 97 insertions(+), 111 deletions(-) diff --git a/app/(app)/calendar/[naddr]/_components/CreateEventButton.tsx b/app/(app)/calendar/[naddr]/_components/CreateEventButton.tsx index c6a6c1b..ed9a4e3 100644 --- a/app/(app)/calendar/[naddr]/_components/CreateEventButton.tsx +++ b/app/(app)/calendar/[naddr]/_components/CreateEventButton.tsx @@ -3,16 +3,20 @@ import { useModal } from "@/app/_providers/modal/provider"; import CreateCalendarEventModal from "@/components/Modals/CreateCalendarEvent"; type CreateEventButtonProps = { - eventReference: string; + eventIdentifier: string; }; export default function CreateEventButton({ - eventReference, + eventIdentifier, }: CreateEventButtonProps) { const modal = useModal(); return ( - ); diff --git a/app/(app)/calendar/[naddr]/_components/Header.tsx b/app/(app)/calendar/[naddr]/_components/Header.tsx index e75f4cf..2884251 100644 --- a/app/(app)/calendar/[naddr]/_components/Header.tsx +++ b/app/(app)/calendar/[naddr]/_components/Header.tsx @@ -19,9 +19,9 @@ import { checkPayment, updateListUsersFromZaps, } from "@/lib/actions/zap"; -import { useModal } from "@/app/_providers/modal/provider"; import { type NDKEvent } from "@nostr-dev-kit/ndk"; import { btcToSats, formatNumber } from "@/lib/utils"; +import { nip19 } from "nostr-tools"; const CreateEventButton = dynamic(() => import("./CreateEventButton"), { ssr: false, @@ -32,13 +32,12 @@ const EditCalendarButton = dynamic(() => import("./EditCalendarButton"), { export default function Header({ event }: { event: NDKEvent }) { const { currentUser } = useCurrentUser(); - const modal = useModal(); const { ndk } = useNDK(); const [checkingPayment, setCheckingPayment] = useState(false); const [hasValidPayment, setHasValidPayment] = useState(false); const { pubkey, tags } = event; const { profile } = useProfile(pubkey); - const eventReference = event.encode(); + const identifier = event.tagId(); const name = getTagValues("name", tags) ?? "Untitled"; const image = getTagValues("banner", tags) ?? @@ -134,7 +133,7 @@ export default function Header({ event }: { event: NDKEvent }) {
{!!currentUser && currentUser.pubkey === pubkey && ( <> - + )} diff --git a/app/(app)/explore/_components/CalendarCard.tsx b/app/(app)/explore/_components/CalendarCard.tsx index 2b30122..335780f 100644 --- a/app/(app)/explore/_components/CalendarCard.tsx +++ b/app/(app)/explore/_components/CalendarCard.tsx @@ -13,15 +13,17 @@ import { import { cn, getLettersPlain, getTwoLetters } from "@/lib/utils"; import { NDKEvent } from "@nostr-dev-kit/ndk"; import { BANNER } from "@/constants/app"; -import { getNameToShow } from "@/lib/utils"; import { nip19 } from "nostr-tools"; import useProfile from "@/lib/hooks/useProfile"; import useEvents from "@/lib/hooks/useEvents"; -import { getTagsValues, getTagValues } from "@/lib/nostr/utils"; -import { useNDK } from "@/app/_providers/ndk"; +import { + getTagsValues, + getTagValues, + sortEventsByTagNumber, +} from "@/lib/nostr/utils"; import { Skeleton } from "@/components/ui/skeleton"; -import { AspectRatio } from "@/components/ui/aspect-ratio"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { unixTimeNowInSeconds } from "@/lib/nostr/dates"; type CalendarCardProps = { calendar: NDKEvent; @@ -29,12 +31,9 @@ type CalendarCardProps = { export default function CalendarCard({ calendar }: CalendarCardProps) { const { pubkey, tags, content } = calendar; - const { ndk } = useNDK(); - const npub = nip19.npubEncode(pubkey); const { profile } = useProfile(pubkey); const encodedEvent = calendar.encode(); const [upcomingEvents, setUpcomingEvents] = useState([]); - const [isFetching, setIsFetching] = useState(false); const name = getTagValues("name", tags); const image = getTagValues("image", tags); const banner = @@ -46,38 +45,25 @@ export default function CalendarCard({ calendar }: CalendarCardProps) { .map((e) => nip19.decode(e)) .filter(({ type }) => type === "naddr") .map((e) => e.data as nip19.AddressPointer); - - async function handleFetchEvents(data: nip19.AddressPointer[]) { - if (!ndk) return; - setIsFetching(true); - const events: NDKEvent[] = []; - const promiseArray = []; - for (const info of data) { - const calendarEventPromise = ndk - .fetchEvent({ - authors: [info.pubkey], - ["#d"]: [info.identifier], - kinds: [info.kind], - }) - .then((e) => e && events.push(e)) - .catch((err) => console.log("err")); - promiseArray.push(calendarEventPromise); - } - await Promise.all(promiseArray); - setUpcomingEvents(events); - setIsFetching(false); - } + const { events } = useEvents({ + filter: { + kinds: calendarEventIdentifiers.map((k) => k.kind), + authors: calendarEventIdentifiers.map((k) => k.pubkey), + ["#d"]: calendarEventIdentifiers.map((k) => k.identifier), + }, + }); useEffect(() => { - if ( - !ndk || - calendarEventIdentifiers.length === 0 || - isFetching || - upcomingEvents.length - ) - return; - handleFetchEvents(calendarEventIdentifiers); - }, [ndk, calendarEventIdentifiers]); + if (events) { + const filteredEvents = events.filter( + (e) => + parseInt(getTagValues("start", e.tags) ?? "0") > + unixTimeNowInSeconds(), + ); + const sortedEvents = sortEventsByTagNumber(filteredEvents, "start"); + setUpcomingEvents(sortedEvents); + } + }, [events]); return ( @@ -119,34 +105,40 @@ export default function CalendarCard({ calendar }: CalendarCardProps) { Upcoming Events: -
    - {upcomingEvents.map((item) => { - const { tags, content } = item; - const encodedEvent = item.encode(); - const name = getTagValues("name", tags); - const description = content; - return ( -
  • - -
    -

    - {name} -

    -

    - {description ?? ""} -

    -
    -
    - -
    - -
  • - ); - })} -
+ {upcomingEvents.length ? ( +
    + {upcomingEvents.map((item) => { + const { tags, content } = item; + const encodedEvent = item.encode(); + const name = getTagValues("name", tags); + const description = content; + return ( +
  • + +
    +

    + {name} +

    +

    + {description ?? ""} +

    +
    +
    + +
    + +
  • + ); + })} +
+ ) : ( +
+

No upcoming events

+
+ )}
diff --git a/components/Modals/CreateCalendarEvent.tsx b/components/Modals/CreateCalendarEvent.tsx index 9f3391b..d668a6b 100644 --- a/components/Modals/CreateCalendarEvent.tsx +++ b/components/Modals/CreateCalendarEvent.tsx @@ -34,7 +34,14 @@ import useCurrentUser from "@/lib/hooks/useCurrentUser"; import useImageUpload from "@/lib/hooks/useImageUpload"; import { NDKEvent } from "@nostr-dev-kit/ndk"; import { getTagValues } from "@/lib/nostr/utils"; -export default function CreateCalendarEventModal() { + +type CreateCalendarEventModalProps = { + calendar?: string; +}; + +export default function CreateCalendarEventModal({ + calendar: _calendar, +}: CreateCalendarEventModalProps) { const modal = useModal(); const now = new Date(new Date().setHours(12, 0, 0, 0)); const [isLoading, setIsLoading] = useState(false); @@ -73,7 +80,7 @@ export default function CreateCalendarEventModal() { const [timezone, setTimezone] = useState( Intl.DateTimeFormat().resolvedOptions().timeZone, ); - const [calendar, setCalendar] = useState(); + const [calendar, setCalendar] = useState(_calendar ?? ""); const [location, setLocation] = useState<{ address: string; name: string; @@ -154,6 +161,7 @@ export default function CreateCalendarEventModal() { kind: 31923, }; const event = await createEvent(ndk, preEvent); + if (event) { const encodedEvent = event.encode(); if (calendar) { @@ -326,7 +334,7 @@ export default function CreateCalendarEventModal() { ({ ...o, label: getTagValues("name", o.tags) as string, - value: o.encode(), + value: o.tagId(), }) as NDKEvent & { label: string; value: string; @@ -339,7 +347,7 @@ export default function CreateCalendarEventModal() { } className="px-0 pr-1 font-normal" value={calendar} - onChange={(calendar) => setCalendar(calendar.encode())} + onChange={(calendar) => setCalendar(calendar.tagId())} /> diff --git a/containers/EventsTimeline/EventsFromCalendar.tsx b/containers/EventsTimeline/EventsFromCalendar.tsx index a5f839c..921074e 100644 --- a/containers/EventsTimeline/EventsFromCalendar.tsx +++ b/containers/EventsTimeline/EventsFromCalendar.tsx @@ -35,47 +35,12 @@ export default function EventsFromCalendar({ ["#d"]: calendarEventIdentifiers.map((k) => k.identifier), }, }); - // async function handleFetchEvents(data: nip19.AddressPointer[]) { - // if (!ndk) return; - // setIsFetching(true); - // const events: NDKEvent[] = []; - // const promiseArray = []; - // for (const info of data) { - // console.log("INFO", info); - // const calendarEventPromise = ndk - // .fetchEvent({ - // authors: [info.pubkey], - // ["#d"]: [info.identifier], - // kinds: [info.kind], - // }) - // .then((e) => e && events.push(e)) - // .catch((err) => console.log("err")); - // promiseArray.push(calendarEventPromise); - // } - // await Promise.all(promiseArray); - // setEvents(events); - // setIsFetching(false); - // } - - // useEffect(() => { - // if ( - // !ndk || - // calendarEventIdentifiers.length === 0 || - // isFetching || - // events.length - // ) - // return; - // handleFetchEvents(calendarEventIdentifiers); - // }, [ndk, calendarEventIdentifiers]); - useEffect(() => { if (events) { const grouped = groupEventsByDay(events); - console.log("Runnign group", events, " to", grouped); setEventsByDay(grouped); } }, [events]); - console.log(eventsByDay); if (isFetching) { if (Loader) { return ; diff --git a/lib/nostr/utils.ts b/lib/nostr/utils.ts index a6e1ce1..648e955 100644 --- a/lib/nostr/utils.ts +++ b/lib/nostr/utils.ts @@ -43,11 +43,29 @@ export function aTagToNip19(aTag: string[]): string { identifier: tagIdSplit[2] as string, }); } +export function sortEventsByTagNumber( + events: T[], + key: string, + swap?: boolean, +) { + const direction = swap ? -1 : 1; + return events.sort((a, b) => { + const aVal = parseInt(getTagValues(key, a.tags) ?? "0"); + const bVal = parseInt(getTagValues(key, b.tags) ?? "0"); + if (aVal > bVal) { + return direction; + } else if (aVal < bVal) { + return direction * -1; + } + return 0; + }); +} export const getTagValues = (name: string, tags: string[][]) => { const [itemTag] = tags.filter((tag: string[]) => tag[0] === name); const [, item] = itemTag || [, undefined]; return item; }; + export const getTagAllValues = (name: string, tags: string[][]) => { const [itemTag] = tags.filter((tag: string[]) => tag[0] === name); const itemValues = itemTag || [, undefined];