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

100% Statements 29/29
100% Branches 9/9
100% Functions 6/6
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 1012x   2x 2x     2x 2x 2x 2x 2x           207x       207x                         42x         207x   207x   207x     207x           207x   207x 8x 8x 8x     207x 140x 2x 2x       207x                         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";
 
interface MessageFormData {
  text: string;
}
 
const StyledButton = styled(Button)<ButtonProps>(() => ({
  flexShrink: 0,
}));
 
const StyledForm = styled("form")(({ theme }) => ({
  alignItems: "center",
  display: "flex",
  gap: theme.spacing(1),
  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: "var(--mui-palette-background-paper)" }}
      />
 
      <StyledButton
        type="submit"
        variant="contained"
        color="primary"
        onClick={onSubmit}
        loading={isPending}
        disabled={!messageText.trim() || isPending}
      >
        {t("global:send")}
      </StyledButton>
    </StyledForm>
  );
}