All files / app/features/messages/groupchats GroupChatSendField.tsx

100% Statements 29/29
100% Branches 9/9
100% Functions 5/5
100% Lines 28/28

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 1072x   2x 2x     2x 2x 2x 2x 2x 2x           2x                   209x                       42x         209x   209x   209x     209x           209x   209x 8x 8x 8x     209x 140x 2x 2x       209x                         136x 136x                                        
import { ButtonProps, styled } from "@mui/material";
import { UseMutationResult } from "@tanstack/react-query";
import Button from "components/Button";
import TextField from "components/TextField";
import { Empty } from "google-protobuf/google/protobuf/empty_pb";
import { RpcError } from "grpc-web";
import { useTranslation } from "i18n";
import { GLOBAL, MESSAGES } from "i18n/namespaces";
import { usePersistedState } from "platform/usePersistedState";
import React from "react";
import { useForm } from "react-hook-form";
import { theme } from "theme";
 
interface MessageFormData {
  text: string;
}
 
const StyledButton = styled(Button)<ButtonProps>({
  display: "block",
  flexShrink: 0,
  marginInlineStart: theme.spacing(1),
  height: theme.spacing(5),
  marginBottom: 0,
  marginTop: "auto",
  alignItems: "center",
});
 
const StyledForm = styled("form")(({ theme }) => ({
  alignItems: "flex-start",
  display: "flex",
  marginTop: theme.spacing(3),
}));
 
interface GroupChatSendFieldProps {
  sendMutation: UseMutationResult<string | undefined | Empty, RpcError, string>;
  chatId: number;
  currentUserId: number;
}
 
export default function GroupChatSendField({
  sendMutation,
  chatId,
  currentUserId,
}: GroupChatSendFieldProps) {
  const { t } = useTranslation([GLOBAL, MESSAGES]);
 
  const { mutate: handleSend, isPending } = sendMutation;
 
  const { register, handleSubmit, reset, watch } = useForm<MessageFormData>();
 
  const [persistedMessage, setPersistedMessage, clearPersistedMessage] =
    usePersistedState(
      `messages.${currentUserId}.${chatId}`,
      "",
      "sessionStorage",
    );
 
  const messageText = watch("text", persistedMessage ?? "");
 
  const onSubmit = handleSubmit(async (data: MessageFormData) => {
    handleSend(data.text.trimEnd());
    clearPersistedMessage();
    reset({ text: "" });
  });
 
  const handleKeyDown = (event: React.KeyboardEvent) => {
    if (event.key === "Enter" && event.ctrlKey) {
      event.preventDefault();
      onSubmit();
    }
  };
 
  const { onChange: textOnChange, ...textRegisterRest } = register("text");
 
  return (
    <StyledForm onSubmit={onSubmit}>
      <TextField
        id="group-chat-message-field"
        {...textRegisterRest}
        label={t("messages:chat_input.label")}
        defaultValue={persistedMessage ?? ""}
        multiline
        fullWidth
        onKeyDown={handleKeyDown}
        onChange={(event) => {
          setPersistedMessage(event.target.value);
          textOnChange(event);
        }}
        maxRows={4}
        size="small"
        sx={{ background: theme.palette.common.white }}
      />
 
      <StyledButton
        type="submit"
        variant="contained"
        color="primary"
        onClick={onSubmit}
        loading={isPending}
        disabled={!messageText.trim() || isPending}
      >
        {t("global:send")}
      </StyledButton>
    </StyledForm>
  );
}