frontend/src/chat/ChatInput.tsx

170 lines
4.7 KiB
TypeScript

import {
Box,
Grid2 as Grid,
IconButton,
TextareaAutosize,
Theme,
Typography,
useTheme
} from "@mui/material";
import { useGlobalState, useNoteAPI, useSnackbar } from "providers";
import React, { useState } from "react";
import { Note } from "models";
import { pond } from "protobuf-ts/pond";
import { makeStyles } from "@mui/styles";
import { ArrowUpward } from "@mui/icons-material";
const useStyles = makeStyles((theme: Theme) => ({
textAreaBox: {
width: "100%",
padding: theme.spacing(1.5),
paddingTop: theme.spacing(0.75),
},
textAreaClass: {
resize: "none",
padding: theme.spacing(2),
paddingRight: theme.spacing(7),
backgroundColor: theme.palette.background.paper,
borderColor: theme.palette.background.default,
color: theme.palette.text.primary,
borderRadius: "5px",
width: "100%",
fontFamily: theme.typography.fontFamily,
fontSize: theme.typography.body2.fontSize,
'&:focus': {
outline: "none",
boxShadow: "none",
borderColor: "ActiveBorder",
}
}
}))
interface Props {
parent: string;
newNoteMethod: (note: Note) => void;
parentType: string; // the object type the note is for ie "bin", "team" etc.
type?: pond.NoteType;
}
/**
* renders the text area to enter you message and the button to submit it
* @returns text area to enter your message
*/
export default function ChatInput(props: Props) {
const [message, setMessage] = useState("");
const classes = useStyles();
const { parent, type, parentType } = props;
const [{ user }] = useGlobalState();
const noteAPI = useNoteAPI();
const { openSnack } = useSnackbar();
const [shift, setShift] = useState(false);
const theme = useTheme();
// const [uploadedFiles, setUploadedFiles] = useState<Map<string, string>>(new Map());
const clearEntry = () => {
setMessage("");
};
const onKeyDown = (event: any) => {
if (event.key === "Shift") {
setShift(true);
}
if (event.key === "Enter" && !shift) {
event.preventDefault();
}
};
const onKeyUp = (event: any) => {
if (event.key === "Shift") {
setShift(false);
}
if (event.key === "Enter" && !shift) {
validateMessage();
}
};
const validateMessage = () => {
let valid = false;
let i = 0;
while (!valid && i < message.length) {
if (message[i] !== " " && message[i] !== "\n" && message[i] !== undefined) {
valid = true;
}
i++;
}
valid ? submit() : openSnack("Invalid Message");
clearEntry();
// setUploadedFiles(new Map());
};
const submit = () => {
if (message !== "" && message !== "\n") {
let newNote = Note.create();
newNote.settings.objectKey = parent;
newNote.settings.userId = user.id();
if (type) {
newNote.settings.objectType = type;
}
newNote.settings.timestamp = Date.now();
newNote.settings.content = message;
noteAPI
.addNote(newNote.settings, undefined, [parent], [parentType])
.then(resp => {
newNote.settings.key = resp.data.note
props.newNoteMethod(newNote);
openSnack("Message Sent");
})
.catch(_err => {
console.error(_err)
openSnack("Message Failed to send");
});
}
clearEntry();
};
const getPlaceholder = () => {
if (type === pond.NoteType.NOTE_TYPE_TEAM) return "Message team..."
return "Type to chat..."
}
return (
<React.Fragment>
<Grid
container
direction="row-reverse"
alignItems="center"
alignContent="center"
justifyContent="space-between"
spacing={1}
style={{ marginTop: theme.spacing(1) }}>
<Grid size={{ xs: 12 }} >
<Box className={classes.textAreaBox}>
<Box style={{ position: "relative", display: "inline-block", width: "100%" }}>
<TextareaAutosize
value={message}
className={classes.textAreaClass}
onChange={e => setMessage(e.target.value)}
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
placeholder={getPlaceholder()}
/>
<Box
style={{
position: "absolute",
right: theme.spacing(1),
top: "50%",
transform: "translateY(-50%)",
}}
>
<IconButton onClick={validateMessage}>
<ArrowUpward/>
</IconButton>
</Box>
</Box>
</Box>
</Grid>
</Grid>
{/* <Typography>{Array.from(uploadedFiles.values()).toString()}</Typography> */}
</React.Fragment>
);
}