1
1
import * as Tooltip from '@radix-ui/react-tooltip'
2
+ import { useWallet } from '@solana/wallet-adapter-react'
2
3
import { AccountMeta , PublicKey } from '@solana/web3.js'
3
4
import { MultisigAccount , TransactionAccount } from '@sqds/mesh/lib/types'
4
5
import { useRouter } from 'next/router'
@@ -28,6 +29,7 @@ import { usePythContext } from '../../contexts/PythContext'
28
29
import { StatusFilterContext } from '../../contexts/StatusFilterContext'
29
30
import { PRICE_FEED_MULTISIG } from '../../hooks/useMultisig'
30
31
import VerifiedIcon from '../../images/icons/verified.inline.svg'
32
+ import VotedIcon from '../../images/icons/voted.inline.svg'
31
33
import { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'
32
34
import ClusterSwitch from '../ClusterSwitch'
33
35
import CopyPubkey from '../common/CopyPubkey'
@@ -56,11 +58,13 @@ const getMappingCluster = (cluster: string) => {
56
58
const ProposalRow = ( {
57
59
proposal,
58
60
verified,
61
+ voted,
59
62
setCurrentProposalPubkey,
60
63
multisig,
61
64
} : {
62
65
proposal : TransactionAccount
63
66
verified : boolean
67
+ voted : boolean
64
68
setCurrentProposalPubkey : Dispatch < SetStateAction < string | undefined > >
65
69
multisig : MultisigAccount | undefined
66
70
} ) => {
@@ -100,7 +104,10 @@ const ProposalRow = ({
100
104
'...' +
101
105
proposal . publicKey . toBase58 ( ) . slice ( - 6 ) }
102
106
</ span > { ' ' }
103
- { verified ? < VerifiedIconWithTooltip /> : null }
107
+ < div className = "mr-2 items-center flex" >
108
+ { verified ? < VerifiedIconWithTooltip /> : null }
109
+ </ div >
110
+ { voted ? < VotedIconWithTooltip /> : null }
104
111
</ div >
105
112
< div >
106
113
< StatusTag proposalStatus = { status } />
@@ -167,6 +174,25 @@ const VerifiedIconWithTooltip = () => {
167
174
)
168
175
}
169
176
177
+ const VotedIconWithTooltip = ( ) => {
178
+ return (
179
+ < div className = "flex items-center" >
180
+ < Tooltip . Provider delayDuration = { 100 } skipDelayDuration = { 500 } >
181
+ < Tooltip . Root >
182
+ < Tooltip . Trigger >
183
+ < VotedIcon />
184
+ </ Tooltip . Trigger >
185
+ < Tooltip . Content side = "top" sideOffset = { 8 } >
186
+ < span className = "inline-block bg-darkGray3 p-2 text-xs text-light hoverable:bg-darkGray" >
187
+ You have voted on this proposal.
188
+ </ span >
189
+ </ Tooltip . Content >
190
+ </ Tooltip . Root >
191
+ </ Tooltip . Provider >
192
+ </ div >
193
+ )
194
+ }
195
+
170
196
const ParsedAccountPubkeyRow = ( {
171
197
mapping,
172
198
title,
@@ -187,7 +213,7 @@ const ParsedAccountPubkeyRow = ({
187
213
}
188
214
189
215
const getProposalStatus = (
190
- proposal : TransactionAccount | undefined ,
216
+ proposal : TransactionAccount | ClientProposal | undefined ,
191
217
multisig : MultisigAccount | undefined
192
218
) : string => {
193
219
if ( multisig && proposal ) {
@@ -1054,6 +1080,8 @@ const Proposal = ({
1054
1080
)
1055
1081
}
1056
1082
1083
+ type ClientProposal = TransactionAccount & { verified : boolean ; voted : boolean }
1084
+
1057
1085
const Proposals = ( {
1058
1086
publisherKeyToNameMapping,
1059
1087
multisigSignerKeyToNameMapping,
@@ -1062,11 +1090,13 @@ const Proposals = ({
1062
1090
multisigSignerKeyToNameMapping : Record < string , string >
1063
1091
} ) => {
1064
1092
const router = useRouter ( )
1093
+ const { connected, publicKey : signerPublicKey } = useWallet ( )
1065
1094
const [ currentProposal , setCurrentProposal ] = useState < TransactionAccount > ( )
1066
1095
const [ currentProposalIndex , setCurrentProposalIndex ] = useState < number > ( )
1067
1096
const [ allProposalsVerifiedArr , setAllProposalsVerifiedArr ] = useState <
1068
1097
boolean [ ]
1069
1098
> ( [ ] )
1099
+ const [ proposalsVotedArr , setProposalsVotedArr ] = useState < boolean [ ] > ( [ ] )
1070
1100
const [ currentProposalPubkey , setCurrentProposalPubkey ] = useState < string > ( )
1071
1101
const { cluster } = useContext ( ClusterContext )
1072
1102
const { statusFilter } = useContext ( StatusFilterContext )
@@ -1076,9 +1106,9 @@ const Proposals = ({
1076
1106
allProposalsIxsParsed,
1077
1107
isLoading : isMultisigLoading ,
1078
1108
} = useMultisigContext ( )
1079
- const [ filteredProposals , setFilteredProposals ] = useState <
1080
- TransactionAccount [ ]
1081
- > ( priceFeedMultisigProposals )
1109
+ const [ filteredProposals , setFilteredProposals ] = useState < ClientProposal [ ] > (
1110
+ [ ]
1111
+ )
1082
1112
1083
1113
useEffect ( ( ) => {
1084
1114
if ( ! isMultisigLoading ) {
@@ -1160,19 +1190,59 @@ const Proposals = ({
1160
1190
] )
1161
1191
1162
1192
useEffect ( ( ) => {
1193
+ const allClientProposals = priceFeedMultisigProposals . map (
1194
+ ( proposal , idx ) => ( {
1195
+ ...proposal ,
1196
+ verified : allProposalsVerifiedArr [ idx ] ,
1197
+ voted : proposalsVotedArr [ idx ] ,
1198
+ } )
1199
+ )
1163
1200
// filter price feed multisig proposals by status
1164
1201
if ( statusFilter === 'all' ) {
1165
- setFilteredProposals ( priceFeedMultisigProposals )
1202
+ // pass priceFeedMultisigProposals and add verified and voted props
1203
+ setFilteredProposals ( allClientProposals )
1166
1204
} else {
1167
1205
setFilteredProposals (
1168
- priceFeedMultisigProposals . filter (
1206
+ allClientProposals . filter (
1169
1207
( proposal ) =>
1170
1208
getProposalStatus ( proposal , priceFeedMultisigAccount ) ===
1171
1209
statusFilter
1172
1210
)
1173
1211
)
1174
1212
}
1175
- } , [ statusFilter , priceFeedMultisigAccount , priceFeedMultisigProposals ] )
1213
+ } , [
1214
+ statusFilter ,
1215
+ priceFeedMultisigAccount ,
1216
+ priceFeedMultisigProposals ,
1217
+ allProposalsVerifiedArr ,
1218
+ proposalsVotedArr ,
1219
+ ] )
1220
+
1221
+ useEffect ( ( ) => {
1222
+ if ( priceFeedMultisigAccount && connected && signerPublicKey ) {
1223
+ const res : boolean [ ] = [ ]
1224
+ priceFeedMultisigProposals . map ( ( proposal ) => {
1225
+ // check if proposal.approved, proposal.cancelled, proposal.rejected has wallet pubkey and return true if anyone of them has wallet pubkey
1226
+ const isProposalVoted =
1227
+ proposal . approved . some (
1228
+ ( p ) => p . toBase58 ( ) === signerPublicKey . toBase58 ( )
1229
+ ) ||
1230
+ proposal . cancelled . some (
1231
+ ( p ) => p . toBase58 ( ) === signerPublicKey . toBase58 ( )
1232
+ ) ||
1233
+ proposal . rejected . some (
1234
+ ( p ) => p . toBase58 ( ) === signerPublicKey . toBase58 ( )
1235
+ )
1236
+ res . push ( isProposalVoted )
1237
+ } )
1238
+ setProposalsVotedArr ( res )
1239
+ }
1240
+ } , [
1241
+ priceFeedMultisigAccount ,
1242
+ priceFeedMultisigProposals ,
1243
+ connected ,
1244
+ signerPublicKey ,
1245
+ ] )
1176
1246
1177
1247
return (
1178
1248
< div className = "relative" >
@@ -1210,7 +1280,8 @@ const Proposals = ({
1210
1280
< ProposalRow
1211
1281
key = { idx }
1212
1282
proposal = { proposal }
1213
- verified = { allProposalsVerifiedArr [ idx ] }
1283
+ verified = { proposal . verified }
1284
+ voted = { proposal . voted }
1214
1285
setCurrentProposalPubkey = { setCurrentProposalPubkey }
1215
1286
multisig = { priceFeedMultisigAccount }
1216
1287
/>
0 commit comments