Add TextBuffer component

This commit is contained in:
He4eT 2021-02-25 19:04:26 +05:00
commit 95c8ae8780
3 changed files with 91 additions and 20 deletions

View file

@ -0,0 +1,8 @@
import { h } from 'preact'
// import { useState, useEffect } from 'preact/hooks'
export default function ({ currentWindow, inputType, sendMessage }) {
return (
<div>InputBox</div>
)
}

View file

@ -3,6 +3,14 @@ import { useState, useEffect } from 'preact/hooks'
import CheapGlkOte from 'cheap-glkote'
import TextBuffer from './TextBuffer'
import InputBox from './InputBox'
const INITIAL_STATUS = {
stage: 'loading',
details: 'Preparing...'
}
const runMachine = ({ Engine, file, handlers }) => {
console.log('runMachine')
@ -16,30 +24,22 @@ const runMachine = ({ Engine, file, handlers }) => {
}
const Handlers = ({
setStatus,
setCurrentWindow,
setInputType,
setInbox
}) => ({
onInit: () => {},
onInit: _ => setStatus({ stage: 'ready' }),
/* */
onUpdateWindows: windows => {
setCurrentWindow(windows
.filter(x => x.type === 'buffer')
.slice(-1)[0])
},
onUpdateInputs: setInputType,
onUpdateContent: messagesByWindow => {
const inbox =
messagesByWindow
.reduce((acc, {id, text}) => {
acc[id] = text
.map(({content}) => content || [null])
.reduce((xs, x) => [...xs, ...x], [])
return acc
}, {})
console.log(JSON.stringify(inbox, null, 1))
setInbox(inbox)
},
onDisable: () => setInputType(null),
onUpdateContent: setInbox,
onDisable: _ => setInputType(null),
/* */
onFileNameRequest: (tosave, usage, _, setFileName) => {
setFileName({ filename: 'filename', usage })
},
@ -47,10 +47,13 @@ const Handlers = ({
return 'content'
},
onFileWrite: (filename, content) => {},
onExit: () => setInputType(null)
/* */
onExit: _ => setInputType(null)
})
export default function ({ vmParts: { file, engine } }) {
const [status, setStatus] = useState(INITIAL_STATUS)
const [currentWindow, setCurrentWindow] = useState(null)
const [inputType, setInputType] = useState(null)
const [inbox, setInbox] = useState([])
@ -62,6 +65,7 @@ export default function ({ vmParts: { file, engine } }) {
useEffect(() => {
const handlers = Handlers({
setStatus,
setCurrentWindow,
setInputType,
setInbox
@ -86,9 +90,13 @@ export default function ({ vmParts: { file, engine } }) {
window.send = x => sendMessage(x, currentWindow)
}, [sendMessage, currentWindow])
return (
<div>
Player
</div>
)
return status.stage !== 'ready'
? (<div>{status.details}</div>)
: (<section>
<TextBuffer {...{
inbox,
currentWindow
}}/>
<InputBox/>
</section>)
}

View file

@ -0,0 +1,55 @@
import { h } from 'preact'
import { useState, useEffect } from 'preact/hooks'
const parseInbox = (inbox, currentWindow) => {
const currentInbox =
inbox.find(({id}) =>
id === currentWindow.id)
if (!currentInbox) return {
clear: false,
incoming: []}
const {clear, text: inboxMessagesRaw} =
currentInbox
const incoming =
inboxMessagesRaw
/* Normalize. */
.map(({content}) =>
content || [{ style: 'emptyLine' }])
/* Flatten. */
.reduce((acc, x) =>
acc.concat(x), [])
/* Collapse empty lines. */
.reduce((acc, x, i, xs) => {
if (x.style !== 'emptyLine') return [...acc, x]
const prev = xs[i - 1] || {}
return prev.style === 'emptyLine'
? acc
: [...acc, x]
}, [])
return {clear, incoming}
}
export default function ({ inbox, currentWindow }) {
const [messages, setMessages] = useState([])
useEffect(() => {
const {incoming, clear} =
parseInbox(inbox, currentWindow)
setMessages(clear
? incoming
: messages.concat(incoming))
}, [inbox])
return (
<div>
{messages?.map(({text}) =>
(<div>{text}</div>))}
</div>
)
}