Add status component

This commit is contained in:
He4eT 2021-03-02 19:29:42 +05:00
commit f02ec6925f
7 changed files with 66 additions and 21 deletions

View file

@ -10,10 +10,10 @@
<body>
<div id="root">
<div class="app">
<div class="app play">
<main>
<div class="status">
Loading...
<div class="status loading">
<div>Loading</div>
</div>
</main>
</div>

View file

@ -9,12 +9,13 @@ import CheapGlkOte from 'cheap-glkote'
import TextBuffer from './TextBuffer'
import InputBox from './InputBox'
import Status from './Status'
import './player.css'
const INITIAL_STATUS = {
stage: 'loading',
details: 'Preparing...'
details: ['Preparing']
}
const runMachine = ({ Engine, file, handlers }) => {
@ -104,7 +105,7 @@ export default function ({ vmParts: { file, engine } }) {
}, [vm])
return status.stage !== 'ready'
? (<div>{status.details}</div>)
? (<Status {...status} />)
: (
<section className='ifplayer'>
<TextBuffer {...{

View file

@ -0,0 +1,23 @@
import { h } from 'preact'
const INITIAL_STATUS = {
stage: 'loading',
details: 'Loading...'
}
const fail = details => (
<div class="status fail">
<h1>Error</h1>
{details.map(x => (<p>{x}</p>))}
<hr />
</div>
)
const loading = details => (
<div class="status loading">
{details.map(x => (<div>{x}</div>))}
</div>
)
export default ({ stage, details }) =>
({fail, loading})[stage](details)

View file

@ -4,33 +4,34 @@ import { useState, useEffect } from 'preact/hooks'
import { engineByFilename } from './common/engines'
import Player from './Player'
import Status from './Status'
const INITIAL_STATUS = {
stage: 'loading',
details: 'Loading...'
details: ['Loading']
}
const prepareVM = ({ url, setStatus, setParts }) => {
const st = (stage, details) => args => {
setStatus({ stage, details })
setStatus({ stage, details: [details] })
return args
}
return Promise.resolve()
.then(st('loading', 'Downloading file...'))
.then(st('loading', 'Downloading file'))
.then(_ => fetch(url))
.then(st('loading', 'Processing file...'))
.then(st('loading', 'Processing file'))
.then(response => response.arrayBuffer())
.then(arrayBuffer => new Uint8Array(arrayBuffer))
.then(st('loading', 'Downloading engine...'))
.then(st('loading', 'Downloading engine'))
.then(file => setParts({
file,
engine: engineByFilename(url)
}))
.then(st('loading', 'Running...'))
.then(st('loading', 'Running'))
.catch(e => {
console.error(e)
setStatus({ stage: 'fail', details: e.message })
setStatus({ stage: 'fail', details: [e.message, url] })
})
}
@ -47,5 +48,5 @@ export default function ({ url }) {
return vmParts
? (<Player vmParts={vmParts} />)
: (<div>{status.details}</div>)
: (<Status {...status} />)
}

View file

@ -33,6 +33,6 @@ export const engineByFilename = filename => {
if (format) {
return format.engine
} else {
throw new Error(`Unsupported file type: ${filename}`)
throw new Error('Unsupported file type')
}
}

View file

@ -9,7 +9,7 @@
padding: var(--outer-padding);
}
.inputBox {
.ifplayer .inputBox {
flex: 0 1 auto;
font: inherit;
@ -22,7 +22,7 @@
margin-top: var(--input-box-margin);
}
.textBuffer {
.ifplayer .textBuffer {
flex: 2 1 auto;
overflow-y: scroll;
box-sizing: border-box;
@ -34,19 +34,35 @@
scrollbar-width: thin;
}
.textBuffer::-webkit-scrollbar {
.ifplayer .textBuffer::-webkit-scrollbar {
width: 8px;
}
.textBuffer::-webkit-scrollbar-thumb {
.ifplayer .textBuffer::-webkit-scrollbar-thumb {
background-color: var(--main-color);
border: 4px solid var(--bg-color);
border-left-width: 0px;
}
.textBuffer > br:first-child,
.textBuffer > br:last-child,
.textBuffer > br + br + br {
.ifplayer .textBuffer > br:first-child,
.ifplayer .textBuffer > br:last-child,
.ifplayer .textBuffer > br + br + br {
display: none;
}
.status {
padding: var(--inner-padding);
}
.status.loading > div:after {
animation: dots0123 1s infinite;
content: '';
}
@keyframes dots0123 {
0% { content: ''; }
33% { content: '.'; }
66% { content: '..'; }
100% { content: '...'; }
}

View file

@ -67,3 +67,7 @@ summary:hover {
ul {
list-style: square;
}
.status {
padding: 8px;
}