File size: 9,320 Bytes
a3de571
 
 
 
2de827e
9ba1026
8c8edb7
a3de571
728ac49
2de827e
 
 
 
728ac49
2de827e
 
 
 
cf7d706
2de827e
8c8edb7
728ac49
86cc9a8
2de827e
 
 
 
 
827e364
15698cf
2de827e
 
2d0c3d8
 
 
 
 
 
 
 
 
 
b832130
 
 
 
9b0ef7c
b832130
 
265b8b3
 
 
 
 
fdb3927
265b8b3
 
 
 
 
 
2d0c3d8
6c29de6
265b8b3
6c29de6
265b8b3
728ac49
 
265b8b3
 
 
 
 
86cc9a8
9e5b045
 
 
 
 
 
 
 
 
435ec37
2de827e
265b8b3
 
 
 
 
 
 
 
9e5b045
 
 
 
265b8b3
 
2de827e
265b8b3
 
 
 
2de827e
265b8b3
 
827e364
265b8b3
79d91d2
265b8b3
2de827e
 
 
0920432
 
f0f023f
462df3a
0920432
 
 
 
462df3a
0920432
 
462df3a
f0f023f
0920432
f0f023f
0920432
 
 
86cc9a8
 
e01d533
 
 
 
1410aee
e01d533
 
 
 
 
 
8c8edb7
 
 
 
 
7c98df5
8c8edb7
 
7c98df5
8c8edb7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7c98df5
8c8edb7
 
 
 
 
 
 
 
 
0181a40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8c8edb7
 
728ac49
df73cb7
 
 
 
 
4f08056
 
 
8c8edb7
 
df73cb7
e01d533
8487836
6de3914
36864be
 
 
 
 
e504282
8c8edb7
 
 
6de3914
8c8edb7
36864be
 
8c8edb7
8eedc8c
8c8edb7
bef4985
6abe8b6
7e66b3c
37fb96f
 
36864be
 
 
37fb96f
 
 
36864be
37fb96f
 
36864be
37fb96f
8c8edb7
 
e504282
 
6abe8b6
cf7d706
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
let isLooping = false; // Flag to manage loop state
let isLoadingMusic = false; // Flag to manage loading state
let currentPlaying = ''; // Store the filename of the currently playing music
let trackList = []; // Store currently displayed track filenames
let currentPage = 1;
let totalPages = 0;
let audio = new Audio();

window.onload = () => {
    // Attach click handlers for paging
    document.getElementById('prev-page').addEventListener('click', () => changePage(-1));
    document.getElementById('next-page').addEventListener('click', () => changePage(1));
    
    loadMusicList();
    document.getElementById('search-bar').addEventListener('keyup', () => {
        currentPage = 1; // Reset to first page on new search
        loadMusicList();
    });
    document.getElementById('audio-player').style.display = 'none';
    updatePageIndicator();
    setupCustomAudioPlayer();
};

function changePage(direction) {
    currentPage += direction;
    loadMusicList();
}

function updatePageIndicator(totalPages) {
    document.getElementById('page-indicator').textContent = `${currentPage}/${totalPages}`;
}

function debounce(func, delay) {
    let debounceTimer;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(() => func.apply(context, args), delay);
    };
}

function toggleLoop() {
    isLooping = !isLooping;
    document.getElementById('loop-toggle').textContent = `Loop: ${isLooping ? 'On' : 'Off'}`;
    const player = document.getElementById('audio-player');
    player.loop = isLooping;
}

function updateNavigationVisibility(searchQuery, totalPages) {
    const navigation = document.getElementById('navigation');
    if (searchQuery) {
        navigation.style.display = 'none'; // Hide navigation during search
    } else {
        navigation.style.display = 'flex'; // Show navigation when not searching
        document.getElementById('prev-page').disabled = currentPage <= 1;
        document.getElementById('next-page').disabled = currentPage >= totalPages;
    }
}

// Call loadMusicList when the search input changes
document.getElementById('search-bar').addEventListener('keyup', debounce(() => {
    currentPage = 1;
    loadMusicList();
}, 500)); // Waits for 0.5s of inactivity after typing

function loadMusicList() {
    const searchQuery = document.getElementById('search-bar').value.toLowerCase();
    const params = new URLSearchParams({ page: currentPage });
    
    if (searchQuery) {
        params.append('search', searchQuery); // Add search query to the request if it exists
    }

    // Disabling buttons and showing loading indicator before the request
    document.getElementById('prev-page').disabled = true;
    document.getElementById('next-page').disabled = true;
    
    const loaderContainer = document.getElementById('loader-container');
    loaderContainer.innerHTML = ''; // Clears any existing loader elements if they are present
    const loaderElement = document.createElement('div');
    loaderElement.classList.add('loader');
    loaderContainer.appendChild(loaderElement);
     
    fetch(`/tracks?${params}`)
    .then(response => response.json())
    .then(data => {
        const { tracks, total } = data;
        const musicList = document.getElementById('music-list');
        musicList.innerHTML = '';
        trackList = [];
        const totalPages = Math.ceil(total / 5);
        
         // Hide loading indicator
        loaderContainer.innerHTML = '';

        // Re-enable buttons based on page state
        document.getElementById('prev-page').disabled = currentPage === 1;
        document.getElementById('next-page').disabled = currentPage === totalPages || searchQuery;

        tracks.forEach(track => {
            trackList.push(track.filename);
            const musicItem = createMusicItem(track);
            musicList.appendChild(musicItem);
        });

        // Show/hide navigation based on whether there is a search query
        updatePageIndicator(totalPages);
        updateNavigationVisibility(searchQuery, totalPages);
        updatePlayingIndicator();
    });
}

function createMusicItem(track) {
    const musicItem = document.createElement('div');
    musicItem.classList.add('music-item');
    musicItem.setAttribute('data-filename', track.filename);

    const artworkImg = document.createElement('img');
    artworkImg.src = track.artwork ? track.artwork : 'placeholder_art.png';
    artworkImg.alt = 'Album Art';
    artworkImg.classList.add('album-art');

    const fileNameSpan = document.createElement('span');
    fileNameSpan.textContent = track.filename;

    musicItem.append(artworkImg, fileNameSpan);

    // Bind the music item click to playMusic
    musicItem.addEventListener('click', () => playMusic(track.filename));

    return musicItem;
}

function updatePlayingIndicator() {
    const musicItems = document.querySelectorAll('.music-item');
    musicItems.forEach(item => {
        if (item.getAttribute('data-filename') === currentPlaying) {
            item.style.boxShadow = '0 0 10px rgba(255, 255, 255, 0.5)'; // Green box shadow
        } else {
            item.style.boxShadow = ''; // Remove box shadow from other items
        }
    });
}

function setupCustomAudioPlayer() {
    // Play/Pause toggle
    document.getElementById('play-pause-btn').addEventListener('click', function() {
        if (audio.paused) {
            audio.play();
            this.textContent = '❙❙'; // Update button text to "❙❙"
        } else {
            audio.pause();
            this.textContent = 'β–Ά'; // Update button text to "β–Ά"
        }
    });

    // Update progress bar as the audio plays
    audio.addEventListener('timeupdate', function() {
        const progress = document.getElementById('progress-bar');
        progress.value = (audio.currentTime / audio.duration) * 100;
    });

    // Seek in the audio when the progress bar value changes
    document.getElementById('progress-bar').addEventListener('input', function() {
        const duration = audio.duration;
        audio.currentTime = (this.value * duration) / 100;
    });

    // Mute toggle
    document.getElementById('mute-btn').addEventListener('click', function() {
        audio.muted = !audio.muted;
        this.textContent = audio.muted ? 'πŸ”Š' : 'πŸ”‡'; // Update button text based on mute state
    });

    // Volume control
    document.getElementById('volume-control').addEventListener('input', function() {
        audio.volume = this.value / 100;
    });

    // Initial volume (100%)
    audio.volume = 1.0;

    audio.addEventListener('timeupdate', function() {
        updateProgress();
    });

    // When audio metadata is loaded, update duration
    audio.addEventListener('loadedmetadata', function() {
        document.getElementById('duration').textContent = formatTime(audio.duration);
    });
}

function updateProgress() {
    const progress = document.getElementById('progress-bar');
    progress.value = (audio.currentTime / audio.duration) * 100;
    document.getElementById('current-time').textContent = formatTime(audio.currentTime);
}

function formatTime(seconds) {
    let minutes = Math.floor(seconds / 60);
    minutes = (minutes >= 10) ? minutes : "0" + minutes;
    seconds = Math.floor(seconds % 60);
    seconds = (seconds >= 10) ? seconds : "0" + seconds;
    return minutes + ":" + seconds;
}

function playMusic(fileName) {
    if (isLoadingMusic && fileName === currentPlaying) {
        console.log("This song is already loading.");
        return;
    } else if (!isLoadingMusic && fileName === currentPlaying) {
        console.log("This song is already playing.");
        return;
    }

    isLoadingMusic = true;
    currentPlaying = fileName;

    updatePlayingIndicator();
    document.getElementById('audio-player').style.display = 'none'; // Hide custom player UI

    const loaderContainer = document.getElementById('loader-container');
    loaderContainer.innerHTML = '';
    const loaderElement = document.createElement('div');
    loaderElement.classList.add('loader');
    loaderContainer.appendChild(loaderElement);

    // Set the new source file for audio
    audio.src = `/music/${fileName}`;
    audio.load(); // Start loading the new source file

    audio.oncanplaythrough = () => {
        document.getElementById('audio-player').style.display = 'flex'; // Show custom player UI
        loaderContainer.innerHTML = '';
        isLoadingMusic = false;
        document.getElementById('play-pause-btn').textContent = '❙❙'; // Update play/pause button
        audio.play(); // Start playback
    };

    // Updated onended event handler within playMusic function
    audio.onended = () => {
      if (isLooping) {
          // Replay the current song
          audio.currentTime = 0;
          audio.play();
      } else {
          const currentIndex = trackList.indexOf(currentPlaying);
          if (currentIndex !== -1 && currentIndex < trackList.length - 1) {
              playMusic(trackList[currentIndex + 1]);
          }
      }
  };

    audio.onerror = () => {
        isLoadingMusic = false;
        alert(`Error loading the music: ${fileName}`);
        currentPlaying = ''; // Reset the current playing track
    };
}