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; `; |