From 9342c214c2d076839e658397237c3276b0a71865 Mon Sep 17 00:00:00 2001 From: ChiragPansuriya-iView <134677881+ChiragPansuriya-iView@users.noreply.github.com> Date: Fri, 23 Feb 2024 13:48:34 +0530 Subject: [PATCH 1/2] feat: governance proposal list ui v2 (#980) * fix: governance proposal list ui updated as per figma * fix: lint error fixed * fix: refactoring governance box * fix: color and style change * fix: search functionality added * fix: remove second dropdown and updated UI as per figma * fix: revert victory package changes * fix: removed victory package * fix: dropdown click issue fixed * chore: rename option * fix: replace getKeys to objectKeys in Statesdropdown --------- Co-authored-by: n0izn0iz --- assets/icons/passed.svg | 3 + assets/icons/reject.svg | 3 + assets/icons/voting.svg | 3 + package.json | 1 - .../GovernanceBox/ConfirmationVote.tsx | 113 --- .../GovernanceBox/GovernanceBox.tsx | 475 +++------- .../GovernanceBox/GovernanceExpire.tsx | 66 ++ .../GovernanceBox/GovernanceProgressBar.tsx | 69 ++ .../GovernanceBox/GovernanceTitle.tsx | 59 ++ .../components/sorts/SearchInputRounded.tsx | 47 + .../screens/Governance/GovernanceDetails.tsx | 811 ------------------ .../screens/Governance/GovernanceScreen.tsx | 80 +- .../screens/Governance/NavBarGovernance.tsx | 86 -- .../components/dropdowns/StatesDropdown.tsx | 158 ++++ packages/utils/style/colors.ts | 2 +- packages/utils/types/gov.ts | 32 +- yarn.lock | 3 +- 17 files changed, 584 insertions(+), 1427 deletions(-) create mode 100644 assets/icons/passed.svg create mode 100644 assets/icons/reject.svg create mode 100644 assets/icons/voting.svg delete mode 100644 packages/components/GovernanceBox/ConfirmationVote.tsx create mode 100644 packages/components/GovernanceBox/GovernanceExpire.tsx create mode 100644 packages/components/GovernanceBox/GovernanceProgressBar.tsx create mode 100644 packages/components/GovernanceBox/GovernanceTitle.tsx create mode 100644 packages/components/sorts/SearchInputRounded.tsx delete mode 100644 packages/screens/Governance/GovernanceDetails.tsx delete mode 100644 packages/screens/Governance/NavBarGovernance.tsx create mode 100644 packages/screens/Governance/components/dropdowns/StatesDropdown.tsx diff --git a/assets/icons/passed.svg b/assets/icons/passed.svg new file mode 100644 index 0000000000..542cc79046 --- /dev/null +++ b/assets/icons/passed.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/reject.svg b/assets/icons/reject.svg new file mode 100644 index 0000000000..dda8936c72 --- /dev/null +++ b/assets/icons/reject.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/voting.svg b/assets/icons/voting.svg new file mode 100644 index 0000000000..1dde87532b --- /dev/null +++ b/assets/icons/voting.svg @@ -0,0 +1,3 @@ + + + diff --git a/package.json b/package.json index 87a48c5933..274fa73cca 100644 --- a/package.json +++ b/package.json @@ -150,7 +150,6 @@ "text-encoding-polyfill": "^0.6.7", "tsx": "^4.7.0", "uuid": "^9.0.0", - "victory": "^36.6.12", "victory-native": "^36.6.8", "waveform-data": "^4.3.0", "yaml": "^2.3.4", diff --git a/packages/components/GovernanceBox/ConfirmationVote.tsx b/packages/components/GovernanceBox/ConfirmationVote.tsx deleted file mode 100644 index f4366e0cba..0000000000 --- a/packages/components/GovernanceBox/ConfirmationVote.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import React, { useState } from "react"; -import { View, StyleProp, ViewStyle } from "react-native"; - -import checklogo from "../../../assets/icons/checklogo.svg"; -import { BrandText } from "../../components/BrandText/BrandText"; -import ModalBase from "../../components/modals/ModalBase"; -import { neutral44 } from "../../utils/style/colors"; -import { SVG } from "../SVG"; - -const Separator: React.FC<{ style?: StyleProp }> = ({ style }) => ( - -); - -export const ConfirmationVote: React.FC<{ - visible?: boolean; - onClose: () => void; - numberProposal: string; - vote: string; -}> = ({ visible, onClose, numberProposal, vote }) => { - const [displayConfirmation, setDisplayConfirmation] = useState(visible); - function handleConfirmClick() { - onClose(); - setDisplayConfirmation(false); - } - - return ( - { - handleConfirmClick(); - console.log(displayConfirmation); - }} - label="Successful vote" - visible={displayConfirmation} - width={372} - childrenBottom={ - <> - - - - - - - You have successfully voted{" "} - - {vote} - - - - - - - - on proposal{" "} - - #{numberProposal} - - - - - - } - > - - - - - ); -}; diff --git a/packages/components/GovernanceBox/GovernanceBox.tsx b/packages/components/GovernanceBox/GovernanceBox.tsx index 5cfea70e83..e2e79ea43d 100644 --- a/packages/components/GovernanceBox/GovernanceBox.tsx +++ b/packages/components/GovernanceBox/GovernanceBox.tsx @@ -1,401 +1,130 @@ -import { LinearGradient } from "expo-linear-gradient"; -import React, { Suspense, useState } from "react"; -import { - ColorValue, - DimensionValue, - ScrollView, - TouchableOpacity, - View, -} from "react-native"; - -import { BrandText } from "../../components/BrandText/BrandText"; -import { LegacyTertiaryBox } from "../../components/boxes/LegacyTertiaryBox"; -import { tulipTree } from "../../utils/style/colors"; +import React from "react"; +import { TouchableOpacity, View } from "react-native"; -import { ProposalStatus } from "@/utils/types/gov"; +import { GovernanceExpire } from "./GovernanceExpire"; +import PassedSVG from "../../../assets/icons/passed.svg"; +import RejectSVG from "../../../assets/icons/reject.svg"; +import VotingSVG from "../../../assets/icons/voting.svg"; -// FIXME: code dedup +import { BrandText } from "@/components/BrandText"; +import { GovernanceProgressBar } from "@/components/GovernanceBox/GovernanceProgressBar"; +import { GovernanceTitle } from "@/components/GovernanceBox/GovernanceTitle"; +import { + additionalSuccess, + errorColor, + neutral17, + neutral22, + neutralA3, + primaryColor, + secondaryColor, + withAlpha, +} from "@/utils/style/colors"; +import { fontSemibold14 } from "@/utils/style/fonts"; +import { layout } from "@/utils/style/layout"; +import { Proposal } from "@/utils/types/gov"; export const GovernanceBox: React.FC<{ - numberProposal: string; - titleProposal: string; - descriptionProposal: string; - votingEndTime: string; - votingStartTime: string; - colorMostVoted: ColorValue | undefined; - percentageYesValue: number; - percentageNoValue: number; - percentageNoWithVetoValue: number; - percentageAbstainValue: number; - votingSubmitTime: string; - votingDepositEndTime: string; - status: ProposalStatus; -}> = ({ - numberProposal, - titleProposal, - descriptionProposal, - votingEndTime, - colorMostVoted, - percentageYesValue, - percentageNoValue, - percentageNoWithVetoValue, - percentageAbstainValue, - votingStartTime, - votingSubmitTime, - votingDepositEndTime, - status, -}) => { - const totalUsers = - percentageYesValue + - percentageNoValue + - percentageNoWithVetoValue + - percentageAbstainValue; - const totalParticipant = totalUsers - percentageAbstainValue; - const percentageTotalParticipant = - ((totalParticipant / totalUsers) * 100).toFixed(2).toString() + "%"; - const [displayGovernanceDetails, setDisplayGovernanceDetails] = - useState(false); - - const test = "%"; - const percentageYes = - ((percentageYesValue / totalUsers) * 100) - .toFixed(2) - .toString() - .substring(0, 5) + test; - const percentageNo = - ((percentageNoValue / totalUsers) * 100) - .toFixed(2) - .toString() - .substring(0, 5) + test; - - const percentageNoWithVeto = ((percentageNoWithVetoValue / totalUsers) * 100) - .toFixed(2) - .toString(); - - let topPercentage; - if (percentageYesValue > percentageNoValue) { - topPercentage = percentageYes; - colorMostVoted = "#16BBFF"; - } else { - topPercentage = percentageNo; - colorMostVoted = tulipTree; - } - - const numberProposalHashtag = "#" + numberProposal; - - function activePopup() { - setDisplayGovernanceDetails(!displayGovernanceDetails); - } - - function activeGovernanceDetailsPopup() { - if (displayGovernanceDetails) { - const GovernanceDetails = React.lazy(() => - import("@/screens/Governance/GovernanceDetails").then((module) => ({ - default: module.GovernanceDetails, - })), - ); - - return ( - }> - activePopup()} - numberProposal={numberProposalHashtag} - titleProposal={titleProposal} - descriptionProposal={descriptionProposal} - totalParticipant={totalParticipant} - percentageTotalParticipant={percentageTotalParticipant} - votingEndTime={votingEndTime} - votingStartTime={votingStartTime} - votingSubmitTime={votingSubmitTime} - votingDepositEndTime={votingDepositEndTime} - percentageYes={percentageYes} - percentageNo={percentageNo} - percentageNoWithVeto={percentageNoWithVeto} - status={status} - /> - - ); - } else { - return <>; - } - } - + proposal: Proposal; +}> = ({ proposal }) => { return ( - - { - activePopup(); + + - {activeGovernanceDetailsPopup()} - - + - {status === "PROPOSAL_STATUS_VOTING" && ( - - - VOTING PERIOD - + {proposal.status === "PROPOSAL_STATUS_VOTING" && ( + + + )} - {status === "PROPOSAL_STATUS_REJECTED" && ( - - - REJECTED - - + {proposal.status === "PROPOSAL_STATUS_REJECTED" && ( + )} - {status === "PROPOSAL_STATUS_PASSED" && ( - - - PASSED - - + {proposal.status === "PROPOSAL_STATUS_PASSED" && ( + )} - - - - {numberProposalHashtag} - - - - {titleProposal} - - - - - - {descriptionProposal} - - - - - - - - - - - - + {"#" + proposal.proposal_id + " " + proposal.content.title} + - - - - Voting End Time - - - - {votingEndTime.slice(0, 10)} - {"\u00A0"} - {votingEndTime.slice(11, 16)} - {"\u00A0"} UTC - - - - - - - - Turnout - - - - {percentageTotalParticipant} - - - - - - - - Most voted on - - - - - - - {topPercentage} - - - - + - - - + + + + + Reviews + + + 35 + + + + ); }; diff --git a/packages/components/GovernanceBox/GovernanceExpire.tsx b/packages/components/GovernanceBox/GovernanceExpire.tsx new file mode 100644 index 0000000000..9808da45d1 --- /dev/null +++ b/packages/components/GovernanceBox/GovernanceExpire.tsx @@ -0,0 +1,66 @@ +import React from "react"; +import { StyleProp, View, ViewStyle } from "react-native"; + +import { BrandText } from "../BrandText/BrandText"; + +import { neutral22, redDefault } from "@/utils/style/colors"; +import { fontSemibold12 } from "@/utils/style/fonts"; +import { layout } from "@/utils/style/layout"; + +const getExpireDate = (votingEndTime: string): string => { + const currentTime: Date = new Date(); + const endTime: Date = new Date(votingEndTime); + const difference: number = endTime.getTime() - currentTime.getTime(); + const days: number = Math.floor(difference / (1000 * 60 * 60 * 24)); + const hours: number = Math.floor( + (difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), + ); + if (days === 0) { + return `Expires in ${hours}h`; + } else { + return `Expires in ${days}d ${hours}h`; + } +}; + +export const GovernanceExpire: React.FC<{ + style?: StyleProp; + votingEndTime: string; +}> = ({ votingEndTime, style }) => { + return ( + + + + + + {getExpireDate(votingEndTime)} + + + + ); +}; diff --git a/packages/components/GovernanceBox/GovernanceProgressBar.tsx b/packages/components/GovernanceBox/GovernanceProgressBar.tsx new file mode 100644 index 0000000000..171e5996b5 --- /dev/null +++ b/packages/components/GovernanceBox/GovernanceProgressBar.tsx @@ -0,0 +1,69 @@ +import React from "react"; +import { DimensionValue, View } from "react-native"; + +import { + additionalRed, + additionalSuccess, + errorColor, + neutral55, +} from "@/utils/style/colors"; +import { layout } from "@/utils/style/layout"; +import { FinalTallyResult } from "@/utils/types/gov"; + +export const GovernanceProgressBar: React.FC<{ + result: FinalTallyResult; +}> = ({ result }) => { + const percentageYesValue = parseFloat(result.yes); + const percentageNoWithVetoValue = parseFloat(result.no_with_veto); + const percentageNoValue = parseFloat(result.no); + const percentageAbstainValue = parseFloat(result.abstain); + + const totalUsers = + percentageYesValue + + percentageNoValue + + percentageNoWithVetoValue + + percentageAbstainValue; + + const percentageYes: DimensionValue = `${(percentageYesValue / totalUsers) * 100}%`; + const percentageNo: DimensionValue = `${(percentageNoValue / totalUsers) * 100}%`; + const percentageNoWithVeto: DimensionValue = `${(percentageNoWithVetoValue / totalUsers) * 100}%`; + const percentageAbstain: DimensionValue = `${(percentageAbstainValue / totalUsers) * 100}%`; + + return ( + <> + + + + + + + + ); +}; diff --git a/packages/components/GovernanceBox/GovernanceTitle.tsx b/packages/components/GovernanceBox/GovernanceTitle.tsx new file mode 100644 index 0000000000..b6df983e12 --- /dev/null +++ b/packages/components/GovernanceBox/GovernanceTitle.tsx @@ -0,0 +1,59 @@ +import React from "react"; +import { View } from "react-native"; +import { SvgProps } from "react-native-svg"; + +import { BrandText } from "@/components/BrandText"; +import { SVG } from "@/components/SVG"; +import { neutral22, primaryColor } from "@/utils/style/colors"; +import { fontSemibold12 } from "@/utils/style/fonts"; +import { layout } from "@/utils/style/layout"; + +export const GovernanceTitle: React.FC<{ + titleColor?: string; + borderColor?: string; + title: string; + hasBorder?: boolean; + iconSVG: React.FC; +}> = ({ + titleColor = primaryColor, + title, + hasBorder = false, + iconSVG, + borderColor, +}) => { + return ( + <> + + + + + + {title} + + + + + ); +}; diff --git a/packages/components/sorts/SearchInputRounded.tsx b/packages/components/sorts/SearchInputRounded.tsx new file mode 100644 index 0000000000..7cec5ae339 --- /dev/null +++ b/packages/components/sorts/SearchInputRounded.tsx @@ -0,0 +1,47 @@ +import React from "react"; +import { TextInput, TextStyle } from "react-native"; + +import searchSVG from "../../../assets/icons/search.svg"; +import { fontMedium14 } from "../../utils/style/fonts"; +import { layout } from "../../utils/style/layout"; +import { SVG } from "../SVG"; +import { PrimaryBox } from "../boxes/PrimaryBox"; + +import { neutral33, secondaryColor } from "@/utils/style/colors"; + +export const SearchInputRounded: React.FC<{ + handleChangeSearch: (e: string) => void; +}> = ({ handleChangeSearch }) => { + return ( + + + + + ); +}; diff --git a/packages/screens/Governance/GovernanceDetails.tsx b/packages/screens/Governance/GovernanceDetails.tsx deleted file mode 100644 index f6bfde96ab..0000000000 --- a/packages/screens/Governance/GovernanceDetails.tsx +++ /dev/null @@ -1,811 +0,0 @@ -import { isDeliverTxFailure, MsgVoteEncodeObject } from "@cosmjs/stargate"; -import moment from "moment"; -import React, { useCallback, useState } from "react"; -import { ScrollView, StyleProp, View, ViewStyle } from "react-native"; -import { RadioButton } from "react-native-paper"; -import { VictoryPie } from "victory"; - -import ModalBase from "../../components/modals/ModalBase"; -import useSelectedWallet from "../../hooks/useSelectedWallet"; - -import { BrandText } from "@/components/BrandText"; -import { ConfirmationVote } from "@/components/GovernanceBox/ConfirmationVote"; -import { LegacyTertiaryBox } from "@/components/boxes/LegacyTertiaryBox"; -import { PrimaryButton } from "@/components/buttons/PrimaryButton"; -import { SecondaryButton } from "@/components/buttons/SecondaryButton"; -import { useFeedbacks } from "@/context/FeedbacksProvider"; -import { getKeplrSigningStargateClient } from "@/networks"; -import { neutral44, tulipTree } from "@/utils/style/colors"; -import { ProposalStatus } from "@/utils/types/gov"; - -const Separator: React.FC<{ style?: StyleProp }> = ({ style }) => ( - -); - -export const GovernanceDetails: React.FC<{ - visible?: boolean; - onClose: () => void; - numberProposal: string; - titleProposal: string; - descriptionProposal: string; - totalParticipant: number; - percentageTotalParticipant: string; - votingEndTime: string; - votingStartTime: string; - votingSubmitTime: string; - votingDepositEndTime: string; - percentageYes: string; - percentageNo: string; - percentageNoWithVeto: string; - status: ProposalStatus; -}> = ({ - visible, - onClose, - numberProposal, - titleProposal, - descriptionProposal, - totalParticipant, - percentageTotalParticipant, - votingStartTime, - votingEndTime, - votingSubmitTime, - votingDepositEndTime, - percentageYes, - percentageNo, - percentageNoWithVeto, - status, -}) => { - const [displayVote, setdisplayVote] = useState(false); - const [displayConfirmationVote, setdisplayConfirmationVote] = useState(false); - const [checked, setChecked] = useState("nothingChecked"); - const [displayPopup] = useState(visible); - const { setToastError } = useFeedbacks(); - - function activeVotePopup() { - onClose(); - setdisplayVote(!displayVote); - } - - const valueChartYes = parseInt(percentageYes.replace("%", ""), 10); - const valueChartNo = parseInt(percentageNo.replace("%", ""), 10); - const valueChartAbstain = 100 - valueChartYes - valueChartNo; - - const selectedWallet = useSelectedWallet(); - let voteOption = 0; - - if (checked === "Yes") { - voteOption = 1; - } - - if (checked === "No") { - voteOption = 3; - } - - if (checked === "NoWithVeto") { - voteOption = 4; - } - - if (checked === "Abstain") { - voteOption = 2; - } - - const handlePress = useCallback(async () => { - if (!selectedWallet?.connected || !selectedWallet.address) { - setToastError({ - title: "Wallet Error", - message: "You need to register your teritori wallet", - }); - return; - } - - try { - const client = await getKeplrSigningStargateClient( - selectedWallet.networkId, - ); - - const vote: MsgVoteEncodeObject = { - typeUrl: "/cosmos.gov.v1beta1.MsgVote", - value: { - proposalId: BigInt(numberProposal.substring(1)), - voter: String(selectedWallet.address), - option: voteOption, - }, - }; - const result = await client.signAndBroadcast( - selectedWallet.address, - [vote], - "auto", - ); - if (isDeliverTxFailure(result)) { - setToastError({ - title: "Vote failed", - message: "Transaction failed", - }); - } - } catch (err) { - console.error(err); - if (err instanceof Error) { - setToastError({ - title: "Vote failed", - message: err.message, - }); - } - } - }, [ - numberProposal, - selectedWallet?.address, - selectedWallet?.connected, - selectedWallet?.networkId, - setToastError, - voteOption, - ]); - - function deleteConfirmationVote() { - setdisplayConfirmationVote(false); - setdisplayVote(!displayVote); - } - - function activeConfirmationVotePopup() { - if (displayConfirmationVote && checked !== "nothingChecked") { - return ( - deleteConfirmationVote()} - /> - ); - } else { - return <>; - } - } - - function activeVote() { - setdisplayVote(!displayVote); - } - - const canVoteDeposit = () => moment(votingDepositEndTime).isAfter(moment()); - - return ( - { - activeVotePopup(); - }} - label="Governance Details" - visible={displayPopup} - width={1300} - > - - - - {numberProposal} - - - - - {titleProposal} - - - {status === "PROPOSAL_STATUS_VOTING" && ( - - - VOTING PERIOD - - - )} - {status === "PROPOSAL_STATUS_REJECTED" && ( - - - REJECTED - - - )} - - {status === "PROPOSAL_STATUS_PASSED" && ( - - - PASSED - - - )} - - - - - - Submit Time - - - {votingSubmitTime.slice(0, 10)} - {"\u00A0"} - {votingSubmitTime.slice(11, 16)} - {"\u00A0"} UTC - - - - - - - Deposit End Time - - - {votingDepositEndTime.slice(0, 10)} - {"\u00A0"} - {votingDepositEndTime.slice(11, 16)} - {"\u00A0"} UTC - - - - - - - Voting Start - - - {votingStartTime.slice(0, 10)} - {"\u00A0"} - {votingStartTime.slice(11, 16)} - {"\u00A0"} UTC - - - - - - - Voting End - - - {votingEndTime.slice(0, 10)} - {"\u00A0"} - {votingEndTime.slice(11, 16)} - {"\u00A0"} UTC - - - - - - - - - Total - - - - - {totalParticipant} - - - - - - null} - /> - - - - - Turnout: - - - {percentageTotalParticipant} - - - - - - - Yes {percentageYes} - - - - - - - Yes {percentageNo} - - - - - - - NoWithVeto {percentageNoWithVeto} - - - - - - - NoWithVeto {percentageNoWithVeto} - - - - {canVoteDeposit() && ( - activeVote()} - /> - )} - - - {activeConfirmationVotePopup()} - - setdisplayVote(false)} - label="Your vote" - visible={displayVote} - width={372} - childrenBottom={ - <> - - - - - - - - { - if (checked !== "nothingChecked") { - handlePress(); - activeVotePopup(); - setdisplayConfirmationVote(true); - } - }} - /> - - - - } - > - - {numberProposal} - - - IncreaseMaxValidators=100 to MaxValidators=110 {"\n"} - {"\n"} - - - - - setChecked("Yes")} - /> - - setChecked("No")} - /> - setChecked("NoWithVeto")} - /> - setChecked("Abstain")} - /> - - - - Yes - - - No - - - NoWithVeto - - - Abstain - - - - - - - - - - - - - - - - {descriptionProposal} - - - - - ); -}; diff --git a/packages/screens/Governance/GovernanceScreen.tsx b/packages/screens/Governance/GovernanceScreen.tsx index 68f8c54f95..07c930e8e8 100644 --- a/packages/screens/Governance/GovernanceScreen.tsx +++ b/packages/screens/Governance/GovernanceScreen.tsx @@ -1,20 +1,22 @@ import React, { useEffect, useMemo, useState } from "react"; import { View } from "react-native"; -import { NavBarGovernance } from "./NavBarGovernance"; +import { StatesDropdown } from "./components/dropdowns/StatesDropdown"; +import { GovernanceBox } from "../../components/GovernanceBox/GovernanceBox"; import { BrandText } from "@/components/BrandText"; -import { GovernanceBox } from "@/components/GovernanceBox/GovernanceBox"; import { ScreenContainer } from "@/components/ScreenContainer"; +import { SearchInputRounded } from "@/components/sorts/SearchInputRounded"; import { useSelectedNetworkId } from "@/hooks/useSelectedNetwork"; import { mustGetCosmosNetwork, NetworkKind } from "@/networks"; +import { fontSemibold20, fontSemibold28 } from "@/utils/style/fonts"; +import { layout } from "@/utils/style/layout"; import { Proposal, ProposalStatus } from "@/utils/types/gov"; -// FIXME: properly handle pagination - export const GovernanceScreen: React.FC = () => { const [proposals, setProposals] = useState([]); const [filter, setFilter] = useState(); + const [searchInput, setSearchInput] = useState(""); const selectedNetworkId = useSelectedNetworkId(); useEffect(() => { @@ -40,43 +42,55 @@ export const GovernanceScreen: React.FC = () => { ); return ( - - Decentralized Governance - - + Decentralized Governance + } + > + + Decentralized Governance + + setSearchInput(text)} + /> + + + - {filteredProposals.map((proposals, index) => ( - - ))} + {filteredProposals + .filter((value) => + value.content.title + .toLowerCase() + .includes(searchInput.toLowerCase()), + ) + .map((proposals) => ( + + ))} ); diff --git a/packages/screens/Governance/NavBarGovernance.tsx b/packages/screens/Governance/NavBarGovernance.tsx deleted file mode 100644 index 67852283f8..0000000000 --- a/packages/screens/Governance/NavBarGovernance.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React, { useState } from "react"; -import { TouchableOpacity, View } from "react-native"; - -import { BrandText } from "@/components/BrandText"; -import { neutral33 } from "@/utils/style/colors"; -import { ProposalStatus } from "@/utils/types/gov"; - -const def = { - all: { - name: "All Periods", - filter: undefined, - }, - voting: { - name: "Voting", - filter: "PROPOSAL_STATUS_VOTING", - }, - passed: { - name: "Passed", - filter: "PROPOSAL_STATUS_PASSED", - }, - rejected: { - name: "Rejected", - filter: "PROPOSAL_STATUS_REJECTED", - }, -}; - -export const NavBarGovernance: React.FC<{ - onChange: (filter?: ProposalStatus) => void; -}> = ({ onChange }) => { - const [selected, setSelected] = useState("all"); - - return ( - - - {getKeys(def).map((key) => { - return ( - { - onChange(def[key].filter as any); // FIXME: typing - setSelected(key); - }} - style={{ - height: "100%", - borderRightColor: neutral33, - borderRightWidth: 1, - }} - > - - - {def[key].name} - - - - ); - })} - - - ); -}; - -const getKeys = Object.keys as (obj: T) => (keyof T)[]; diff --git a/packages/screens/Governance/components/dropdowns/StatesDropdown.tsx b/packages/screens/Governance/components/dropdowns/StatesDropdown.tsx new file mode 100644 index 0000000000..9fd8ba53c8 --- /dev/null +++ b/packages/screens/Governance/components/dropdowns/StatesDropdown.tsx @@ -0,0 +1,158 @@ +import React, { useState } from "react"; +import { TouchableOpacity, View, ViewStyle } from "react-native"; + +import chevronDownSVG from "./../../../../../assets/icons/chevron-down.svg"; +import chevronUpSVG from "./../../../../../assets/icons/chevron-up.svg"; + +import { BrandText } from "@/components/BrandText"; +import { SVG } from "@/components/SVG"; +import { Separator } from "@/components/separators/Separator"; +import { SpacerColumn } from "@/components/spacer"; +import { useDropdowns } from "@/hooks/useDropdowns"; +import { neutral33, neutral55, secondaryColor } from "@/utils/style/colors"; +import { fontMedium14, fontSemibold14 } from "@/utils/style/fonts"; +import { layout } from "@/utils/style/layout"; +import { ProposalStatus } from "@/utils/types/gov"; +import { objectKeys } from "@/utils/typescript"; + +const def = { + all: { + name: "All states", + filter: undefined, + }, + voting: { + name: "Voting", + filter: "PROPOSAL_STATUS_VOTING", + }, + passed: { + name: "Passed", + filter: "PROPOSAL_STATUS_PASSED", + }, + rejected: { + name: "Rejected", + filter: "PROPOSAL_STATUS_REJECTED", + }, +}; + +interface StatesDropdownGovProps { + style?: ViewStyle; + onChange: (filter?: ProposalStatus) => void; +} + +export const StatesDropdown = ({ style, onChange }: StatesDropdownGovProps) => { + const [isDropdownOpen, setDropdownState, ref] = useDropdowns(); + const [selected, setSelected] = useState("all"); + + return ( + + + + + isDropdownOpen ? setDropdownState(false) : setDropdownState(true) + } + > + + {def[selected].name} + + + + {isDropdownOpen && ( + + + + {objectKeys(def).map((key, index) => { + return ( + { + onChange(def[key].filter as any); + setSelected(key); + setDropdownState(false); + }} + style={{ + paddingTop: layout.spacing_x1_5, + width: "100%", + }} + > + + {def[key].name} + + + {objectKeys(def).length - 1 !== index && ( + <> + + + + )} + + ); + })} + + )} + + + + ); +}; diff --git a/packages/utils/style/colors.ts b/packages/utils/style/colors.ts index cb2a1c74fc..0df679439d 100644 --- a/packages/utils/style/colors.ts +++ b/packages/utils/style/colors.ts @@ -17,7 +17,6 @@ export const blueDefault = "#007AFF"; export const codGrayColor = "#1C1C1C"; export const mineShaftColor = "#3D3D3D"; export const reefColor = "#D2FFAE"; -export const tulipTree = "#EAA54B"; export const gameHighlight = "#FCEE4F"; export const yankeesBlue = "#16283C"; @@ -44,6 +43,7 @@ export const transparentColor = "transparent"; export const additionalRed = "#FFAEAE"; export const additionalGreen = successColor; +export const additionalSuccess = "#3EBE7B"; export const azureBlue = "#0A84FF"; export const azureBlue20 = "rgba(10, 132, 255, 0.3)"; diff --git a/packages/utils/types/gov.ts b/packages/utils/types/gov.ts index e12bac513f..f3316675b2 100644 --- a/packages/utils/types/gov.ts +++ b/packages/utils/types/gov.ts @@ -3,14 +3,32 @@ export type ProposalStatus = | "PROPOSAL_STATUS_REJECTED" | "PROPOSAL_STATUS_VOTING"; -// FIXME: fully define type +interface Content { + "@type": string; + title: string; + description: string; +} + +export interface FinalTallyResult { + yes: string; + abstain: string; + no: string; + no_with_veto: string; +} + +interface TotalDeposit { + denom: string; + amount: string; +} + export interface Proposal { - content: any; - status: ProposalStatus; proposal_id: string; - final_tally_result: any; - voting_end_time: string; - voting_start_time: string; - deposit_end_time: string; + content: Content; + status: ProposalStatus; + final_tally_result: FinalTallyResult; submit_time: string; + deposit_end_time: string; + total_deposit: TotalDeposit[]; + voting_start_time: string; + voting_end_time: string; } diff --git a/yarn.lock b/yarn.lock index d1ac532048..6c2e12a5e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19161,7 +19161,6 @@ __metadata: tsx: ^4.7.0 typescript: ^5.3.0 uuid: ^9.0.0 - victory: ^36.6.12 victory-native: ^36.6.8 waveform-data: ^4.3.0 yaml: ^2.3.4 @@ -20510,7 +20509,7 @@ __metadata: languageName: node linkType: hard -"victory@npm:^36.6.12, victory@npm:^36.8.2": +"victory@npm:^36.8.2": version: 36.8.2 resolution: "victory@npm:36.8.2" dependencies: From fe0f35dcbd55a406313ecbb40c5ed03603dbe649 Mon Sep 17 00:00:00 2001 From: Sakul Budhathoki Date: Fri, 23 Feb 2024 18:56:55 +0545 Subject: [PATCH 2/2] feat: re-export Shutdown function from wesh module (#992) * feat: re-export Shutdown function from wesh module * fix: transport issue on web; disable WebsocketTransport on web --- .gitignore | 6 +++--- packages/weshnet/client.ts | 2 +- .../src/main/java/expo/modules/weshd/WeshdModule.kt | 8 ++++++-- weshd/index.ts | 4 ++++ weshd/ios/src/WeshdModule.swift | 13 +++++++++---- weshd/src/WeshdModule.web.ts | 1 + 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index ef60fb6bab..a2c570ba73 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,6 @@ web-build/ /cache/ /ios /android -/weshd/ios/Frameworks/ -/weshd/android/libs/ /app-build/ # macOS @@ -93,7 +91,9 @@ substreams-*/target # weshnet -/temp/ +/weshd/ios/Frameworks/ +/weshd/android/libs/ +/weshd/temp/ # eslint /.eslintcache diff --git a/packages/weshnet/client.ts b/packages/weshnet/client.ts index 813efb541d..40ffceab62 100644 --- a/packages/weshnet/client.ts +++ b/packages/weshnet/client.ts @@ -11,7 +11,7 @@ import { afterWeshnetConnectionAction } from "./services"; const createWeshClient = (url: string) => { const rpc = new GrpcWebImpl(url, { debug: false, - transport: grpc.WebsocketTransport(), + transport: Platform.OS === "web" ? undefined : grpc.WebsocketTransport(), }); const client = new ProtocolServiceClientImpl(rpc); diff --git a/weshd/android/src/main/java/expo/modules/weshd/WeshdModule.kt b/weshd/android/src/main/java/expo/modules/weshd/WeshdModule.kt index cf5fef30c6..56108b5ff1 100644 --- a/weshd/android/src/main/java/expo/modules/weshd/WeshdModule.kt +++ b/weshd/android/src/main/java/expo/modules/weshd/WeshdModule.kt @@ -65,11 +65,15 @@ fun getAbsolutePathForWeshDir(context: Context): String { // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread. Function("boot") { -> - val absolutePath = getAbsolutePathForWeshDir(context) - Wesh.boot(absolutePath) + val absolutePath = getAbsolutePathForWeshDir(context) + Wesh.boot(absolutePath) } + Function("shutdown") { -> + Wesh.shutdown() + } + AsyncFunction("getPort") { -> return@AsyncFunction Wesh.getPort() } diff --git a/weshd/index.ts b/weshd/index.ts index e03396acf9..7eeba63748 100644 --- a/weshd/index.ts +++ b/weshd/index.ts @@ -12,6 +12,10 @@ export async function getPort() { return await WeshdModule.getPort(); } +export async function shutdown() { + return await WeshdModule.shutdown(); +} + export async function setValueAsync(value: string) { return await WeshdModule.setValueAsync(value); } diff --git a/weshd/ios/src/WeshdModule.swift b/weshd/ios/src/WeshdModule.swift index 452f0e8e82..406c26047d 100644 --- a/weshd/ios/src/WeshdModule.swift +++ b/weshd/ios/src/WeshdModule.swift @@ -27,11 +27,16 @@ public class WeshdModule: Module { Events("onChange") // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread. - AsyncFunction("boot") { - WeshFramework.WeshBoot(getDocumentsDirectory()) + AsyncFunction("boot") { + WeshFramework.WeshBoot(getDocumentsDirectory()) } - AsyncFunction("getPort") { () -> Int in - return WeshFramework.WeshGetPort() + + AsyncFunction("getPort") { () -> Int in + return WeshFramework.WeshGetPort() + } + + AsyncFunction("shutdown") { + WeshFramework.WeshShutdown() } // Defines a JavaScript function that always returns a Promise and whose native code diff --git a/weshd/src/WeshdModule.web.ts b/weshd/src/WeshdModule.web.ts index 736cb9dbf6..2c20dbedb2 100644 --- a/weshd/src/WeshdModule.web.ts +++ b/weshd/src/WeshdModule.web.ts @@ -12,4 +12,5 @@ export default { const params = new URL(window?.location?.href || ""); return Number(params?.searchParams?.get("weshPort") || 0); }, + shutdown() {}, };