From aa5df514a4feff90f4be61f9ec0e2bb09b249ebf Mon Sep 17 00:00:00 2001 From: Mason Ballengee Date: Thu, 18 Jul 2024 13:25:20 -0400 Subject: [PATCH] Fix enabling of media object action buttons On page load, both initial and refreshed, in mobile browsers there was some sort of race condition that was disabling the Add to Playlist, Timeline, and Thumbnail buttons immediately after being enabled. Changing the event listener for disabling the buttons to be triggered on the player emptying instead of loading seems to fix that race condition, but uncovered a separate one when switching canvases. This second race condition behaved similarly to the first, where the enabling function would be run before the disabling function. Adding a fallback enabling function that triggers on loadstart seems to fix this second race condition. There may still be some flakiness, especially on apple devices, because events triggering properly sometimes just doesn't happen. --- app/assets/javascripts/player_listeners.js | 71 ++++++++++++++-------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/app/assets/javascripts/player_listeners.js b/app/assets/javascripts/player_listeners.js index fb66f3fceb..237334c931 100644 --- a/app/assets/javascripts/player_listeners.js +++ b/app/assets/javascripts/player_listeners.js @@ -35,6 +35,51 @@ let isPlaying = false; function addActionButtonListeners(player, mediaObjectId, sectionIds) { if (player && player.player != undefined) { let currentIndex = parseInt(player.dataset.canvasindex); + /* Ensure we only add player listeners once */ + if (firstLoad === true) { + /* Add player event listeners to update UI components on the page */ + // Listen to 'seeked' event to udate add to playlist form when using while media is playing or manually seeking + player.player.on('seeked', () => { + if (getActiveItem() != undefined) { + activeTrack = getActiveItem(false); + if (activeTrack != undefined) { + streamId = activeTrack.streamId; + } + disableEnableCurrentTrack(activeTrack, player.player.currentTime(), isPlaying, currentSectionLabel); + } + }); + + player.player.on('play', () => { isPlaying = true; }); + + player.player.on('pause', () => { isPlaying = false; }); + + /* + Disable action buttons tied to player related information on player's 'emptied' event which functions + parallel to the player's src changes. So, that the user doesn't interact with them get corrupted data + in the UI when player is loading the new section media into it. + Once the player is fully loaded these buttons are enabled as needed. + */ + player.player.on('emptied', () => { + resetAllActionButtons(); + }); + + /* + Enable action buttons on player's 'loadstart' event which functions parallel to the player's src changes. + Sometimes the player event to disable the buttons is triggered after the function to enable the buttons, + resulting in the buttons never enabling. Since the enabling of the action buttons occurs before the player + is emptied, it is also possible that the information populating the buttons is for the old canvas, so we + run `buildActionButtons` again rather than just enabling the buttons. + */ + player.player.on('loadstart', () => { + let addToPlaylistBtn = document.getElementById('addToPlaylistBtn'); + let thumbnailBtn = document.getElementById('thumbnailBtn'); + let timelineBtn = document.getElementById('timelineBtn'); + + if (addToPlaylistBtn.disabled && thumbnailBtn.disabled && timelineBtn.disabled) { + buildActionButtons(player, mediaObjectId, sectionIds); + } + }); + } /* For both Android and iOS, player.readyState() is 0 until media playback is started. Therefore, use player.src() to check whether there's a playable media @@ -69,32 +114,6 @@ function addActionButtonListeners(player, mediaObjectId, sectionIds) { resetAllActionButtons(); } - /* Add player event listeners to update UI components on the page */ - // Listen to 'seeked' event to udate add to playlist form - player.player.on('seeked', () => { - if (getActiveItem() != undefined) { - activeTrack = getActiveItem(false); - if (activeTrack != undefined) { - streamId = activeTrack.streamId; - } - disableEnableCurrentTrack(activeTrack, player.player.currentTime(), isPlaying, currentSectionLabel); - } - }); - - player.player.on('play', () => { isPlaying = true; }); - - player.player.on('pause', () => { isPlaying = false; }); - - /* - Disable action buttons tied to player related information on player's 'loadstart' event which functions - parallel to the player's src changes. So, that the user doesn't interact with them get corrupted data - in the UI when player is loading the new section media into it. - Once the player is fully loaded these buttons are enabled as needed. - */ - player.player.on('loadstart', () => { - resetAllActionButtons(); - }); - // Collapse sub-panel related to the selected option in the add to playlist form when it is collapsed let playlistSection = $('#playlistitem_scope_section'); let playlistTrack = $('#playlistitem_scope_track');