Skip to content

Commit

Permalink
Use optimistic updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
Preslav Le committed Dec 9, 2022
1 parent f3af80a commit dff08ce
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 11 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

This example demonstrates how to build a fully functional chat app using React, Next.js and Convex.

The app was build within few hours. Limitation:
* The computer plays random moves.
* No optimistic updates.
The app was build within few hours. The computer just does random valid moves for now. Will improve later.

## Run locally

Expand Down
7 changes: 5 additions & 2 deletions convex/games.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ export const get = query(async ({ db }, id: Id<"games">) => {
return await db.get(id);
})

export const openGames = query(async ({ db }) => {
export const ongoingGames = query(async ({ db }) => {
// Games are considered completed after an hour.
let minStartTime = Date.now() - 3600 * 1000;
return await db.query("games")
.withIndex("finished", q => q.eq("finished", false))
.order("desc")
.filter(q => q.gt(q.field("_creationTime"), minStartTime))
.take(10);
Expand All @@ -28,6 +29,7 @@ export const newGame = mutation(async (
pgn: game.pgn(),
player1,
player2,
finished: false,
})
})

Expand Down Expand Up @@ -67,7 +69,8 @@ async function performMove(
}

await db.patch(state._id, {
pgn: nextState,
pgn: nextState.pgn(),
finished: nextState.isGameOver(),
});
}

Expand Down
3 changes: 2 additions & 1 deletion convex/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export default defineSchema({
s.literal<string>("random"),
s.null(),
),
})
finished: s.boolean(),
}).index("finished", ["finished"]),
})
4 changes: 2 additions & 2 deletions convex/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function getCurrentPlayer(state: Document<"games">) : string | null {
return (game.turn() == 'w') ? state.player1 : state.player2;
}

export function validateMove(state: Document<"games">, player: string, from: string, to: string) : string | null {
export function validateMove(state: Document<"games">, player: string, from: string, to: string) : Chess | null {
if (getCurrentPlayer(state) != player) {
// Wrong player.
return null;
Expand All @@ -30,5 +30,5 @@ export function validateMove(state: Document<"games">, player: string, from: str
valid = game.move(moveAndPromote);
}

return valid ? game.pgn() : null;
return valid ? game : null;
}
4 changes: 2 additions & 2 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useRouter } from 'next/router'
export default function App(props: {userName: string | null}) {
const router = useRouter();

const openGames : Document<"games">[] = useQuery("games:openGames") || [];
const ongoingGames : Document<"games">[] = useQuery("games:ongoingGames") || [];
const startNewGame = useMutation("games:newGame");

async function newGame(event: FormEvent) {
Expand Down Expand Up @@ -79,7 +79,7 @@ export default function App(props: {userName: string | null}) {
<table>
<tbody>
{
openGames.map((game, i) => (
ongoingGames.map((game, i) => (
<tr key={i}>
<td>{gameTitle(game)}</td>
<td>
Expand Down
15 changes: 14 additions & 1 deletion pages/play.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,20 @@ export default function Game(props: {userName: string}) {
const gameId = new Id("games", router.query.gameId as string);

const gameState = useQuery('games:get', gameId)
const performMove = useMutation('games:move');
const performMove = useMutation('games:move').withOptimisticUpdate(
(localStore, gameId, _, from, to) => {
const state = localStore.getQuery("games:get", [gameId]);
if (state != "undefined") {
const game = new Chess();
game.loadPgn(state.pgn);
game.move({from, to});
const newState = { ...state };
newState.pgn = game.pgn();
console.log("nextState", game.history(), gameId);
localStore.setQuery("games:get", [gameId], newState);
}
}
);
const joinGame = useMutation("games:joinGame");
const makeComputerMove = useMutation("games:makeComputerMove")
if (!gameState) {
Expand Down

0 comments on commit dff08ce

Please sign in to comment.