nocopyrightsounds-widget 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +205 -74
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
class NCSWidget {
|
|
2
2
|
constructor(options = {}) {
|
|
3
3
|
this.position = options.position || 'bottom-right';
|
|
4
|
-
|
|
5
|
-
// 🌟 L'URL de VOTRE serveur par défaut (les autres devs n'auront rien à faire)
|
|
6
|
-
this.apiUrl = options.apiUrl || 'https://ncs-backend-api.onrender.com';
|
|
4
|
+
this.apiUrl = options.apiUrl || 'https://ncs-backend-api.onrender.com'; // ⚠️ METTEZ VOTRE URL RENDER ICI
|
|
7
5
|
|
|
8
6
|
this.audio = new Audio();
|
|
9
7
|
this.isPlaying = false;
|
|
10
8
|
|
|
11
|
-
//
|
|
9
|
+
// Historique et File d'attente (Préchargement)
|
|
10
|
+
this.trackHistory = [];
|
|
11
|
+
this.currentHistoryIndex = -1;
|
|
12
|
+
this.nextTracksQueue = [];
|
|
13
|
+
this.isPreloading = false;
|
|
14
|
+
|
|
12
15
|
this.isBrowser = typeof window !== 'undefined';
|
|
13
16
|
if (this.isBrowser) {
|
|
14
17
|
this.audio.volume = localStorage.getItem('ncs_volume') || 0.5;
|
|
@@ -16,16 +19,18 @@ class NCSWidget {
|
|
|
16
19
|
this.savedTrack = localStorage.getItem('ncs_currentTrack') || null;
|
|
17
20
|
this.savedCover = localStorage.getItem('ncs_currentCover') || null;
|
|
18
21
|
this.savedTitle = localStorage.getItem('ncs_currentTitle') || null;
|
|
22
|
+
this.isWidgetOpen = localStorage.getItem('ncs_isOpen') === 'true';
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
this.initDOM();
|
|
22
26
|
this.attachEvents();
|
|
23
27
|
|
|
24
|
-
//
|
|
28
|
+
// Initialisation de la musique
|
|
25
29
|
if (this.savedTrack && this.savedTime > 0) {
|
|
26
30
|
this.restoreTrack();
|
|
31
|
+
this.fillQueue(this.genreSelect.value); // Lancer le préchargement en fond
|
|
27
32
|
} else {
|
|
28
|
-
this.
|
|
33
|
+
this.changeGenre(this.genreSelect.value);
|
|
29
34
|
}
|
|
30
35
|
}
|
|
31
36
|
|
|
@@ -38,44 +43,68 @@ class NCSWidget {
|
|
|
38
43
|
const style = document.createElement('style');
|
|
39
44
|
style.textContent = `
|
|
40
45
|
#ncs-persistent-widget { position: fixed; ${this.getPositionStyles()} z-index: 99999; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
|
|
46
|
+
|
|
47
|
+
/* État Réduit */
|
|
41
48
|
.ncs-minimized { width: 55px; height: 55px; border-radius: 50%; background: linear-gradient(135deg, #1DB954, #1ed760); cursor: pointer; display: flex; justify-content: center; align-items: center; box-shadow: 0 6px 15px rgba(29, 185, 84, 0.4); font-size: 24px; transition: transform 0.2s; }
|
|
42
49
|
.ncs-minimized:hover { transform: scale(1.1); }
|
|
43
|
-
.ncs-expanded { width: 300px; background: #181818; color: white; border-radius: 16px; padding: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); display: none; border: 1px solid #282828; }
|
|
44
|
-
.ncs-expanded.active { display: block; animation: ncsFadeIn 0.3s ease; }
|
|
45
50
|
.ncs-minimized.hidden { display: none; }
|
|
46
51
|
|
|
52
|
+
/* État Agrandit */
|
|
53
|
+
.ncs-expanded { width: 320px; background: #181818; color: white; border-radius: 16px; padding: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); display: none; border: 1px solid #282828; }
|
|
54
|
+
.ncs-expanded.active { display: block; animation: ncsFadeIn 0.3s ease; }
|
|
55
|
+
|
|
56
|
+
/* Header & Infos */
|
|
47
57
|
.ncs-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; }
|
|
48
|
-
.ncs-header strong { font-size: 14px; font-weight: 600; color: #b3b3b3; letter-spacing: 1px; text-transform: uppercase; }
|
|
58
|
+
.ncs-header strong { font-size: 14px; font-weight: 600; color: #b3b3b3; letter-spacing: 1px; text-transform: uppercase; display: flex; align-items: center; gap: 8px; }
|
|
49
59
|
.ncs-close-btn { background: transparent; border: none; color: #b3b3b3; font-size: 18px; cursor: pointer; padding: 0; transition: color 0.2s; }
|
|
50
60
|
.ncs-close-btn:hover { color: white; }
|
|
51
61
|
|
|
62
|
+
/* Animation Visualizer */
|
|
63
|
+
.ncs-visualizer { display: flex; gap: 2px; height: 12px; align-items: flex-end; opacity: 0; transition: opacity 0.3s; }
|
|
64
|
+
.ncs-visualizer.playing { opacity: 1; }
|
|
65
|
+
.ncs-bar { width: 3px; background: #1DB954; border-radius: 2px; animation: bounce 0.5s infinite alternate; }
|
|
66
|
+
.ncs-bar:nth-child(2) { animation-delay: 0.15s; }
|
|
67
|
+
.ncs-bar:nth-child(3) { animation-delay: 0.3s; }
|
|
68
|
+
@keyframes bounce { from { height: 3px; } to { height: 12px; } }
|
|
69
|
+
|
|
52
70
|
.ncs-track-info { display: flex; align-items: center; margin-bottom: 15px; }
|
|
53
|
-
.ncs-cover { width:
|
|
71
|
+
.ncs-cover { width: 65px; height: 65px; border-radius: 8px; background: #282828; margin-right: 15px; object-fit: cover; box-shadow: 0 4px 10px rgba(0,0,0,0.3); }
|
|
54
72
|
.ncs-details { flex: 1; overflow: hidden; }
|
|
55
|
-
#ncs-track-name { font-size:
|
|
73
|
+
#ncs-track-name { font-size: 14px; font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 5px; }
|
|
56
74
|
#ncs-genre { width: 100%; padding: 4px 8px; background: #282828; color: #b3b3b3; border: 1px solid #333; border-radius: 4px; font-size: 12px; cursor: pointer; outline: none; }
|
|
57
75
|
|
|
76
|
+
/* Progress & Controls */
|
|
58
77
|
.ncs-progress-container { margin-bottom: 15px; display:flex; align-items:center; gap: 10px; font-size: 11px; color: #b3b3b3; }
|
|
59
78
|
.ncs-slider { -webkit-appearance: none; width: 100%; height: 4px; background: #535353; border-radius: 2px; outline: none; cursor: pointer; }
|
|
60
79
|
.ncs-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 12px; height: 12px; border-radius: 50%; background: #1DB954; cursor: pointer; transition: transform 0.1s; }
|
|
61
80
|
.ncs-slider::-webkit-slider-thumb:hover { transform: scale(1.2); }
|
|
62
81
|
|
|
63
|
-
.ncs-controls { display: flex; justify-content: center; align-items: center; gap:
|
|
64
|
-
.ncs-btn-circle { width:
|
|
82
|
+
.ncs-controls { display: flex; justify-content: center; align-items: center; gap: 15px; margin-bottom: 15px; }
|
|
83
|
+
.ncs-btn-circle { width: 50px; height: 50px; border-radius: 50%; background: white; color: black; border: none; font-size: 20px; cursor: pointer; display:flex; justify-content:center; align-items:center; transition: transform 0.2s; padding-left: 4px; }
|
|
84
|
+
.ncs-btn-circle.paused { padding-left: 0; }
|
|
65
85
|
.ncs-btn-circle:hover { transform: scale(1.05); }
|
|
66
|
-
.ncs-btn-icon { background: transparent; border: none; color: #b3b3b3; font-size: 20px; cursor: pointer; transition: color 0.2s; }
|
|
86
|
+
.ncs-btn-icon { background: transparent; border: none; color: #b3b3b3; font-size: 20px; cursor: pointer; transition: color 0.2s; padding: 5px; }
|
|
67
87
|
.ncs-btn-icon:hover { color: white; }
|
|
88
|
+
.ncs-btn-icon:disabled { color: #333; cursor: not-allowed; }
|
|
68
89
|
|
|
69
|
-
.ncs-
|
|
90
|
+
.ncs-bottom-bar { display: flex; justify-content: space-between; align-items: center; }
|
|
91
|
+
.ncs-volume-container { display: flex; align-items: center; gap: 8px; color: #b3b3b3; flex: 1; margin-right: 15px; }
|
|
92
|
+
.ncs-download-btn { color: #b3b3b3; text-decoration: none; font-size: 18px; transition: color 0.2s; }
|
|
93
|
+
.ncs-download-btn:hover { color: #1DB954; }
|
|
70
94
|
|
|
71
95
|
@keyframes ncsFadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
|
|
72
96
|
`;
|
|
73
97
|
|
|
74
98
|
this.container.innerHTML = `
|
|
75
|
-
<div class="ncs-minimized">🎧</div>
|
|
76
|
-
<div class="ncs-expanded">
|
|
99
|
+
<div class="ncs-minimized ${this.isWidgetOpen ? 'hidden' : ''}">🎧</div>
|
|
100
|
+
<div class="ncs-expanded ${this.isWidgetOpen ? 'active' : ''}">
|
|
77
101
|
<div class="ncs-header">
|
|
78
|
-
<strong>
|
|
102
|
+
<strong>
|
|
103
|
+
NCS Player
|
|
104
|
+
<div class="ncs-visualizer" id="ncs-vis">
|
|
105
|
+
<div class="ncs-bar"></div><div class="ncs-bar"></div><div class="ncs-bar"></div>
|
|
106
|
+
</div>
|
|
107
|
+
</strong>
|
|
79
108
|
<button class="ncs-close-btn">✖</button>
|
|
80
109
|
</div>
|
|
81
110
|
|
|
@@ -99,13 +128,17 @@ class NCSWidget {
|
|
|
99
128
|
</div>
|
|
100
129
|
|
|
101
130
|
<div class="ncs-controls">
|
|
131
|
+
<button id="ncs-prev" class="ncs-btn-icon" disabled>⏮</button>
|
|
102
132
|
<button id="ncs-play-pause" class="ncs-btn-circle">▶</button>
|
|
103
133
|
<button id="ncs-next" class="ncs-btn-icon">⏭</button>
|
|
104
134
|
</div>
|
|
105
135
|
|
|
106
|
-
<div class="ncs-
|
|
107
|
-
<
|
|
108
|
-
|
|
136
|
+
<div class="ncs-bottom-bar">
|
|
137
|
+
<div class="ncs-volume-container">
|
|
138
|
+
<span>🔉</span>
|
|
139
|
+
<input type="range" id="ncs-volume" class="ncs-slider" min="0" max="1" step="0.05" value="${this.audio.volume}">
|
|
140
|
+
</div>
|
|
141
|
+
<a id="ncs-download" class="ncs-download-btn" href="#" target="_blank" title="Télécharger ce titre">⬇️</a>
|
|
109
142
|
</div>
|
|
110
143
|
</div>
|
|
111
144
|
`;
|
|
@@ -113,11 +146,13 @@ class NCSWidget {
|
|
|
113
146
|
document.head.appendChild(style);
|
|
114
147
|
document.body.appendChild(this.container);
|
|
115
148
|
|
|
116
|
-
// Références
|
|
117
149
|
this.minimized = this.container.querySelector('.ncs-minimized');
|
|
118
150
|
this.expanded = this.container.querySelector('.ncs-expanded');
|
|
119
151
|
this.playBtn = this.container.querySelector('#ncs-play-pause');
|
|
120
152
|
this.nextBtn = this.container.querySelector('#ncs-next');
|
|
153
|
+
this.prevBtn = this.container.querySelector('#ncs-prev');
|
|
154
|
+
this.downloadBtn = this.container.querySelector('#ncs-download');
|
|
155
|
+
this.visualizer = this.container.querySelector('#ncs-vis');
|
|
121
156
|
this.genreSelect = this.container.querySelector('#ncs-genre');
|
|
122
157
|
this.trackName = this.container.querySelector('#ncs-track-name');
|
|
123
158
|
this.coverImg = this.container.querySelector('#ncs-cover');
|
|
@@ -140,32 +175,37 @@ class NCSWidget {
|
|
|
140
175
|
attachEvents() {
|
|
141
176
|
if (!this.isBrowser) return;
|
|
142
177
|
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
|
|
178
|
+
this.minimized.addEventListener('click', () => this.toggleState(true));
|
|
179
|
+
this.container.querySelector('.ncs-close-btn').addEventListener('click', () => this.toggleState(false));
|
|
180
|
+
|
|
146
181
|
this.playBtn.addEventListener('click', () => this.togglePlay());
|
|
147
|
-
this.nextBtn.addEventListener('click', () => this.
|
|
148
|
-
this.
|
|
182
|
+
this.nextBtn.addEventListener('click', () => this.handleNext());
|
|
183
|
+
this.prevBtn.addEventListener('click', () => this.handlePrev());
|
|
184
|
+
this.genreSelect.addEventListener('change', (e) => this.changeGenre(e.target.value));
|
|
149
185
|
|
|
150
|
-
|
|
186
|
+
this.audio.addEventListener('play', () => {
|
|
187
|
+
this.playBtn.innerHTML = '⏸';
|
|
188
|
+
this.playBtn.classList.add('paused');
|
|
189
|
+
this.visualizer.classList.add('playing');
|
|
190
|
+
});
|
|
191
|
+
this.audio.addEventListener('pause', () => {
|
|
192
|
+
this.playBtn.innerHTML = '▶';
|
|
193
|
+
this.playBtn.classList.remove('paused');
|
|
194
|
+
this.visualizer.classList.remove('playing');
|
|
195
|
+
});
|
|
151
196
|
this.audio.addEventListener('timeupdate', () => this.updateProgress());
|
|
152
197
|
this.audio.addEventListener('loadedmetadata', () => {
|
|
153
198
|
this.progressBar.max = this.audio.duration;
|
|
154
199
|
this.timeTotal.innerText = this.formatTime(this.audio.duration);
|
|
155
200
|
});
|
|
156
|
-
this.audio.addEventListener('ended', () => this.
|
|
201
|
+
this.audio.addEventListener('ended', () => this.handleNext());
|
|
157
202
|
|
|
158
|
-
|
|
159
|
-
this.progressBar.addEventListener('input', (e) => {
|
|
160
|
-
this.audio.currentTime = e.target.value;
|
|
161
|
-
});
|
|
162
|
-
|
|
203
|
+
this.progressBar.addEventListener('input', (e) => { this.audio.currentTime = e.target.value; });
|
|
163
204
|
this.volumeBar.addEventListener('input', (e) => {
|
|
164
205
|
this.audio.volume = e.target.value;
|
|
165
206
|
localStorage.setItem('ncs_volume', e.target.value);
|
|
166
207
|
});
|
|
167
208
|
|
|
168
|
-
// Sauvegarde de la progression chaque seconde
|
|
169
209
|
setInterval(() => {
|
|
170
210
|
if (this.isPlaying && this.audio.currentTime > 0) {
|
|
171
211
|
localStorage.setItem('ncs_currentTime', this.audio.currentTime);
|
|
@@ -173,22 +213,25 @@ class NCSWidget {
|
|
|
173
213
|
}, 1000);
|
|
174
214
|
}
|
|
175
215
|
|
|
176
|
-
toggleState() {
|
|
177
|
-
|
|
178
|
-
|
|
216
|
+
toggleState(isOpen) {
|
|
217
|
+
if (isOpen) {
|
|
218
|
+
this.minimized.classList.add('hidden');
|
|
219
|
+
this.expanded.classList.add('active');
|
|
220
|
+
} else {
|
|
221
|
+
this.minimized.classList.remove('hidden');
|
|
222
|
+
this.expanded.classList.remove('active');
|
|
223
|
+
}
|
|
224
|
+
localStorage.setItem('ncs_isOpen', isOpen);
|
|
179
225
|
}
|
|
180
226
|
|
|
181
227
|
togglePlay() {
|
|
182
228
|
if (this.isPlaying) {
|
|
183
229
|
this.audio.pause();
|
|
184
|
-
this.playBtn.innerHTML = '▶';
|
|
185
230
|
} else {
|
|
186
|
-
// Reprendre là où on en était si c'est le 1er clic après un changement de page
|
|
187
231
|
if (this.savedTime > 0 && this.audio.currentTime === 0) {
|
|
188
232
|
this.audio.currentTime = this.savedTime;
|
|
189
233
|
}
|
|
190
234
|
this.audio.play();
|
|
191
|
-
this.playBtn.innerHTML = '⏸';
|
|
192
235
|
}
|
|
193
236
|
this.isPlaying = !this.isPlaying;
|
|
194
237
|
}
|
|
@@ -205,47 +248,135 @@ class NCSWidget {
|
|
|
205
248
|
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
|
|
206
249
|
}
|
|
207
250
|
|
|
251
|
+
// ----------------------------------------------------
|
|
252
|
+
// GESTION DES REQUÊTES ET DE LA FILE D'ATTENTE (NOUVEAU)
|
|
253
|
+
// ----------------------------------------------------
|
|
254
|
+
|
|
255
|
+
async fetchSingleTrack(genre) {
|
|
256
|
+
try {
|
|
257
|
+
const response = await fetch(`${this.apiUrl}/search?genre=${genre}`);
|
|
258
|
+
const data = await response.json();
|
|
259
|
+
return (data && data.length > 0) ? data[0] : null;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
console.error("Erreur API NCS:", error);
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async fillQueue(genre) {
|
|
267
|
+
if (this.isPreloading) return; // Éviter de lancer plusieurs recherches en même temps
|
|
268
|
+
this.isPreloading = true;
|
|
269
|
+
|
|
270
|
+
// Tant qu'on n'a pas 2 musiques d'avance, on cherche silencieusement
|
|
271
|
+
while (this.nextTracksQueue.length < 2) {
|
|
272
|
+
const track = await this.fetchSingleTrack(genre);
|
|
273
|
+
if (track) {
|
|
274
|
+
// Vérifier qu'on n'ajoute pas un doublon dans la file
|
|
275
|
+
const isDuplicate = this.nextTracksQueue.find(t => t.audioUrl === track.audioUrl);
|
|
276
|
+
if (!isDuplicate) this.nextTracksQueue.push(track);
|
|
277
|
+
} else {
|
|
278
|
+
break; // Stop si l'API ne répond plus
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
this.isPreloading = false;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async changeGenre(genre) {
|
|
286
|
+
this.nextTracksQueue = []; // On vide la file d'attente car le genre a changé
|
|
287
|
+
this.trackName.innerText = "Recherche...";
|
|
288
|
+
|
|
289
|
+
const track = await this.fetchSingleTrack(genre);
|
|
290
|
+
if (track) {
|
|
291
|
+
this.setTrack(track, true);
|
|
292
|
+
this.fillQueue(genre); // On lance le préchargement en fond !
|
|
293
|
+
} else {
|
|
294
|
+
this.trackName.innerText = "Aucune piste trouvée.";
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ----------------------------------------------------
|
|
299
|
+
// GESTION DU LECTEUR ET HISTORIQUE
|
|
300
|
+
// ----------------------------------------------------
|
|
301
|
+
|
|
208
302
|
restoreTrack() {
|
|
209
303
|
this.audio.src = this.savedTrack;
|
|
210
304
|
this.trackName.innerText = this.savedTitle;
|
|
211
305
|
if (this.savedCover) this.coverImg.src = this.savedCover;
|
|
212
|
-
|
|
306
|
+
this.downloadBtn.href = this.savedTrack;
|
|
307
|
+
|
|
308
|
+
this.trackHistory = [{
|
|
309
|
+
audioUrl: this.savedTrack,
|
|
310
|
+
title: this.savedTitle,
|
|
311
|
+
coverUrl: this.savedCover
|
|
312
|
+
}];
|
|
313
|
+
this.currentHistoryIndex = 0;
|
|
213
314
|
}
|
|
214
315
|
|
|
215
|
-
|
|
216
|
-
this.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
316
|
+
setTrack(track, addToHistory = false) {
|
|
317
|
+
this.audio.src = track.audioUrl;
|
|
318
|
+
this.trackName.innerText = track.title;
|
|
319
|
+
if (track.coverUrl) this.coverImg.src = track.coverUrl;
|
|
320
|
+
this.downloadBtn.href = track.audioUrl;
|
|
321
|
+
|
|
322
|
+
if (addToHistory) {
|
|
323
|
+
// Effacer le "futur" si on était revenu en arrière avant d'avancer
|
|
324
|
+
this.trackHistory = this.trackHistory.slice(0, this.currentHistoryIndex + 1);
|
|
325
|
+
this.trackHistory.push(track);
|
|
326
|
+
this.currentHistoryIndex = this.trackHistory.length - 1;
|
|
327
|
+
this.prevBtn.disabled = this.currentHistoryIndex <= 0;
|
|
328
|
+
}
|
|
220
329
|
|
|
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
|
-
|
|
330
|
+
if (this.isBrowser) {
|
|
331
|
+
localStorage.setItem('ncs_currentTrack', track.audioUrl);
|
|
332
|
+
localStorage.setItem('ncs_currentTitle', track.title);
|
|
333
|
+
localStorage.setItem('ncs_currentCover', track.coverUrl);
|
|
334
|
+
localStorage.setItem('ncs_currentTime', 0);
|
|
335
|
+
this.savedTime = 0;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (this.isPlaying) {
|
|
339
|
+
this.audio.play();
|
|
340
|
+
} else if (this.audio.currentTime === 0 && this.playBtn.innerHTML === '⏸') {
|
|
341
|
+
this.audio.play();
|
|
342
|
+
this.isPlaying = true;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async handleNext() {
|
|
347
|
+
const genre = this.genreSelect.value;
|
|
348
|
+
|
|
349
|
+
// Cas 1 : On a reculé dans l'historique et on veut revenir à la musique suivante connue
|
|
350
|
+
if (this.currentHistoryIndex < this.trackHistory.length - 1) {
|
|
351
|
+
this.currentHistoryIndex++;
|
|
352
|
+
this.setTrack(this.trackHistory[this.currentHistoryIndex], false);
|
|
353
|
+
this.prevBtn.disabled = this.currentHistoryIndex <= 0;
|
|
354
|
+
}
|
|
355
|
+
// Cas 2 : L'historique est au bout, on pioche dans la file d'attente (instantané !)
|
|
356
|
+
else if (this.nextTracksQueue.length > 0) {
|
|
357
|
+
const nextTrack = this.nextTracksQueue.shift(); // Prend la 1ère de la file
|
|
358
|
+
this.setTrack(nextTrack, true);
|
|
359
|
+
this.fillQueue(genre); // On refait le plein discrètement
|
|
360
|
+
}
|
|
361
|
+
// Cas 3 : L'utilisateur clique trop vite et la file d'attente est vide (Secours)
|
|
362
|
+
else {
|
|
363
|
+
this.trackName.innerText = "Recherche...";
|
|
364
|
+
const track = await this.fetchSingleTrack(genre);
|
|
365
|
+
if (track) {
|
|
366
|
+
this.setTrack(track, true);
|
|
367
|
+
this.fillQueue(genre);
|
|
246
368
|
}
|
|
247
|
-
}
|
|
248
|
-
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
handlePrev() {
|
|
373
|
+
if (this.currentHistoryIndex > 0) {
|
|
374
|
+
this.currentHistoryIndex--;
|
|
375
|
+
this.setTrack(this.trackHistory[this.currentHistoryIndex], false);
|
|
376
|
+
this.prevBtn.disabled = this.currentHistoryIndex <= 0;
|
|
377
|
+
|
|
378
|
+
this.savedTime = 0;
|
|
379
|
+
localStorage.setItem('ncs_currentTime', 0);
|
|
249
380
|
}
|
|
250
381
|
}
|
|
251
382
|
}
|