import { h } from 'preact' import { useEffect, useRef, useState } from 'preact/hooks' import TextMessage from './TextMessage' const trimInputPrompt = messages => messages.length < 1 ? messages : messages.slice(-1)[0].text === '>' ? messages.slice(0, messages.length - 1) : messages const parseInbox = (inbox, currentWindow) => { const currentInbox = inbox.find(({ id }) => id === currentWindow.id) if (!currentInbox) { return { clear: false, incoming: [] } } const { clear, text: inboxMessagesRaw } = currentInbox const eol = { style: 'endOfLine' } const incoming = inboxMessagesRaw /* Normalize. */ .map(({ content }) => content ? [...trimInputPrompt(content), eol] : [eol]) /* Flatten. */ .reduce((acc, x) => acc.concat(x), []) return { clear, incoming } } export default function ({ inbox, currentWindow }) { const [messages, setMessages] = useState([]) const textBufferEl = useRef(null) useEffect(() => { const { incoming, clear } = parseInbox(inbox, currentWindow) setMessages(clear ? incoming : messages.concat(incoming)) setTimeout(() => { const inputs = textBufferEl.current.querySelectorAll('.message.input') const lastInput = inputs[inputs.length - 1] textBufferEl.current.scrollTop = lastInput ? lastInput.offsetTop : textBufferEl.current.scrollHeight * 2 }, 0) }, [inbox]) return (
{messages.map(TextMessage)}
) }