replay popups on spectator page

This commit is contained in:
legop3
2026-06-07 17:39:31 -04:00
parent 87473fc424
commit a994759eb5
2 changed files with 10 additions and 2 deletions
@@ -323,7 +323,7 @@ function createReplayCaptionBuilder({ io, rovers, getActiveDrivers, getNickname,
} }
function build({ job, usedSources = [], missingSources = [] }) { function build({ job, usedSources = [], missingSources = [] }) {
const lines = [`**${job.title}**`, '', `Requested by ${job.requester}.`]; const lines = [`# ${job.title}`, '', `Requested by ${job.requester}.`];
const driverLines = buildReplayDriverLines(job.requester, usedSources); const driverLines = buildReplayDriverLines(job.requester, usedSources);
if (driverLines.length) { if (driverLines.length) {
lines.push('', ...driverLines); lines.push('', ...driverLines);
@@ -1,7 +1,7 @@
// Spectator Content // Spectator Content
// Purpose: Defines the Spectator Content module and the local helpers/components used in this file. // Purpose: Defines the Spectator Content module and the local helpers/components used in this file.
// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit. // Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit.
import { useSession } from '../../context/SessionContext.jsx'; import { useSession, useSessionActions, useSessionSelector } from '../../context/SessionContext.jsx';
import { useSpectatorMode } from '../../hooks/useSpectatorMode.js'; import { useSpectatorMode } from '../../hooks/useSpectatorMode.js';
import useDefaultNickname from '../../hooks/useDefaultNickname.js'; import useDefaultNickname from '../../hooks/useDefaultNickname.js';
import useUserIdentitySync from '../../hooks/useUserIdentitySync.js'; import useUserIdentitySync from '../../hooks/useUserIdentitySync.js';
@@ -12,6 +12,7 @@ import RoverQueuesPanel from '../../components/RoverQueuesPanel/index.jsx';
import RawUserPilePanel from '../../components/RawUserPilePanel/index.jsx'; import RawUserPilePanel from '../../components/RawUserPilePanel/index.jsx';
import ButtonBoxPanel from '../../components/ButtonBoxPanel/index.jsx'; import ButtonBoxPanel from '../../components/ButtonBoxPanel/index.jsx';
import RewardRunOverlay from '../../components/RewardRunOverlay/index.jsx'; import RewardRunOverlay from '../../components/RewardRunOverlay/index.jsx';
import ReplayReadyPopup from '../../components/ReplaySourcesPanel/ReplayReadyPopup.jsx';
import usePortraitLayout from './hooks/usePortraitLayout.js'; import usePortraitLayout from './hooks/usePortraitLayout.js';
import RoverRow from './components/RoverRow.jsx'; import RoverRow from './components/RoverRow.jsx';
import SecondaryRow from './components/SecondaryRow.jsx'; import SecondaryRow from './components/SecondaryRow.jsx';
@@ -19,6 +20,8 @@ import LogsRow from './components/LogsRow.jsx';
export default function SpectatorContent() { export default function SpectatorContent() {
const { session } = useSession(); const { session } = useSession();
const latestReplay = useSessionSelector((state) => state.latestReplay);
const { clearLatestReplay } = useSessionActions();
const inLockdown = session?.mode === 'lockdown'; const inLockdown = session?.mode === 'lockdown';
useDefaultNickname(); useDefaultNickname();
// The spectator route is not rendered through App.jsx, so it must opt into // The spectator route is not rendered through App.jsx, so it must opt into
@@ -95,6 +98,11 @@ export default function SpectatorContent() {
</main> </main>
<AlertFeed /> <AlertFeed />
<RewardRunOverlay /> <RewardRunOverlay />
{/* Spectators do not have the replay request panel that normal web users see, so
the spectator route listens to every ready replay directly. This intentionally
uses latestReplay instead of latestRequestedReplay because all spectators should
get the fullscreen replay when a Discord-hosted replay becomes available. */}
<ReplayReadyPopup replay={latestReplay} onClose={clearLatestReplay} />
</div> </div>
); );
} }