elseifplayer/src/components/Player/OutputBox/GridBuffer/GridBuffer.jsx

79 lines
1.9 KiB
JavaScript

import { useEffect, useState } from 'preact/hooks'
import TextMessage from '../TextMessage/TextMessage'
import * as s from '../../Player.module.scss'
export default function GridBuffer ({ inbox, currentWindow }) {
const [prevMessages, setPrevMessages] = useState([])
const [messages, setMessages] = useState([])
useEffect(() => {
const currentInboxObj =
inbox.find(({ id }) =>
id === currentWindow.id)
const currentInbox = currentInboxObj?.lines ?? []
const newOrPrev = (cur, prev) => (i) => {
const byId = (list, i) =>
list.find(({ line }) => line === i)
return byId(cur, i) || byId(prev, i)
}
const rawMessages =
Array(currentWindow.gridheight)
.fill(null)
.map((_, i) => i)
.map(newOrPrev(currentInbox, prevMessages))
/* */
const shouldUpdatePrev = (rawMessages, prevMessages) => {
const serialize = JSON.stringify
return serialize(rawMessages) !== serialize(prevMessages)
}
if (shouldUpdatePrev(rawMessages, prevMessages)) {
setPrevMessages(rawMessages)
}
/* */
const rawMessagesContent =
rawMessages
.map((x) => x.content)
.flat()
.map((message) => ({
...message,
text: message.text.trim(),
}))
const isEmpty =
rawMessagesContent
.map(({ text }) => text.length)
.every((l) => l === 0)
const getGridStyle = ({ style }) => {
if (['alert', 'normal'].includes(style)) return 'grid'
return style || 'grid'
}
const messages =
rawMessagesContent
.map((message) => ({
style: getGridStyle(message),
text: message.text.replace(' ', ' / '),
}))
setMessages(isEmpty ? [] : messages)
}, [inbox, currentWindow, prevMessages])
return (
<section className={[s.buffer, s.gridBuffer].join(' ')}>
{messages.map(TextMessage)}
</section>
)
}