import { Hash, HashedObject, MutableObject, MutationEvent, Resources } from '@hyper-hyper-space/core'; import { ChatSpace, Conversation, Message, Profile } from '@hyper-hyper-space/home'; import { useObjectDiscoveryIfNecessary, useObjectState } from '@hyper-hyper-space/react'; import { Avatar, Button, Chip, IconButton, Stack, TextField, Typography } from '@mui/material'; import CircularProgress from '@mui/material/CircularProgress'; import { Box } from '@mui/system'; import { Fragment, useEffect, useRef, useState } from 'react'; import { DateUtils } from '../../model/DateUtils'; import { ProfileUtils } from '../../model/ProfileUtils'; import { AllChatsNav } from './AllChats'; function Chat(props: {onClose: () => void, chatWidth: string, noSummary: boolean, identityHash?: Hash, conv?: Conversation, chats: ChatSpace, resources: Resources, resourcesForDiscovery: Resources, nav: AllChatsNav}) { const remoteId = props.conv?.getRemoteIdentity(); const profileHash = new Profile(remoteId).hash(); const [loadedProfile, setLoadedProfile] = useState(); const discoveredProfile = useObjectDiscoveryIfNecessary(props.resourcesForDiscovery, profileHash, loadedProfile); const [profile, setProfile] = useState(); const profileState = useObjectState(profile); const convState = useObjectState(props.conv, {filterMutations: (ev: MutationEvent) => MutableObject.isContentChangeEvent(ev)}); useEffect(() => { const loadRemoteProfile = async () => { if (props.conv === undefined) { setLoadedProfile(undefined); } else { //const remoteId = props.conv?.getRemoteIdentity(); //profile = await props.resources.store.load(new Profile(remoteId).hash(), true, true) as Profile; const profile = await props.resources.store.load(profileHash, true, true) as Profile; setLoadedProfile(profile); } }; loadRemoteProfile(); }, [profileHash]); useEffect(() => { let profile = discoveredProfile; if (profile !== undefined) { const profileHash = profile.hash(); if (!profile.isWatchingForChanges()) { props.resources.store.save(profile).then(() => { props.resources.store.load(profileHash, true, true).then((loadedProfile?: HashedObject) => { profile = loadedProfile as Profile; profile.startSync(); setProfile(profile) }); }); } else { profile.startSync(); setProfile(profile); } return () => { profile?.stopSync(); } } }, [discoveredProfile]); const contact = profileState?.getValue() === undefined ? undefined : ProfileUtils.createContact(profileState?.getValue() as Profile); const name = profileState?.getValue()?.owner?.info?.name === undefined? '' : (profileState?.getValue()?.owner?.info?.name as string).trim().split(' ')[0]; const messages = convState?.getValue()?.getSortedMessages() || []; const [newMessage, setNewMessage] = useState(''); const newMessageChanged = (e: React.ChangeEvent) => { setNewMessage(e.currentTarget.value); } const post = () => { if (props.conv !== undefined && newMessage.trim().length > 0) { // add conversation to chat space if not already there (i.e. this is its first message) if (!props.chats.conversations?.hasByHash(props.conv?.getLastHash())) { props.chats.conversations?.add(props.conv as Conversation); props.chats.conversations?.save(); } props.conv?.post(newMessage); setNewMessage(''); } }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { e.preventDefault(); post(); } } const chatEndRef = useRef(null); useEffect(() => { chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }); }); useEffect(() => { if (convState?.value !== undefined) { if (convState?.value._unreadMessages.size > 0) { convState?.value.markAsRead(); } } }, [convState]); return ( {props.noSummary && } {props.nav.viewProfile(props.identityHash as Hash)}}>{contact?.picture !== undefined && } {contact?.picture === undefined && {contact?.initials || ''} } {contact?.name || ''}
{(convState?.getValue()?.getSortedMessages() || []).map((m: Message, idx: number) => { const ownMessage = m.getAuthor()?.getLastHash() === props.conv?.getLocalIdentity().getLastHash(); const delivered = !ownMessage || !props.conv?._unconfirmedMessages.has(m.getLastHash()); const prevMessage = idx>0? convState?.getValue()?.getSortedMessages()[idx-1] : undefined; const dateNotice = (prevMessage === undefined) || (prevMessage !== undefined && !DateUtils.sameDay(new Date(prevMessage.timestamp as number), new Date(m.timestamp as number)))? DateUtils.formatDay(m.timestamp as number) : undefined; return {dateNotice && {dateNotice} } {ownMessage && You}{!ownMessage && {name}} {m.content || ''} {!delivered && } {DateUtils.getHourAndMinutes(new Date(m.timestamp as number))} })}
{/*{Array(100).fill(1).map(() => ( You: How's it going Micah? Micah: It's all good ))}*/}
{props.conv && }
); } export default Chat;