diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 2ed8cbe..b085920 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -9,12 +9,39 @@ import { TimedPollVoteMsg } from './models/TimedPollVoteMsg' import TimedPollVote from './utils/proto/TimedPollVote' import { DetailedTimedPoll } from './models/DetailedTimedPoll' +function decodeWakuMessages( + messages: WakuMessage[] | null | undefined, + decoder: { decode: (payload: Uint8Array | undefined, timestamp: Date | undefined) => T | undefined } +) { + return ( + messages + ?.map((msg) => decoder.decode(msg.payload, msg.timestamp)) + .filter((poll: T | undefined): poll is T => !!poll) ?? [] + ) +} + +async function receiveNewWakuMessages(lastTimestamp: number, topic: string, waku: Waku | undefined) { + const messages = await waku?.store.queryHistory({ contentTopics: [topic] }) + + if (messages) { + messages.sort((a, b) => (a.timestamp && b.timestamp && a.timestamp?.getTime() < b.timestamp?.getTime() ? 1 : -1)) + const lastMessageIndex = messages.findIndex((message) => message.timestamp?.getTime() === lastTimestamp) + const newMessages = lastMessageIndex === -1 ? messages : messages.slice(0, lastMessageIndex) + return newMessages + } + return [] +} + class WakuVoting { private appName: string private waku: Waku | undefined public tokenAddress: string private pollInitTopic: string private timedPollVoteTopic: string + + private timedPollInitMessages: PollInitMsg[] = [] + private timedPollVotesMessages: TimedPollVoteMsg[] = [] + private static async createWaku() { const waku = await Waku.create() const nodes = await getStatusFleetNodes() @@ -64,13 +91,14 @@ class WakuVoting { } private async getTimedPolls() { - const messages = await this.waku?.store.queryHistory({ contentTopics: [this.pollInitTopic] }) - return ( - messages - ?.filter((e): e is WakuMessage & { payload: Uint8Array } => !!e?.payload) - .map((msg) => PollInit.decode(msg.payload, msg.timestamp)) - .filter((poll): poll is PollInitMsg => !!poll) ?? [] - ) + const lastTimestamp = this.timedPollInitMessages?.[0]?.timestamp ?? 0 + + const newMessages = await receiveNewWakuMessages(lastTimestamp, this.pollInitTopic, this.waku) + const newPollInitMessages = decodeWakuMessages(newMessages, PollInit) + if (newPollInitMessages.length > 0) { + this.timedPollInitMessages = [...newPollInitMessages, ...this.timedPollInitMessages] + } + return this.timedPollInitMessages } public async sendTimedPollVote( @@ -92,13 +120,14 @@ class WakuVoting { } private async getTimedPollsVotes() { - const messages = await this.waku?.store.queryHistory({ contentTopics: [this.timedPollVoteTopic] }) - return ( - messages - ?.filter((e): e is WakuMessage & { payload: Uint8Array } => !!e?.payload) - .map((msg) => TimedPollVote.decode(msg.payload, msg.timestamp)) - .filter((poll): poll is TimedPollVoteMsg => !!poll) ?? [] - ) + const lastTimestamp = this.timedPollVotesMessages?.[0]?.timestamp ?? 0 + + const newMessages = await receiveNewWakuMessages(lastTimestamp, this.timedPollVoteTopic, this.waku) + const newVoteMessages = decodeWakuMessages(newMessages, TimedPollVote) + if (newVoteMessages.length > 0) { + this.timedPollVotesMessages = [...newVoteMessages, ...this.timedPollVotesMessages] + } + return this.timedPollVotesMessages } public async getDetailedTimedPolls() { diff --git a/packages/core/src/models/TimedPollVoteMsg.ts b/packages/core/src/models/TimedPollVoteMsg.ts index b54d7a7..a35bb42 100644 --- a/packages/core/src/models/TimedPollVoteMsg.ts +++ b/packages/core/src/models/TimedPollVoteMsg.ts @@ -39,7 +39,7 @@ export function createSignMsgParams(message: Message) { if (message.tokenAmount) { msgParams.message = { ...msgParams.message, tokenAmount: message.tokenAmount.toString() } - msgParams.types.Mail.push({ name: 'minToken', type: 'uint256' }) + msgParams.types.Mail.push({ name: 'tokenAmount', type: 'uint256' }) } return msgParams } diff --git a/packages/core/src/utils/proto/PollInit.ts b/packages/core/src/utils/proto/PollInit.ts index 96cf7f3..61d3372 100644 --- a/packages/core/src/utils/proto/PollInit.ts +++ b/packages/core/src/utils/proto/PollInit.ts @@ -48,10 +48,13 @@ export function encode(pollInit: PollInitMsg) { } export function decode( - payload: Uint8Array, + payload: Uint8Array | undefined, timestamp: Date | undefined, recoverFunction?: ({ data, sig }: { data: any; sig: string }) => string ) { + if (!payload) { + return undefined + } try { const msg = proto.PollInit.decode(payload) if (!timestamp || timestamp.getTime() != msg.timestamp) { diff --git a/packages/core/src/utils/proto/TimedPollVote.ts b/packages/core/src/utils/proto/TimedPollVote.ts index 2075ddd..ab1ad59 100644 --- a/packages/core/src/utils/proto/TimedPollVote.ts +++ b/packages/core/src/utils/proto/TimedPollVote.ts @@ -33,10 +33,13 @@ export function encode(timedPollVote: TimedPollVoteMsg) { } export function decode( - payload: Uint8Array, + payload: Uint8Array | undefined, timestamp: Date | undefined, recoverFunction?: ({ data, sig }: { data: any; sig: string }) => string ) { + if (!payload) { + return undefined + } try { const msg = proto.TimedPollVote.decode(payload) if (!timestamp || timestamp.getTime() != msg.timestamp) { diff --git a/packages/react-components/src/Poll.tsx b/packages/react-components/src/Poll.tsx index 3330f2d..71ec616 100644 --- a/packages/react-components/src/Poll.tsx +++ b/packages/react-components/src/Poll.tsx @@ -16,11 +16,15 @@ export function Poll({ poll, wakuVoting, signer }: PollProps) { const [selectedAnswer, setSelectedAnswer] = useState(0) const [tokenAmount, setTokenAmount] = useState(0) const [address, setAddress] = useState('') - + const [userInVoters, setUserInVoters] = useState(false) useEffect(() => { signer.getAddress().then((e) => setAddress(e)) }, [signer]) + useEffect(() => { + setUserInVoters(!!poll.votesMessages.find((vote) => vote.voter === address)) + }, [poll]) + return ( @@ -28,7 +32,7 @@ export function Poll({ poll, wakuVoting, signer }: PollProps) { {poll.poll.pollType === PollType.WEIGHTED ? 'WEIGHTED' : 'NON WEIGHTED'} - {!poll.votesMessages.find((vote) => vote.voter === address) && ( + {!userInVoters && (
setSelectedAnswer(Number.parseInt((e.target as any).value ?? 0))}> {poll.poll.answers.map((answer, idx) => { @@ -51,7 +55,7 @@ export function Poll({ poll, wakuVoting, signer }: PollProps) { )}
)} - {poll.votesMessages.find((vote) => vote.voter === address) && ( + {userInVoters && (
Results {poll.answers.map((answer, idx) => { @@ -65,21 +69,23 @@ export function Poll({ poll, wakuVoting, signer }: PollProps) {
)} - + {!userInVoters && ( + + )} ) } diff --git a/packages/react-components/src/PollList.tsx b/packages/react-components/src/PollList.tsx index a1128f4..9df4d4e 100644 --- a/packages/react-components/src/PollList.tsx +++ b/packages/react-components/src/PollList.tsx @@ -19,7 +19,7 @@ export function PollList({ wakuVoting, signer }: PollListProps) { if (wakuVoting) { setPolls(await wakuVoting.getDetailedTimedPolls()) } - }, 1000) + }, 5000) return () => clearInterval(interval) }, [wakuVoting]) diff --git a/packages/react-components/src/index.tsx b/packages/react-components/src/index.tsx index 8aab2a9..d06025e 100644 --- a/packages/react-components/src/index.tsx +++ b/packages/react-components/src/index.tsx @@ -30,9 +30,9 @@ function Example({ appName }: ExampleProps) { provider.send('eth_requestAccounts', []) }, []) return ( - + showNewPollBox && setShowNewPollBox(false)}> {showNewPollBox && ( - + e.stopPropagation()}> Question @@ -83,7 +83,7 @@ function Example({ appName }: ExampleProps) { )} - + )