Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions frontend/src/features/playScenario/PlayScenarioPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { applyStateOperations } from "../../components/StateVariables/stateOpera
import NotesPanel from "./components/NotesPanel";
import ResourcesPanel from "./components/ResourcesPanel";
import SceneTimer from "./components/SceneTimer";
import { PlayIcon } from "lucide-react";

const sceneCache = new Map();

Expand Down Expand Up @@ -83,6 +84,23 @@ const navigateMultiplayer = async (
};
};

function playAudios(scene) {
const audios = scene.components.filter((c) => c.type === "audio");
const playables = [];
for (const audio of audios) {
const playable = new Audio(audio.url);
playable.loop = audio.loop;
playable.play();
playables.push(playable);
}
return () => {
for (const p of playables) {
p.pause();
p.currentTime = 0;
}
};
}

/**
* This page allows users to play a scenario.
*
Expand All @@ -107,6 +125,7 @@ export default function PlayScenarioPage({ group }) {

const [resourcesOpen, setResourcesOpen] = useState(false);
const [noteOpen, setNoteOpen] = useState(false);
const [audioAllowed, setAudioAllowed] = useState(false);

const currScene = sceneCache.get(sceneId);

Expand Down Expand Up @@ -284,6 +303,16 @@ export default function PlayScenarioPage({ group }) {
onSceneChange();
};

useEffect(() => {
if (!currScene || !audioAllowed) return;
try {
const endPlayback = playAudios(currScene);
return () => endPlayback();
} catch {
toast.error("The audio on this scene failed to play");
}
}, [currScene, audioAllowed]);

if (loading) return <LoadingPage text="Loading Scene..." />;
if (authError) return <></>;
if (isMultiplayer && !group) return <LoadingPage text="Loading Scene..." />;
Expand All @@ -305,6 +334,14 @@ export default function PlayScenarioPage({ group }) {
/>
</div>
)}
{!audioAllowed && (
<div className="absolute top-4 left-4 z-30">
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Not familiar with this part of the code, why is there a z-30 here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i think to make sure its always on top when it comes to elements on the screen, but yea not the best way. I approved incase we want this for the milestone

<button className="btn" onClick={() => setAudioAllowed(true)}>
<PlayIcon size={16} />
Enable Audio
</button>
</div>
)}
<PlayScenarioCanvas
scene={currScene}
incrementor={isMultiplayer ? incrementor : undefined}
Expand Down
Loading