This commit is contained in:
Josh Patra
2025-04-20 16:23:23 -04:00
parent 737ec9bd14
commit 8d9a493e46

View File

@@ -158,7 +158,7 @@
let iframeElement: HTMLIFrameElement; let iframeElement: HTMLIFrameElement;
let widget: any; let widget: any;
let widgetReady = false; let widgetReady = false;
let loading = true; // disable play until we warm up the widget let loading = true;
let artworkUrl = ''; let artworkUrl = '';
let isPlaying = false; let isPlaying = false;
let currentPosition = 0; let currentPosition = 0;
@@ -209,12 +209,9 @@
function startPolling() { function startPolling() {
isPlaying = true; isPlaying = true;
// clear any previous timers
clearInterval(progressInterval); clearInterval(progressInterval);
clearTimeout(snippetTimeout); clearTimeout(snippetTimeout);
// progress bar updater
progressInterval = setInterval(() => { progressInterval = setInterval(() => {
widget.getPosition((pos: number) => { widget.getPosition((pos: number) => {
const limit = gameOver ? fullDuration : segmentDurations[attemptCount]; const limit = gameOver ? fullDuration : segmentDurations[attemptCount];
@@ -222,12 +219,13 @@
}); });
}, 100); }, 100);
// clamp at the end of this segment
if (!gameOver) { if (!gameOver) {
// +100ms fudge so we never cut off at 1.999s instead of 2s
const clampMs = segmentDurations[attemptCount] + 100;
snippetTimeout = setTimeout(() => { snippetTimeout = setTimeout(() => {
widget.pause(); widget.pause();
currentPosition = segmentDurations[attemptCount]; currentPosition = segmentDurations[attemptCount];
}, segmentDurations[attemptCount]); }, clampMs);
} }
} }
@@ -238,7 +236,6 @@
} }
onMount(async () => { onMount(async () => {
// dynamically load SC API if needed
if (typeof window.SC === 'undefined') { if (typeof window.SC === 'undefined') {
await new Promise<void>((resolve, reject) => { await new Promise<void>((resolve, reject) => {
const tag = document.createElement('script'); const tag = document.createElement('script');
@@ -250,23 +247,20 @@
}); });
} }
// darkmode listener
window window
.matchMedia('(prefers-color-scheme: dark)') .matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (e) => (darkMode = e.matches)); .addEventListener('change', (e) => (darkMode = e.matches));
// countdown
updateTime(); updateTime();
countdownInterval = setInterval(updateTime, 1000); countdownInterval = setInterval(updateTime, 1000);
// SoundCloud widget
widget = SC.Widget(iframeElement); widget = SC.Widget(iframeElement);
widget.bind(SC.Widget.Events.READY, () => { widget.bind(SC.Widget.Events.READY, () => {
// grab duration & artwork
widget.getDuration((d: number) => (fullDuration = d)); widget.getDuration((d: number) => (fullDuration = d));
widget.getCurrentSound((sound: any) => { widget.getCurrentSound((sound: any) => {
artworkUrl = sound.artwork_url || ''; artworkUrl = sound.artwork_url || '';
}); });
// warm up on Netlify
setTimeout(() => { setTimeout(() => {
widget.play(); widget.play();
widget.pause(); widget.pause();
@@ -276,9 +270,7 @@
}, 1000); }, 1000);
}); });
widget.bind(SC.Widget.Events.PLAY, () => { // no more PLAY binding here!
startPolling();
});
widget.bind(SC.Widget.Events.PAUSE, stopAllTimers); widget.bind(SC.Widget.Events.PAUSE, stopAllTimers);
widget.bind(SC.Widget.Events.FINISH, () => { widget.bind(SC.Widget.Events.FINISH, () => {
currentPosition = gameOver ? fullDuration : segmentDurations[attemptCount]; currentPosition = gameOver ? fullDuration : segmentDurations[attemptCount];
@@ -307,7 +299,6 @@
function playSegment() { function playSegment() {
if (!widgetReady || loading) return; if (!widgetReady || loading) return;
stopAllTimers(); stopAllTimers();
currentPosition = 0;
widget.seekTo(0); widget.seekTo(0);
widget.play(); widget.play();
startPolling(); startPolling();
@@ -521,13 +512,14 @@
</div> </div>
{/if} {/if}
<!-- Invisible iframe for mobile autoplay -->
<iframe <iframe
bind:this={iframeElement} bind:this={iframeElement}
src={`https://w.soundcloud.com/player/?url=${encodeURIComponent(currentTrack.url)}`} src={`https://w.soundcloud.com/player/?url=${encodeURIComponent(currentTrack.url)}`}
style="position:absolute; width:0; height:0; border:0; overflow:hidden; visibility:hidden;" style="position:absolute; width:0; height:0; border:0; overflow:hidden; visibility:hidden;"
allow="autoplay" allow="autoplay"
title="preview player" title="preview player"
/> ></iframe>
<!-- Bottompinned controls --> <!-- Bottompinned controls -->
<div class="mt-auto px-4 pb-4"> <div class="mt-auto px-4 pb-4">