Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /* eslint-disable react/no-array-index-key */
import React, { useContext, useEffect, useRef } from 'react';
import { css } from '@emotion/react';
import {
ButtonBlock as ButtonBlockModel,
ButtonBlockStyle,
supportActionList as buttonBlockSupportActionList
} from '@uniquegood/realworld-web-interface/lib/models/game/Block/Button';
import { useGameStateContext } from '@lib/providers/GameState';
import { useRunStatement } from '@lib/utils/Game/Statement';
export default function ButtonBlock({ id, actionMap, style, contents }: ButtonBlockModel) {
const { render, saveOnServer } = useGameStateContext();
const { runStatement } = useRunStatement();
const buttonRef = useRef<HTMLButtonElement | null>(null);
const isProcessingRef = useRef(false);
useEffect(() => {
const listeners = buttonBlockSupportActionList.reduce((arr, action) => {
const statementList = actionMap[action]?.statementList;
if (statementList && buttonRef.current) {
const listener = async () => {
if (isProcessingRef.current) {
return;
}
isProcessingRef.current = true;
for await (const statement of statementList) {
await runStatement({
statement,
withParameter: {
blockId: id,
originActionType: action
}
});
}
saveOnServer();
render();
isProcessingRef.current = false;
};
buttonRef.current.addEventListener(`${action}`, listener);
arr.push({ type: action, listener });
}
return arr;
}, [] as { type: string; listener: () => unknown }[]);
return () => {
listeners.forEach(({ type, listener }) => {
if (!buttonRef.current || !type) {
return;
}
buttonRef.current.removeEventListener(type, listener);
});
};
}, []);
const containerStyle = React.useMemo(() => {
const styleObj = ButtonBlockStyle.parse(style);
return css`
text-align: ${styleObj.align};
background-color: ${styleObj.backgroundColor};
border-width: ${styleObj.borderWidth}px;
border-color: ${styleObj.borderColor};
border-radius: ${styleObj.borderRadius}px;
font-size: ${styleObj.fontSize}px;
color: ${styleObj.fontColor};
font-family: ${styleObj.fontFamily};
font-weight: ${styleObj.isBold ? 'bold' : 'normal'};
font-style: ${styleObj.isItalic ? 'italic' : 'normal'};
text-decoration: ${styleObj.isUnderline ? 'underline' : 'none'};
`;
}, [style]);
return (
<button ref={buttonRef} type="button" css={[buttonStyle, containerStyle]}>
<p
style={{
textAlign: style.align
}}
>
{contents}
</p>
</button>
);
}
const buttonStyle = css`
width: 100%;
height: 100%;
border: none;
white-space: pre-line;
cursor: pointer;
padding: 8px 12px;
border-radius: 8px;
`;
|