fix the bugs with skipping

This commit is contained in:
dylan 2024-04-22 19:52:11 -07:00
parent f4e55a2257
commit e2d1b006fe
4 changed files with 53 additions and 22 deletions

View File

@ -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 ""

View File

@ -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<DialogTextImperatives>) => {
const {children: str, onFinish, speed = 15} = props;
const [len, setLen] = useState(0);
const interval = useRef<unknown>(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 <MathText>{str.slice(0, len)}</MathText>
}
});

View File

@ -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<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, emotion: "", text: ""}});
const dialogGoing = useRef(false);
const dialogTextRef = useRef<DialogTextImperatives>(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 }) => {
`}>
<strong>{speakingChar.displayName}</strong> {visualState.dialog.emotion && <em>({visualState.dialog.emotion})</em>}
</div>
<DialogText onFinish={() => {
dialogGoing.current = false;
}}>
<DialogText onFinish={onDialogFinish} ref={dialogTextRef}>
{visualState.dialog.text}
</DialogText>
</>

View File

@ -2,6 +2,7 @@
"compilerOptions": {
"target": "es2017",
"module": "es2022",
"lib": ["DOM"],
"moduleResolution": "node",
"jsx": "react-jsx",
"allowImportingTsExtensions": true,