From f89cf12ab34f8c348e25f8ef331692c21f5d6a47 Mon Sep 17 00:00:00 2001 From: Yue Fung Lee Date: Fri, 1 Dec 2023 00:46:24 -0500 Subject: [PATCH] Added Chatting between users --- frontend/src/logic/fakeUsers.ts | 40 ++++++++++++ frontend/src/pages/FakeUserSelection.sass | 29 +++++++++ frontend/src/pages/FakeUserSelection.tsx | 47 ++++++++++++++ frontend/src/pages/UserChat.tsx | 75 +++++++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 frontend/src/logic/fakeUsers.ts create mode 100644 frontend/src/pages/FakeUserSelection.sass create mode 100644 frontend/src/pages/FakeUserSelection.tsx create mode 100644 frontend/src/pages/UserChat.tsx diff --git a/frontend/src/logic/fakeUsers.ts b/frontend/src/logic/fakeUsers.ts new file mode 100644 index 0000000..343c6c9 --- /dev/null +++ b/frontend/src/logic/fakeUsers.ts @@ -0,0 +1,40 @@ +export const target_interests = [ + "gaming", "cooking", "sci-fi", "sports", "music", "programming", "first-person shooters", "painting", "baking", "astronomy", "archery" +] + +export const target_names = [ + "John", "Mary", "Bob", "Alice", "Jane", "Frank", "Sally", "Jack", "Jill", "Joe", "Sue" +] + +interface User { + name: string; + interests: string[]; +} + +export function generateFakeUsers(interests: string[]): User[] { + let fakeUsers = []; + const randomNumber = Math.floor(Math.random() * target_names.length) + 1; + + for (let i = 0; i < randomNumber; i++) { + const randomName = target_names[Math.floor(Math.random() * target_names.length)]; + const randomNumberOfInterests = Math.floor(Math.random() * target_interests.length) + 1; + const randomInterests: string[] = []; + for (let j = 0; j < 3; j++) { + const randomInterest = target_interests[Math.floor(Math.random() * target_interests.length)]; + if (!randomInterests.includes(randomInterest)) { + randomInterests.push(randomInterest); + } + } + + // add a random interest from the user's interests + const randomInterest = interests[Math.floor(Math.random() * interests.length)]; + if (!randomInterests.includes(randomInterest)) { + randomInterests.push(randomInterest); + } + + const newUser = { name: randomName, interests: randomInterests }; + fakeUsers.push(newUser); + } + + return fakeUsers; +} \ No newline at end of file diff --git a/frontend/src/pages/FakeUserSelection.sass b/frontend/src/pages/FakeUserSelection.sass new file mode 100644 index 0000000..5c61a4a --- /dev/null +++ b/frontend/src/pages/FakeUserSelection.sass @@ -0,0 +1,29 @@ +@import "../index" + +.user-card + display: flex + align-items: center + justify-content: space-between + margin: 10px + border: solid $c-green + border-radius: 20px + padding: 10px + + +.user-interests + display: flex + flex-direction: row + flex-wrap: wrap + gap: 5px + padding: 5px + +.user-interest + background-color: $c-green + color: white + border-radius: 20px + padding: 5px 10px + margin: 0 + display: flex + align-items: center + justify-content: space-between + height: 30px \ No newline at end of file diff --git a/frontend/src/pages/FakeUserSelection.tsx b/frontend/src/pages/FakeUserSelection.tsx new file mode 100644 index 0000000..f8cc007 --- /dev/null +++ b/frontend/src/pages/FakeUserSelection.tsx @@ -0,0 +1,47 @@ +import { useNavigate, useLocation } from "react-router-dom" +import { Icon } from '@iconify/react'; +import "./FakeUserSelection.sass"; +import { startHumanChat } from "../logic/sdk"; + +export default function FakeUserSelection() { + + const navigate = useNavigate(); + const location = useLocation(); + const { fakeUsers, interests } = location.state; + + const handleUserClick = (user: any) => { + startHumanChat(interests, user.name, user.interests).then((sessionId) => { + console.log(sessionId); + navigate('/user-chat', { state: { user: user, sessionId: sessionId } }); + }) + } + + return ( +
+ navigate(-1)} /> +
+

Learning Partners

+
+ {fakeUsers.map((user: any, index: any) => ( +
handleUserClick(user) + }> +
+
+ {user.name[0]} +
+

{user.name}

+
+
+

Interests

+
+ {user.interests.map((interest: any, i: any) => ( + {interest} + ))} +
+
+
+ ))} +
+ ) +} \ No newline at end of file diff --git a/frontend/src/pages/UserChat.tsx b/frontend/src/pages/UserChat.tsx new file mode 100644 index 0000000..19ac848 --- /dev/null +++ b/frontend/src/pages/UserChat.tsx @@ -0,0 +1,75 @@ +import { useLocation, useNavigate } from 'react-router-dom'; +import { Icon } from '@iconify/react'; +import { useState, useRef, useEffect } from 'react'; +import { humanChatMessage } from '../logic/sdk'; + +export default function Character() { + const location = useLocation(); + const navigate = useNavigate(); + const { user, sessionId } = location.state; + + type Message = { text: string, sender: string }; + const [messages, setMessages] = useState([]); + const [message, setMessage] = useState(''); + + const messageEndRef = useRef(null); + + const scrollToBottom = () => { + messageEndRef.current?.scrollIntoView({ behavior: "smooth" }) + } + + useEffect(() => { + scrollToBottom() + }, [messages]); + + const handleSendClick = () => { + if (message !== '') { + setMessages(prevMessages => [...prevMessages, { text: message, sender: 'me' }]); + setMessage(''); + humanChatMessage(sessionId, message).then((response) => { + setMessages(prevMessages => [...prevMessages, { text: response.msg, sender: 'other' }]); + }) + } + + } + + return ( +
+
+
+ navigate(-1)} /> +
+
+ {user.name[0]} +
+

{user.name}

+
+
+
+ {messages.length === 0 ? ( +

Say hi to your chat partner and introduce yourself!

+ ) : ( + messages.map((message, index) => ( +
+

{message.text}

+
+ )) + )} +
+
+
+
+ setMessage(e.target.value)} + placeholder='Type a message...' + /> + +
+
+ ) +} \ No newline at end of file