It's cleaner anyway to use `tokio::broadcast::channel` than the list
of callbacks.
Also make it send pings only on long pauses between frames, as when
the camera is disconnected.
Users are often puzzled why there are short recordings. Previously
the only way to see this was to examine Moonfire's logs. This should
be a much better experience to find it right in the UI where you're
wondering, and without the potential the logs are gone.
Fixes#302
Fixes#286.
I dug into Firefox code a bit to understand this but got a lost. But
I guess there are different policies for what's accessible via
`video.src = ""` than for `<video src="">`. This works for now, matches
what other players such as `mpegts.js` do, and is closer to what Safari
MME (required on iPhone) needs anyway. (With MME, apparently you have to
use `video.srcObject`, or the `MediaSource`'s `sourceopen` event will
never fire.)
* The `DisplaySelector` wasn't getting the correct flex layout.
Before this was done by a manual style on a `Paper` element. That
broke when adding the inner `<CardContent>` to because that's the
container that needs the `display: "flex"`. But really, it's clearer
to do this with `<FormGroup>` anyway, so do that.
* Switch from `<Card><CardContent>` to `<Paper sx={{ padding: ... }}>`.
The card content has extra padding (16 px in general, 24 at the bottom
of the last element to fit with an action). I'm not quite sure the
best way to remove it, and the simpler `<Paper>` seems fine for this
use anyway.
* strongly encourage the single-binary approach and say why.
* fix a broken link in troubleshooting guide (and regenerate toc).
* add a couple more comments to the docker compose snippet
Noticed this while looking at these `act` warnings. I didn't manage to
solve those, but at least this makes the tests more consistent with
current docs.
In the upgrade I managed to dust off some tests that I'd been skipping
for quite a while. It turns out one of them was pointing out a real
problem: in the network error case, we didn't display the error to the
user properly. It's really sad this reaches our code as a `TypeError`,
but it is what it is.