Agent: Claude Code Started: 2026-03-15 00:17:51 Working Directory: /home/sacha/sync/static-blog/
I'm not sure how to write this so that it waits for player.duration to be available before setting the interval. This is an audio element.
assets/js/misc.js:808-835
808: async function startAudioLoop(player) { 809: let waitFunc = new Promise((res) => { 810: let p = async function() { 811: console.log(player.duration, player.duration.isNan); 812: if (!player.duration.isNaN) { ...
Let me read the relevant section of the file to understand the current code.
Tool: read Timestamp: 2026-03-15 00:17:53 Parameters: file_path: /home/sacha/sync/static-blog/assets/js/misc.js offset: 800 limit: 60
```
800→ window.addEventListener('resize', positionSidenotes);
801→ window.addEventListener('load', positionSidenotes);
802→ const observer = new MutationObserver(positionSidenotes);
803→ observer.observe(document.body, { childList: true, subtree: true });
804→}
805→
806→window.playLoopTimer = null;
807→
808→async function startAudioLoop(player) {
809→ let waitFunc = new Promise((res) => {
810→ let p = async function() {
811→ console.log(player.duration, player.duration.isNan);
812→ if (!player.duration.isNaN) {
813→ res(player.duration);
814→ }
815→ else {
816→ console.log('waiting for duration');
817→ setTimeout(p, 50);
818→ }
819→ };
820→ return p;
821→ });
822→ player.currentTime = 0;
823→ player.play();
824→ console.log('waiting?');
825→ await waitFunc;
826→ console.log('setting timer', player.duration);
827→ if (player.duration > 0) {
828→ window.playLoopTimer = setInterval(function() {
829→ console.log('playing');
830→ player.currentTime = 0;
831→ player.play();
832→ }, player.duration * 2000);
833→ }
834→}
835→
836→function playAudioFromIcon(event) {
837→ event.preventDefault();
838→ let playOptions = event.target.closest('.subed-summary')?.querySelector('.play-options input:checked')?.value;
839→ let link = event.target.tagName == 'a' ? event.target : event.target.closest('a.audio-icon');
840→ let player = document.querySelector('audio#icon-player');
841→ document.querySelectorAll('.subed-summary .highlight').forEach((o) => o.classList.remove('highlight'));
842→ if (!link) return;
843→ link.classList.add('highlight');
844→ console.log('playOptions', playOptions);
845→ if (window.playLoopTimer) { clearInterval(window.playLoopTimer); }
846→ if (!player) {
847→ player = document.createElement('audio');
848→ player.setAttribute('id', 'icon-player');
849→ document.body.appendChild(player);
850→ }
851→ if (player.src == link.href) {
852→ if (playOptions == 'loop') {
853→ if (window.playLoopTimer) {
854→ clearInterval(window.playLoopTimer);
855→ player.pause();
856→ } else {
857→ startAudioLoop(player);
858→ }
859→ } else {
<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>
```
There are two bugs here:
p — it just returns it.isNaN is a global function, not a property — player.duration.isNaN is always undefined (falsy), so the condition !player.duration.isNaN is always true, meaning it never waits.The cleanest fix is to use the loadedmetadata event (which fires once duration is available) with a fallback poll:
Tool: edit Timestamp: 2026-03-15 00:18:23 Parameters: file_path: /home/sacha/sync/static-blog/assets/js/misc.js old_string: async function startAudioLoop(player) { let waitFunc = new Promise((res) => { let p = async function() { console.log(player.duration, player.duration.isNan); if (!player.duration.isNaN) { res(player.duration); } else { console.log('waiting for duration'); setTimeout(p, 50); } }; return p; }); player.currentTime = 0; player.play(); console.log('waiting?'); await waitFunc; console.log('setting timer', player.duration); new_string: async function startAudioLoop(player) { let waitFunc = new Promise((res) => { if (!isNaN(player.duration) && player.duration > 0) { res(player.duration); } else { player.addEventListener('loadedmetadata', () => res(player.duration), { once: true }); } }); player.currentTime = 0; player.play(); await waitFunc; console.log('setting timer', player.duration);
╭─────────╮
│ changes │
╰─────────╯
@@ -1,21 +1,14 @@
async function startAudioLoop(player) {
let waitFunc = new Promise((res) => {
- let p = async function() {
- console.log(player.duration, player.duration.isNan);
- if (!player.duration.isNaN) {
- res(player.duration);
- }
- else {
- console.log('waiting for duration');
- setTimeout(p, 50);
- }
- };
- return p;
+ if (!isNaN(player.duration) && player.duration > 0) {
+ res(player.duration);
+ } else {
+ player.addEventListener('loadedmetadata', () => res(player.duration), { once: true });
+ }
});
player.currentTime = 0;
player.play();
- console.log('waiting?');
await waitFunc;
console.log('setting timer', player.duration);
if (player.duration > 0) {
\ No newline at end of file
Key changes:
!isNaN(player.duration) && player.duration > 0 to check if duration is already known (e.g. same file replayed)loadedmetadata with { once: true } — this is the correct event for when duration becomes availablep())