echo-web/frontend/src/App.tsx
2022-08-09 14:51:09 +01:00

60 lines
2.3 KiB
TypeScript

import { AppShell, Box, Button, Grid, Group, Input, Stack, TextInput } from "@mantine/core"
import { useState, createRef, useEffect } from "react"
import { useDispatch, useSelector } from "react-redux"
import ChannelList from "./components/ChannelList"
import Header from "./components/Header"
import MemberList from "./components/MemberList"
import Message from "./components/Message"
import { chatActions } from "./slices/chat"
import { RootState } from "./store"
function App() {
const [opened, setOpened] = useState(false);
const [message, setMessage] = useState("");
const dispatch = useDispatch();
const isConnected = useSelector((state: RootState) => state.chat.isConnected);
const currentChannel = useSelector((state: RootState) => state.chat.currentChannel);
const messages = useSelector((state: RootState) => state.chat.messages);
const messagesEndRef = createRef<HTMLDivElement>();
const chatDisabled = currentChannel === null || !isConnected;
const sendMessage = () => {
dispatch(chatActions.sendMessage({ content: message }));
setMessage("");
}
useEffect(() => {
messagesEndRef.current?.scrollIntoView();
}, [messages]);
return (
<AppShell
padding={0}
navbarOffsetBreakpoint="sm"
navbar={<ChannelList hidden={!opened} />}
header={<Header opened={opened} setOpened={setOpened} />}
aside={<MemberList />}
>
<Stack sx={{ height: "calc(100vh - 60px)", maxHeight: "calc(100vh - 60px)" }} spacing={0}>
<Stack sx={{ overflowY: "scroll", flexGrow: 1 }} p="md">
{messages.map((msg, i) => (
<Message key={`msg${i}`} message={msg} />
))}
<div ref={messagesEndRef} />
</Stack>
<Group p="md" sx={(theme) => ({ borderTop: `1px solid ${theme.colorScheme === 'dark' ? theme.colors.dark[5] : theme.colors.gray[2]}` })}>
<TextInput sx={{ flexGrow: 1 }} placeholder="Message" disabled={chatDisabled} value={message} onChange={(event) => setMessage(event.target.value)} onKeyUp={(event) => {
if (event.key === "Enter") {
sendMessage();
}
}}/>
<Button disabled={chatDisabled} onClick={() => sendMessage()}>Send</Button>
</Group>
</Stack>
</AppShell>
)
}
export default App