All files / lib/components/Game/Screen/FreeForm/Page/Block/InputText index.tsx

0% Statements 0/24
0% Branches 0/8
0% Functions 0/5
0% Lines 0/24

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 99 100 101 102                                                                                                                                                                                                           
import React from 'react';
import { css } from '@emotion/react';
import {
  InputTextBlock as InputTextBlockModel,
  InputTextBlockStyle
} from '@uniquegood/realworld-web-interface/lib/models/game/Block/InputText';
import { useGameStateContext } from '@lib/providers/GameState';
import produce from 'immer';
import { useRunStatement } from '@lib/utils/Game/Statement';
import { useContentAnalyticsContext } from '@lib/providers/ContentAnalytics';
import { useGameParameterContext } from '@lib/providers/GameParameter';
 
export default function InputTextBlock({ placeholder, actionMap, style, id }: InputTextBlockModel) {
  const { consumeEvent } = useContentAnalyticsContext();
 
  const { gameStateRef, render, saveOnServer } = useGameStateContext();
  const { runStatement } = useRunStatement();
  const { parameterMapRef } = useGameParameterContext();
  // const isProcessingRef = React.useRef(false);
 
  async function handleChangeText(value: string) {
    // if (isProcessingRef.current) return;
    // isProcessingRef.current = true;
 
    parameterMapRef.current = produce(parameterMapRef.current, (draft) => {
      if (!draft[`block-${id}`]) {
        draft[`block-${id}`] = {};
      }
      if (!draft[`block-${id}`].changeText) {
        draft[`block-${id}`].changeText = {};
      }
      draft[`block-${id}`]!.changeText!.input = {
        value,
        type: 'string'
      };
 
      return draft;
    });
 
    const statementList = actionMap.changeText?.statementList;
    if (statementList) {
      // CA: 사용자 텍스트 입력 이벤트
      consumeEvent({
        eventType: 'UserInput',
        metadata: {
          currentScreen: gameStateRef.current.currentScreenId,
          blockId: id,
          inputText: value
        }
      });
 
      for await (const statement of statementList) {
        await runStatement({
          statement,
          withParameter: {
            blockId: id,
            originActionType: 'changeText'
          }
        });
      }
      saveOnServer();
      render();
    }
 
    // isProcessingRef.current = false;
  }
 
  const containerStyle = React.useMemo(() => {
    const styleObj = InputTextBlockStyle.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};
      &::placeholder {
        color: ${styleObj.placeholderColor};
      }
    `;
  }, [style]);
 
  return (
    <input
      type="text"
      css={[defaultInputTextWrap, containerStyle]}
      placeholder={placeholder || '텍스트를 입력해주세요.'}
      onChange={(e) => handleChangeText(e.target.value)}
    />
  );
}
 
const defaultInputTextWrap = css`
  width: 100%;
  height: 100%;
  border-style: solid;
  padding: 0 12px;
  outline: none;
`;