Skip to content

Commit

Permalink
mostly working salvos
Browse files Browse the repository at this point in the history
  • Loading branch information
monoxane committed Mar 16, 2023
1 parent 4dc478b commit 77f03e4
Show file tree
Hide file tree
Showing 9 changed files with 862 additions and 85 deletions.
31 changes: 28 additions & 3 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ package main

import (
"encoding/json"
"io/ioutil"
"log"
"os"

"github.com/monoxane/nk"
)

type Configuration struct {
Server Server `json:"server"`
Router Router `json:"router"`
Probe Probe `json:"probe"`
Server Server `json:"server"`
Router Router `json:"router"`
Probe Probe `json:"probe"`
Salvos []Salvo `json:"salvos"`
}
type Server struct {
Port int `json:"port"`
Expand All @@ -25,6 +29,27 @@ type Probe struct {
RouterDestination int `json:"router_destination"`
}

type Salvo struct {
Label string `json:"label"`
Destinations []nk.Destination `json:"destinations"`
}

func (c *Configuration) Save() {
file, err := json.MarshalIndent(c, "", " ")
if err != nil {
log.Printf("unable to marshal config: %s", err)
return
}

err = ioutil.WriteFile("config.json", file, 0777)
if err != nil {
log.Printf("unable to save config: %s", err)
return
}

log.Print("saved config")
}

var Config Configuration

func init() {
Expand Down
15 changes: 15 additions & 0 deletions config.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"server": {
"port": 8080
},
"router": {
"ip": "10.101.0.2",
"address": 254,
"model": "NK-3G72"
},
"probe": {
"enabled": true,
"router_destination": 72
},
"salvos": []
}
32 changes: 32 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ func serveHTTP() {

svc.GET("/v1/matrix", HandleMatrix)

svc.POST("/v1/salvos", HandleSalvoPost)

svc.GET("/v1/config", HandleConfig)

if Config.Probe.Enabled {
Expand Down Expand Up @@ -179,6 +181,36 @@ func HandleConfig(c *gin.Context) {
c.JSON(http.StatusOK, Config)
}

func HandleSalvoPost(c *gin.Context) {
var salvo Salvo
err := c.BindJSON(&salvo)
if err != nil {
log.Printf("unable to bind salvo to object: %s", err)
c.Status(http.StatusBadRequest)

return
}

log.Printf("saving salvo: %+v", salvo)

for i, existingSalvo := range Config.Salvos {
if existingSalvo.Label == salvo.Label {
log.Printf("updating existing salvo")
Config.Salvos[i] = salvo
c.Status(http.StatusOK)
Config.Save()

return
}
}

Config.Salvos = append(Config.Salvos, salvo)
log.Printf("added new salvo")
Config.Save()

c.Status(http.StatusOK)
}

func HandleMatrixWS(c *gin.Context) {
w := c.Writer
r := c.Request
Expand Down
1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"devDependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"css-loader": "^6.7.3",
"eslint-plugin-react": "^7.32.2",
"prettier": "1.17.0",
"sass": "^1.58.3",
"sass-loader": "^13.2.0",
Expand Down
186 changes: 112 additions & 74 deletions ui/src/App.jsx

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions ui/src/JSmpegPlayer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ import React, { useState, useEffect, useRef } from 'react';

import JSMpeg from '@cycjimmy/jsmpeg-player';

import imgs from './imgs'

const JSmpegPlayer = ({ url, active }) => {
const videoRef = useRef(null)
const [player, setPlayer] = useState(null)

useEffect(() => {
console.log(player, active)
if (active && !player) {
setPlayer(new JSMpeg.VideoElement(
const p = new JSMpeg.VideoElement(
videoRef.current,
url,
{
autoplay: false
autoplay: false,
poster: imgs.probe_slate
},
{}
));
)
setPlayer(p);
} else {
player?.destroy()
setPlayer(null)
Expand Down
172 changes: 172 additions & 0 deletions ui/src/Salvos.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import React, { useState, useEffect } from 'react';
import useAxios from 'axios-hooks';
import axios from 'axios';

import useMatrix from './useMatrix'

import {
Button,
ButtonSet,
Column,
ComboBox,
Grid,
Table,
TableHead,
TableRow,
TableContainer,
TableHeader,
TableBody,
TableCell,
TableToolbar,
TableToolbarContent,
IconButton,
Modal
} from '@carbon/react';

import {
TrashCan,
Add,
Redo,
QueryQueue
} from '@carbon/icons-react';

const Salvos = function Salvos() {
const {matrix, loading: matrixLoading, error: matrixError, route} = useMatrix()
const [{ data: config, loading: configLoading, error: configError }, refresh] = useAxios(
'/v1/config'
)

const [currentSalvo, setCurrentSalvo] = useState({})
const [newSalvoName, setNewSalvoName] = useState()

useEffect(() => {
console.log("Current Salvo", currentSalvo)
}, [currentSalvo])

const headers = ['Destination', 'Saved Source', 'Current Source', "Actions"];

const recallCurrentSalvo = () => {
currentSalvo.destinations.map((destination, index) => {
setTimeout(
() => route(destination.id, destination.source.id),
100 * index
)
})
}

const saveCurrentSalvo = () => {
const salvo = {...currentSalvo}
salvo.destinations.map(destination => destination = matrix.destinations[destination.id - 1])
console.log(salvo)
axios.post('/v1/salvos', salvo)
.then(() => {
refresh()
})
.catch((err) => {
console.log("unable to save salvo", err)
});
}

return (
<Grid>
{configLoading && "Loading..."}
{configError && "Error"}
{!configLoading && !configError &&
<Column sm={4} lg={16}>
<TableToolbar>
<TableToolbarContent>
<strong style={{marginTop: "1em", marginRight: "1em", minWidth: "50px"}}>Selected Salvo:</strong>
<ComboBox
items={[newSalvoName && {label:`${newSalvoName} (New)`}, ...config.salvos].filter(Boolean)}
selectedItem={currentSalvo}
itemToString={(item) => (item ? item.label : '')}
placeholder="Type to Filter..."
onChange={(event) => {
if (event.selectedItem == null) {return}
if (event.selectedItem.destinations == undefined) {
if(newSalvoName != "") {
setCurrentSalvo({ label: newSalvoName, destinations: []})
}
} else {
setCurrentSalvo(event.selectedItem)
}
}}
onInputChange={(event) => setNewSalvoName(event)}
/>
<Button
style={{marginLeft:"0.6em"}}
disabled={!currentSalvo.label}
onClick={() => saveCurrentSalvo()}
>
Save
</Button>
<Button
disabled={!currentSalvo.label}
kind="danger"
onClick={() => recallCurrentSalvo()}
>
Recall
</Button>
</TableToolbarContent>
</TableToolbar>
{currentSalvo.label &&
<>
<Table size="lg" useZebraStyles={false} style={{height: "80%", overflow: "scroll"}}>
<TableHead>
<TableRow>
{headers.map((header) => (
<TableHeader id={header.key} key={header}>
{header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{currentSalvo.destinations?.map((row) => row != null && (
<TableRow key={row.id}>
<TableCell>{row.label}</TableCell>
<TableCell>{row.source.label}</TableCell>
<TableCell>{matrix.destinations[row.id-1].source.label}</TableCell>
<TableCell>
<IconButton
kind='ghost'
label="Recall this Destination"
size="sm"
onClick={() => { route(row.id, row.source.id)}}
>
<Redo />
</IconButton>
<IconButton
kind='ghost'
label="Remove from Salvo"
size="sm"
onClick={() => setCurrentSalvo({...currentSalvo, destinations: [...currentSalvo.destinations.filter(savedDestination => savedDestination.id != row.id)]})}
>
<TrashCan />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<ComboBox
items={matrix.destinations?.filter((destination) => !currentSalvo.destinations.find(({ id }) => destination.id === id))}
itemToString={(item) => (item ? `${item.label} <= ${item.source.label}` : '')}
placeholder="Type to Filter..."
helperText="Add Destination to Salvo"
direction={currentSalvo.destinations.length > 10 ? "top" : "bottom"}
onChange={
(event) => {
if (event.selectedItem) setCurrentSalvo({...currentSalvo, destinations: [...currentSalvo.destinations, event.selectedItem].sort((a, b) => (a.id - b.id))})
}
}
/>
</>
}
</Column>
}
</Grid>
)
}

export default Salvos
4 changes: 4 additions & 0 deletions ui/src/imgs.js

Large diffs are not rendered by default.

Loading

0 comments on commit 77f03e4

Please sign in to comment.