Skip to content

Commit

Permalink
Co-authored-by: Lesaun Harvey <[email protected]>
Browse files Browse the repository at this point in the history
Co-authored-by: Eric Wheeler <[email protected]>
  • Loading branch information
pwnedzen committed Nov 24, 2021
1 parent df832c4 commit dd35282
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 43 deletions.
31 changes: 22 additions & 9 deletions components/converse/ChatBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ import Menu from "@mui/material/Menu";
import { Conversation, Line, LineConversation } from "../../models";
import { DataStore } from "aws-amplify";

interface Props {
speakers: (string | null)[] | undefined;
activeSpeaker: string | undefined;
setActiveSpeaker: React.Dispatch<React.SetStateAction<string | undefined>>;
conversation: Conversation;
}

const saveLine = async (conversation: Conversation, text: string, activeSpeaker: string) => {
const line = await DataStore.save(
new Line({
Expand All @@ -32,6 +25,13 @@ const saveLine = async (conversation: Conversation, text: string, activeSpeaker:
);
};

interface Props {
speakers: (string | null)[] | undefined;
activeSpeaker: string | undefined;
setActiveSpeaker: React.Dispatch<React.SetStateAction<string | undefined>>;
conversation: Conversation;
}

export default function ChatBox({
speakers,
activeSpeaker,
Expand All @@ -40,15 +40,22 @@ export default function ChatBox({
}: Props) {
const [text, setText] = React.useState("");
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);

const open = Boolean(anchorEl);

const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};

const handleClose = () => {
setAnchorEl(null);
};

const sendText = () => {
if (activeSpeaker === undefined) { return }
saveLine(conversation, text, activeSpeaker)
setText("")
}

return (
<Paper
component="form"
Expand Down Expand Up @@ -87,11 +94,17 @@ export default function ChatBox({
<InputBase
value={text}
onChange={(e) => setText(e.target.value)}
onKeyPress={(e) => {
if (e.key === 'Enter') {
sendText();
e.preventDefault();
}
}}
sx={{ ml: 1, flex: 1 }}
inputProps={{ "aria-label": "speak as speaker" }}
/>
<IconButton color="primary"
onClick={() => activeSpeaker !== undefined ? saveLine(conversation, text, activeSpeaker) : null}
onClick={sendText}
sx={{ p: "10px" }} aria-label="Send Chat">
<SendIcon />
</IconButton>
Expand Down
38 changes: 25 additions & 13 deletions components/converse/ChatWindow.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// A react component that renders a chat window with different colors for speakers and left and right sides.
import React from "react";
import React, { useEffect, useRef, useState } from "react";
import Paper from "@mui/material/Paper";
import { Conversation } from "../../models";
import { LineConversation, Conversation, Line } from "../../models";
import { DataStore } from "aws-amplify";

const Chat = ({ align, text, color }: any) => {
return (
Expand Down Expand Up @@ -29,27 +30,37 @@ const Chat = ({ align, text, color }: any) => {
};

interface Props {
conversation: Conversation | undefined;
activeSpeaker: String | undefined;
lineConversations: LineConversation[];
}

const ChatWindow = ({ conversation, activeSpeaker }: Props) => {
const ChatWindow = ({ lineConversations, activeSpeaker }: Props) => {
const el = useRef<null | HTMLDivElement>(null);

const scrollToBottom = () => {
el.current?.scrollIntoView()
}

useEffect(() => {
scrollToBottom()
}, [lineConversations]);

return (
<div>
{conversation !== undefined && activeSpeaker !== undefined
? conversation.lines !== undefined
? conversation.lines.map((conversationLine, i: number) =>
conversationLine ? (
<div style={{maxHeight: "calc(100% - 64px)", overflow: "scroll"}}>
{activeSpeaker !== undefined
? lineConversations !== undefined
? lineConversations.map((lineConversation, i: number) =>
lineConversation ? (
<Chat
key={conversationLine.line.speaker + i.toString()}
key={lineConversation.line.speaker + i.toString()}
align={
conversationLine.line.speaker === activeSpeaker
lineConversation.line.speaker === activeSpeaker
? "left"
: "right"
}
text={conversationLine.line.text}
text={lineConversation.line.text}
color={
conversationLine.line.speaker === activeSpeaker
lineConversation.line.speaker === activeSpeaker
? "white"
: "lightgreen"
}
Expand All @@ -58,6 +69,7 @@ const ChatWindow = ({ conversation, activeSpeaker }: Props) => {
)
: null
: null}
<div ref={el} />
</div>
);
};
Expand Down
88 changes: 67 additions & 21 deletions pages/converse.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,44 @@
import React, { useEffect, useState } from "react";
import Amplify, { DataStore, Predicates } from "aws-amplify";
import React, { useEffect, useState } from 'react';
import Amplify, { DataStore, Predicates, syncExpression } from 'aws-amplify';
import { AmplifyAuthenticator } from '@aws-amplify/ui-react';

import type { NextPage } from "next";
import Head from "next/head";
import type { NextPage } from 'next';
import Head from 'next/head';

import { AmplifyAuthenticator } from "@aws-amplify/ui-react";
import awsconfig from "../aws-exports";
import awsconfig from '../aws-exports';

import ChatActions from "../components/converse/ChatActions";
import ConversationCreateForm from "../components/converse/ConversationCreateForm";
import ChatWindow from "../components/converse/ChatWindow";
import ConversationList from "../components/converse/ConversationList";
import ChatActions from '../components/converse/ChatActions';
import ConversationCreateForm from '../components/converse/ConversationCreateForm';
import ChatWindow from '../components/converse/ChatWindow';
import ConversationList from '../components/converse/ConversationList';

import styles from "../styles/Converse.module.css";
import { Conversation } from "../models";
import styles from '../styles/Converse.module.css';
import { Conversation, Line, LineConversation } from '../models';

Amplify.configure(awsconfig);
DataStore.start()

const Converse: NextPage = () => {
const [lines, setLines] = useState<Line[]>([]);
const [conversations, setConversations] = useState<Conversation[]>([]);
const [selectedConversationId, setSelectedConversationId] = useState("");
const [lineConversations, setLineConversations] = useState<LineConversation[]>([]);

const [lineById, setLineById] = useState<Record<string,Line>>({});
const [conversationById, setConversationById] = useState<Record<string,Conversation>>({});

const [selectedConversationId, setSelectedConversationId] = useState('');
const [selectedConversation, setSelectedConversation] =
useState<Conversation>();
const [activeSpeaker, setActiveSpeaker] = useState<string | undefined>();

const setSelectedConversationWithId = (id: string | null) => {
if (id === null) {
setSelectedConversation(undefined)
setSelectedConversationId("")
setActiveSpeaker(undefined)
setSelectedConversation(undefined);
setSelectedConversationId('');
setActiveSpeaker(undefined);
} else {
setSelectedConversationId(id);
if (id !== "") {
if (id !== '') {
for (let i = 0; i < conversations.length; i++) {
if (conversations[i].id === id) {
setSelectedConversation(conversations[i]);
Expand All @@ -50,12 +57,51 @@ const Converse: NextPage = () => {
).subscribe((snapshot) => {
const { items } = snapshot;
setConversations(items);
const newItemsById: any = {}
items.forEach(item => { newItemsById[item.id] = item})
setConversationById({ ...conversationById, ...newItemsById })
});
return () => subscription.unsubscribe();
}, []);

useEffect(() => {
const subscription = DataStore.observeQuery(
Line,
Predicates.ALL
).subscribe((snapshot) => {
const { items } = snapshot;
setLines(items);
const newItemsById: any = {}
items.forEach(item => { newItemsById[item.id] = item})
setLineById({ ...lineById, ...newItemsById })
});
return () => subscription.unsubscribe();
}, []);

console.log(conversations);

useEffect(() => {
const subscription = DataStore.observeQuery(
LineConversation,
Predicates.ALL
).subscribe((snapshot) => {
const { items } = snapshot;
setLineConversations(items);
const newItemsById: any = {}
items.forEach(item => { newItemsById[item.id] = item })
});
return () => subscription.unsubscribe();
}, []);

const lineConversationsWithObjects : any = lineConversations
.filter((lc: any) =>
lc.conversationID === selectedConversationId ||
(lc.conversation !== undefined && lc.conversation.id === selectedConversationId))
.map((lc: any) =>
lc.hasOwnProperty("conversationID") && lc.hasOwnProperty("lineID") &&
(!lc.hasOwnProperty("line") || !lc.hasOwnProperty("conversation"))
? { ...lc, line: lineById[lc.lineID], conversation: conversationById[lc.conversationID] }
: lc)
.filter(lc => lc.hasOwnProperty("line") && lc.hasOwnProperty("conversation"))

return (
<AmplifyAuthenticator>
<div className={styles.container}>
Expand All @@ -77,8 +123,8 @@ const Converse: NextPage = () => {
) : (
<>
<ChatWindow
conversation={selectedConversation}
activeSpeaker={activeSpeaker}
lineConversations={lineConversationsWithObjects}
/>
<ChatActions
conversation={selectedConversation}
Expand All @@ -94,4 +140,4 @@ const Converse: NextPage = () => {
);
};

export default Converse
export default Converse;

0 comments on commit dd35282

Please sign in to comment.