Compare commits

..

No commits in common. "52ad6cc8041a1dd95cbee8866e079c04e8574ef0" and "538f7dc5a7358280b8ff57937e7f1dba5c15ea9a" have entirely different histories.

3 changed files with 16 additions and 49 deletions

View file

@ -1,4 +1,4 @@
.PHONY: deploy clean start debug frontend install-service
.PHONY: deploy clean start default frontend
server/server: frontend
rm -rf server/dist
@ -8,23 +8,19 @@ server/server: frontend
frontend:
npm run build
deploy: server/server install-service
ssh kiosk "systemctl --user stop digital-turntable.service" || true
scp server/server kiosk:~/server
ssh kiosk "chmod +x ~/server && systemctl --user start digital-turntable.service"
install-service:
ssh kiosk "mkdir -p ~/.config/systemd/user"
scp server/digital-turntable.service kiosk:~/.config/systemd/user/digital-turntable.service
ssh kiosk "systemctl --user daemon-reload && systemctl --user enable digital-turntable.service"
deploy: server/server
scp server/server kiosk:
clean:
rm -rf dist server/dist server/server
start: deploy
# TODO: This doesn't kill weston nicely; I should handle that? Or background or something
ssh kiosk "pgrep -f './server' || ./server &"
ssh kiosk "pkill -f 'weston --shell=kiosk-shell.so'" || true
ssh kiosk weston --shell=kiosk-shell.so -- firefox --kiosk localhost:8000 --remote-debugging-port=9222
debug: deploy
ssh kiosk "pgrep -f './server' || ./server &"
ssh kiosk "pkill -f 'weston --shell=kiosk-shell.so'" || true
ssh -L 6000:localhost:6000 kiosk weston --shell=kiosk-shell.so -- firefox --kiosk localhost:8000 --start-debugger-server 6000

View file

@ -1,13 +0,0 @@
[Unit]
Description=Digital Turntable kiosk server
After=network.target
[Service]
Type=simple
WorkingDirectory=%h
ExecStart=%h/server
Restart=on-failure
RestartSec=2
[Install]
WantedBy=default.target

View file

@ -52,40 +52,20 @@ function navidromeURL(path: string, params: Record<string, string>): string {
}).toString();
}
const WELCOME_TEXT = "Scan an album to begin.";
function App() {
const [album, setAlbum] = useState<AlbumType | null>(null);
const [buffer, setBuffer] = useState<string[]>([]);
const [nowPlaying, play] = useState<number>(0);
const [displayText, setDisplayText] = useState(WELCOME_TEXT);
const [searching, setSearching] = useState(false);
const [paused, setPaused] = useState(true);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const audioRef = useRef<HTMLAudioElement | null>(null);
const [lastClicked, setLastClicked] = useState(new Date);
const click = () => setLastClicked(new Date);
useEffect(() => {
const IDLE_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes
window.setTimeout(() => {
setDisplayText("Asleep. Tap screen to scan.");
fetch('/api/reader/auto', { method: 'POST' });
}, lastClicked.getTime() + IDLE_TIMEOUT_MS - new Date().getTime());
return () => {
setDisplayText(WELCOME_TEXT);
fetch('/api/reader/on', { method: 'POST' });
}
}, [lastClicked]);
const handleEnded = () => {
if ((album?.tracks?.length ?? 0) > nowPlaying + 1) { // if there's a next track
play(nowPlaying + 1);
setPaused(false);
} else {
setAlbum(null);
setDisplayText(WELCOME_TEXT); // Either I could always be diligent about resetting it elsewhere…or I can just do it here!
}
};
@ -149,7 +129,7 @@ function App() {
console.log("empty barcode; ignoring");
return;
}
setDisplayText("Searching…");
setSearching(true);
console.log("Scanned barcode:", barcode);
var mbRelease: IRelease | IReleaseMatch;
if (barcode.startsWith("mbid:")) {
@ -165,8 +145,8 @@ function App() {
inc: ['artist-credits', 'release-groups', 'genres'], // TODO
});
if (searchResponse.count === 0) {
setDisplayText("No album found for barcode: " + barcode);
setTimeout(() => setDisplayText(WELCOME_TEXT), 3000);
console.log("No album found for barcode:", barcode); // TODO: some kind of toast?
setSearching(false);
return;
}
mbRelease = searchResponse.releases[0];
@ -199,6 +179,7 @@ function App() {
// # …and play!
play(0);
setPaused(false);
setSearching(false);
} else { // Not found in Navidrome; populate with MusicBrainz data instead
const fullMbRelease = await mbApi.lookup('release', mbRelease.id, ['recordings', 'artist-credits', 'release-groups']);
const tracks: Track[] = fullMbRelease.media[0].tracks.map((t: ITrack) => ({ // TODO: handle multi-disc albums
@ -215,6 +196,7 @@ function App() {
coverArtLink: await getCoverArtSrcURL(fullMbRelease.id, fullMbRelease['release-group']?.id || '') || '',
})
console.log(album);
setSearching(false);
}
}
@ -232,7 +214,7 @@ function App() {
<p className='welcome' style={{ gridColumn: 'span 2' }}>This album cannot be played, as Chandler doesn't own a copy.</p>
);
return (
<div className="app" onPointerDown={click}>
<div className="app">
<audio
ref={audioRef}
src={album.tracks[nowPlaying].source}
@ -249,8 +231,10 @@ function App() {
{player}
</div>
)
} else if (searching) {
return (<div className="welcome">Searching</div>);
} else {
return (<div className="welcome" onPointerDown={click}>{displayText}</div>);
return (<div className="welcome">Scan an album to begin.</div>);
}
}