Untitled
unknown
typescript
5 years ago
5.5 kB
10
Indexable
import React, { useRef, useState } from "react";
import { useLocation } from "react-router-dom";
import { WriteTextControls } from "../../../reducers/interfaceData/types";
import { connect, ConnectedProps } from "react-redux";
import { useEffectOnce, useKeyPressEvent } from "react-use";
// @ts-ignore
import { composedWithMarkupTraps } from "../../../hocs/withMarkupTraps/withMarkupTraps";
// @ts-ignore
import { Button } from "../../Button";
import { WithMarkUpTrapsProps } from "../../../hocs/withMarkupTraps/types";
import useMobileDetect from "../../../customHooks/useMobileDetect";
import "./index.pcss";
type RootState = {
interfaceData: {
ui: {
writeTextControls: WriteTextControls;
};
};
};
const mapState = ({
interfaceData: {
ui: { writeTextControls },
},
}: RootState) => ({
writeTextControls,
});
const connector = connect(mapState);
type PropsFromRedux = ConnectedProps<typeof connector>;
type HotKeys = string[];
type Props = PropsFromRedux & {
hotKeys: HotKeys;
renderMarkupTrapButton: ({ onClick, disabled }: WithMarkUpTrapsProps) => void;
onConfirm: (text: string, markAsTrap?: boolean) => void;
buttonText: string;
placeholder: string;
};
const SUBMIT_KEY = "Enter";
const WriteTextControls = ({ writeTextControls, hotKeys, onConfirm, buttonText, placeholder, renderMarkupTrapButton }: Props) => {
const textAreaRef = useRef<HTMLTextAreaElement>(null);
const [text, setText] = useState("");
const { isMobile } = useMobileDetect();
const { state } = useLocation<{ id: string }>();
const [withLowerCase, setWithLowerCase] = useState(false);
useKeyPressEvent(SUBMIT_KEY, () => onEnter());
useEffectOnce(() => checkForLoweCase());
const onEnter = () => {
if (!isUserWroteText()) {
return;
}
onConfirm(getText());
handleResetText();
setFocusOnTextArea();
};
const checkForLoweCase = () => {
if (!writeTextControls.options || !writeTextControls.options.withLowerCase || !writeTextControls.options.withLowerCase.length) {
return;
}
const { id } = state;
return setWithLowerCase(Boolean(writeTextControls.options.withLowerCase.find((gameId) => gameId === id)));
};
const renderHotKeys = (hotKeys: string[]) => {
if (!hotKeys || !hotKeys.length) {
return null;
}
const getTextWithHotKey = (cursorPosition: number, hotKey: string) => {
return [text.slice(0, cursorPosition).concat(hotKey), text.slice(cursorPosition)].join("");
};
const onClick = (e: React.MouseEvent<HTMLButtonElement>, hotKey: string) => {
e.preventDefault();
const cursorPosition = textAreaRef?.current?.selectionStart;
if (cursorPosition) {
const text = getTextWithHotKey(cursorPosition, hotKey);
setText(text);
}
};
return hotKeys.map((hotKey) => (
<Button
key={hotKey}
classNames="write-text-controls__hotKey"
clickHandler={(e: React.MouseEvent<HTMLButtonElement>) => onClick(e, hotKey)}
text={hotKey}
/>
));
};
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setText(e.target.value);
};
const handleResetText = () => {
setText("");
};
const setFocusOnTextArea = () => {
textAreaRef?.current?.focus();
};
const getText = () => {
if (withLowerCase) {
return text.toLowerCase();
}
return text;
};
const isUserWroteText = () => {
return text.trim().length;
};
const setInitialSettings = () => {
handleResetText();
setFocusOnTextArea();
};
const onClick = (e: React.MouseEvent<HTMLButtonElement>, markAsTrap?: boolean) => {
e.preventDefault();
onConfirm(getText(), markAsTrap);
setInitialSettings();
};
const onAltClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
onConfirm("");
setInitialSettings();
};
return (
<div className="write-text-controls">
<form className="write-text-controls__form">
{renderHotKeys(hotKeys || writeTextControls.quotes)}
<textarea
ref={textAreaRef}
onChange={handleChange}
className="write-text-controls__textarea"
cols={10}
rows={2.5}
placeholder={placeholder || writeTextControls.placeholder}
value={text}
autoFocus={!isMobile}
/>
<Button
classNames="write-text-controls__button write-text-controls__button--with-margin-bottom"
clickHandler={onClick}
disabled={!isUserWroteText()}
text={writeTextControls.ready}
/>
<Button classNames="write-text-controls__button" clickHandler={onAltClick} text={buttonText || writeTextControls.noText} />
</form>
{renderMarkupTrapButton({
onClick: (e: React.MouseEvent<HTMLButtonElement>) => onClick(e, true),
disabled: false,
})}
</div>
);
};
export default connector(composedWithMarkupTraps(WriteTextControls));Editor is loading...