diff --git a/src/common/features/entry-management/entry-metadata-manager/entry-metadata-builder.ts b/src/common/features/entry-management/entry-metadata-manager/entry-metadata-builder.ts index 7e85ab5ce04..6d0fd20bfb5 100644 --- a/src/common/features/entry-management/entry-metadata-manager/entry-metadata-builder.ts +++ b/src/common/features/entry-management/entry-metadata-manager/entry-metadata-builder.ts @@ -69,9 +69,9 @@ export class EntryMetadataBuilder { if (nextImages) { if (selectionTouched && selectedThumbnail) { - nextImages = [selectedThumbnail, ...image!.splice(0, 9)]; + nextImages = [selectedThumbnail, ...(image?.splice(0, 9) ?? [])]; } else { - nextImages = [...image!.splice(0, 9)]; + nextImages = [...(image?.splice(0, 9) ?? [])]; } } else if (selectedThumbnail === localThumbnail) { ls.remove("draft_selected_image"); @@ -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: { diff --git a/src/common/features/polls/api/get-poll-details-query.ts b/src/common/features/polls/api/get-poll-details-query.ts index f81fe8fcd02..f4df61a4f18 100644 --- a/src/common/features/polls/api/get-poll-details-query.ts +++ b/src/common/features/polls/api/get-poll-details-query.ts @@ -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; diff --git a/src/common/features/polls/api/sign-poll-vote.ts b/src/common/features/polls/api/sign-poll-vote.ts index dde4fea5002..41311de71a4 100644 --- a/src/common/features/polls/api/sign-poll-vote.ts +++ b/src/common/features/polls/api/sign-poll-vote.ts @@ -56,7 +56,7 @@ export function useSignPollVoteByKey(poll: ReturnType !!el), diff --git a/src/common/features/polls/components/poll-option-with-results.tsx b/src/common/features/polls/components/poll-option-with-results.tsx index 48b3fa93a12..557f46bc259 100644 --- a/src/common/features/polls/components/poll-option-with-results.tsx +++ b/src/common/features/polls/components/poll-option-with-results.tsx @@ -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( @@ -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 (
{activeChoice === choice && }
{choice} - {((votesCount * 100) / totalVotes).toFixed(2)}% ({votesCount} {_t("polls.votes")}) + {progress}% ( + {interpretation === "number_of_votes" + ? `${votesCount} ${_t("polls.votes")}` + : choiceHp.toFixed(2)} + )
diff --git a/src/common/features/polls/components/poll-widget.tsx b/src/common/features/polls/components/poll-widget.tsx index e6bd2f1b849..66d84887dc3 100644 --- a/src/common/features/polls/components/poll-widget.tsx +++ b/src/common/features/polls/components/poll-widget.tsx @@ -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; @@ -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("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]); @@ -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) { @@ -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 (
@@ -104,6 +122,7 @@ export function PollWidget({ poll, isReadOnly, entry }: Props) { {poll.choices.map((choice) => resultsMode ? ( ) )} + {resultsMode && ( +
+
{_t("polls.interpretation")}
+ ) => + setInterpretation(e.target.value as PollSnapshot["interpretation"]) + } + > + + + +
+ )}
{showVote && (
@@ -212,7 +223,6 @@ export function PollsCreation({ hasEmptyOrDuplicatedChoices || !title || typeof accountAge !== "number" || - interpretation === "tokens" || isExpiredEndDate } iconPlacement="left" diff --git a/src/common/features/polls/hooks/use-polls-creation-management.ts b/src/common/features/polls/hooks/use-polls-creation-management.ts index 324fd0b842a..aa24341336d 100644 --- a/src/common/features/polls/hooks/use-polls-creation-management.ts +++ b/src/common/features/polls/hooks/use-polls-creation-management.ts @@ -79,6 +79,12 @@ export function usePollsCreationManagement(poll?: PollSnapshot) { setHideVotes, voteChange, setVoteChange, - isExpiredEndDate + isExpiredEndDate, + clearAll: () => { + clearTitle(); + clearChoices(); + clearAccountAge(); + clearEndDate(); + } }; } diff --git a/src/common/features/ui/button/styles.ts b/src/common/features/ui/button/styles.ts index 42d6f44d2d6..bbb1bac1c05 100644 --- a/src/common/features/ui/button/styles.ts +++ b/src/common/features/ui/button/styles.ts @@ -14,7 +14,7 @@ export const BUTTON_STYLES: Record = { export const BUTTON_OUTLINE_STYLES: Record = { primary: - "border-blue-dark-sky hover:border-blue-dark-sky-hover focus:border-blue-dark-sky-active text-blue-dark-sky hover:text-blue-dark-sky-hover focus:text-blue-dark-sky-active", + "border-blue-dark-sky hover:border-blue-dark-sky-hover focus:border-blue-dark-sky-active text-blue-dark-sky hover:text-blue-dark-sky-hover focus:text-blue-dark-sky-active disabled:opacity-50", secondary: "border-gray-400 hover:border-gray-700 focus:border-gray-800 text-gray-600 hover:text-gray-700 focus:gray-800", link: "", diff --git a/src/common/features/ui/input/form-controls/select.tsx b/src/common/features/ui/input/form-controls/select.tsx index 27c4c22862b..a8b0ce538a9 100644 --- a/src/common/features/ui/input/form-controls/select.tsx +++ b/src/common/features/ui/input/form-controls/select.tsx @@ -5,10 +5,11 @@ import { useFilteredProps } from "../../../../util/props-filter"; // TODO: Add styles for select in input-group -export interface SelectProps extends HTMLProps { +export interface SelectProps extends Omit, "size"> { type: "select"; children: ReactNode; full?: boolean; + size?: "md" | "xs"; } export function Select(props: SelectProps) { @@ -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 })} diff --git a/src/common/i18n/locales/en-US.json b/src/common/i18n/locales/en-US.json index 168627dddc5..fd35a2951c5 100644 --- a/src/common/i18n/locales/en-US.json +++ b/src/common/i18n/locales/en-US.json @@ -90,7 +90,8 @@ "actions": "Actions", "restore": "Restore", "success": "Success", - "error": "Error" + "error": "Error", + "reset-form": "Reset form" }, "confirm": { "title": "Are you sure?", @@ -2450,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" } } diff --git a/tailwind.config.js b/tailwind.config.js index 0ed5c6a07cf..a22476f93cf 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -253,6 +253,7 @@ module.exports = { "green-040": "#e3fceb", warning: { default: "#fcc920", + "020": "#c39f2a", "030": "#ffe08a", "040": "#fff0c7", "046": "#fffcf2"