From e2d1b006fee20edea5f568f723a0045e352bf9ce Mon Sep 17 00:00:00 2001 From: dylan <> Date: Mon, 22 Apr 2024 19:52:11 -0700 Subject: [PATCH] fix the bugs with skipping --- src/client/app.tsx | 6 ++-- src/client/player/DialogText.tsx | 49 ++++++++++++++++++++++++-------- src/client/player/Player.tsx | 19 +++++++------ tsconfig.json | 1 + 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/client/app.tsx b/src/client/app.tsx index aeead01..6d4086a 100644 --- a/src/client/app.tsx +++ b/src/client/app.tsx @@ -13,9 +13,11 @@ calvin (mathstruck) "Wow, did you know that $a^2+b^2=c^2$?" calvin (thinking) "Something else" -bridget (surprised) "Me again" +bridget (surprised) "Me again000000" -kit (smiling) "I'm Kit!" +kit (smiling) "I'm Kit 1!" + +kit (smiling) "I'm Kit 2!" board "" diff --git a/src/client/player/DialogText.tsx b/src/client/player/DialogText.tsx index 8b13ad8..f82b993 100644 --- a/src/client/player/DialogText.tsx +++ b/src/client/player/DialogText.tsx @@ -1,26 +1,51 @@ -import { useEffect, useLayoutEffect, useState } from "react"; +import { ForwardedRef, forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react"; import { MathText } from "./MathText"; -export const DialogText = (props: {children: string, onFinish?: () => void}) => { - const {children: str, onFinish} = props; +export type DialogTextImperatives = { + skip(): void; +} + +export const DialogText = forwardRef((props: {children: string, speed?: number, onFinish?: () => void}, forwardedRef: ForwardedRef) => { + const {children: str, onFinish, speed = 15} = props; const [len, setLen] = useState(0); + const interval = useRef(null); + + useImperativeHandle(forwardedRef, () => { + return { + skip() { + setLen(str.length); + } + } + }, [str, setLen]); useLayoutEffect(() => { setLen(0); }, [str]); useEffect(() => { - const interval = setInterval(() => { - setLen(l => Math.max(l+1, str.length)); - }, 70); - if (len === str.length) { - // clearInterval(interval); - onFinish && onFinish(); - } + interval.current = setInterval(() => { + setLen(l => { + return Math.min(l+1, str.length) + }); + }, 1000/speed); return () => { - clearInterval(interval); + if (interval.current) { + clearInterval(interval.current as any); + interval.current = null; + } }; }, [str, setLen]); + useLayoutEffect(() => { + if (len === str.length) { + if (interval.current) { + clearInterval(interval.current as any); + interval.current = null; + } + console.log("onFinish"); + onFinish && onFinish(); + } + }, [len]); + return {str.slice(0, len)} -} \ No newline at end of file +}); \ No newline at end of file diff --git a/src/client/player/Player.tsx b/src/client/player/Player.tsx index b0a0f49..ae9c110 100644 --- a/src/client/player/Player.tsx +++ b/src/client/player/Player.tsx @@ -3,7 +3,7 @@ import { Mathuscript, parseMathuscript } from "./parse"; import { useCallback, useMemo, useRef, useState } from "react"; import { MathText } from "./MathText"; import { characterData } from "./data"; -import { DialogText } from "./DialogText"; +import { DialogText, DialogTextImperatives } from "./DialogText"; type VisualState = { turn: number, @@ -45,7 +45,6 @@ const afterStep = (state: VisualState, step: Mathuscript[number]): VisualState = dialog.emotion = char.emotion; dialog.text = step.text; } - console.log(newState); return newState; } @@ -65,16 +64,18 @@ export const MathuscriptPlayer = (props: { script: string }) => { const [index, setIndex] = useState(0); const [visualState, setVisualState] = useState({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, emotion: "", text: ""}}); const dialogGoing = useRef(false); + const dialogTextRef = useRef(null); const doStep = useCallback(() => { + goAgain.current = false; if (dialogGoing.current) { - console.log("dialog running"); + if (dialogTextRef.current) { + dialogTextRef.current.skip(); + } return; } - goAgain.current = false; const step = parsedScript[index]; if (step) { - console.log(step); setIndex(i => i+1); setVisualState(state => afterStep(state, step)); if (step.name === "board") { @@ -87,6 +88,10 @@ export const MathuscriptPlayer = (props: { script: string }) => { } }, [index, parsedScript, setIndex, setVisualState]); + const onDialogFinish = useCallback(() => { + dialogGoing.current = false; + }, []); + if (goAgain.current) { doStep(); } @@ -218,9 +223,7 @@ export const MathuscriptPlayer = (props: { script: string }) => { `}> {speakingChar.displayName} {visualState.dialog.emotion && ({visualState.dialog.emotion})} - { - dialogGoing.current = false; - }}> + {visualState.dialog.text} diff --git a/tsconfig.json b/tsconfig.json index 8036425..8f3d69f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "target": "es2017", "module": "es2022", + "lib": ["DOM"], "moduleResolution": "node", "jsx": "react-jsx", "allowImportingTsExtensions": true,