Further simplify custom streams UI to prevent jank

Editing URLs and stream kind after the fact doesn't update properly, and
can lead to janky behavior when the URL duplicates another stream,
because the stream datas get merged together and the row disappears.
Moving to larger more atomic editing operations removes these corner
cases.
This commit is contained in:
Max Goodhart
2020-11-10 23:22:28 -08:00
parent 76329cafdb
commit bfebd88e4c

View File

@@ -465,21 +465,22 @@ function App({ wsEndpoint, role }) {
[gridCount, sharedState, focusedInputIdx],
)
const handleChangeCustomStream = useCallback((origLink, customStream) => {
if (!customStream.label && !customStream.link) {
send({
type: 'delete-custom-stream',
url: origLink,
})
return
}
const handleChangeCustomStream = useCallback((url, customStream) => {
send({
type: 'update-custom-stream',
url: origLink,
url,
data: customStream,
})
})
const handleDeleteCustomStream = useCallback((url) => {
send({
type: 'delete-custom-stream',
url,
})
return
})
const setStreamCensored = useCallback((isCensored) => {
send({
type: 'set-stream-censored',
@@ -730,15 +731,14 @@ function App({ wsEndpoint, role }) {
We need it to be part of the array (rather than JSX below) for DOM diffing to match the key and retain focus.
*/}
{customStreams.map(({ link, label, kind }, idx) => (
<div>
<CustomStreamInput
key={idx}
link={link}
label={label}
kind={kind}
onChange={handleChangeCustomStream}
/>
</div>
<CustomStreamInput
key={idx}
link={link}
label={label}
kind={kind}
onChange={handleChangeCustomStream}
onDelete={handleDeleteCustomStream}
/>
))}
<CreateCustomStreamInput onCreate={handleChangeCustomStream} />
</div>
@@ -1110,64 +1110,62 @@ function GridControls({
)
}
function CustomStreamInput({ onChange, ...props }) {
const handleChangeLink = useCallback(
(value) => {
onChange(props.link, { ...props, link: value })
},
[onChange, props.link],
)
function CustomStreamInput({ onChange, onDelete, ...props }) {
const handleChangeLabel = useCallback(
(value) => {
onChange(props.link, { ...props, label: value })
},
[onChange, props.link],
)
const handleChangeKind = useCallback(
(ev) => {
onChange(props.link, { ...props, kind: ev.target.value })
},
[onChange, props.link],
[onChange, props],
)
const handleDeleteClick = useCallback(() => {
onDelete(props.link)
}, [onDelete, props.link])
return (
<>
<LazyChangeInput
onChange={handleChangeLink}
placeholder="https://..."
value={props.link}
/>
<div>
<LazyChangeInput
value={props.label}
onChange={handleChangeLabel}
placeholder="Label (optional)"
value={props.label}
/>{' '}
<a href={props.link}>{props.link}</a> <span>({props.kind})</span>{' '}
<button onClick={handleDeleteClick}>x</button>
</div>
)
}
function CreateCustomStreamInput({ onCreate }) {
const [link, setLink] = useState('')
const [kind, setKind] = useState('video')
const [label, setLabel] = useState('')
const handleSubmit = useCallback(
(ev) => {
ev.preventDefault()
onCreate(link, { link, kind, label })
setLink('')
setKind('video')
setLabel('')
},
[onCreate, link, kind, label],
)
return (
<form onSubmit={handleSubmit}>
<input
value={link}
onChange={(ev) => setLink(ev.target.value)}
placeholder="https://..."
/>
<select onChange={handleChangeKind} value={props.kind}>
<select onChange={(ev) => setKind(ev.target.value)} value={kind}>
<option value="video">video</option>
<option value="audio">audio</option>
<option value="web">web</option>
<option value="overlay">overlay</option>
<option value="background">background</option>
</select>
</>
)
}
function CreateCustomStreamInput({ onCreate }) {
const [stream, setStream] = useState({ link: '' })
const handleChangeStream = useCallback((oldLink, stream) => {
setStream(stream)
})
const handleSubmit = useCallback(
(ev) => {
ev.preventDefault()
onCreate(stream.link, stream)
setStream({ link: '' })
},
[onCreate, stream],
)
return (
<form onSubmit={handleSubmit}>
<CustomStreamInput onChange={handleChangeStream} {...stream} />
<input
value={label}
onChange={(ev) => setLabel(ev.target.value)}
placeholder="Label (optional)"
/>
<button type="submit">add stream</button>
</form>
)