Rearrange components

This commit is contained in:
He4eT 2023-06-03 22:50:37 +03:00 committed by Alexey
commit daa26965cd
16 changed files with 14 additions and 11 deletions

View file

@ -0,0 +1,79 @@
import { h } from 'preact'
import { useEffect, useState } from 'preact/hooks'
import TextMessage from './TextMessage'
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'
else return style || 'grid'
}
const messages =
rawMessagesContent
.map((message) => ({
style: getGridStyle(message),
text: message.text.replace(' ', ' / '),
}))
setMessages(isEmpty ? [] : messages)
}, [inbox, currentWindow, prevMessages])
return (
<section
className='buffer gridBuffer'>
{messages.map(TextMessage)}
</section>
)
}

View file

@ -0,0 +1,93 @@
import { h } from 'preact'
import { useEffect, useRef, useState } from 'preact/hooks'
import TextMessage from './TextMessage'
const isFakeStatus = (w) =>
w.height < 5
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 { 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 {
incoming,
clear: isFakeStatus(currentWindow)
? true
: currentInbox.clear,
}
}
export default function TextBuffer ({ inbox, currentWindow }) {
const [messages, setMessages] = useState([])
const textBufferEl = useRef(null)
useEffect(() => {
const { incoming, clear } =
parseInbox(inbox, currentWindow)
setMessages((messages) => clear
? incoming
: messages.concat(incoming))
setTimeout(() => {
const inputs =
textBufferEl.current.querySelectorAll('.message.input')
const lastInput =
inputs[inputs.length - 1]
textBufferEl.current.scrollTo({
top: lastInput
? lastInput.offsetTop
: textBufferEl.current.scrollHeight,
behavior: 'smooth',
})
}, 0)
}, [currentWindow, inbox])
const classes = [
isFakeStatus(currentWindow)
? 'gridBuffer'
: 'textBuffer',
'buffer'].join(' ')
return (
<section
tabindex='0'
ref={textBufferEl}
className={classes}>
{messages.map(TextMessage)}
</section>
)
}

View file

@ -0,0 +1,16 @@
import { h } from 'preact'
export default function TextMessage ({ style, text }) {
const defaultContent = (
<span className={['message', style].join(' ')}>
{text}
</span>)
return ({
grid: (text?.length > 0 ? <div>{text}</div> : <br />),
input: (<span className='message input'>&gt; {text}</span>),
subheader: (<strong className='message subheader'>{text}</strong>),
emphasized: (<em className='message emphasized'>{text}</em>),
endOfLine: (<br />),
})[style] || defaultContent
}