Make stream list scrollable

This commit is contained in:
Max Goodhart
2020-07-27 14:33:33 -07:00
parent cea7210485
commit c9bf2ca2a6

View File

@@ -7,7 +7,7 @@ import { patch as patchJSON } from 'jsondiffpatch'
import { h, Fragment, render } from 'preact' import { h, Fragment, render } from 'preact'
import { useEffect, useState, useCallback, useRef } from 'preact/hooks' import { useEffect, useState, useCallback, useRef } from 'preact/hooks'
import { State } from 'xstate' import { State } from 'xstate'
import styled, { css } from 'styled-components' import styled, { createGlobalStyle } from 'styled-components'
import { useHotkeys } from 'react-hotkeys-hook' import { useHotkeys } from 'react-hotkeys-hook'
import '../index.css' import '../index.css'
@@ -42,6 +42,17 @@ const hotkeyTriggers = [
'p', 'p',
] ]
const GlobalStyle = createGlobalStyle`
html {
height: 100%;
}
html, body {
display: flex;
flex: 1;
}
`
function useYDoc(keys) { function useYDoc(keys) {
const [doc, setDoc] = useState(new Y.Doc()) const [doc, setDoc] = useState(new Y.Doc())
const [docValue, setDocValue] = useState() const [docValue, setDocValue] = useState()
@@ -376,94 +387,111 @@ function App({ wsEndpoint }) {
) )
return ( return (
<div> <Stack flex="1">
<h1>Streamwall ({location.host})</h1> <Stack>
<div> <h1>Streamwall ({location.host})</h1>
connection status: {isConnected ? 'connected' : 'connecting...'}
</div>
{delayState && (
<StreamDelayBox
delayState={delayState}
setStreamCensored={setStreamCensored}
/>
)}
<StyledDataContainer isConnected={isConnected}>
<div> <div>
{range(0, gridCount).map((y) => ( connection status: {isConnected ? 'connected' : 'connecting...'}
<StyledGridLine>
{range(0, gridCount).map((x) => {
const idx = gridCount * y + x
const { isListening = false, isBlurred = false, state } =
stateIdxMap.get(idx) || {}
const { streamId } = sharedState.views?.[idx] || ''
const isDragHighlighted =
dragStart !== undefined &&
idxInBox(gridCount, dragStart, dragEnd, idx)
return (
<GridInput
idx={idx}
spaceValue={streamId}
isError={state && state.matches('displaying.error')}
isDisplaying={state && state.matches('displaying')}
isListening={isListening}
isBlurred={isBlurred}
isHighlighted={isDragHighlighted}
showDebug={showDebug}
onMouseDown={handleDragStart}
onMouseEnter={setDragEnd}
onFocus={handleFocusInput}
onBlur={handleBlurInput}
onChangeSpace={handleSetView}
onSetListening={handleSetListening}
onSetBlurred={handleSetBlurred}
onReloadView={handleReloadView}
onBrowse={handleBrowse}
onDevTools={handleDevTools}
/>
)
})}
</StyledGridLine>
))}
</div> </div>
<label> {delayState && (
<input <StreamDelayBox
type="checkbox" delayState={delayState}
value={showDebug} setStreamCensored={setStreamCensored}
onChange={handleChangeShowDebug}
/> />
Show stream debug tools )}
</label> <StyledDataContainer isConnected={isConnected}>
<div> <div>
{isConnected {range(0, gridCount).map((y) => (
? normalStreams.map((row) => ( <StyledGridLine>
<StreamLine id={row._id} row={row} onClickId={handleClickId} /> {range(0, gridCount).map((x) => {
)) const idx = gridCount * y + x
: 'loading...'} const { isListening = false, isBlurred = false, state } =
</div> stateIdxMap.get(idx) || {}
<h2>Custom Streams</h2> const { streamId } = sharedState.views?.[idx] || ''
<div> const isDragHighlighted =
{/* dragStart !== undefined &&
idxInBox(gridCount, dragStart, dragEnd, idx)
return (
<GridInput
idx={idx}
spaceValue={streamId}
isError={state && state.matches('displaying.error')}
isDisplaying={state && state.matches('displaying')}
isListening={isListening}
isBlurred={isBlurred}
isHighlighted={isDragHighlighted}
showDebug={showDebug}
onMouseDown={handleDragStart}
onMouseEnter={setDragEnd}
onFocus={handleFocusInput}
onBlur={handleBlurInput}
onChangeSpace={handleSetView}
onSetListening={handleSetListening}
onSetBlurred={handleSetBlurred}
onReloadView={handleReloadView}
onBrowse={handleBrowse}
onDevTools={handleDevTools}
/>
)
})}
</StyledGridLine>
))}
</div>
<label>
<input
type="checkbox"
value={showDebug}
onChange={handleChangeShowDebug}
/>
Show stream debug tools
</label>
</StyledDataContainer>
</Stack>
<Stack flex="1" scroll={true}>
<StyledDataContainer isConnected={isConnected}>
<div>
{isConnected
? normalStreams.map((row) => (
<StreamLine
id={row._id}
row={row}
onClickId={handleClickId}
/>
))
: 'loading...'}
</div>
<h2>Custom Streams</h2>
<div>
{/*
Include an empty object at the end to create an extra input for a new custom stream. Include an empty object at the end to create an extra input for a new custom stream.
We need it to be part of the array (rather than JSX below) for DOM diffing to match the key and retain focus. We need it to be part of the array (rather than JSX below) for DOM diffing to match the key and retain focus.
*/} */}
{[...customStreams, { link: '', label: '', kind: 'video' }].map( {[...customStreams, { link: '', label: '', kind: 'video' }].map(
({ link, label, kind }, idx) => ( ({ link, label, kind }, idx) => (
<CustomStreamInput <CustomStreamInput
key={idx} key={idx}
idx={idx} idx={idx}
link={link} link={link}
label={label} label={label}
kind={kind} kind={kind}
onChange={handleChangeCustomStream} onChange={handleChangeCustomStream}
/> />
), ),
)} )}
</div> </div>
</StyledDataContainer> </StyledDataContainer>
</div> </Stack>
</Stack>
) )
} }
const Stack = styled.div`
display: flex;
flex-direction: column;
flex: ${({ flex }) => flex};
${({ scroll }) => scroll && `overflow-y: auto`};
`
function StreamDelayBox({ delayState, setStreamCensored }) { function StreamDelayBox({ delayState, setStreamCensored }) {
const handleToggleStreamCensored = useCallback(() => { const handleToggleStreamCensored = useCallback(() => {
setStreamCensored(!delayState.isCensored) setStreamCensored(!delayState.isCensored)
@@ -805,7 +833,13 @@ const StyledStreamLine = styled.div`
function main() { function main() {
const script = document.getElementById('main-script') const script = document.getElementById('main-script')
render(<App wsEndpoint={script.dataset.wsEndpoint} />, document.body) render(
<>
<GlobalStyle />
<App wsEndpoint={script.dataset.wsEndpoint} />
</>,
document.body,
)
} }
main() main()