/** * @file Story toast notification component for new chapter unlocks. * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ /* eslint-disable react/no-multi-comp -- Sub-component is tightly coupled to the toast container */ import { STORY_CHAPTERS } from "@elysium/types"; import { type JSX, useEffect } from "react"; import { useGame } from "../../context/gameContext.js"; interface StoryToastItemProperties { readonly chapterId: string; } /** * Renders a single story chapter toast notification. * @param props - The toast item properties. * @param props.chapterId - The chapter ID to display. * @returns The JSX element or null if chapter is not found. */ const StoryToastItem = ({ chapterId, }: StoryToastItemProperties): JSX.Element | null => { const { dismissStoryChapter } = useGame(); const chapter = STORY_CHAPTERS.find((storyChapter) => { return storyChapter.id === chapterId; }); useEffect(() => { const timer = setTimeout(() => { dismissStoryChapter(chapterId); }, 4000); return (): void => { clearTimeout(timer); }; }, [ chapterId, dismissStoryChapter ]); if (chapter === undefined) { return null; } function handleClick(): void { dismissStoryChapter(chapterId); } return (
{"📖"}
{"✨ New Chapter!"} {chapter.title}
); }; /** * Renders the story toast container with pending chapter notifications. * @returns The JSX element or null if there are no pending chapters. */ const StoryToast = (): JSX.Element | null => { const { unlockedStoryChapterIds: pendingChapterIds } = useGame(); if (pendingChapterIds.length === 0) { return null; } return ( <> {pendingChapterIds.map((id) => { return ; })} ); }; export { StoryToast };