-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from ostyjs/note-enhancements
Note Widget enhancements
- Loading branch information
Showing
26 changed files
with
345 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
templates/react-shadcn/src/features/note-comments-widget/hooks/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
import { useSubscription } from 'nostr-hooks'; | ||
import { useEffect, useMemo } from 'react'; | ||
|
||
export const useNoteCommentsWidget = (event: NDKEvent) => { | ||
const rootEventId = useMemo(() => { | ||
const rootTags = event | ||
.getMatchingTags('e') | ||
.filter((tag) => tag.length > 2 && tag[3] === 'root'); | ||
|
||
if (rootTags.length === 0) { | ||
return event.id; | ||
} | ||
|
||
if (rootTags[0].length < 2) { | ||
return event.id; | ||
} | ||
|
||
return rootTags[0][1]; | ||
}, [event]); | ||
|
||
const subId = `note-comments-${rootEventId}`; | ||
|
||
const { createSubscription, events, loadMore, hasMore, isLoading } = useSubscription(subId); | ||
|
||
const processedEvents = useMemo( | ||
() => | ||
events | ||
?.filter((e) => { | ||
const eTags = e.getMatchingTags('e'); | ||
if (eTags.length === 0) { | ||
return false; | ||
} | ||
|
||
if (event.id === rootEventId) { | ||
return ( | ||
eTags.some((eTag) => eTag.length > 3 && eTag[1] === event.id && eTag[3] === 'root') && | ||
!eTags.some((eTag) => eTag.length > 3 && eTag[3] === 'reply') | ||
); | ||
} else { | ||
return ( | ||
eTags.some( | ||
(eTag) => eTag.length > 3 && eTag[1] === event.id && eTag[3] === 'reply', | ||
) && | ||
eTags.some((eTag) => eTag.length > 3 && eTag[1] === rootEventId && eTag[3] === 'root') | ||
); | ||
} | ||
}) | ||
.reverse(), | ||
[events, event, rootEventId], | ||
); | ||
|
||
useEffect(() => { | ||
createSubscription({ | ||
filters: [{ kinds: [1], '#e': [rootEventId], limit: 10 }], | ||
opts: { groupableDelay: 500 }, | ||
}); | ||
}, [createSubscription]); | ||
|
||
return { | ||
processedEvents, | ||
loadMore, | ||
hasMore, | ||
isLoading, | ||
}; | ||
}; |
46 changes: 46 additions & 0 deletions
46
templates/react-shadcn/src/features/note-comments-widget/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
|
||
import { Button } from '@/shared/components/ui/button'; | ||
|
||
import { Spinner } from '@/shared/components/spinner'; | ||
|
||
import { cn } from '@/shared/utils'; | ||
|
||
import { NewNoteWidget } from '@/features/new-note-widget'; | ||
import { NoteByEvent } from '@/features/note-widget'; | ||
|
||
import { useNoteCommentsWidget } from './hooks'; | ||
|
||
export const NoteCommentsWidget = ({ event }: { event: NDKEvent }) => { | ||
const { processedEvents, hasMore, loadMore } = useNoteCommentsWidget(event); | ||
|
||
return ( | ||
<> | ||
<NewNoteWidget replyingToEvent={event} /> | ||
|
||
<div className="bg-foreground/5 pl-4 -mx-2"> | ||
{processedEvents === undefined ? ( | ||
<Spinner /> | ||
) : ( | ||
processedEvents.length > 0 && ( | ||
<div className="pt-2 flex flex-col gap-2"> | ||
{processedEvents.map((event, i) => ( | ||
<div className={cn({ 'border-b': i !== processedEvents.length - 1 })}> | ||
<NoteByEvent key={event.id} event={event} /> | ||
</div> | ||
))} | ||
</div> | ||
) | ||
)} | ||
|
||
{hasMore && ( | ||
<div className="py-4 flex justify-center"> | ||
<Button variant="secondary" onClick={() => loadMore(50)} className="w-full"> | ||
Load more | ||
</Button> | ||
</div> | ||
)} | ||
</div> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
templates/react-shadcn/src/features/note-widget/components/note-comment-btn/hooks/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
import { useSubscription } from 'nostr-hooks'; | ||
import { useEffect, useMemo } from 'react'; | ||
|
||
export const useNoteCommentBtn = (event: NDKEvent | undefined) => { | ||
const rootEventId = useMemo(() => { | ||
if (!event) { | ||
return undefined; | ||
} | ||
|
||
const rootTags = event | ||
.getMatchingTags('e') | ||
.filter((tag) => tag.length > 2 && tag[3] === 'root'); | ||
|
||
if (rootTags.length === 0) { | ||
return event.id; | ||
} | ||
|
||
if (rootTags[0].length < 2) { | ||
return event.id; | ||
} | ||
|
||
return rootTags[0][1]; | ||
}, [event]); | ||
|
||
const subId = rootEventId ? `note-comments-${rootEventId}` : undefined; | ||
|
||
const { createSubscription, events } = useSubscription(subId); | ||
|
||
const processedEvents = useMemo( | ||
() => | ||
events | ||
?.filter((e) => { | ||
const eTags = e.getMatchingTags('e'); | ||
if (eTags.length === 0) { | ||
return false; | ||
} | ||
|
||
if (event?.id === rootEventId) { | ||
return ( | ||
eTags.some( | ||
(eTag) => eTag.length > 3 && eTag[1] === event?.id && eTag[3] === 'root', | ||
) && !eTags.some((eTag) => eTag.length > 3 && eTag[3] === 'reply') | ||
); | ||
} else { | ||
return ( | ||
eTags.some( | ||
(eTag) => eTag.length > 3 && eTag[1] === event?.id && eTag[3] === 'reply', | ||
) && | ||
eTags.some((eTag) => eTag.length > 3 && eTag[1] === rootEventId && eTag[3] === 'root') | ||
); | ||
} | ||
}) | ||
.reverse(), | ||
[events, event, rootEventId], | ||
); | ||
|
||
const count = useMemo(() => processedEvents?.length || 0, [processedEvents]); | ||
|
||
useEffect(() => { | ||
rootEventId && | ||
createSubscription({ | ||
filters: [{ kinds: [1], '#e': [rootEventId], limit: 10 }], | ||
opts: { groupableDelay: 500 }, | ||
}); | ||
}, [createSubscription, rootEventId]); | ||
|
||
return { count }; | ||
}; |
17 changes: 16 additions & 1 deletion
17
templates/react-shadcn/src/features/note-widget/components/note-comment-btn/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
templates/react-shadcn/src/features/note-widget/components/note-footer/hooks/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { useState } from 'react'; | ||
import { useInView } from 'react-intersection-observer'; | ||
|
||
export const useNoteFooter = () => { | ||
const [showingComments, setShowingComments] = useState(false); | ||
|
||
const { ref, inView } = useInView({ | ||
threshold: 0, | ||
triggerOnce: true, | ||
}); | ||
|
||
return { | ||
ref, | ||
showingComments, | ||
setShowingComments, | ||
inView, | ||
}; | ||
}; |
33 changes: 22 additions & 11 deletions
33
templates/react-shadcn/src/features/note-widget/components/note-footer/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,39 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
import { useState } from 'react'; | ||
|
||
import { NewNoteWidget } from '@/features/new-note-widget'; | ||
import { NoteCommentsWidget } from '@/features/note-comments-widget'; | ||
|
||
import { NoteBookmarkBtn, NoteCommentBtn, NoteLikeBtn, NoteRepostBtn, NoteZapBtn } from '..'; | ||
import { | ||
NoteBookmarkBtn, | ||
NoteCommentBtn, | ||
NoteLikeBtn, | ||
NoteRepostBtn, | ||
NoteZapBtn, | ||
} from '@/features/note-widget/components'; | ||
|
||
import { useNoteFooter } from './hooks'; | ||
|
||
export const NoteFooter = ({ event }: { event: NDKEvent }) => { | ||
const [isCommenting, setIsCommenting] = useState(false); | ||
const { inView, ref, setShowingComments, showingComments } = useNoteFooter(); | ||
|
||
return ( | ||
<> | ||
<div className="flex items-center justify-between gap-2"> | ||
<NoteCommentBtn onClick={() => setIsCommenting((prev) => !prev)} /> | ||
<div className="flex items-center justify-between gap-2" ref={ref}> | ||
<NoteCommentBtn | ||
onClick={() => setShowingComments((prev) => !prev)} | ||
event={event} | ||
inView={inView} | ||
/> | ||
|
||
<NoteZapBtn event={event} /> | ||
<NoteZapBtn event={event} inView={inView} /> | ||
|
||
<NoteLikeBtn event={event} /> | ||
<NoteLikeBtn event={event} inView={inView} /> | ||
|
||
<NoteRepostBtn event={event} /> | ||
<NoteRepostBtn event={event} inView={inView} /> | ||
|
||
<NoteBookmarkBtn event={event} /> | ||
<NoteBookmarkBtn event={event} inView={inView} /> | ||
</div> | ||
|
||
{isCommenting && <NewNoteWidget replyingToEvent={event} />} | ||
{showingComments && <NoteCommentsWidget event={event} />} | ||
</> | ||
); | ||
}; |
Oops, something went wrong.