From fe9bd73c3e498aa2157a6de580ee4b5bf8e17b7a Mon Sep 17 00:00:00 2001 From: Atridad Lahiji Date: Sun, 8 Oct 2023 13:21:30 -0600 Subject: [PATCH] Optimistic updates for votes --- app/(client)/room/[id]/VoteUI.tsx | 38 +++++++++++++++++++++++-------- next.config.mjs | 3 +++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/(client)/room/[id]/VoteUI.tsx b/app/(client)/room/[id]/VoteUI.tsx index bfcd1f1..9408a25 100644 --- a/app/(client)/room/[id]/VoteUI.tsx +++ b/app/(client)/room/[id]/VoteUI.tsx @@ -4,6 +4,8 @@ import { EventTypes } from "@/_utils/types"; import Image from "next/image"; import { useEffect, useState } from "react"; +import { experimental_useOptimistic } from "react"; + import LoadingIndicator from "@/_components/LoadingIndicator"; import type { PresenceItem, RoomResponse, VoteResponse } from "@/_utils/types"; import { useUser } from "@clerk/nextjs"; @@ -36,9 +38,11 @@ const VoteUI = () => { const [copied, setCopied] = useState(false); const [roomFromDb, setRoomFromDb] = useState(); - const [votesFromDb, setVotesFromDb] = useState(undefined); + const [optimisticVotes, setOptimisticVotes] = + experimental_useOptimistic(votesFromDb); + const getRoomHandler = () => { fetch(`/api/internal/room/${roomId}`, { cache: "no-cache", @@ -102,7 +106,8 @@ const VoteUI = () => { const getVoteForCurrentUser = () => { if (roomFromDb) { return ( - votesFromDb && votesFromDb.find((vote) => vote.userId === user?.id) + optimisticVotes && + optimisticVotes.find((vote) => vote.userId === user?.id) ); } else { return null; @@ -110,6 +115,19 @@ const VoteUI = () => { }; const setVoteHandler = async (value: string) => { + const newVotes = optimisticVotes?.map((vote) => { + if (vote.userId === user?.id) { + return { + ...vote, + value, + }; + } else { + return vote; + } + }); + + setOptimisticVotes(newVotes); + if (roomFromDb) { await fetch(`/api/internal/room/${roomId}/vote`, { cache: "no-cache", @@ -142,7 +160,7 @@ const VoteUI = () => { }; const downloadLogs = () => { - if (roomFromDb && votesFromDb) { + if (roomFromDb && optimisticVotes) { const jsonObject = roomFromDb?.logs .map((item) => { return { @@ -164,7 +182,7 @@ const VoteUI = () => { roomName: roomFromDb.roomName, storyName: storyNameText, scale: roomScale, - votes: votesFromDb.map((vote) => { + votes: optimisticVotes.map((vote) => { return { value: vote.value, }; @@ -301,10 +319,10 @@ const VoteUI = () => {

{roomFromDb && - votesFromDb && + optimisticVotes && voteString( roomFromDb.visible, - votesFromDb, + optimisticVotes, presenceItem.data )} @@ -395,7 +413,7 @@ const VoteUI = () => { false, true, roomFromDb.storyName === storyNameText || - votesFromDb?.length === 0 + optimisticVotes?.length === 0 ? false : true ) @@ -408,7 +426,7 @@ const VoteUI = () => { } > {roomFromDb.storyName === storyNameText || - votesFromDb?.length === 0 ? ( + optimisticVotes?.length === 0 ? ( <> Reset @@ -420,9 +438,9 @@ const VoteUI = () => { - {votesFromDb && + {optimisticVotes && (roomFromDb.logs.length > 0 || - votesFromDb.length > 0) && ( + optimisticVotes.length > 0) && (