diff --git a/src/js/components/events/Note.tsx b/src/js/components/events/Note.tsx index fd667ef3..21e57c8f 100644 --- a/src/js/components/events/Note.tsx +++ b/src/js/components/events/Note.tsx @@ -16,7 +16,7 @@ import Torrent from '../Torrent'; import EventComponent from './EventComponent'; import EventDropdown from './EventDropdown'; -import Reactions from './Reactions'; +import Reactions from './ReactionButtons'; const MSG_TRUNCATE_LENGTH = 500; const MSG_TRUNCATE_LINES = 8; diff --git a/src/js/components/events/Reactions.tsx b/src/js/components/events/ReactionButtons.tsx similarity index 69% rename from src/js/components/events/Reactions.tsx rename to src/js/components/events/ReactionButtons.tsx index 2ee3043d..7d48ffc1 100644 --- a/src/js/components/events/Reactions.tsx +++ b/src/js/components/events/ReactionButtons.tsx @@ -21,13 +21,15 @@ import SocialNetwork from '../../nostr/SocialNetwork'; import Identicon from '../Identicon'; import ZapModal from '../modal/Zap'; -const Reactions = (props) => { +import ReactionsList from './ReactionsList'; + +const ReactionButtons = (props) => { const [state, setState] = useState({ reposts: 0, reposted: false, likes: 0, zappers: null as string[] | null, - totalZapped: '', + totalZapAmount: '', liked: false, zapped: false, repostedBy: new Set(), @@ -181,7 +183,7 @@ const Reactions = (props) => { const zappers = zapEvents .map((event) => Events.getZappingUser(event.id)) .filter((user) => user !== null) as string[]; - const totalZapped = zapEvents.reduce((acc, event) => { + const totalZapAmount = zapEvents.reduce((acc, event) => { const bolt11 = event?.tags.find((tag) => tag[0] === 'bolt11')[1]; if (!bolt11) { console.log('Invalid zap, missing bolt11 tag'); @@ -199,7 +201,8 @@ const Reactions = (props) => { reposts: repostedBy.size, reposted: repostedBy.has(myPub), likes: likedBy.size, - totalZapped: totalZapped && formatAmount(totalZapped), + totalZapAmount, + formattedZapAmount: totalZapAmount && formatAmount(totalZapAmount), zappers, liked: likedBy.has(myPub), likedBy, @@ -223,73 +226,82 @@ const Reactions = (props) => { function renderReactionBtns() { const s = state; + const likes = Array.from(s.likedBy) || []; + const reposts = Array.from(s.repostedBy) || []; + const zaps = Array.from(s.zappers || []); + console.log('111', likes, reposts, zaps); return ( -
- replyBtnClicked()} - > - - {s.replyCount || ''} - - {props.settings.showReposts ? ( - <> - repostBtnClicked(e)} - > - - toggleReposts(e)} + <> + {props.standalone && ( + + )} +
+ replyBtnClicked()} + > + + {s.replyCount || ''} + + {props.settings.showReposts ? ( + <> + repostBtnClicked(e)} > - {s.reposts || ''} - - - - ) : ( - '' - )} - {props.settings.showLikes ? ( - <> - likeBtnClicked(e)} - > - {s.liked ? : } - toggleLikes(e)}> - {s.likes || ''} - - - - ) : ( - '' - )} - {props.settings.showZaps && state.lightning ? ( - <> - { - e.preventDefault(); - e.stopPropagation(); - setState((prevState) => ({ ...prevState, showZapModal: true })); - }} - className={`btn-ghost flex-1 hover:bg-transparent btn content-center gap-2 rounded-none p-2 + + toggleReposts(e)} + > + {s.reposts || ''} + + + + ) : ( + '' + )} + {props.settings.showLikes ? ( + <> + likeBtnClicked(e)} + > + {s.liked ? : } + toggleLikes(e)}> + {s.likes || ''} + + + + ) : ( + '' + )} + {props.settings.showZaps && state.lightning ? ( + <> + { + e.preventDefault(); + e.stopPropagation(); + setState((prevState) => ({ ...prevState, showZapModal: true })); + }} + className={`btn-ghost flex-1 hover:bg-transparent btn content-center gap-2 rounded-none p-2 ${s.zapped ? 'text-iris-orange' : 'text-neutral-500 hover:text-iris-orange'}`} - > - - toggleZaps(e)}> - {s.totalZapped || ''} - - - - ) : ( - '' - )} -
+ > + + toggleZaps(e)}> + {s.totalZapAmount || ''} + + + + ) : ( + '' + )} +
+ ); } @@ -342,4 +354,4 @@ const Reactions = (props) => { ); }; -export default memo(Reactions); +export default memo(ReactionButtons); diff --git a/src/js/components/events/ReactionsList.tsx b/src/js/components/events/ReactionsList.tsx new file mode 100644 index 00000000..5a38a07a --- /dev/null +++ b/src/js/components/events/ReactionsList.tsx @@ -0,0 +1,103 @@ +import { memo, useState } from 'react'; +import { Event, nip19 } from 'nostr-tools'; +import { Link } from 'preact-router'; + +import { decodeInvoice, formatAmount } from '../../Lightning'; +import Events from '../../nostr/Events'; +import Identicon from '../Identicon'; +import Modal from '../modal/Modal'; +import Name from '../Name'; + +const Reaction = memo( + ({ event }: { event: Event }) => { + const reactor = (event.kind === 9735 ? Events.getZappingUser(event.id) : event.pubkey) || ''; + const invoice = + event.kind === 9735 ? event.tags?.find((tag) => tag[0] === 'bolt11')?.[1] : undefined; + const amount = invoice ? decodeInvoice(invoice)?.amount : undefined; + console.log('amount', amount, 'invoice', invoice, 'event', event); + return ( + + +
+ + {amount && {formatAmount(amount / 1000)}} +
+ + ); + }, + (prevProps, nextProps) => prevProps.event.id === nextProps.event.id, +); + +const ReactionsList = (props) => { + const { likes, reposts, zaps, totalZapAmount, formattedZapAmount } = props; + const [modalReactions, setModalReactions] = useState([] as Event[]); + const [modalTitle, setModalTitle] = useState(''); + console.log(333, likes.length, reposts.length, zaps.length, totalZapAmount, formattedZapAmount); + return ( + <> +
+ {modalReactions.length > 0 && ( + setModalReactions([])}> +
+

{modalTitle}

+
+
+ {modalReactions.map((event) => ( + + ))} +
+
+ )} +
+ {likes.length > 0 && ( +
+ { + setModalReactions(likes); + setModalTitle('Liked by'); + }} + className="cursor-pointer hover:underline" + > + {likes.length} Likes + +
+ )} + {reposts.length > 0 && ( +
+ { + setModalReactions(reposts); + setModalTitle('Reposted by'); + }} + className="cursor-pointer hover:underline" + > + {reposts.length} Reposts + +
+ )} + {zaps.length > 0 && ( +
+ { + setModalReactions(zaps); + setModalTitle('Zapped by'); + }} + className="cursor-pointer hover:underline" + > + {zaps.length} Zaps + {totalZapAmount > 0 && ( + ({formattedZapAmount}) + )} + +
+ )} +
+ + ); +}; + +export default ReactionsList;