Add reload button to control interface

This commit is contained in:
Max Goodhart
2020-06-19 08:01:59 -07:00
parent 1a3c82b2a5
commit a58a94aa51
5 changed files with 81 additions and 26 deletions

View File

@@ -175,6 +175,17 @@ export default class StreamWindow extends EventEmitter {
}
}
reloadView(viewIdx) {
const view = this.views.find(
(v) =>
v.state.matches('displaying') &&
v.state.context.pos.spaces.includes(viewIdx),
)
if (view) {
view.send('RELOAD')
}
}
send(...args) {
this.overlayView.webContents.send(...args)
}

View File

@@ -60,6 +60,8 @@ async function main() {
streamWindow.setViews(new Map(msg.views))
} else if (msg.type === 'set-listening-view') {
streamWindow.setListeningView(msg.viewIdx)
} else if (msg.type === 'reload-view') {
streamWindow.reloadView(msg.viewIdx)
}
}

View File

@@ -16,14 +16,11 @@ const viewStateMachine = Machine(
},
states: {
empty: {
entry: [
assign({
pos: {},
info: {},
url: null,
}),
'hideView',
],
entry: assign({
pos: {},
info: {},
url: null,
}),
invoke: {
src: 'clearView',
onError: {
@@ -45,6 +42,7 @@ const viewStateMachine = Machine(
}),
cond: 'urlUnchanged',
},
RELOAD: '.loading',
},
states: {
loading: {
@@ -80,6 +78,7 @@ const viewStateMachine = Machine(
running: {
initial: 'muted',
entry: 'positionView',
exit: 'hideView',
on: {
DISPLAY: {
actions: [

View File

@@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="redo-alt" class="svg-inline--fa fa-redo-alt fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256.455 8c66.269.119 126.437 26.233 170.859 68.685l35.715-35.715C478.149 25.851 504 36.559 504 57.941V192c0 13.255-10.745 24-24 24H345.941c-21.382 0-32.09-25.851-16.971-40.971l41.75-41.75c-30.864-28.899-70.801-44.907-113.23-45.273-92.398-.798-170.283 73.977-169.484 169.442C88.764 348.009 162.184 424 256 424c41.127 0 79.997-14.678 110.629-41.556 4.743-4.161 11.906-3.908 16.368.553l39.662 39.662c4.872 4.872 4.631 12.815-.482 17.433C378.202 479.813 319.926 504 256 504 119.034 504 8.001 392.967 8 256.002 7.999 119.193 119.646 7.755 256.455 8z"></path></svg>

After

Width:  |  Height:  |  Size: 781 B

View File

@@ -2,11 +2,13 @@ import range from 'lodash/range'
import ReconnectingWebSocket from 'reconnecting-websocket'
import { h, render } from 'preact'
import { useEffect, useState, useCallback, useRef } from 'preact/hooks'
import styled from 'styled-components'
import { State } from 'xstate'
import styled, { css } from 'styled-components'
import '../index.css'
import { GRID_COUNT } from '../constants'
import SoundIcon from '../static/volume-up-solid.svg'
import ReloadIcon from '../static/redo-alt-solid.svg'
function emptyStateIdxMap() {
return new Map(
@@ -15,7 +17,7 @@ function emptyStateIdxMap() {
{
streamId: null,
url: null,
state: {},
state: State.from({}),
isListening: false,
},
]),
@@ -47,13 +49,13 @@ function App({ wsEndpoint }) {
continue
}
const streamId = streams.find((d) => d.Link === url)?._id
const isListening =
viewState.state.displaying?.running === 'listening'
const state = State.from(viewState.state)
const isListening = state.matches('displaying.running.listening')
for (const space of pos.spaces) {
Object.assign(newStateIdxMap.get(space), {
streamId,
url,
state: viewState.state,
state,
isListening,
})
}
@@ -102,6 +104,15 @@ function App({ wsEndpoint }) {
)
}, [])
const handleReloadView = useCallback((idx) => {
wsRef.current.send(
JSON.stringify({
type: 'reload-view',
viewIdx: idx,
}),
)
}, [])
return (
<div>
<h1>Stream Wall</h1>
@@ -120,9 +131,11 @@ function App({ wsEndpoint }) {
idx={idx}
onChangeSpace={handleSetView}
spaceValue={streamId}
isError={state === 'error'}
isError={state.matches('error')}
isDisplaying={state.matches('displaying')}
isListening={isListening}
onSetListening={handleSetListening}
onReloadView={handleReloadView}
/>
)
})}
@@ -154,9 +167,11 @@ function GridInput({
idx,
onChangeSpace,
spaceValue,
isDisplaying,
isError,
isListening,
onSetListening,
onReloadView,
}) {
const [editingValue, setEditingValue] = useState()
const handleFocus = useCallback((ev) => {
@@ -177,16 +192,29 @@ function GridInput({
() => onSetListening(idx, !isListening),
[idx, onSetListening, isListening],
)
const handleReloadClick = useCallback(() => onReloadView(idx), [
idx,
onReloadView,
])
const handleClick = useCallback((ev) => {
ev.target.select()
})
return (
<StyledGridContainer>
<ListeningButton
isListening={isListening}
onClick={handleListeningClick}
tabIndex={1}
/>
{isDisplaying && (
<StyledGridButtons side="left">
<StyledButton onClick={handleReloadClick}>
<ReloadIcon />
</StyledButton>
</StyledGridButtons>
)}
<StyledGridButtons side="right">
<ListeningButton
isListening={isListening}
onClick={handleListeningClick}
tabIndex={1}
/>
</StyledGridButtons>
<StyledGridInput
name={idx}
value={editingValue || spaceValue || ''}
@@ -216,12 +244,12 @@ const StyledGridLine = styled.div`
display: flex;
`
const StyledListeningButton = styled.button`
const StyledButton = styled.button`
display: flex;
align-items: center;
border: 2px solid gray;
border-color: ${({ isListening }) => (isListening ? 'red' : 'gray')};
background: ${({ isListening }) => (isListening ? '#c77' : '#ccc')};
border-color: gray;
background: #ccc;
border-radius: 5px;
&:focus {
@@ -235,13 +263,27 @@ const StyledListeningButton = styled.button`
}
`
const StyledListeningButton = styled(StyledButton)`
${({ isListening }) =>
isListening &&
`
border-color: red;
background: #c77;
`};
`
const StyledGridContainer = styled.div`
position: relative;
`
${StyledListeningButton} {
position: absolute;
bottom: 5px;
right: 5px;
const StyledGridButtons = styled.div`
display: flex;
position: absolute;
bottom: 0;
${({ side }) => (side === 'left' ? 'left: 0' : 'right: 0')};
${StyledButton} {
margin: 5px;
}
`