fix the bugs with skipping
This commit is contained in:
		@@ -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 ""
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
}
 | 
			
		||||
});
 | 
			
		||||
@@ -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>
 | 
			
		||||
							</>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user