From 76d40c6debd50e4f1f34a6dfa544c078d16239bb Mon Sep 17 00:00:00 2001 From: austinkelsay Date: Wed, 24 Apr 2024 14:30:40 -0500 Subject: [PATCH] Starting on handlesubmit for course form, added filter to zaps, using subscribemany for zaps --- src/components/forms/CourseForm.js | 51 ++++++++++++++++++++---------- src/components/zaps/ZapForm.js | 51 ++++++++++++++++++++++++++++++ src/hooks/useNostr.js | 46 +++++++++++++++++---------- 3 files changed, 114 insertions(+), 34 deletions(-) diff --git a/src/components/forms/CourseForm.js b/src/components/forms/CourseForm.js index ebdff8c..4db082b 100644 --- a/src/components/forms/CourseForm.js +++ b/src/components/forms/CourseForm.js @@ -64,36 +64,53 @@ const CourseForm = () => { const createdAt = Math.floor(Date.now() / 1000); // UNIX timestamp const eventKind = 30050; // Custom kind for a course list + // Publish unpublished drafts as NIP-23 events + const publishedLessons = await Promise.all( + lessons.map(async (lesson) => { + console.log('lesson:', lesson); + if (lesson.type === 'draft') { + const draftEvent = { + kind: 30023, + created_at: createdAt, + content: lesson.content, + tags: [ + ["d", lesson.id], + ["title", lesson.title], + // Add other metadata tags as needed + ], + pubkey: pubkey, + }; + console.log('draftEvent:', draftEvent); + return draftEvent; + } + })); + const tags = [ ["title", title], ["summary", summary], ["price", checked ? price.toString() : "free"], ["image", coverImage], - ...lessons.map(lesson => ["a", lesson.id, lesson.title.toLowerCase()]), + ...publishedLessons.map(lesson => ["a", `30023:${lesson.id}:${lesson.id}`]), ...topics.map(topic => ["topic", topic.trim().toLowerCase()]) ]; const content = JSON.stringify({ description: "Course content details" }); // Placeholder content - const eventData = JSON.stringify([0, pubkey, createdAt, eventKind, tags, content]); - - const nostrEvent = { - id: '', // ID would typically be a hash of eventData, to be filled in after eventData is signed - pubkey, - created_at: createdAt, + const courseEvent = { kind: eventKind, - tags, - content, - sig: '', // Signature to be generated externally + created_at: createdAt, + content: content, + tags: tags, + pubkey: pubkey, }; - console.log(nostrEvent); // Logging the event + console.log('courseEvent:', courseEvent); }; const handleLessonChange = (e, index) => { const selectedLessonId = e.value; const selectedLesson = getContentOptions(index).flatMap(group => group.items).find(lesson => lesson.value === selectedLessonId); - + const updatedLessons = lessons.map((lesson, i) => i === index ? { ...lesson, id: selectedLessonId, title: selectedLesson.label.props.content.title } : lesson ); @@ -112,11 +129,11 @@ const CourseForm = () => { const removeLesson = (index) => { const updatedLessons = lessons.filter((_, i) => i !== index); const updatedSelectedLessons = selectedLessons.filter((_, i) => i !== index); - + if (updatedLessons.length === 0) { updatedLessons.push({ id: uuidv4(), title: 'Select a lesson' }); } - + setLessons(updatedLessons); setSelectedLessons(updatedSelectedLessons); }; @@ -140,7 +157,7 @@ const CourseForm = () => { label: handleLessonSelect(content, index)} selected={lessons[index] && lessons[index].id === draft.id} />, value: draft.id })); - + const resourceOptions = resources.map(resource => { const { id, title, summary, image, published_at } = parseEvent(resource); return { @@ -148,7 +165,7 @@ const CourseForm = () => { value: id }; }); - + const workshopOptions = workshops.map(workshop => { const { id, title, summary, image, published_at } = parseEvent(workshop); return { @@ -156,7 +173,7 @@ const CourseForm = () => { value: id }; }); - + return [ { label: 'Drafts', diff --git a/src/components/zaps/ZapForm.js b/src/components/zaps/ZapForm.js index fa8a61d..68a3276 100644 --- a/src/components/zaps/ZapForm.js +++ b/src/components/zaps/ZapForm.js @@ -20,3 +20,54 @@ const ZapForm = ({ event }) => { }; export default ZapForm; + + +// import React, { useState } from "react"; +// import { Button } from 'primereact/button'; +// import { InputText } from 'primereact/inputtext'; +// import { InputTextarea } from 'primereact/inputtextarea'; +// import { useNostr } from "@/hooks/useNostr"; + +// const ZapForm = ({event}) => { +// const [zapAmount, setZapAmount] = useState(0); +// const [comment, setComment] = useState(""); + +// const { zapEvent } = useNostr(); + +// const handleZapButton = (amount) => { +// setZapAmount(amount); +// }; + +// const handleCustomAmountChange = (event) => { +// setZapAmount(event.target.value); +// }; + +// const handleCommentChange = (event) => { +// setComment(event.target.value); +// }; + +// const handleSubmit = async () => { +// const millisatAmount = zapAmount * 1000; +// const response = await zapEvent(event, millisatAmount, comment); + +// console.log('zap response:', response); +// }; + +// return ( +//
+//
+// {[1, 10, 21, 100, 500, 1000].map(amount => ( +//
+//
+// +//
+// +//
+// ); +// }; + +// export default ZapForm; \ No newline at end of file diff --git a/src/hooks/useNostr.js b/src/hooks/useNostr.js index afff44e..0b9683b 100644 --- a/src/hooks/useNostr.js +++ b/src/hooks/useNostr.js @@ -166,33 +166,45 @@ export function useNostr() { try { // Collect all #a and #e tag values from the list of events let aTags = []; + let aTagsAlt = []; let eTags = []; events.forEach(event => { aTags.push(`${event.kind}:${event.id}:${event.d}`); + aTagsAlt.push(`${event.kind}:${event.pubkey}:${event.d}`); eTags.push(event.id); }); // Create filters for batch querying const filterA = { kinds: [9735], '#a': aTags }; const filterE = { kinds: [9735], '#e': eTags }; + const filterAAlt = { kinds: [9735], '#a': aTagsAlt }; // Perform batch queries - const [zapsA, zapsE] = await Promise.all([ - pool.querySync(defaultRelays, filterA), - pool.querySync(defaultRelays, filterE) - ]); - - // Combine results and filter out duplicates - const combinedZaps = [...zapsA]; - const existingIds = new Set(zapsA.map(zap => zap.id)); - zapsE.forEach(zap => { - if (!existingIds.has(zap.id)) { - combinedZaps.push(zap); - existingIds.add(zap.id); + // const [zapsA, zapsE] = await Promise.all([ + // pool.querySync(defaultRelays, filterA), + // pool.querySync(defaultRelays, filterE) + // ]); + let allZaps = [] + + await new Promise((resolve) => pool.subscribeMany(defaultRelays, [filterA, filterE, filterAAlt], { + onerror: (error) => { + console.error('Failed to fetch zaps for events:', error); + resolve([]); + }, + onevent: (event) => { + allZaps.push(event); + }, + oneose: () => { + resolve(allZaps); } - }); - - return combinedZaps; + })) + + // remove any duplicates + allZaps = allZaps.filter((zap, index, self) => index === self.findIndex((t) => ( + t.id === zap.id + ))) + + return allZaps; } catch (error) { console.error('Failed to fetch zaps for events:', error); return []; @@ -275,12 +287,12 @@ export function useNostr() { kind: 9734, content: "", tags: [ - ["relays", defaultRelays[4], defaultRelays[5]], + ["relays", defaultRelays.join(",")], ["amount", amount.toString()], // ["lnurl", lnurl], ["e", event.id], ["p", event.pubkey], - ["a", `${event.kind}:${event.id}:${event.d}`], + ["a", `${event.kind}:${event.pubkey}:${event.d}`], ], created_at: Math.floor(Date.now() / 1000) }