fuzzyworld

hawk / time-arrows / files / public / main.js

Branch time-arrows · default branch · all branches

main.js

Blame: the commit that last changed each line · file · history

187c6bc2 2023-10-13 Pavel Safronov1document.getElementById('version').innerText = hawkInfo.version;
2document.getElementById('updated').innerText = hawkInfo.updated;
3
601035fb 2023-10-12 Pavel Safronov4const urlParams = new URLSearchParams(window.location.search);
5const code = urlParams.get('code');
6const error = urlParams.get('error');
7if (code) {
8 getToken(code).then(() => {
9 window.history.replaceState({}, document.title, '/');
0e0eaeff 2023-10-13 Pavel Safronov10 window.location = getSpotifyRedirectURL();
601035fb 2023-10-12 Pavel Safronov11 })
12} else if (error) {
13 console.error(error);
14 window.history.replaceState({}, document.title, '/');
0e0eaeff 2023-10-13 Pavel Safronov15 window.location = getSpotifyRedirectURL();
601035fb 2023-10-12 Pavel Safronov16}
17
18const accessToken = localStorage.getItem('access_token');
19const showSignInButton = !accessToken
20
21const signInButton = document.getElementById('signin');
0d3f2167 2023-10-13 Pavel Safronov22const signOutButton = document.getElementById('signout');
601035fb 2023-10-12 Pavel Safronov23const controlsDiv = document.getElementById('controls');
3e4871e9 2023-10-14 Pavel Safronov24const clearCacheButton = document.getElementById('clear-cache');
601035fb 2023-10-12 Pavel Safronov25if (showSignInButton) {
26 signInButton.setAttribute('style', 'display: block');
27 signInButton.addEventListener('click', signIn);
0d3f2167 2023-10-13 Pavel Safronov28 signOutButton.setAttribute('style', 'display: none');
3e4871e9 2023-10-14 Pavel Safronov29 clearCacheButton.setAttribute('style', 'display: none');
601035fb 2023-10-12 Pavel Safronov30 controlsDiv.setAttribute('style', 'display: none');
31} else {
32 signInButton.setAttribute('style', 'display: none');
33 controlsDiv.setAttribute('style', 'display: block');
0d3f2167 2023-10-13 Pavel Safronov34 signOutButton.setAttribute('style', 'display: block');
3e4871e9 2023-10-14 Pavel Safronov35 clearCacheButton.setAttribute('style', 'display: block');
cc1af884 2023-10-13 Pavel Safronov36 setCurrentPlayingSong();
37 setInterval(setCurrentPlayingSong, 5 * 1000);
601035fb 2023-10-12 Pavel Safronov38}
39
3397fb1c 2023-10-13 Pavel Safronov40async function setCurrentPlayingSong() {
41 const currentSongSpan = document.getElementById('current-song');
42 const currentTrack = await getPlayingTrack();
43 if (currentTrack && currentTrack.is_playing) {
44 currentSongSpan.innerText = `${currentTrack.item.name} by ${currentTrack.item.artists[0].name}`;
45 } else {
46 currentSongSpan.innerText = 'Nothing playing';
47 }
48}
49
50function formatDuration(ms) {
51 // Convert milliseconds to total seconds
52 let totalSeconds = Math.floor(ms / 1000);
53
54 // Calculate minutes and seconds
55 let minutes = Math.floor(totalSeconds / 60);
56 let seconds = totalSeconds % 60;
57
58 // Ensure seconds are always 2 digits
59 let formattedSeconds = seconds.toString().padStart(2, '0');
60
61 // Return formatted string
62 return `${minutes}:${formattedSeconds}`;
63}
64
65async function searchForMatch() {
66 const searchButton = document.getElementById('search');
8edcc887 2023-10-13 Pavel Safronov67 searchButton.setAttribute('disabled', 'disabled');
68 try {
69 const minutes = document.getElementById('minutes-input').value;
70 const seconds = document.getElementById('seconds-input').value;
71 const tracks = await search(minutes, seconds);
72 const resultsDiv = document.getElementById('results');
791409a6 2023-10-13 Pavel Safronov73 if (tracks.length == 0) {
cc1af884 2023-10-13 Pavel Safronov74 resultsDiv.innerHTML = 'No songs found for that duration.';
791409a6 2023-10-13 Pavel Safronov75 } else {
76 resultsDiv.innerHTML = '';
77 tracks.forEach(track => {
78 const songItem = document.querySelector('#song-item');
79 const html = interpolate(songItem.innerHTML, {
80 name: track.name,
81 artist: track.artists[0].name,
82 duration: formatDuration(track.duration_ms),
83 trackId: track.id,
84 trackHref: track.external_urls.spotify
85 });
86 resultsDiv.innerHTML += html;
8edcc887 2023-10-13 Pavel Safronov87 });
791409a6 2023-10-13 Pavel Safronov88 }
8286d52b 2023-10-13 Pavel Safronov89 } catch (e) {
90 console.error(e);
91 reportStatus(`Encountered error while searching: ${e}`);
8edcc887 2023-10-13 Pavel Safronov92 } finally {
93 searchButton.removeAttribute('disabled');
94 }
95}
3bf5fcbb 2023-10-13 Pavel Safronov96
97async function search(minutes, seconds) {
8c91be32 2023-10-13 Pavel Safronov98 reportStatus(`Retrieving albums`);
e39bdb17 2023-10-14 Pavel Safronov99 const albums = await getAlbums((state) => {
100 const { processedCount, totalCount } = state;
101 if (totalCount <= 0) {
102 totalCount = "???"
103 }
104 reportStatus(`Retrieving albums: ${processedCount} of ${totalCount}`);
105 });
3bf5fcbb 2023-10-13 Pavel Safronov106
107 const foundTracks = [];
4d32aa41 2023-10-13 Pavel Safronov108 for (let i = 0; i < albums.length; i++) {
109 const album = albums[i];
e39bdb17 2023-10-14 Pavel Safronov110 const tracks = await getTracks(album.album.id, (state) => {
111 const { processedCount, totalCount } = state;
112 if (totalCount <= 0) {
113 totalCount = "???"
114 }
115 reportStatus(`Retrieving tracks for album ${i + 1} of ${albums.length}: ${processedCount} of ${totalCount}`);
116 });
3bf5fcbb 2023-10-13 Pavel Safronov117
4d32aa41 2023-10-13 Pavel Safronov118 for (let j = 0; j < tracks.length; j++) {
119 const track = tracks[j];
3bf5fcbb 2023-10-13 Pavel Safronov120 const duration = track.duration_ms;
121 const durationInSeconds = Math.floor(duration / 1000);
122 const durationInMinutes = Math.floor(durationInSeconds / 60);
123 const durationInRemainingSeconds = durationInSeconds % 60;
124
125 if (durationInMinutes == minutes && durationInRemainingSeconds == seconds) {
126 foundTracks.push(track);
127 }
128 }
129 }
8c91be32 2023-10-13 Pavel Safronov130
131 reportStatus(`Found ${foundTracks.length} track(s)`);
3bf5fcbb 2023-10-13 Pavel Safronov132 return foundTracks;
cc1af884 2023-10-13 Pavel Safronov133}
134
135async function pauseOrPlay() {
136 const currentTrack = await getPlayingTrack();
137 if (currentTrack && currentTrack.is_playing) {
138 await pause();
139 } else {
140 await play();
141 }
142 setCurrentPlayingSong();
3397fb1c 2023-10-13 Pavel Safronov143}
144
145async function playChosenSong(trackId) {
146 await playTrack(trackId);
147 setCurrentPlayingSong();
8c91be32 2023-10-13 Pavel Safronov148}
149
150let statusText = '';
151setInterval(() => {
152 const statusDiv = document.getElementById('status');
153 statusDiv.innerText = statusText;
e39bdb17 2023-10-14 Pavel Safronov154}, 100);
8c91be32 2023-10-13 Pavel Safronov155
156function reportStatus(text) {
157 statusText = text;
158}
159
160async function clearDb() {
161 await deleteDb();
162 window.location.reload();
3bf5fcbb 2023-10-13 Pavel Safronov163}