diff --git a/backend/controller/gameController.ts b/backend/controller/gameController.ts index d4d2184..7174123 100644 --- a/backend/controller/gameController.ts +++ b/backend/controller/gameController.ts @@ -42,9 +42,11 @@ export const gameController = createController({ theme: pickRandom(collection.entries.filter((e) => e.selected)).id, }); upsertGameState(db, newGame); + // Emit new game event with gameId for spectating emit({ type: "new", user, + gameId: uuid, }); emit({ type: "updateStage", diff --git a/backend/entities/game.ts b/backend/entities/game.ts index fffd1da..d8c6a36 100644 --- a/backend/entities/game.ts +++ b/backend/entities/game.ts @@ -233,7 +233,7 @@ export const game = { if (!isValid(serverGame, x, y)) return; if (isQuestionMark[x][y]) return; if (isFlagged[x][y]) return; - serverGame.lastClick = [x, y]; + if (initial) serverGame.lastClick = [x, y]; if (mines[x][y]) { serverGame.finished = Date.now(); diff --git a/shared/events.ts b/shared/events.ts index d66ab56..4945108 100644 --- a/shared/events.ts +++ b/shared/events.ts @@ -6,6 +6,7 @@ export type Events = | { type: "new"; user: string; + gameId: string; } | { type: "loss"; diff --git a/src/components/Feed/Feed.tsx b/src/components/Feed/Feed.tsx index 7c1e465..7fb2114 100644 --- a/src/components/Feed/Feed.tsx +++ b/src/components/Feed/Feed.tsx @@ -24,12 +24,19 @@ const Feed: React.FC = () => { const data = JSON.parse(event.data) as Events; const newItems = [...items]; if (data.type === "new" && data.user !== user) { - newItems.push({ + // Remove any existing gameStarted items for this user + const filteredItems = newItems.filter( + item => !(item.type === "gameStarted" && item.user === data.user) + ); + filteredItems.push({ type: "gameStarted", user: data.user, + gameId: data.gameId, id: crypto.randomUUID(), decay: Date.now() + 1000 * 3, }); + setItems(filteredItems); + return; } if (data.type === "loss") { newItems.push({ diff --git a/src/components/Feed/FeedItem.tsx b/src/components/Feed/FeedItem.tsx index c74b393..bb4deec 100644 --- a/src/components/Feed/FeedItem.tsx +++ b/src/components/Feed/FeedItem.tsx @@ -5,6 +5,7 @@ import GemsIcon from "../GemIcon"; import type { Rarity as RarityType } from "../../../shared/lootboxes"; import { Rarity } from "../Rarity"; import { themes } from "../../themes"; +import { Link } from "wouter"; interface BaseFeedItem { decay: number; @@ -14,6 +15,7 @@ interface BaseFeedItem { interface GameStartedItem extends BaseFeedItem { type: "gameStarted"; user: string; + gameId: string; } interface GameFinishedItem extends BaseFeedItem { @@ -59,7 +61,19 @@ const FeedItemWrapper: React.FC = ({ children }) => { const FeedItemElement: React.FC<{ item: FeedItem }> = ({ item }) => { switch (item.type) { case "gameStarted": - return {item.user} started a game; + return ( + + + {item.user} started a game -{" "} + + spectate + + + + ); case "gameFinished": return ( diff --git a/src/views/profile/Profile.tsx b/src/views/profile/Profile.tsx index 9ec4560..2fb04a5 100644 --- a/src/views/profile/Profile.tsx +++ b/src/views/profile/Profile.tsx @@ -73,7 +73,7 @@ const TouchTooltip = ({ }; interface ProfileProps { - username?: string; + username?: string | undefined; } const Profile: React.FC = ({ username: targetUsername }) => {