Skip to content

Commit

Permalink
Add modals and help
Browse files Browse the repository at this point in the history
  • Loading branch information
pcprince committed Aug 8, 2024
1 parent 65e20f3 commit 97b3cc4
Show file tree
Hide file tree
Showing 9 changed files with 261 additions and 81 deletions.
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<title>Spotify Clip Quiz</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
<button class="btn btn-primary" id="authorise-button">Authorise</button>
<body style="text-align: center;">
<button class="btn btn-success" id="authorise-button" style="font-size: small;">Authorise</button>
</body>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
Expand Down
6 changes: 4 additions & 2 deletions js/game.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* July 2024
*****************************************************************************/

/* global populateClipList, connectToPlayer, endTimer, playAll */
/* global playClipButtons, startTimerButton */
/* global populateClipList, connectToPlayer, endTimer, playAll, stopClip */
/* global playClipButtons, startTimerButton, helpButton */
/* global guessInput, giveUpButton, unguessedClips, revealSong */
/* global songClips */

Expand Down Expand Up @@ -44,6 +44,8 @@ function startGame () {
guessInput.disabled = false;
giveUpButton.disabled = false;

helpButton.disabled = false;

}

function endGame () {
Expand Down
35 changes: 27 additions & 8 deletions js/pkce.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
*****************************************************************************/

/* global localStorage, location */
/* global enablePrepareUI */

const clientId = 'b91c4f9175aa4b9d8ed6f43c23a5620c';
let redirectUri = (location.hostname === 'localhost' || location.hostname === '127.0.0.1') ? 'http://localhost:8000' : 'https://pcprince.co.uk/music-quiz';
redirectUri += '/play.html';
const homeURL = (location.hostname === 'localhost' || location.hostname === '127.0.0.1') ? 'http://localhost:8000' : 'https://pcprince.co.uk/music-quiz';
const redirectURL = homeURL + '/play.html';

const scope = 'streaming user-read-email user-read-private';
const authUrl = new URL('https://accounts.spotify.com/authorize');
Expand Down Expand Up @@ -56,7 +57,7 @@ async function redirect () {
scope,
code_challenge_method: 'S256',
code_challenge: codeChallenge,
redirect_uri: redirectUri
redirect_uri: redirectURL
};

authUrl.search = new URLSearchParams(params).toString();
Expand All @@ -82,7 +83,7 @@ async function authorise () {
client_id: clientId,
grant_type: 'authorization_code',
code,
redirect_uri: redirectUri,
redirect_uri: redirectURL,
code_verifier: codeVerifier
})
};
Expand All @@ -92,13 +93,31 @@ async function authorise () {
const body = await fetch(url, payload);
const response = await body.json();

localStorage.setItem('access_token', response.access_token);
if (response.access_token) {

console.log('Obtained access token:', response.access_token);
localStorage.setItem('access_token', response.access_token);

token = response.access_token;
console.log('Obtained access token:', response.access_token);

spotifyReady = true;
token = response.access_token;

spotifyReady = true;

enablePrepareUI();

} else {

console.error('Failed to verify code');
console.error('Error:', response.error);
console.log('Redirecting to home page in 3 seconds...');

setTimeout(() => {

window.location.href = homeURL;

}, 3000);

}

} else {

Expand Down
31 changes: 29 additions & 2 deletions js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@

/* global Spotify */
/* global token, songClips, updateGuessUI */
/* global helpButton */

// Define browser elements at the top of the script
const stopButton = document.getElementById('stop-button');
const resumeButton = document.getElementById('resume-button');

const prevButton = document.getElementById('prev-button');
const nextButton = document.getElementById('next-button');

const clipInfo = document.getElementById('clip-info');

let currentClipIndex = 0;
Expand All @@ -20,6 +23,9 @@ let isStopped = false;
let player;
let deviceId;

let stopAttempts = 0;
const MAX_STOP_ATTEMPTS = 5;

function playSpecificClip (index) {

currentClipIndex = index;
Expand Down Expand Up @@ -173,6 +179,15 @@ function playClipsSequentially () {

function stopClip () {

stopAttempts++;

if (stopAttempts > MAX_STOP_ATTEMPTS) {

console.error('Failed to stop playback after ' + MAX_STOP_ATTEMPTS + ' attempts. Giving up.');
return;

}

if (currentClipIndex !== -1) {

console.log('Stopping:', currentClipIndex);
Expand All @@ -190,9 +205,19 @@ function stopClip () {
headers: {
'Authorization': `Bearer ${token}`
}
}).then(() => {
}).then((response) => {

isStopped = true;
if (response.ok) {

isStopped = true;
stopAttempts = 0;

} else {

console.log('Failed to stop clip. Trying again...');
stopClip();

}

});

Expand Down Expand Up @@ -268,4 +293,6 @@ function resetUI () {
prevButton.disabled = true;
nextButton.disabled = true;

helpButton.disabled = true;

}
91 changes: 79 additions & 12 deletions js/songClips.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,22 @@

// https://open.spotify.com/playlist/5Rrf7mqN8uus2AaQQQNdc1

/* global token, prepareUI */
/* global stopButton, resumeButton, prevButton, nextButton, playSpecificClip */
/* global bootstrap */
/* global token, currentClipIndex */
/* global stopButton, resumeButton, prevButton, nextButton */
/* global prepareUI, resumeClip, stopClip, pauseTimer, resumeTimer, addSecondsToTimer, playSpecificClip */

const songUiContainer = document.getElementById('song-ui-container');

const helpButton = document.getElementById('help-button');
const helpModal = new bootstrap.Modal(document.getElementById('help-modal'), {
backdrop: 'static',
keyboard: false
});
const reselectNumberSpan = document.getElementById('reselect-number-span');
const cancelReselectButton = document.getElementById('cancel-reselect-button');
const reselectButton = document.getElementById('reselect-button');

// Song clip JSON structure
const fixedSongs = [
{
Expand Down Expand Up @@ -38,6 +49,21 @@ const DISTANCE_FROM_END_MS = 10000;

let songClips = [];

function selectRandomClip (durationMs) {

// Ensure that the start time is within valid range
const maxStartTime = Math.max(0, durationMs - DISTANCE_FROM_END_MS - 5000); // Last 10 seconds + 5 seconds clip length
const minStartTime = DISTANCE_FROM_START_MS; // Avoid the first 10 seconds
let startTime = Math.floor(Math.random() * (maxStartTime - minStartTime + 1)) + minStartTime;
startTime = Math.floor(startTime / 1000);

let clipLength = 5000; // Always 5 seconds
clipLength = Math.floor(clipLength / 1000);

return {startTime, clipLength};

}

async function getRandomSongsFromSpotifyRadio (playlistId, numberOfSongs, token) {

const allTracks = [];
Expand Down Expand Up @@ -75,21 +101,19 @@ async function getRandomSongsFromSpotifyRadio (playlistId, numberOfSongs, token)
const track = item.track;
const durationMs = track.duration_ms; // Track duration in milliseconds

// Ensure that the start time is within valid range
const maxStartTime = Math.max(0, durationMs - DISTANCE_FROM_END_MS - 5000); // Last 10 seconds + 5 seconds clip length
const minStartTime = DISTANCE_FROM_START_MS; // Avoid the first 10 seconds
const startTime = Math.floor(Math.random() * (maxStartTime - minStartTime + 1)) + minStartTime;
const randomClip = selectRandomClip(durationMs);

// Specific remasters seem to break the search
const trackName = track.name.split(' - ')[0];

return {
songName: trackName,
// TODO: This may cause issues when guessing the name of an artist for a song with multiple artists
// FIXME: This may cause issues when guessing the name of an artist for a song with multiple artists. Replace with array and check array
artist: track.artists.map(artist => artist.name).join(', '),
durationMs: track.duration_ms,
uri: track.uri,
startTime: Math.floor(startTime / 1000), // Convert to seconds
clipLength: 5 // Always 5 seconds
startTime: randomClip.startTime, // Convert to seconds
clipLength: randomClip.clipLength
};

});
Expand Down Expand Up @@ -133,7 +157,7 @@ async function searchTrack (songName, artist) {

const track = data.tracks.items[0];

return track.uri;
return track;

} else {

Expand Down Expand Up @@ -234,9 +258,14 @@ function processSongList (songs) {

if (!clip.uri) {

searchTrack(clip.songName, clip.artist).then(uri => {
searchTrack(clip.songName, clip.artist).then(track => {

songClips[i].uri = uri;
if (track) {

songClips[i].uri = track.uri;
songClips[i].durationMs = track.durationMs;

}

});

Expand All @@ -258,3 +287,41 @@ async function populateClipList (playlistId) {
processSongList(songs);

}

helpButton.addEventListener('click', () => {

reselectNumberSpan.innerText = currentClipIndex + 1;

stopClip();
pauseTimer();

helpModal.show();

});

cancelReselectButton.addEventListener('click', () => {

resumeClip();
resumeTimer();

helpModal.hide();

});

reselectButton.addEventListener('click', () => {

const newRandomClip = selectRandomClip(songClips[currentClipIndex].durationMs);

console.log('Updated clip ' + currentClipIndex + '. ' + songClips[currentClipIndex].startTime + ' -> ' + newRandomClip.startTime);

songClips[currentClipIndex].startTime = newRandomClip.startTime;
songClips[currentClipIndex].clipLength = newRandomClip.clipLength;

addSecondsToTimer(5);

resumeClip();
resumeTimer();

helpModal.hide();

});
Loading

0 comments on commit 97b3cc4

Please sign in to comment.