Count polls by pubkey

This commit is contained in:
Kieran 2023-09-12 22:17:04 +01:00
parent 4927e0c4f8
commit 377dfd5d30
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
3 changed files with 48 additions and 12 deletions

View File

@ -17,12 +17,15 @@ interface PollProps {
zaps: Array<ParsedZap>;
}
type PollTally = "zaps" | "pubkeys";
export default function Poll(props: PollProps) {
const { formatMessage } = useIntl();
const publisher = useEventPublisher();
const { wallet } = useWallet();
const { preferences: prefs, publicKey: myPubKey, relays } = useLogin();
const pollerProfile = useUserProfile(props.ev.pubkey);
const [tallyBy, setTallyBy] = useState<PollTally>("pubkeys");
const [error, setError] = useState("");
const [invoice, setInvoice] = useState("");
const [voting, setVoting] = useState<number>();
@ -33,6 +36,7 @@ export default function Poll(props: PollProps) {
const options = props.ev.tags
.filter(a => a[0] === "poll_option")
.sort((a, b) => (Number(a[1]) > Number(b[1]) ? 1 : -1));
async function zapVote(ev: React.MouseEvent, opt: number) {
ev.stopPropagation();
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 (
<>
<small>
<FormattedMessage
defaultMessage="You are voting with {amount} sats"
values={{
amount: formatShort(prefs.defaultZapAmount),
}}
/>
</small>
<div className="flex f-space p">
<small>
<FormattedMessage
defaultMessage="You are voting with {amount} sats"
values={{
amount: formatShort(prefs.defaultZapAmount),
}}
/>
</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">
{options.map(a => {
const opt = Number(a[1]);
const desc = a[2];
const zapsOnOption = props.zaps.filter(b => b.pollOption === opt);
const total = zapsOnOption.reduce((acc, v) => (acc += v.amount), 0);
const weight = allTotal === 0 ? 0 : total / allTotal;
const total = (() => {
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 (
<div key={a[1]} className="flex" onClick={e => zapVote(e, opt)}>
<div className="f-grow">{opt === voting ? <Spinner /> : <>{desc}</>}</div>

View File

@ -154,6 +154,9 @@
"4rYCjn": {
"defaultMessage": "Note to Self"
},
"5BVs2e": {
"defaultMessage": "zap"
},
"5JcXdV": {
"defaultMessage": "Create Account"
},
@ -1200,6 +1203,9 @@
"rudscU": {
"defaultMessage": "Failed to load follows, please try again later"
},
"sUNhQE": {
"defaultMessage": "user"
},
"sWnYKw": {
"defaultMessage": "Snort is designed to have a similar experience to Twitter."
},
@ -1292,6 +1298,9 @@
"x82IOl": {
"defaultMessage": "Mute"
},
"xIcAOU": {
"defaultMessage": "Votes by {type}"
},
"xIoGG9": {
"defaultMessage": "Go to"
},

View File

@ -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",
"4Z3t5i": "Use imgproxy to compress images",
"4rYCjn": "Note to Self",
"5BVs2e": "zap",
"5JcXdV": "Create Account",
"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.",
@ -392,6 +393,7 @@
"rmdsT4": "{n} days",
"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",
"sUNhQE": "user",
"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.",
"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/q8d5": "This note has been marked as sensitive, click here to reveal",
"x82IOl": "Mute",
"xIcAOU": "Votes by {type}",
"xIoGG9": "Go to",
"xJ9n2N": "Your public key",
"xKflGN": "{username}''s Follows on Nostr",
@ -440,4 +443,4 @@
"zjJZBd": "You're ready!",
"zonsdq": "Failed to load LNURL service",
"zvCDao": "Automatically show latest notes"
}
}