Count polls by pubkey
This commit is contained in:
parent
4927e0c4f8
commit
377dfd5d30
@ -17,12 +17,15 @@ interface PollProps {
|
|||||||
zaps: Array<ParsedZap>;
|
zaps: Array<ParsedZap>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PollTally = "zaps" | "pubkeys";
|
||||||
|
|
||||||
export default function Poll(props: PollProps) {
|
export default function Poll(props: PollProps) {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
const publisher = useEventPublisher();
|
const publisher = useEventPublisher();
|
||||||
const { wallet } = useWallet();
|
const { wallet } = useWallet();
|
||||||
const { preferences: prefs, publicKey: myPubKey, relays } = useLogin();
|
const { preferences: prefs, publicKey: myPubKey, relays } = useLogin();
|
||||||
const pollerProfile = useUserProfile(props.ev.pubkey);
|
const pollerProfile = useUserProfile(props.ev.pubkey);
|
||||||
|
const [tallyBy, setTallyBy] = useState<PollTally>("pubkeys");
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [invoice, setInvoice] = useState("");
|
const [invoice, setInvoice] = useState("");
|
||||||
const [voting, setVoting] = useState<number>();
|
const [voting, setVoting] = useState<number>();
|
||||||
@ -33,6 +36,7 @@ export default function Poll(props: PollProps) {
|
|||||||
const options = props.ev.tags
|
const options = props.ev.tags
|
||||||
.filter(a => a[0] === "poll_option")
|
.filter(a => a[0] === "poll_option")
|
||||||
.sort((a, b) => (Number(a[1]) > Number(b[1]) ? 1 : -1));
|
.sort((a, b) => (Number(a[1]) > Number(b[1]) ? 1 : -1));
|
||||||
|
|
||||||
async function zapVote(ev: React.MouseEvent, opt: number) {
|
async function zapVote(ev: React.MouseEvent, opt: number) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
if (voting || !publisher) return;
|
if (voting || !publisher) return;
|
||||||
@ -93,24 +97,44 @@ export default function Poll(props: PollProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const allTotal = props.zaps.filter(a => a.pollOption !== undefined).reduce((acc, v) => (acc += v.amount), 0);
|
const totalVotes = (() => {
|
||||||
|
switch (tallyBy) {
|
||||||
|
case "zaps":
|
||||||
|
return props.zaps.filter(a => a.pollOption !== undefined).reduce((acc, v) => (acc += v.amount), 0);
|
||||||
|
case "pubkeys":
|
||||||
|
return new Set(props.zaps.filter(a => a.pollOption !== undefined).map(a => unwrap(a.sender))).size;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<small>
|
<div className="flex f-space p">
|
||||||
<FormattedMessage
|
<small>
|
||||||
defaultMessage="You are voting with {amount} sats"
|
<FormattedMessage
|
||||||
values={{
|
defaultMessage="You are voting with {amount} sats"
|
||||||
amount: formatShort(prefs.defaultZapAmount),
|
values={{
|
||||||
}}
|
amount: formatShort(prefs.defaultZapAmount),
|
||||||
/>
|
}}
|
||||||
</small>
|
/>
|
||||||
|
</small>
|
||||||
|
<button type="button" onClick={() => setTallyBy(s => s !== "zaps" ? "zaps" : "pubkeys")}>
|
||||||
|
<FormattedMessage defaultMessage="Votes by {type}" values={{
|
||||||
|
type: tallyBy === "zaps" ? <FormattedMessage defaultMessage="zap" /> : <FormattedMessage defaultMessage="user" />
|
||||||
|
}} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div className="poll-body">
|
<div className="poll-body">
|
||||||
{options.map(a => {
|
{options.map(a => {
|
||||||
const opt = Number(a[1]);
|
const opt = Number(a[1]);
|
||||||
const desc = a[2];
|
const desc = a[2];
|
||||||
const zapsOnOption = props.zaps.filter(b => b.pollOption === opt);
|
const zapsOnOption = props.zaps.filter(b => b.pollOption === opt);
|
||||||
const total = zapsOnOption.reduce((acc, v) => (acc += v.amount), 0);
|
const total = (() => {
|
||||||
const weight = allTotal === 0 ? 0 : total / allTotal;
|
switch (tallyBy) {
|
||||||
|
case "zaps": return zapsOnOption.reduce((acc, v) => (acc += v.amount), 0);
|
||||||
|
case "pubkeys": return new Set(zapsOnOption.map(a => unwrap(a.sender))).size;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
const weight = totalVotes === 0 ? 0 : total / totalVotes;
|
||||||
return (
|
return (
|
||||||
<div key={a[1]} className="flex" onClick={e => zapVote(e, opt)}>
|
<div key={a[1]} className="flex" onClick={e => zapVote(e, opt)}>
|
||||||
<div className="f-grow">{opt === voting ? <Spinner /> : <>{desc}</>}</div>
|
<div className="f-grow">{opt === voting ? <Spinner /> : <>{desc}</>}</div>
|
||||||
|
@ -154,6 +154,9 @@
|
|||||||
"4rYCjn": {
|
"4rYCjn": {
|
||||||
"defaultMessage": "Note to Self"
|
"defaultMessage": "Note to Self"
|
||||||
},
|
},
|
||||||
|
"5BVs2e": {
|
||||||
|
"defaultMessage": "zap"
|
||||||
|
},
|
||||||
"5JcXdV": {
|
"5JcXdV": {
|
||||||
"defaultMessage": "Create Account"
|
"defaultMessage": "Create Account"
|
||||||
},
|
},
|
||||||
@ -1200,6 +1203,9 @@
|
|||||||
"rudscU": {
|
"rudscU": {
|
||||||
"defaultMessage": "Failed to load follows, please try again later"
|
"defaultMessage": "Failed to load follows, please try again later"
|
||||||
},
|
},
|
||||||
|
"sUNhQE": {
|
||||||
|
"defaultMessage": "user"
|
||||||
|
},
|
||||||
"sWnYKw": {
|
"sWnYKw": {
|
||||||
"defaultMessage": "Snort is designed to have a similar experience to Twitter."
|
"defaultMessage": "Snort is designed to have a similar experience to Twitter."
|
||||||
},
|
},
|
||||||
@ -1292,6 +1298,9 @@
|
|||||||
"x82IOl": {
|
"x82IOl": {
|
||||||
"defaultMessage": "Mute"
|
"defaultMessage": "Mute"
|
||||||
},
|
},
|
||||||
|
"xIcAOU": {
|
||||||
|
"defaultMessage": "Votes by {type}"
|
||||||
|
},
|
||||||
"xIoGG9": {
|
"xIoGG9": {
|
||||||
"defaultMessage": "Go to"
|
"defaultMessage": "Go to"
|
||||||
},
|
},
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
"4Vmpt4": "Nostr Plebs is one of the first NIP-05 providers in the space and offers a good collection of domains at reasonable prices",
|
"4Vmpt4": "Nostr Plebs is one of the first NIP-05 providers in the space and offers a good collection of domains at reasonable prices",
|
||||||
"4Z3t5i": "Use imgproxy to compress images",
|
"4Z3t5i": "Use imgproxy to compress images",
|
||||||
"4rYCjn": "Note to Self",
|
"4rYCjn": "Note to Self",
|
||||||
|
"5BVs2e": "zap",
|
||||||
"5JcXdV": "Create Account",
|
"5JcXdV": "Create Account",
|
||||||
"5oTnfy": "Buy Handle",
|
"5oTnfy": "Buy Handle",
|
||||||
"5rOdPG": "Once you setup your key manager extension and generated a key, you can follow our new users flow to setup your profile and help you find some interesting people on Nostr to follow.",
|
"5rOdPG": "Once you setup your key manager extension and generated a key, you can follow our new users flow to setup your profile and help you find some interesting people on Nostr to follow.",
|
||||||
@ -392,6 +393,7 @@
|
|||||||
"rmdsT4": "{n} days",
|
"rmdsT4": "{n} days",
|
||||||
"rrfdTe": "This is the same technology which is used by Bitcoin and has been proven to be extremely secure.",
|
"rrfdTe": "This is the same technology which is used by Bitcoin and has been proven to be extremely secure.",
|
||||||
"rudscU": "Failed to load follows, please try again later",
|
"rudscU": "Failed to load follows, please try again later",
|
||||||
|
"sUNhQE": "user",
|
||||||
"sWnYKw": "Snort is designed to have a similar experience to Twitter.",
|
"sWnYKw": "Snort is designed to have a similar experience to Twitter.",
|
||||||
"svOoEH": "Name-squatting and impersonation is not allowed. Snort and our partners reserve the right to terminate your handle (not your account - nobody can take that away) for violating this rule.",
|
"svOoEH": "Name-squatting and impersonation is not allowed. Snort and our partners reserve the right to terminate your handle (not your account - nobody can take that away) for violating this rule.",
|
||||||
"tOdNiY": "Dark",
|
"tOdNiY": "Dark",
|
||||||
@ -422,6 +424,7 @@
|
|||||||
"x/Fx2P": "Fund the services that you use by splitting a portion of all your zaps into a pool of funds!",
|
"x/Fx2P": "Fund the services that you use by splitting a portion of all your zaps into a pool of funds!",
|
||||||
"x/q8d5": "This note has been marked as sensitive, click here to reveal",
|
"x/q8d5": "This note has been marked as sensitive, click here to reveal",
|
||||||
"x82IOl": "Mute",
|
"x82IOl": "Mute",
|
||||||
|
"xIcAOU": "Votes by {type}",
|
||||||
"xIoGG9": "Go to",
|
"xIoGG9": "Go to",
|
||||||
"xJ9n2N": "Your public key",
|
"xJ9n2N": "Your public key",
|
||||||
"xKflGN": "{username}''s Follows on Nostr",
|
"xKflGN": "{username}''s Follows on Nostr",
|
||||||
@ -440,4 +443,4 @@
|
|||||||
"zjJZBd": "You're ready!",
|
"zjJZBd": "You're ready!",
|
||||||
"zonsdq": "Failed to load LNURL service",
|
"zonsdq": "Failed to load LNURL service",
|
||||||
"zvCDao": "Automatically show latest notes"
|
"zvCDao": "Automatically show latest notes"
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user