mirror of
https://github.com/He4eT/elseifplayer.git
synced 2026-05-05 01:17:22 +00:00
Rearrange components
This commit is contained in:
parent
39e8b8a526
commit
daa26965cd
16 changed files with 14 additions and 11 deletions
79
src/components/Player/OutputBox/GridBuffer.jsx
Normal file
79
src/components/Player/OutputBox/GridBuffer.jsx
Normal 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>
|
||||
)
|
||||
}
|
||||
93
src/components/Player/OutputBox/TextBuffer.jsx
Normal file
93
src/components/Player/OutputBox/TextBuffer.jsx
Normal 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>
|
||||
)
|
||||
}
|
||||
16
src/components/Player/OutputBox/TextMessage.jsx
Normal file
16
src/components/Player/OutputBox/TextMessage.jsx
Normal 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'>> {text}</span>),
|
||||
subheader: (<strong className='message subheader'>{text}</strong>),
|
||||
emphasized: (<em className='message emphasized'>{text}</em>),
|
||||
endOfLine: (<br />),
|
||||
})[style] || defaultContent
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue