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

100% Statements 28/28
100% Branches 5/5
100% Functions 5/5
100% Lines 27/27

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 1041x   1x 1x     1x 1x 1x 1x 1x 1x           1x                   87x                       32x         87x   87x   87x     87x           87x 3x 3x 3x     87x 41x 1x 1x       87x                         39x 39x                                      
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),
}));
 
export 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 } = useForm<MessageFormData>();
 
  const [persistedMessage, setPersistedMessage, clearPersistedMessage] =
    usePersistedState(
      `messages.${currentUserId}.${chatId}`,
      "",
      "sessionStorage",
    );
 
  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}
      >
        {t("global:send")}
      </StyledButton>
    </StyledForm>
  );
}