Skip to content
This repository has been archived by the owner on Jan 15, 2025. It is now read-only.

Commit

Permalink
Polls: added tokens interpretation and switcher
Browse files Browse the repository at this point in the history
  • Loading branch information
dkildar committed May 3, 2024
1 parent 4dfca6d commit 11c98c7
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export class EntryMetadataBuilder {
question: poll.title,
choices: poll.choices,
preferred_interpretation: poll.interpretation,
token: null,
token: poll.interpretation === "tokens" ? "HIVE:HP" : null,
hide_votes: poll.hideVotes,
vote_change: poll.voteChange,
filters: {
Expand Down
8 changes: 6 additions & 2 deletions src/common/features/polls/api/get-poll-details-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ interface GetPollDetailsQueryResponse {
parent_permlink: string;
permlink: string;
platform: null;
poll_choices: { choice_num: number; choice_text: string; votes?: { total_votes: number } }[];
poll_stats: { total_voting_accounts_num: number };
poll_choices: {
choice_num: number;
choice_text: string;
votes?: { total_votes: number; hive_hp_incl_proxied: number | null };
}[];
poll_stats: { total_voting_accounts_num: number; total_hive_hp_incl_proxied: number | null };
poll_trx_id: string;
poll_voters?: { name: string; choice_num: number }[];
post_body: string;
Expand Down
30 changes: 27 additions & 3 deletions src/common/features/polls/components/poll-option-with-results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ import React, { useMemo } from "react";
import { PollCheck } from "./poll-option";
import { useGetPollDetailsQuery } from "../api";
import { Entry } from "../../../store/entries/types";
import { PollSnapshot } from "./polls-creation";
import { _t } from "../../../i18n";

export interface Props {
activeChoice?: string;
choice: string;
entry?: Entry;
interpretation: PollSnapshot["interpretation"];
}

export function PollOptionWithResults({ choice, activeChoice, entry }: Props) {
export function PollOptionWithResults({ choice, activeChoice, entry, interpretation }: Props) {
const pollDetails = useGetPollDetailsQuery(entry);

const votesCount = useMemo(
Expand All @@ -24,6 +26,24 @@ export function PollOptionWithResults({ choice, activeChoice, entry }: Props) {
() => Math.max(pollDetails.data?.poll_stats.total_voting_accounts_num ?? 0, 1),
[pollDetails.data?.poll_stats.total_voting_accounts_num]
);
const totalHp = useMemo(
() => pollDetails.data?.poll_stats.total_hive_hp_incl_proxied ?? 0,
[pollDetails.data?.poll_stats.total_hive_hp_incl_proxied]
);
const choiceHp = useMemo(
() =>
pollDetails.data?.poll_choices.find((pc) => pc.choice_text === choice)?.votes
?.hive_hp_incl_proxied ?? 0,
[pollDetails.data?.poll_choices, choice]
);

const progress = useMemo(() => {
if (interpretation === "tokens") {
return ((choiceHp * 100) / totalHp).toFixed(2);
}

return ((votesCount * 100) / totalVotes).toFixed(2);
}, [totalHp, choiceHp, votesCount, totalVotes, interpretation]);

return (
<div
Expand All @@ -38,14 +58,18 @@ export function PollOptionWithResults({ choice, activeChoice, entry }: Props) {
"bg-blue-dark-sky bg-opacity-50 min-h-[52px] absolute top-0 left-0 bottom-0": true
})}
style={{
width: `${((votesCount * 100) / totalVotes).toFixed(2)}%`
width: `${progress}%`
}}
/>
{activeChoice === choice && <PollCheck checked={activeChoice === choice} />}
<div className="flex w-full gap-2 justify-between">
<span>{choice}</span>
<span className="text-xs whitespace-nowrap">
{((votesCount * 100) / totalVotes).toFixed(2)}% ({votesCount} {_t("polls.votes")})
{progress}% (
{interpretation === "number_of_votes"
? `${votesCount} ${_t("polls.votes")}`
: choiceHp.toFixed(2)}
)
</span>
</div>
</div>
Expand Down
37 changes: 37 additions & 0 deletions src/common/features/polls/components/poll-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useMappedStore } from "../../../store/use-mapped-store";
import { format, isBefore } from "date-fns";
import useLocalStorage from "react-use/lib/useLocalStorage";
import { PREFIX } from "../../../util/local-storage";
import { FormControl } from "@ui/input";

interface Props {
poll: PollSnapshot;
Expand All @@ -34,6 +35,8 @@ export function PollWidget({ poll, isReadOnly, entry }: Props) {
const [resultsMode, setResultsMode] = useState(false);
const [isVotedAlready, setIsVotedAlready] = useState(false);
const [showEndDate, setShowEndDate] = useLocalStorage(PREFIX + "_plls_set", false);
const [interpretation, setInterpretation] =
useState<PollSnapshot["interpretation"]>("number_of_votes");

const endTimeFullDate = useMemo(() => format(poll.endTime, "dd.MM.yyyy HH:mm"), [poll.endTime]);
const isFinished = useMemo(() => isBefore(poll.endTime, new Date()), [poll.endTime]);
Expand All @@ -49,6 +52,10 @@ export function PollWidget({ poll, isReadOnly, entry }: Props) {
() => pollDetails.data?.status === "Active" && !resultsMode,
[pollDetails.data?.status, resultsMode]
);
const isInterpretationSelectionDisabled = useMemo(
() => pollDetails.data?.poll_stats.total_hive_hp_incl_proxied === null,
[pollDetails.data?.poll_stats.total_hive_hp_incl_proxied]
);

useEffect(() => {
if (activeUserVote) {
Expand All @@ -67,6 +74,17 @@ export function PollWidget({ poll, isReadOnly, entry }: Props) {
setIsVotedAlready(!!activeUserVote);
}, [activeUserVote]);

useEffect(() => {
if (isInterpretationSelectionDisabled) {
setInterpretation("number_of_votes");
} else {
setInterpretation(
(pollDetails.data?.preferred_interpretation ??
"number_of_votes") as PollSnapshot["interpretation"]
);
}
}, [pollDetails.data, isInterpretationSelectionDisabled]);

return (
<div className="grid grid-cols-4">
<div className="col-span-4 sm:col-span-3 flex flex-col gap-4 border border-[--border-color] rounded-3xl p-4 dark:border-gray-900">
Expand Down Expand Up @@ -104,6 +122,7 @@ export function PollWidget({ poll, isReadOnly, entry }: Props) {
{poll.choices.map((choice) =>
resultsMode ? (
<PollOptionWithResults
interpretation={interpretation}
key={choice}
entry={entry}
choice={choice}
Expand All @@ -118,6 +137,24 @@ export function PollWidget({ poll, isReadOnly, entry }: Props) {
/>
)
)}
{resultsMode && (
<div className="flex items-center gap-2 flex-wrap">
<div>{_t("polls.interpretation")}</div>
<FormControl
full={false}
disabled={isInterpretationSelectionDisabled}
type="select"
size="xs"
value={interpretation}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
setInterpretation(e.target.value as PollSnapshot["interpretation"])
}
>
<option value="number_of_votes">{_t("polls.number_of_votes")}</option>
<option value="tokens">{_t("polls.tokens")}</option>
</FormControl>
</div>
)}
</div>
{showVote && (
<Button
Expand Down
4 changes: 3 additions & 1 deletion src/common/features/ui/input/form-controls/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { useFilteredProps } from "../../../../util/props-filter";

// TODO: Add styles for select in input-group

export interface SelectProps extends HTMLProps<HTMLSelectElement> {
export interface SelectProps extends Omit<HTMLProps<HTMLSelectElement>, "size"> {
type: "select";
children: ReactNode;
full?: boolean;
size?: "md" | "xs";
}

export function Select(props: SelectProps) {
Expand All @@ -20,6 +21,7 @@ export function Select(props: SelectProps) {
className={classNameObject({
[INPUT_STYLES]: true,
[INPUT_DARK_STYLES]: true,
"px-2 py-1 text-sm": props.size === "xs",
[props.className ?? ""]: true,
"!w-auto": props.full === false
})}
Expand Down
3 changes: 2 additions & 1 deletion src/common/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -2451,6 +2451,7 @@
"vote-change": "Changing a vote",
"current-standing": "Hide votes",
"finished": "Finished",
"expired-date": "End date should be in present or future"
"expired-date": "End date should be in present or future",
"interpretation": "Interpretation"
}
}

0 comments on commit 11c98c7

Please sign in to comment.