feat: add live listener count

This commit is contained in:
2024-07-26 22:34:44 +01:00
parent eae55aeb94
commit 45853a4d55
6 changed files with 138 additions and 17 deletions

View File

@@ -27,11 +27,16 @@
<div class="button-container">
<button id="play-btn" class="button">play</button>
</div>
<div class="volume-slider-container">
<output id="current-volume-label" for="volume-slider">100%</output>
<input id="volume-slider" type="range" min="0" max="100" step="1">
<div class="status-bar">
<p id="listener-count">0 person tuned in</p>
<div class="volume-slider-container">
<output id="current-volume-label" for="volume-slider">100%</output>
<input id="volume-slider" type="range" min="0" max="100" step="1" />
</div>
</div>
</main>
<img class="cat" src="./images/cat-0.png">
<img class="eeping-cat" src="./images/eeping-cat.png">
</div>

View File

@@ -1,3 +1,7 @@
const CROSSFADE_DURATION_MS = 5000;
const CROSSFADE_INTERVAL_MS = 20;
const AUDIO_DURATION_MS = 60000;
const playBtn = document.getElementById("play-btn");
const catImg = document.getElementsByClassName("cat")[0];
const volumeSlider = document.getElementById("volume-slider");
@@ -5,16 +9,14 @@ const currentVolumeLabel = document.getElementById("current-volume-label");
const clickAudio = document.getElementById("click-audio");
const clickReleaseAudio = document.getElementById("click-release-audio");
const meowAudio = document.getElementById("meow-audio");
const CROSSFADE_DURATION_MS = 5000;
const CROSSFADE_INTERVAL_MS = 20;
const AUDIO_DURATION_MS = 60000;
const listenerCountLabel = document.getElementById("listener-count");
let isPlaying = false;
let isFading = false;
let currentAudio;
let maxVolume = 100;
let currentVolume = 0;
let ws = connectToWebSocket();
function playAudio() {
// add a random query parameter at the end to prevent browser caching
@@ -22,11 +24,17 @@ function playAudio() {
currentAudio.onplay = () => {
isPlaying = true;
playBtn.innerText = "pause";
if (ws) {
ws.send("playing");
}
};
currentAudio.onpause = () => {
isPlaying = false;
currentVolume = 0;
playBtn.innerText = "play";
if (ws) {
ws.send("paused");
}
};
currentAudio.onended = () => {
currentVolume = 0;
@@ -122,6 +130,31 @@ function enableSpaceBarControl() {
});
}
function connectToWebSocket() {
const ws = new WebSocket(`ws://${location.host}/ws`);
ws.onmessage = (event) => {
console.log(event.data);
if (typeof event.data !== "string") {
return;
}
const listenerCountStr = event.data;
const listenerCount = Number.parseInt(listenerCountStr);
if (Number.isNaN(listenerCount)) {
return;
}
if (listenerCount <= 1) {
listenerCountLabel.innerText = `${listenerCount} person tuned in`;
} else {
listenerCountLabel.innerText = `${listenerCount} ppl tuned in`;
}
};
return ws;
}
playBtn.onmousedown = () => {
clickAudio.play();
document.addEventListener(
@@ -157,7 +190,15 @@ volumeSlider.oninput = () => {
clickReleaseAudio.volume = volumeSlider.value / 100;
meowAudio.volume = volumeSlider.value / 100;
};
volumeSlider.value = 100;
window.addEventListener("offline", () => {
ws = null;
});
window.addEventListener("online", () => {
ws = connectToWebSocket();
});
animateCat();
enableSpaceBarControl();

View File

@@ -108,6 +108,25 @@ a {
border-radius: 2px;
}
.status-bar {
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: -10;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 2rem;
z-index: 0;
color: var(--text);
}
.status-bar > #listener-count {
margin: 0;
opacity: 0.8;
}
.header {
font-weight: 800;
margin-bottom: 1rem;
@@ -152,11 +171,6 @@ a {
}
.volume-slider-container {
position: absolute;
top: 0;
right: 0;
padding: 0.5rem 1rem;
margin: 1rem;
display: flex;
justify-content: start;
align-items: center;