diff --git a/server/src/services/discordBotService/replayWorkflow.js b/server/src/services/discordBotService/replayWorkflow.js index c7e0a99e..a1cf135f 100644 --- a/server/src/services/discordBotService/replayWorkflow.js +++ b/server/src/services/discordBotService/replayWorkflow.js @@ -323,7 +323,7 @@ function createReplayCaptionBuilder({ io, rovers, getActiveDrivers, getNickname, } 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); if (driverLines.length) { lines.push('', ...driverLines); diff --git a/webui/src/spectate/SpectatorApp/SpectatorContent.jsx b/webui/src/spectate/SpectatorApp/SpectatorContent.jsx index d52fc9e4..d9247d73 100644 --- a/webui/src/spectate/SpectatorApp/SpectatorContent.jsx +++ b/webui/src/spectate/SpectatorApp/SpectatorContent.jsx @@ -1,7 +1,7 @@ // Spectator Content // 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. -import { useSession } from '../../context/SessionContext.jsx'; +import { useSession, useSessionActions, useSessionSelector } from '../../context/SessionContext.jsx'; import { useSpectatorMode } from '../../hooks/useSpectatorMode.js'; import useDefaultNickname from '../../hooks/useDefaultNickname.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 ButtonBoxPanel from '../../components/ButtonBoxPanel/index.jsx'; import RewardRunOverlay from '../../components/RewardRunOverlay/index.jsx'; +import ReplayReadyPopup from '../../components/ReplaySourcesPanel/ReplayReadyPopup.jsx'; import usePortraitLayout from './hooks/usePortraitLayout.js'; import RoverRow from './components/RoverRow.jsx'; import SecondaryRow from './components/SecondaryRow.jsx'; @@ -19,6 +20,8 @@ import LogsRow from './components/LogsRow.jsx'; export default function SpectatorContent() { const { session } = useSession(); + const latestReplay = useSessionSelector((state) => state.latestReplay); + const { clearLatestReplay } = useSessionActions(); const inLockdown = session?.mode === 'lockdown'; useDefaultNickname(); // The spectator route is not rendered through App.jsx, so it must opt into @@ -95,6 +98,11 @@ export default function SpectatorContent() { + {/* 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. */} + ); }