import type { Chat, Message as MessageType } from '../../graphql/schema/chat.gen' import type { Author } from '../../graphql/schema/core.gen' import { clsx } from 'clsx' import { For, createSignal, Show, onMount, createEffect, createMemo, on } from 'solid-js' import { useInbox } from '../../context/inbox' import { useLocalize } from '../../context/localize' import { useSession } from '../../context/session' import { useRouter } from '../../stores/router' import { showModal } from '../../stores/ui' import { Icon } from '../_shared/Icon' import { Popover } from '../_shared/Popover' import SimplifiedEditor from '../Editor/SimplifiedEditor' import CreateModalContent from '../Inbox/CreateModalContent' import DialogCard from '../Inbox/DialogCard' import DialogHeader from '../Inbox/DialogHeader' import { Message } from '../Inbox/Message' import MessagesFallback from '../Inbox/MessagesFallback' import Search from '../Inbox/Search' import { Modal } from '../Nav/Modal' import styles from '../../styles/Inbox.module.scss' type InboxSearchParams = { initChat: string chat: string } const userSearch = (array: Author[], keyword: string) => { return array.filter((value) => new RegExp(keyword.trim(), 'gi').test(value.name)) } const handleOpenInviteModal = () => { showModal('inviteToChat') } export const InboxView = () => { const { t } = useLocalize() const { chats, messages, actions: { loadChats, loadRecipients, getMessages, sendMessage, createChat }, } = useInbox() const [recipients, setRecipients] = createSignal([]) const [sortByGroup, setSortByGroup] = createSignal(false) const [sortByPerToPer, setSortByPerToPer] = createSignal(false) const [currentDialog, setCurrentDialog] = createSignal() const [messageToReply, setMessageToReply] = createSignal(null) const [isClear, setClear] = createSignal(false) const [isScrollToNewVisible, setIsScrollToNewVisible] = createSignal(false) const { author } = useSession() const currentUserId = createMemo(() => author()?.id) const { changeSearchParams, searchParams } = useRouter() const messagesContainerRef: { current: HTMLDivElement } = { current: null, } // Поиск по диалогам const getQuery = (query) => { if (query().length >= 2) { const match = userSearch(recipients(), query()) setRecipients(match) } else { // setRecipients(cashedRecipients()) } } const handleOpenChat = async (chat: Chat) => { setCurrentDialog(chat) changeSearchParams({ chat: chat.id, }) try { await getMessages(chat.id) } catch (error) { console.error('[getMessages]', error) } finally { messagesContainerRef.current.scroll({ top: messagesContainerRef.current.scrollHeight, behavior: 'instant', }) } } onMount(async () => { try { const response = await loadRecipients() // time ago in seconds setRecipients(response as unknown as Author[]) } catch (error) { console.log(error) } await loadChats() }) const handleSubmit = async (message: string) => { await sendMessage({ body: message, chat_id: currentDialog()?.id.toString(), reply_to: messageToReply()?.id, }) setClear(true) setMessageToReply(null) messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight setClear(false) } createEffect(async () => { if (searchParams().chat) { const chatToOpen = chats()?.find((chat) => chat.id === searchParams().chat) if (!chatToOpen) return await handleOpenChat(chatToOpen) return } if (searchParams().initChat) { try { const newChat = await createChat([Number(searchParams().initChat)], '') await loadChats() changeSearchParams({ initChat: null, chat: newChat.chat.id, }) const chatToOpen = chats().find((chat) => chat.id === newChat.chat.id) await handleOpenChat(chatToOpen) } catch (error) { console.error(error) } } }) const chatsToShow = () => { const sorted = chats().sort((a, b) => { return b.updated_at - a.updated_at }) if (sortByPerToPer()) { return sorted.filter((chat) => (chat.title || '').trim().length === 0) } else if (sortByGroup()) { return sorted.filter((chat) => (chat.title || '').trim().length > 0) } else { return sorted } } const findToReply = (messageId) => { return messages().find((message) => message.id === messageId) } createEffect( on( () => messages(), () => { if (!messagesContainerRef.current) { return } if (messagesContainerRef.current.scrollTop >= messagesContainerRef.current.scrollHeight) { return } messagesContainerRef.current.scroll({ top: messagesContainerRef.current.scrollHeight, behavior: 'smooth', }) }, ), { defer: true }, ) const handleScrollMessageContainer = () => { if ( messagesContainerRef.current.scrollHeight - messagesContainerRef.current.scrollTop > messagesContainerRef.current.clientHeight * 1.5 ) { setIsScrollToNewVisible(true) } else { setIsScrollToNewVisible(false) } } const handleScrollToNew = () => { messagesContainerRef.current.scroll({ top: messagesContainerRef.current.scrollHeight, behavior: 'smooth', }) setIsScrollToNewVisible(false) } return (
{(chat) => ( handleOpenChat(chat)} isOpened={chat.id === currentDialog()?.id} members={chat.members} ownId={currentUserId()} lastUpdate={chat.updated_at} counter={chat.unread} message={chat.messages.pop()?.body} /> )}
} >
{(triggerRef: (el) => void) => (
)}
(messagesContainerRef.current = el)} onScroll={handleScrollMessageContainer} > {(message) => ( setMessageToReply(message)} /> )} {/*
*/} {/* */} {/*
*/}

FIXME: messageToReply

{/* member.id === Number(messageToReply().author))*/} {/* .name*/} {/* }*/} {/* body={messageToReply().body}*/} {/* cancel={() => setMessageToReply(null)}*/} {/*/>*/}
handleSubmit(message)} submitByCtrlEnter={true} />
) }