Devmightwin commited on
Commit
ec1edeb
Β·
verified Β·
1 Parent(s): cf1690a

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +83 -4
app.js CHANGED
@@ -295,6 +295,83 @@ function cleanTextForTTS(rawText) {
295
  return ensureDevanagariForTTS(cleaned);
296
  }
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  async function playBodoSpeech(btn, text) {
299
  if (activeTtsBtn === btn && currentAudio && !currentAudio.paused) {
300
  currentAudio.pause();
@@ -312,10 +389,11 @@ async function playBodoSpeech(btn, text) {
312
  btn.disabled = false;
313
  btn.innerHTML = `⏹ Stop`;
314
  currentAudio = new Audio(ttsAudioCache.get(cleanText));
 
 
315
  currentAudio.onended = () => {
 
316
  btn.innerHTML = `πŸ”Š Listen`;
317
- activeTtsBtn = null;
318
- currentAudio = null;
319
  };
320
  try { await currentAudio.play(); } catch { btn.innerHTML = `⚠️ Retry`; }
321
  return;
@@ -340,10 +418,11 @@ async function playBodoSpeech(btn, text) {
340
  btn.disabled = false;
341
  btn.innerHTML = `⏹ Stop`;
342
  currentAudio = new Audio(audioUrl);
 
 
343
  currentAudio.onended = () => {
 
344
  btn.innerHTML = `πŸ”Š Listen`;
345
- activeTtsBtn = null;
346
- currentAudio = null;
347
  };
348
  await currentAudio.play();
349
  } catch (err) {
 
295
  return ensureDevanagariForTTS(cleaned);
296
  }
297
 
298
+ // ============================================================
299
+ // FLOATING AUDIO PILL CONTROLLER
300
+ // ============================================================
301
+ const audioPlayerBar = $('audio-player-bar');
302
+ const playerToggleBtn = $('player-toggle-btn');
303
+ const playerPlayIcon = $('player-play-icon');
304
+ const playerPauseIcon = $('player-pause-icon');
305
+ const playerTimer = $('player-timer');
306
+ const playerSeeker = $('player-seeker');
307
+ const playerCloseBtn = $('player-close-btn');
308
+
309
+ function formatAudioTime(seconds) {
310
+ if (isNaN(seconds)) return "00:00";
311
+ const m = Math.floor(seconds / 60).toString().padStart(2, '0');
312
+ const s = Math.floor(seconds % 60).toString().padStart(2, '0');
313
+ return `${m}:${s}`;
314
+ }
315
+
316
+ function bindAudioToPlayer(audio) {
317
+ if (!audioPlayerBar) return;
318
+ audioPlayerBar.classList.remove('hidden');
319
+
320
+ audio.ontimeupdate = () => {
321
+ playerTimer.textContent = formatAudioTime(audio.currentTime);
322
+ if (audio.duration) {
323
+ playerSeeker.value = (audio.currentTime / audio.duration) * 100;
324
+ }
325
+ };
326
+
327
+ audio.onplay = () => {
328
+ playerPlayIcon.classList.add('hidden');
329
+ playerPauseIcon.classList.remove('hidden');
330
+ };
331
+
332
+ audio.onpause = () => {
333
+ playerPlayIcon.classList.remove('hidden');
334
+ playerPauseIcon.classList.add('hidden');
335
+ };
336
+
337
+ audio.onended = () => {
338
+ audioPlayerBar.classList.add('hidden');
339
+ playerSeeker.value = 0;
340
+ playerTimer.textContent = "00:00";
341
+ if (activeTtsBtn) activeTtsBtn.innerHTML = `πŸ”Š Listen`;
342
+ currentAudio = null;
343
+ activeTtsBtn = null;
344
+ };
345
+ }
346
+
347
+ on('player-toggle-btn', 'click', () => {
348
+ if (!currentAudio) return;
349
+ if (currentAudio.paused) {
350
+ currentAudio.play();
351
+ } else {
352
+ currentAudio.pause();
353
+ }
354
+ });
355
+
356
+ if (playerSeeker) {
357
+ playerSeeker.oninput = () => {
358
+ if (currentAudio && currentAudio.duration) {
359
+ currentAudio.currentTime = (playerSeeker.value / 100) * currentAudio.duration;
360
+ }
361
+ };
362
+ }
363
+
364
+ on('player-close-btn', 'click', () => {
365
+ if (currentAudio) {
366
+ currentAudio.pause();
367
+ currentAudio.currentTime = 0;
368
+ currentAudio = null;
369
+ }
370
+ if (activeTtsBtn) activeTtsBtn.innerHTML = `πŸ”Š Listen`;
371
+ activeTtsBtn = null;
372
+ audioPlayerBar.classList.add('hidden');
373
+ });
374
+
375
  async function playBodoSpeech(btn, text) {
376
  if (activeTtsBtn === btn && currentAudio && !currentAudio.paused) {
377
  currentAudio.pause();
 
389
  btn.disabled = false;
390
  btn.innerHTML = `⏹ Stop`;
391
  currentAudio = new Audio(ttsAudioCache.get(cleanText));
392
+ bindAudioToPlayer(currentAudio);
393
+ const cachedBaseOnEnded = currentAudio.onended;
394
  currentAudio.onended = () => {
395
+ cachedBaseOnEnded && cachedBaseOnEnded();
396
  btn.innerHTML = `πŸ”Š Listen`;
 
 
397
  };
398
  try { await currentAudio.play(); } catch { btn.innerHTML = `⚠️ Retry`; }
399
  return;
 
418
  btn.disabled = false;
419
  btn.innerHTML = `⏹ Stop`;
420
  currentAudio = new Audio(audioUrl);
421
+ bindAudioToPlayer(currentAudio);
422
+ const freshBaseOnEnded = currentAudio.onended;
423
  currentAudio.onended = () => {
424
+ freshBaseOnEnded && freshBaseOnEnded();
425
  btn.innerHTML = `πŸ”Š Listen`;
 
 
426
  };
427
  await currentAudio.play();
428
  } catch (err) {