React Simple-Keyboard in Spanish but linking to English physical keyboard

83 Views Asked by At

I have a react project where I am properly displaying different react simple-keyboards such as Spanish. It is properly sending the data to an input field in Spanish. The problem is my physical keyboard is American so when I enable physicalKeyboardHighlight={true} it successfully highlights any letter that exists in both English and Spanish but not the key in the same physical location. When I try using physicalKeyboardHighlightPress={true} it doesn't seem to do anything, probably because my real keyboard is not a Spanish keyboard.

export default function PEConstructedResponse({ data, setReportedRung, rungName }) {
  const [response, setResponse] = useState("");
  const [disableResponding, setDisableResponding] = useState(false);

  // get the current language from the store
  const defaultRTL = useSelector((state) => state.gui.defaultRTL) ? "rtl" : "ltr";
  const currentLanguage = useSelector((state) => state.gui.activeLanguage);
  const dir = useSelector((state) => state.gui.rtl) ? "rtl" : "ltr";
  const keyboardRef = useRef()

  const [showKeyboard, setShowKeyboard] = useState(false);

  //this check allows for a variety of variables to go into place for deciding if the submit button is disabled or not. May be updated to be based off of word count instead of character count in future.
  function checkDisableSubmit() {
    //if not allowed to respond then return true
    if (disableResponding) return true;
    //if response is undefined or null then return true
    if (typeof response == "undefined" || response == null) return true;
    //if less words than minimum. 100 words would have 99 spaces
    if (response.split(" ").length < 100) return true;
  }

  function setSubmitSyle() {
    if (!checkDisableSubmit()) {
      return {
        background: "linear-gradient(#694c87, #422f54)",
        borderColor: "black",
        borderStyle: "solid",
        borderRadius: "4px",
        color: "white",
      };
    }

    return {
      backgroundColor: "#ccc",
      borderColor: "black",
      borderStyle: "solid",
      borderRadius: "4px",
      color: "black",
    };
  }

  const handleKeyPress = (e) => {
    console.log("clicked: ", e);
    // console.log("keyboardRef.current: ", keyboardRef.current)
    // keyboardRef.current.onKeyPress(e.key);
  }

  function displayEmail() {
    return (
      <div className={styles.wrapper}>
        <PEAMHeadings header_type="browser" />

        <div className={`${styles.header} d-flex flex-row p-3`}>
          <div className="pe-cr-header-submit">
            <Button
              style={setSubmitSyle()}
              id={"pe-cr-header-submit-button"}
              className="d-flex flex-column align-items-center justify-content-center gap-1"
              onClick={() => {
                submitResponse();
              }}
              disabled={checkDisableSubmit()}
            >
              <SendIcon fontSize="medium" /> Send
            </Button>
          </div>

          <div className="pe-cr-header-recipients flex-grow-1 d-flex flex-column">
            <div className="d-flex flex-row mx-3 mb-2 align-items-center">
              <div>
                <Badge
                  bg="secondary text-dark"
                  className={styles.emailBadge}
                >
                  To
                </Badge>
              </div>
              <div className={`${styles.emailTextBar} flex-grow-1`}>
                <p className="m-0">[email protected]</p>
              </div>
            </div>

            <div className="d-flex flex-row mx-3 align-items-center">
              <div>
                <Badge
                  bg="secondary text-dark"
                  className={styles.emailBadge}
                >
                  Subject
                </Badge>
              </div>
              <div className={`${styles.emailTextBar} flex-grow-1`}>
                <p className="m-0">{data.content.subject}</p>
              </div>
            </div>
          </div>
        </div>
        <div className={styles.contentArea}>
          <div
            className={styles.npcQuoteArea}
            dir={dir}
            style={{
              color: "black",
              unicodeBidi: "bidi-override",
            }}
            dangerouslySetInnerHTML={{ __html: data.content.prompt }}
          ></div>
          <div className={styles.response}>
            <textarea
              className={styles.responseInput}
              type="text"
              value={response}
              // onChange={(evt) => handleInput(evt.target.value)}
              readOnly={true}
              onKeyDown={(e) => {handleKeyPress(e)}}
              rows={5}
              placeholder="Type your reply here"
              disabled={disableResponding}
              dir={defaultRTL}
            />
            {showKeyboard && (
              <UserKeyboard
                ref={(ref) => (keyboardRef.current = ref)}
                input={response}
                setInput={setResponse}
                tl={currentLanguage}
              />
            )}
            <button
              onClick={(e) => {
                setShowKeyboard(!showKeyboard);
              }}
            >
              <KeyboardIcon />
            </button>
          </div>
        </div>
      </div>
    );
  }

  function displayFeedback() {
    return (
      <>
        <div
          className="container p-3 rounded"
          style={{ backgroundColor: "rgba(0,0,0,.3)" }}
        >
          <div
            className="bg-white p-3"
            dir={dir}
            dangerouslySetInnerHTML={{ __html: data.content.response }}
          ></div>
        </div>
        <div className="d-flex flex-row justify-content-center w-100 mt-3">
          <PillButton
            btnType={"Continue"}
            func={() => endCR()}
          />
        </div>
      </>
    );
  }

  function endCR() {
    setReportedRung(rungName);
  }

  function submitResponse() {
    setDisableResponding(true);
  }

  return (
    <>
      <div className="d-flex flex-column h-100 py-3">
        <div className="h-100 container-md">
          <Row className="h-100">
            <Col className="d-flex flex-column justify-content-center h-100">
              {!disableResponding ? displayEmail() : displayFeedback()}
            </Col>
          </Row>
        </div>
      </div>
    </>
  );
}
const UserKeyboard = forwardRef(({ input, setInput, tl="EN" }, ref) => {
  const [layout, setLayout] = useState("default");
  const defaultRTL = useSelector((state) => state.gui.defaultRTL);
  const tlKeyboard = useSelector((state) => state.gui.tlKeyboard)

  const handleShift = () => {
    const newLayoutName = layout === "default" ? "shift" : "default";
    setLayout(newLayoutName);
  }

  const onKeyPress = (button) => {
    console.log("button pressed: ", button)

    /**
     * If you want to handle the shift and caps lock buttons
     */
    if (button === "{shift}" || button === "{lock}") {
      handleShift();
      return;
    } else if(button === "{tab}") {
      return;
    } else if(button === "{bksp}") {
      setInput(input.substring(0, input.length-1))
    } else if(button === "{space}") {
      setInput(input.concat(" "))
    } else {
      setInput(input.concat(button))
    }
  }

  const newLetter = (letter) => {
    console.log("new letter is: ", letter)
  }

  useImperativeHandle(ref, () => ({
    onKeyPress,
    newLetter
  }))

  return <div>
    <Keyboard
      layout={tl == "EN" ? "" : tlKeyboard.layout}
      rtl={tl == "EN" ? false : defaultRTL ? true : false}
      layoutName={layout}
      onKeyPress={(e) => onKeyPress(e)}
      physicalKeyboardHighlight={true}
    />
  </div>
})

My goal is when I click the ; key on my American keyboard I would get an n with a tilde over top of it. Also this gathering of the keyboard input should only take place when the input field has focus but the default "physicalKeyboardHighlight" appears to completely ignore any need for focus.

I've tried making it so when the input field has onKeyDown={(e) => {handleKeyPress(e)}} that it could send call the same onKeyPress function I have linked to the keyboard but due to the fact that it's sending American keys instead of Spanish keys it's not aware of how to handle it.

0

There are 0 best solutions below