← back to sami__knowyourdeen

Function bodies 62 total

All specs Real LLM only Function bodies
clearPlayerId function · typescript · L32-L34 (3 LOC)
src/hooks/useOnlineStore.ts
function clearPlayerId(roomCode: string) {
  localStorage.removeItem(PLAYER_ID_PREFIX + roomCode);
}
saveLastRoom function · typescript · L38-L40 (3 LOC)
src/hooks/useOnlineStore.ts
function saveLastRoom(roomCode: string) {
  localStorage.setItem(LAST_ROOM_KEY, JSON.stringify({ roomCode, ts: Date.now() }));
}
clearLastRoom function · typescript · L42-L44 (3 LOC)
src/hooks/useOnlineStore.ts
function clearLastRoom() {
  localStorage.removeItem(LAST_ROOM_KEY);
}
getLastRoom function · typescript · L46-L52 (7 LOC)
src/hooks/useOnlineStore.ts
export function getLastRoom(): string | null {
  try {
    const data = JSON.parse(localStorage.getItem(LAST_ROOM_KEY) || '');
    if (Date.now() - data.ts < 60 * 60 * 1000) return data.roomCode;
  } catch { /* ignore */ }
  return null;
}
cleanupStalePlayerIds function · typescript · L55-L64 (10 LOC)
src/hooks/useOnlineStore.ts
function cleanupStalePlayerIds() {
  for (let i = localStorage.length - 1; i >= 0; i--) {
    const key = localStorage.key(i);
    if (!key?.startsWith(PLAYER_ID_PREFIX)) continue;
    try {
      const { ts } = JSON.parse(localStorage.getItem(key)!);
      if (Date.now() - ts > 60 * 60 * 1000) localStorage.removeItem(key);
    } catch { localStorage.removeItem(key!); }
  }
}
applySnapshot function · typescript · L140-L182 (43 LOC)
src/hooks/useOnlineStore.ts
  function applySnapshot(state: RoomStateSnapshot) {
    const myId = get().myPlayerId;
    const isJoined = state.players.some(p => p.id === myId);

    // If we were in a game screen but got removed from the room
    if (!isJoined && get().screen !== 'setup') {
      const socket = get().socket;
      if (socket) socket.close();
      set({ ...initialState, error: 'removedFromRoom' });
      return;
    }

    const scores: Record<string, number> = {};
    for (const p of state.players) {
      scores[p.id] = p.score;
    }

    let screen: OnlineScreen = get().screen;
    if (isJoined) {
      if (state.phase === 'lobby') screen = 'lobby';
      else if (state.phase === 'playing') screen = 'playing';
      else if (state.phase === 'finished') screen = 'finished';
    }

    set({
      roomCode: state.roomCode,
      hostId: state.hostId,
      phase: state.phase,
      players: state.players,
      maxPlayers: state.maxPlayers,
      questionIds: state.questionIds,
      currentQue
handleMessage function · typescript · L184-L303 (120 LOC)
src/hooks/useOnlineStore.ts
  function handleMessage(event: MessageEvent) {
    let msg: ServerMessage;
    try {
      msg = JSON.parse(event.data);
    } catch {
      return;
    }

    switch (msg.type) {
      case 'room-state':
        applySnapshot(msg.state);
        break;

      case 'player-joined': {
        const player = msg.player;
        set(state => ({
          players: [...state.players, player],
        }));
        break;
      }

      case 'player-left': {
        const playerId = msg.playerId;
        set(state => ({
          players: state.players.filter(p => p.id !== playerId),
        }));
        break;
      }

      case 'game-started':
        applySnapshot(msg.state);
        set({
          screen: 'playing',
          lastAnswerCorrect: null,
          lastAnswerPlayerId: null,
          timeoutPlayerId: null,
          rankings: null,
        });
        break;

      case 'answer-revealed': {
        const { letter, correct, scores, playerId } = msg;
        set({
          s
Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
connectToRoom function · typescript · L305-L350 (46 LOC)
src/hooks/useOnlineStore.ts
  function connectToRoom(roomCode: string, playerName: string) {
    const existing = get().socket;
    if (existing) {
      existing.close();
    }

    const playerId = getOrCreatePlayerId(roomCode);
    const socket = new PartySocket({
      host: PARTYKIT_HOST,
      room: roomCode,
      id: playerId,
    });

    set({
      socket,
      myPlayerId: playerId,
      roomCode,
      connecting: true,
      error: null,
    });

    const timeout = setTimeout(() => {
      if (get().connecting) {
        socket.close();
        set({ ...initialState, error: 'connectionTimeout' });
      }
    }, 10_000);

    socket.addEventListener('open', () => {
      clearTimeout(timeout);
      // Use socket.id to guarantee myPlayerId matches server's connection.id
      const actualId = socket.id;
      set({ connected: true, myPlayerId: actualId });
      // Sync localStorage with the actual ID the server sees
      const key = PLAYER_ID_PREFIX + roomCode;
      localStorage.setItem(key, JS
usePresence function · typescript · L6-L28 (23 LOC)
src/hooks/usePresence.ts
export function usePresence() {
  const [count, setCount] = useState<number | null>(null);

  useEffect(() => {
    const socket = new PartySocket({
      host: PARTYKIT_HOST,
      room: '__presence__',
    });

    socket.addEventListener('message', (event) => {
      try {
        const msg = JSON.parse(event.data);
        if (msg.type === 'presence-count') {
          setCount(msg.count);
        }
      } catch { /* ignore */ }
    });

    return () => { socket.close(); };
  }, []);

  return count;
}
useWakeLock function · typescript · L3-L31 (29 LOC)
src/hooks/useWakeLock.ts
export function useWakeLock(active: boolean) {
  const wakeLock = useRef<WakeLockSentinel | null>(null);

  useEffect(() => {
    if (!active) return;

    const request = async () => {
      try {
        if ('wakeLock' in navigator) {
          wakeLock.current = await navigator.wakeLock.request('screen');
        }
      } catch (err) {
        console.warn('Wake Lock error:', err);
      }
    };

    request();

    const handleVisibilityChange = () => {
      if (document.visibilityState === 'visible') request();
    };

    document.addEventListener('visibilitychange', handleVisibilityChange);
    return () => {
      document.removeEventListener('visibilitychange', handleVisibilityChange);
      if (wakeLock.current) wakeLock.current.release();
    };
  }, [active]);
}
t function · typescript · L85-L87 (3 LOC)
src/i18n/translations.ts
export function t(key: TranslationKey, lang: Lang): string {
  return translations[key][lang];
}
Library function · typescript · L7-L126 (120 LOC)
src/Library.tsx
export default function Library({ lang, onBack }: { lang: Lang; onBack: () => void }) {
  const isRTL = lang === 'ar';
  const [activeCategory, setActiveCategory] = useState<string>(CATEGORIES[0].id);
  const [expandedQuestionId, setExpandedQuestionId] = useState<number | null>(null);

  const currentQuestions = useMemo(
    () =>
      questionsDB.filter((q) => {
        const cat = CATEGORIES.find((c) => c.id === activeCategory);
        return cat && q.id >= cat.startId && q.id <= cat.endId;
      }),
    [activeCategory]
  );

  return (
    <div className="w-full max-w-4xl mx-auto animate-fade-in flex flex-col h-[85vh]">
      <div className="bg-white/80 backdrop-blur-md p-6 rounded-3xl shadow-xl flex-1 flex flex-col mb-4 overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between mb-6 pb-4 border-b border-teal-100/50">
          <div className="flex items-center gap-3">
            <BookOpen className="w-8 h-8 text-teal-600" />
            <
‹ prevpage 2 / 2