-
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 #16 from ostyjs/widgets
Widgets
- Loading branch information
Showing
43 changed files
with
1,650 additions
and
5 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
61 changes: 61 additions & 0 deletions
61
templates/react-shadcn/src/features/new-note-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,61 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
import { useActiveUser, useNdk, useRealtimeProfile } from 'nostr-hooks'; | ||
import { useCallback, useState } from 'react'; | ||
|
||
import { useToast } from '@/shared/components/ui/use-toast'; | ||
|
||
export const useNewNoteWidget = ({ | ||
replyingToEvent, | ||
}: { | ||
replyingToEvent?: NDKEvent | undefined; | ||
}) => { | ||
const [content, setContent] = useState<string>(''); | ||
|
||
const { activeUser } = useActiveUser(); | ||
const { profile } = useRealtimeProfile(activeUser?.pubkey); | ||
|
||
const { ndk } = useNdk(); | ||
|
||
const { toast } = useToast(); | ||
|
||
const post = useCallback(() => { | ||
if (!ndk || !ndk.signer) { | ||
return; | ||
} | ||
|
||
const e = new NDKEvent(ndk); | ||
e.kind = 1; | ||
e.content = content; | ||
|
||
if (replyingToEvent) { | ||
const rootTag = replyingToEvent.tags.find((tag) => tag.length > 3 && tag[3] === 'root'); | ||
|
||
if (rootTag) { | ||
e.tags.push(['e', rootTag[1], '', 'root']); | ||
e.tags.push(['e', replyingToEvent.id, '', 'reply']); | ||
} else { | ||
e.tags.push(['e', replyingToEvent.id, '', 'root']); | ||
} | ||
} | ||
|
||
e.publish() | ||
.then((relaySet) => { | ||
if (relaySet.size === 0) { | ||
toast({ | ||
title: 'Error', | ||
description: 'Failed to post note', | ||
variant: 'destructive', | ||
}); | ||
} | ||
}) | ||
.catch((_) => { | ||
toast({ | ||
title: 'Error', | ||
description: 'Failed to post note', | ||
variant: 'destructive', | ||
}); | ||
}); | ||
}, [ndk, content, replyingToEvent, toast]); | ||
|
||
return { content, setContent, post, profile }; | ||
}; |
36 changes: 36 additions & 0 deletions
36
templates/react-shadcn/src/features/new-note-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,36 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
|
||
import { Avatar, AvatarFallback, AvatarImage } from '@/shared/components/ui/avatar'; | ||
import { Button } from '@/shared/components/ui/button'; | ||
import { Textarea } from '@/shared/components/ui/textarea'; | ||
|
||
import { useNewNoteWidget } from './hooks'; | ||
|
||
export const NewNoteWidget = ({ replyingToEvent }: { replyingToEvent?: NDKEvent | undefined }) => { | ||
const { content, post, setContent, profile } = useNewNoteWidget({ replyingToEvent }); | ||
|
||
return ( | ||
<> | ||
<div className="p-2 bg-muted flex flex-col gap-2"> | ||
<div className="flex gap-2"> | ||
<Avatar> | ||
<AvatarImage src={profile?.image} alt={profile?.name} /> | ||
<AvatarFallback className="bg-muted" /> | ||
</Avatar> | ||
|
||
<Textarea | ||
className="bg-background" | ||
value={content} | ||
onChange={(e) => setContent(e.target.value)} | ||
/> | ||
</div> | ||
|
||
<div className="w-full flex gap-2 justify-end"> | ||
<Button className="px-8" onClick={post}> | ||
Post | ||
</Button> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; |
9 changes: 9 additions & 0 deletions
9
templates/react-shadcn/src/features/note-widget/components/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,9 @@ | ||
export * from './note-bookmark-btn'; | ||
export * from './note-comment-btn'; | ||
export * from './note-content'; | ||
export * from './note-footer'; | ||
export * from './note-header'; | ||
export * from './note-like-btn'; | ||
export * from './note-parent-preview'; | ||
export * from './note-repost-btn'; | ||
export * from './note-zap-btn'; |
69 changes: 69 additions & 0 deletions
69
templates/react-shadcn/src/features/note-widget/components/note-bookmark-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, NDKKind } from '@nostr-dev-kit/ndk'; | ||
import { useActiveUser, useNdk, useSubscription } from 'nostr-hooks'; | ||
import { useCallback, useEffect, useMemo } from 'react'; | ||
|
||
export const useNoteBookmarkBtn = (event: NDKEvent) => { | ||
const { ndk } = useNdk(); | ||
|
||
const { myBookmarkList } = useMyBookmarkList(); | ||
|
||
const isBookmarkedByMe = useMemo( | ||
() => myBookmarkList?.getMatchingTags('e')?.some((e) => e.length > 1 && e[1] === event.id), | ||
[myBookmarkList, event], | ||
); | ||
|
||
const bookmark = useCallback(() => { | ||
if (!ndk) { | ||
return; | ||
} | ||
|
||
if (isBookmarkedByMe) { | ||
return; | ||
} | ||
|
||
const e = new NDKEvent(ndk); | ||
e.kind = NDKKind.BookmarkList; | ||
e.tags = [...(myBookmarkList?.tags || [])]; | ||
e.tags.push(['e', event.id]); | ||
e.publish(); | ||
}, [ndk, event, isBookmarkedByMe, myBookmarkList]); | ||
|
||
const unbookmark = useCallback(() => { | ||
if (!ndk) { | ||
return; | ||
} | ||
|
||
if (!isBookmarkedByMe) { | ||
return; | ||
} | ||
|
||
const e = new NDKEvent(ndk); | ||
e.kind = NDKKind.BookmarkList; | ||
e.tags = myBookmarkList?.tags.filter((t) => t[1] !== event.id) || []; | ||
e.publish(); | ||
}, [ndk, event, isBookmarkedByMe, myBookmarkList]); | ||
|
||
return { isBookmarkedByMe, bookmark, unbookmark }; | ||
}; | ||
|
||
const useMyBookmarkList = () => { | ||
const { activeUser } = useActiveUser(); | ||
|
||
const subId = activeUser ? `my-bookmark-list` : undefined; | ||
|
||
const { createSubscription, events } = useSubscription(subId); | ||
|
||
const myBookmarkList = useMemo( | ||
() => (events && events.length > 0 ? events[events.length - 1] : undefined), | ||
[events], | ||
); | ||
|
||
useEffect(() => { | ||
activeUser && | ||
createSubscription({ | ||
filters: [{ kinds: [NDKKind.BookmarkList], authors: [activeUser.pubkey], limit: 1 }], | ||
}); | ||
}, [createSubscription]); | ||
|
||
return { myBookmarkList }; | ||
}; |
25 changes: 25 additions & 0 deletions
25
templates/react-shadcn/src/features/note-widget/components/note-bookmark-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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
import { BookmarkIcon } from 'lucide-react'; | ||
|
||
import { Button } from '@/shared/components/ui/button'; | ||
|
||
import { cn } from '@/shared/utils'; | ||
|
||
import { useNoteBookmarkBtn } from './hooks'; | ||
|
||
export const NoteBookmarkBtn = ({ event }: { event: NDKEvent }) => { | ||
const { isBookmarkedByMe, bookmark, unbookmark } = useNoteBookmarkBtn(event); | ||
|
||
return ( | ||
<> | ||
<Button | ||
variant="link" | ||
size="icon" | ||
className={cn(isBookmarkedByMe ? 'text-green-600' : 'opacity-50 hover:opacity-100')} | ||
onClick={isBookmarkedByMe ? unbookmark : bookmark} | ||
> | ||
<BookmarkIcon size={18} /> | ||
</Button> | ||
</> | ||
); | ||
}; |
13 changes: 13 additions & 0 deletions
13
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { MessageSquareIcon } from 'lucide-react'; | ||
|
||
import { Button } from '@/shared/components/ui/button'; | ||
|
||
export const NoteCommentBtn = ({ onClick }: { onClick: () => void }) => { | ||
return ( | ||
<> | ||
<Button variant="link" size="icon" className="opacity-50 hover:opacity-100" onClick={onClick}> | ||
<MessageSquareIcon size={18} /> | ||
</Button> | ||
</> | ||
); | ||
}; |
9 changes: 9 additions & 0 deletions
9
templates/react-shadcn/src/features/note-widget/components/note-content/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,9 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
|
||
export const NoteContent = ({ event }: { event: NDKEvent }) => { | ||
return ( | ||
<div className="pb-2"> | ||
<p className="[overflow-wrap:anywhere]">{event.content}</p> | ||
</div> | ||
); | ||
}; |
28 changes: 28 additions & 0 deletions
28
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 |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { NDKEvent } from '@nostr-dev-kit/ndk'; | ||
import { useState } from 'react'; | ||
|
||
import { NewNoteWidget } from '@/features/new-note-widget'; | ||
|
||
import { NoteBookmarkBtn, NoteCommentBtn, NoteLikeBtn, NoteRepostBtn, NoteZapBtn } from '..'; | ||
|
||
export const NoteFooter = ({ event }: { event: NDKEvent }) => { | ||
const [isCommenting, setIsCommenting] = useState(false); | ||
|
||
return ( | ||
<div className=""> | ||
<div className="flex items-center justify-between gap-2"> | ||
<NoteCommentBtn onClick={() => setIsCommenting((prev) => !prev)} /> | ||
|
||
<NoteZapBtn event={event} /> | ||
|
||
<NoteLikeBtn event={event} /> | ||
|
||
<NoteRepostBtn event={event} /> | ||
|
||
<NoteBookmarkBtn event={event} /> | ||
</div> | ||
|
||
{isCommenting && <NewNoteWidget replyingToEvent={event} />} | ||
</div> | ||
); | ||
}; |
17 changes: 17 additions & 0 deletions
17
templates/react-shadcn/src/features/note-widget/components/note-header/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,17 @@ | ||
import { useProfile } from 'nostr-hooks'; | ||
import { useNavigate } from 'react-router-dom'; | ||
import { useCopyToClipboard } from 'usehooks-ts'; | ||
|
||
export const useNoteHeader = (pubkey: string) => { | ||
const [, copy] = useCopyToClipboard(); | ||
|
||
const { profile } = useProfile({ pubkey }); | ||
|
||
const navigate = useNavigate(); | ||
|
||
return { | ||
profile, | ||
copy, | ||
navigate, | ||
}; | ||
}; |
Oops, something went wrong.