diff --git a/public/robots.txt b/public/robots.txt index 1f53798..c2a49f4 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,2 +1,2 @@ User-agent: * -Disallow: / +Allow: / diff --git a/src/components/ShareButton.tsx b/src/components/ShareButton.tsx new file mode 100644 index 0000000..da96e7b --- /dev/null +++ b/src/components/ShareButton.tsx @@ -0,0 +1,42 @@ +import { Button } from "./Button"; +import { useState } from "react"; + +interface ShareButtonProps { + gameId: string; + className?: string; +} + +export const ShareButton: React.FC = ({ gameId, className }) => { + const [copied, setCopied] = useState(false); + + const handleShare = async () => { + const shareUrl = `${window.location.origin}/play/${gameId}`; + + try { + await navigator.clipboard.writeText(shareUrl); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch { + // Fallback for browsers that don't support clipboard API + const textArea = document.createElement("textarea"); + textArea.value = shareUrl; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand("copy"); + document.body.removeChild(textArea); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + }; + + return ( + + ); +}; \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index acbe2c0..42a176a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -45,7 +45,9 @@ setup().then(() => { - + + {(params) => } + diff --git a/src/views/endless/Endless.tsx b/src/views/endless/Endless.tsx index 8272380..0e999ff 100644 --- a/src/views/endless/Endless.tsx +++ b/src/views/endless/Endless.tsx @@ -3,9 +3,11 @@ import { useAtom } from "jotai"; import { gameIdAtom, loginTokenAtom } from "../../atoms"; import { Button } from "../../components/Button"; import LeaderboardButton from "../../components/LeaderboardButton"; +import { ShareButton } from "../../components/ShareButton"; import { Fragment, startTransition, Suspense, useEffect } from "react"; import { Board } from "../../components/LazyBoard"; import RegisterButton from "../../components/Auth/RegisterButton"; +import { Link } from "wouter"; interface EndlessProps { gameId?: string; @@ -16,6 +18,7 @@ const Endless: React.FC = (props) => { const [loginToken] = useAtom(loginTokenAtom); const { data: game } = useWSQuery("game.getGameState", gameId!, !!gameId); const { data: settings } = useWSQuery("user.getSettings", null); + const { data: currentUsername } = useWSQuery("user.getSelf", null); const startGame = useWSMutation("game.createGame"); const { data: leaderboard } = useWSQuery("scoreboard.getScoreBoard", 100); const reveal = useWSMutation("game.reveal"); @@ -23,6 +26,9 @@ const Endless: React.FC = (props) => { const placeQuestionMark = useWSMutation("game.placeQuestionMark"); const clearTile = useWSMutation("game.clearTile"); + // Check if current user is spectating someone else's game + const isSpectating = game && game.user !== currentUsername; + useEffect(() => { if (props.gameId) { setGameId(props.gameId); @@ -41,6 +47,18 @@ const Endless: React.FC = (props) => { Stage {game.stage}
+ {isSpectating && ( +
+ Spectating + + {game.user} + +
+ )} +
diff --git a/src/views/profile/Profile.tsx b/src/views/profile/Profile.tsx index 13621a1..9ec4560 100644 --- a/src/views/profile/Profile.tsx +++ b/src/views/profile/Profile.tsx @@ -72,27 +72,35 @@ const TouchTooltip = ({ ); }; -const Profile: React.FC = () => { +interface ProfileProps { + username?: string; +} + +const Profile: React.FC = ({ username: targetUsername }) => { const [availableWeeks, setAvailableWeeks] = useState(16); // Default to 4 months const containerRef = useRef(null); - const { data: username } = useWSQuery("user.getSelf", null); + const { data: currentUsername } = useWSQuery("user.getSelf", null); + + // Use targetUsername if provided, otherwise use current user's username + const profileUsername = targetUsername || currentUsername; + const { data: heatmap } = useWSQuery( "user.getHeatmap", - { id: username! }, - !!username, + { id: profileUsername! }, + !!profileUsername, ); const { data: profile } = useWSQuery( "user.getProfile", - { id: username! }, - !!username, + { id: profileUsername! }, + !!profileUsername, ); const { data: pastGames } = useWSQuery( "game.getGames", { - user: username!, + user: profileUsername!, page: 0, }, - !!username, + !!profileUsername, ); const now = useMemo(() => dayjs(), []); const maxHeat = heatmap ? Math.max(...heatmap) : 0; @@ -158,7 +166,7 @@ const Profile: React.FC = () => {
- {username} + {profileUsername}

Total Games: {profile?.totalGames}