Skip to content

Conversation

@Ammaar-Alam
Copy link
Member

Summary

Added public race UX elements to show minimum player count; fixed player progress bar tracking bugs; changed mistake popup styling

Implementation Notes

  • add a lobby header pill, ready button states, and a “waiting for players” summary so public races show who’s ready and when the countdown can start
  • surface typing mistakes inline via the new typing-error-banner, keep the input container spacing consistent, and extend player progress bars with error
    badges plus richer styling
  • propagate hasError from the client (RaceContext → socket payloads) through race:progress so spectators see when racers must fix mistakes
  • document the October 2025 adaptive training mode architecture in docs/TrainingModeSystem.md and update .env.example with a realistic empty
    SMTP_OAUTH_CACHE JSON template

Copilot AI review requested due to automatic review settings November 12, 2025 20:44
@Ammaar-Alam Ammaar-Alam merged commit 3fbfc62 into master Nov 12, 2025
4 checks passed
@Ammaar-Alam Ammaar-Alam deleted the feat/polish-misc branch November 12, 2025 20:45
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances the race readiness UX for public lobbies and improves error signaling during typing. The changes add visual indicators to show minimum player count requirements, track typing errors in real-time for spectators, and provide better visual feedback through styled error banners and progress bars.

Key Changes

  • Added lobby status pill showing player readiness counts and minimum player requirements for public races
  • Introduced inline typing error banner with improved styling and error propagation from client through server to all race participants
  • Enhanced player progress bars with error indicators and contextual ready button states

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
server/controllers/socket-handlers.js Added hasError field to race progress tracking and broadcast to enable error state visibility for spectators
client/src/context/RaceContext.jsx Updated to emit hasError status and map it to hasMistake property for player state
client/src/pages/Race.jsx Added minimum player logic, readiness calculations, and removed unused useRef import
client/src/components/Typing.jsx Moved error message to new typing-error-banner component positioned below snippet display
client/src/components/Typing.css Added styling for typing-error-banner with animation and added padding-bottom to typing-area
client/src/components/PlayerStatusBar.jsx Implemented pill state management for lobby status display and error indicators on progress bars
client/src/components/PlayerStatusBar.css Added extensive styling for status pill, error indicators, and enhanced progress bar states
.env.example Updated SMTP_OAUTH_CACHE with realistic JSON template structure
Comments suppressed due to low confidence (18)

client/src/components/Typing.jsx:45

  • Unused variable updateProgress.
  const { raceState, setRaceState, typingState, setTypingState, updateProgress, handleInput: raceHandleInput, loadNewSnippet } = useRace();

client/src/components/Typing.jsx:51

  • Unused variable lastTabPress.
  const [lastTabPress, setLastTabPress] = useState(0);

client/src/components/Typing.jsx:51

  • Unused variable setLastTabPress.
  const [lastTabPress, setLastTabPress] = useState(0);

client/src/components/Typing.jsx:58

  • Unused variable tabActionInProgressRef.
  const tabActionInProgressRef = useRef(false);

client/src/context/RaceContext.jsx:570

  • Unused variable currentMode.
    const currentMode = modeOverride || testMode;

client/src/context/RaceContext.jsx:571

  • Unused variable currentDuration.
    const currentDuration = durationOverride || testDuration;

client/src/context/RaceContext.jsx:657

  • Unused variable isTimedMode.
    const isTimedMode = !!(raceState.snippet?.is_timed_test || raceState.timedTest?.enabled || raceState.settings?.testMode === 'timed');

client/src/pages/Race.jsx:23

  • Unused variable typingState.
    typingState,

client/src/context/RaceContext.jsx:784

  • Unused variable wordStart.
      let wordStart = 0;

client/src/context/RaceContext.jsx:845

  • Unused variable isMultiplayer.
        const isMultiplayer = raceState.type !== 'practice';

server/controllers/socket-handlers.js:10

  • Unused variable analytics.
const analytics = require('../utils/analytics');

server/controllers/socket-handlers.js:1731

  • Unused variable timers.
      for (const [key, timers] of inactivityTimers.entries()) {

server/controllers/socket-handlers.js:1836

  • Unused variable startPracticeCountdown.
const startPracticeCountdown = async (io, code) => {

server/controllers/socket-handlers.js:186

  • The value assigned to newHostAssigned here is unused.
                 newHostAssigned = true;

server/controllers/socket-handlers.js:1757

  • The value assigned to isTimed here is unused.
              isTimed = true;

client/src/components/Typing.jsx:733

  • Avoid automated semicolon insertion (98% of all statements in the enclosing function have an explicit semicolon).
  }

client/src/components/Typing.jsx:591

  • This use of variable 'interval' always evaluates to false.
      if (interval) clearInterval(interval);

server/controllers/socket-handlers.js:1731

  • For loop variable timers is not used in the loop body.
      for (const [key, timers] of inactivityTimers.entries()) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +367 to +368
0%, 100% { opacity: 0.9; transform: translate(-50%, 10%) scale(1); }
50% { opacity: 1; transform: translate(-50%, 10%) scale(1.05); }
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The animation transform values are inconsistent with the base style. The base .typing-error-banner uses transform: translate(-50%, 100%) to position the banner below the snippet, but the bannerPulse animation uses translate(-50%, 10%) which would cause the banner to jump to a different position during animation. The animation should maintain the same Y-axis translation as the base transform.

Suggested fix:

@keyframes bannerPulse {
  0%, 100% { opacity: 0.9; transform: translate(-50%, 100%) scale(1); }
  50% { opacity: 1; transform: translate(-50%, 100%) scale(1.05); }
}
Suggested change
0%, 100% { opacity: 0.9; transform: translate(-50%, 10%) scale(1); }
50% { opacity: 1; transform: translate(-50%, 10%) scale(1.05); }
0%, 100% { opacity: 0.9; transform: translate(-50%, 100%) scale(1); }
50% { opacity: 1; transform: translate(-50%, 100%) scale(1.05); }

Copilot uses AI. Check for mistakes.
AZURE_CLIENT_ID=
SMTP_SENDER=[email protected]
SMTP_OAUTH_CACHE= (optional; JSON blob of MSAL cache for headless servers)
SMTP_OAUTH_CACHE= {"Account":{},"IdToken":{},"AccessToken":{},"RefreshToken":{},"AppMetadata":{}}
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a space after the equals sign before the JSON value. While this may work in some environments, it could cause parsing issues as the leading space might be included in the environment variable value. Consider removing the space for consistency with other JSON-valued environment variables, or ensure the consuming code trims whitespace.

Suggested fix:

SMTP_OAUTH_CACHE={"Account":{},"IdToken":{},"AccessToken":{},"RefreshToken":{},"AppMetadata":{}}
Suggested change
SMTP_OAUTH_CACHE= {"Account":{},"IdToken":{},"AccessToken":{},"RefreshToken":{},"AppMetadata":{}}
SMTP_OAUTH_CACHE={"Account":{},"IdToken":{},"AccessToken":{},"RefreshToken":{},"AppMetadata":{}}

Copilot uses AI. Check for mistakes.
@@ -1,4 +1,4 @@
import { useState, useEffect, useRef } from 'react';
import { useState, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import Link.

Suggested change
import { Link, useNavigate } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';

Copilot uses AI. Check for mistakes.

function Race() {
const navigate = useNavigate();
const { socket } = useSocket();
Copy link

Copilot AI Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable socket.

Suggested change
const { socket } = useSocket();

Copilot uses AI. Check for mistakes.
Ammaar-Alam added a commit that referenced this pull request Dec 5, 2025
fixing login/logout redirects; adding unit tests [ALL UNIT-TEST RELATED FILES/CODE IS AI-GENERATED]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants