Added Chatting between users
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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 (
|
||||||
|
<div className="v-layout p-6">
|
||||||
|
<Icon icon="mdi:arrow-left" className="back-button" onClick={() => navigate(-1)} />
|
||||||
|
<div className="flex flex-col flex-1">
|
||||||
|
<h1>Learning Partners</h1>
|
||||||
|
</div>
|
||||||
|
{fakeUsers.map((user: any, index: any) => (
|
||||||
|
<div className="user-card" key={index} onClick={
|
||||||
|
() => handleUserClick(user)
|
||||||
|
}>
|
||||||
|
<div>
|
||||||
|
<div className="w-20 h-20 mx-auto mb-2 p-2 rounded-full border-2 border-dashed border-gray-300 relative">
|
||||||
|
<span className="text-2xl uppercase font-semibold text-gray-400 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">{user.name[0]}</span>
|
||||||
|
</div>
|
||||||
|
<h2>{user.name}</h2>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<p className="font-bold ml-2">Interests</p>
|
||||||
|
<div className="user-interests">
|
||||||
|
{user.interests.map((interest: any, i: any) => (
|
||||||
|
<span className="user-interest" key={i}>{interest}</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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<Message[]>([]);
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
|
||||||
|
const messageEndRef = useRef<HTMLDivElement>(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 (
|
||||||
|
<div className="flex flex-col h-screen">
|
||||||
|
<div className="flex-grow overflow-y-auto p-6">
|
||||||
|
<div className="top-part">
|
||||||
|
<Icon icon="mdi:arrow-left" className="back-button" onClick={() => navigate(-1)} />
|
||||||
|
<div>
|
||||||
|
<div className="w-40 h-40 mx-auto mb-2 p-4 rounded-full border-2 border-dashed border-gray-300 relative">
|
||||||
|
<span className="text-4xl uppercase font-semibold text-gray-400 absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">{user.name[0]}</span>
|
||||||
|
</div>
|
||||||
|
<h2 className='font-bold'>{user.name}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="chat-area">
|
||||||
|
{messages.length === 0 ? (
|
||||||
|
<p className='subtext'>Say hi to your chat partner and introduce yourself!</p>
|
||||||
|
) : (
|
||||||
|
messages.map((message, index) => (
|
||||||
|
<div key={index} className={`message ${message.sender}`}>
|
||||||
|
<p>{message.text}</p>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
<div ref={messageEndRef} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between p-3 bg-white">
|
||||||
|
<input
|
||||||
|
className='flex-1 mr-3'
|
||||||
|
type="text"
|
||||||
|
value={message}
|
||||||
|
onChange={(e) => setMessage(e.target.value)}
|
||||||
|
placeholder='Type a message...'
|
||||||
|
/>
|
||||||
|
<button className="w-auto" onClick={handleSendClick}>
|
||||||
|
<Icon icon="mdi:send" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user