import * as React from "react"; import {useContext, useEffect, useState} from "react"; import {Registry} from "tc-shared/events"; import { PrivateConversationInfo, PrivateConversationUIEvents } from "tc-shared/ui/frames/side/PrivateConversationDefinitions"; import {ContextDivider} from "tc-shared/ui/react-elements/ContextDivider"; import {ConversationPanel} from "./AbstractConversationRenderer"; import {LoadingDots} from "tc-shared/ui/react-elements/LoadingDots"; import {AvatarRenderer} from "tc-shared/ui/react-elements/Avatar"; import {TimestampRenderer} from "tc-shared/ui/react-elements/TimestampRenderer"; import {Translatable} from "tc-shared/ui/react-elements/i18n"; import {getGlobalAvatarManagerFactory} from "tc-shared/file/Avatars"; const cssStyle = require("./PrivateConversationRenderer.scss"); const kTypingTimeout = 5000; const HandlerIdContext = React.createContext(undefined); const EventContext = React.createContext>(undefined); const ConversationEntryInfo = React.memo((props: { chatId: string, initialNickname: string, lastMessage: number }) => { const events = useContext(EventContext); const [ nickname, setNickname ] = useState(props.initialNickname); const [ lastMessage, setLastMessage ] = useState(props.lastMessage); const [ typingTimestamp, setTypingTimestamp ] = useState(0); events.reactUse("notify_partner_name_changed", event => { if(event.chatId !== props.chatId) { return; } setNickname(event.name); }); events.reactUse("notify_partner_changed", event => { if(event.chatId !== props.chatId) { return; } setNickname(event.name); }); events.reactUse("notify_chat_event", event => { if(event.chatId !== props.chatId) { return; } if(event.event.type === "message") { if(event.event.timestamp > lastMessage) { setLastMessage(event.event.timestamp); } if(!event.event.isOwnMessage) { setTypingTimestamp(0); } } else if(event.event.type === "partner-action" || event.event.type === "local-action") { setTypingTimestamp(0); } }); events.reactUse("notify_conversation_state", event => { if(event.chatId !== props.chatId || event.state !== "normal") { return; } let lastStatedMessage = event.events .filter(e => e.type === "message") .sort((a, b) => a.timestamp - b.timestamp) .last()?.timestamp; if(typeof lastStatedMessage === "number" && (typeof lastMessage === "undefined" || lastStatedMessage > lastMessage)) { setLastMessage(lastStatedMessage); } }); events.reactUse("notify_partner_typing", event => { if(event.chatId !== props.chatId) { return; } setTypingTimestamp(Date.now()); }); const isTyping = Date.now() - kTypingTimeout < typingTimestamp; useEffect(() => { if(!isTyping) { return; } const timeout = setTimeout(() => { setTypingTimestamp(0); }, kTypingTimeout); return () => clearTimeout(timeout); }); let lastMessageContent; if(isTyping) { lastMessageContent = Typing ; } else if(lastMessage === 0) { lastMessageContent = No messages; } else { lastMessageContent = ; } return (
{nickname} {lastMessageContent}
); }); const ConversationEntryUnreadMarker = React.memo((props: { chatId: string, initialUnread: boolean }) => { const events = useContext(EventContext); const [ unread, setUnread ] = useState(props.initialUnread); events.reactUse("notify_unread_state_changed", event => { if(event.chatId !== props.chatId) { return; } setUnread(event.unread); }); if(!unread) { return null; } return
; }); const ConversationEntry = React.memo((props: { info: PrivateConversationInfo, selected: boolean }) => { const events = useContext(EventContext); const handlerId = useContext(HandlerIdContext); const [ clientId, setClientId ] = useState(props.info.clientId); events.reactUse("notify_partner_changed", event => { if(event.chatId !== props.info.chatId) return; props.info.clientId = event.clientId; setClientId(event.clientId); }); const avatarFactory = getGlobalAvatarManagerFactory().getManager(handlerId); return (
events.fire("action_select_chat", { chatId: props.info.chatId })} >
{ events.fire("action_close_chat", { chatId: props.info.chatId }); }} />
); }); const OpenConversationsPanel = React.memo(() => { const events = useContext(EventContext); const [ conversations, setConversations ] = useState(() => { events.fire("query_private_conversations"); return "loading"; }); const [ selected, setSelected ] = useState("unselected"); events.reactUse("notify_private_conversations", event => { setConversations(event.conversations); setSelected(event.selected); }); events.reactUse("notify_selected_chat", event => { setSelected(event.chatId); }); let content; if(conversations === "loading") { content = (
loading
); } else if(conversations.length === 0) { content = (
You dont have any chats yet!
); } else { content = conversations.map(e => ) } return (
{content}
); }); export const PrivateConversationsPanel = (props: { events: Registry, handlerId: string }) => (
);