2023-01-08 00:29:59 +00:00
|
|
|
import { useMemo, useState } from "react";
|
|
|
|
import { useSelector } from "react-redux";
|
2023-01-08 17:33:54 +00:00
|
|
|
import { faHeart, faReply, faThumbsDown, faTrash, faBolt, faRepeat } from "@fortawesome/free-solid-svg-icons";
|
2023-01-08 00:29:59 +00:00
|
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
|
|
|
|
|
|
import useEventPublisher from "../feed/EventPublisher";
|
|
|
|
import { normalizeReaction, Reaction } from "../Util";
|
|
|
|
import { NoteCreator } from "./NoteCreator";
|
|
|
|
import LNURLTip from "./LNURLTip";
|
|
|
|
|
|
|
|
export default function NoteFooter(props) {
|
|
|
|
const reactions = props.reactions;
|
|
|
|
const ev = props.ev;
|
|
|
|
|
|
|
|
const login = useSelector(s => s.login.publicKey);
|
|
|
|
const author = useSelector(s => s.users.users[ev.RootPubKey]);
|
|
|
|
const publisher = useEventPublisher();
|
|
|
|
const [reply, setReply] = useState(false);
|
|
|
|
const [tip, setTip] = useState(false);
|
|
|
|
const isMine = ev.RootPubKey === login;
|
|
|
|
|
|
|
|
const groupReactions = useMemo(() => {
|
|
|
|
return reactions?.reduce((acc, { content }) => {
|
|
|
|
let r = normalizeReaction(content ?? "");
|
|
|
|
const amount = acc[r] || 0
|
|
|
|
return { ...acc, [r]: amount + 1 }
|
|
|
|
}, {
|
|
|
|
[Reaction.Positive]: 0,
|
|
|
|
[Reaction.Negative]: 0
|
|
|
|
});
|
|
|
|
}, [reactions]);
|
|
|
|
|
|
|
|
function hasReacted(emoji) {
|
|
|
|
return reactions?.find(({ PubKey, Content }) => Content === emoji && PubKey === login)
|
|
|
|
}
|
|
|
|
|
|
|
|
async function react(content) {
|
|
|
|
let evLike = await publisher.react(ev, content);
|
|
|
|
publisher.broadcast(evLike);
|
|
|
|
}
|
|
|
|
|
|
|
|
async function deleteEvent() {
|
|
|
|
if (window.confirm(`Are you sure you want to delete ${ev.Id.substring(0, 8)}?`)) {
|
|
|
|
let evDelete = await publisher.delete(ev.Id);
|
|
|
|
publisher.broadcast(evDelete);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-08 17:33:54 +00:00
|
|
|
async function repost() {
|
|
|
|
let evRepost = await publisher.repost(ev);
|
|
|
|
publisher.broadcast(evRepost);
|
|
|
|
}
|
|
|
|
|
2023-01-08 00:29:59 +00:00
|
|
|
function tipButton() {
|
|
|
|
let service = author?.lud16 || author?.lud06;
|
|
|
|
if (service) {
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<span className="pill" onClick={(e) => setTip(true)}>
|
|
|
|
<FontAwesomeIcon icon={faBolt} />
|
|
|
|
</span>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2023-01-08 18:35:36 +00:00
|
|
|
function reactionIcon(content, reacted) {
|
2023-01-08 00:29:59 +00:00
|
|
|
switch (content) {
|
|
|
|
case Reaction.Positive: {
|
2023-01-08 18:35:36 +00:00
|
|
|
return <FontAwesomeIcon color={reacted ? "red" : "currentColor"} icon={faHeart} />;
|
2023-01-08 00:29:59 +00:00
|
|
|
}
|
|
|
|
case Reaction.Negative: {
|
2023-01-08 18:35:36 +00:00
|
|
|
return <FontAwesomeIcon color={reacted ? "orange" : "currentColor"} icon={faThumbsDown} />;
|
2023-01-08 00:29:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return content;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
|
|
|
<div className="footer">
|
|
|
|
{isMine ? <span className="pill">
|
|
|
|
<FontAwesomeIcon icon={faTrash} onClick={(e) => deleteEvent()} />
|
|
|
|
</span> : null}
|
|
|
|
{tipButton()}
|
2023-01-08 17:33:54 +00:00
|
|
|
<span className="pill" onClick={() => repost()}>
|
|
|
|
<FontAwesomeIcon icon={faRepeat} />
|
|
|
|
</span>
|
2023-01-08 00:29:59 +00:00
|
|
|
<span className="pill" onClick={(e) => setReply(s => !s)}>
|
|
|
|
<FontAwesomeIcon icon={faReply} />
|
|
|
|
</span>
|
2023-01-08 18:35:36 +00:00
|
|
|
{Object.keys(groupReactions || {}).map((emoji) => {
|
|
|
|
let didReact = hasReacted(emoji);
|
2023-01-08 00:29:59 +00:00
|
|
|
return (
|
2023-01-08 18:35:36 +00:00
|
|
|
<span className="pill" onClick={() => {
|
|
|
|
if (!didReact) {
|
|
|
|
react(emoji);
|
|
|
|
}
|
|
|
|
}} key={emoji}>
|
|
|
|
{reactionIcon(emoji, didReact)}
|
2023-01-08 00:29:59 +00:00
|
|
|
{groupReactions[emoji] ? <> {groupReactions[emoji]}</> : null}
|
|
|
|
</span>
|
|
|
|
)
|
|
|
|
})}
|
|
|
|
</div>
|
|
|
|
<NoteCreator replyTo={ev} onSend={(e) => setReply(false)} show={reply} />
|
|
|
|
<LNURLTip svc={author?.lud16 || author?.lud06} onClose={(e) => setTip(false)} show={tip} />
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
}
|