All files / lib/components/Game/Screen/FreeForm/Page/Block/InputNumber 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 103 104 105 106                                                                                                                                                                                                                   
import React from 'react';
import { css } from '@emotion/react';
import {
  InputNumberBlock as InputNumberBlockModel,
  InputNumberBlockStyle
} from '@uniquegood/realworld-web-interface/lib/models/game/Block/InputNumber';
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 InputNumberBlock({
  placeholder,
  actionMap,
  style,
  id
}: InputNumberBlockModel) {
  const { consumeEvent } = useContentAnalyticsContext();
 
  const { gameStateRef, render, saveOnServer } = useGameStateContext();
  const { runStatement } = useRunStatement();
  const { parameterMapRef } = useGameParameterContext();
  // const isProcessingRef = React.useRef(false);
 
  async function handleChangeText(value: number) {
    // if (isProcessingRef.current) return;
    // isProcessingRef.current = true;
 
    parameterMapRef.current = produce(parameterMapRef.current, (draft) => {
      if (!draft[`block-${id}`]) {
        draft[`block-${id}`] = {};
      }
      if (!draft[`block-${id}`].changeNumber) {
        draft[`block-${id}`].changeNumber = {};
      }
      draft[`block-${id}`]!.changeNumber!.input = {
        value,
        type: 'number'
      };
 
      return draft;
    });
 
    const statementList = actionMap.changeNumber?.statementList;
    if (statementList) {
      // CA: 사용자 텍스트 입력 이벤트
      consumeEvent({
        eventType: 'UserInput',
        metadata: {
          currentScreen: gameStateRef.current.currentScreenId,
          blockId: id,
          inputNumber: `${value}` // FIXME: number는 못보냄
        }
      });
 
      for await (const statement of statementList) {
        await runStatement({
          statement,
          withParameter: {
            blockId: id,
            originActionType: 'changeNumber'
          }
        });
      }
      saveOnServer();
      render();
    }
    // isProcessingRef.current = false;
  }
 
  const containerStyle = React.useMemo(() => {
    const styleObj = InputNumberBlockStyle.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="number"
      css={[defaultInputNumberWrap, containerStyle]}
      placeholder={placeholder || '텍스트를 입력해주세요.'}
      onChange={(e) => handleChangeText(e.target.valueAsNumber)}
    />
  );
}
 
const defaultInputNumberWrap = css`
  width: 100%;
  height: 100%;
  border-style: solid;
  padding: 0 12px;
  outline: none;
`;