From 4ce528eaf507a090ae4f240d7e4d1cf018198788 Mon Sep 17 00:00:00 2001 From: cjcolvar Date: Wed, 10 Apr 2024 14:46:04 -0400 Subject: [PATCH 1/5] Use plain old javascript to get de-duplication of listener registration --- app/views/media_objects/_thumbnail.html.erb | 103 +++++++++++--------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/app/views/media_objects/_thumbnail.html.erb b/app/views/media_objects/_thumbnail.html.erb index e071081bf1..41e6cf7999 100644 --- a/app/views/media_objects/_thumbnail.html.erb +++ b/app/views/media_objects/_thumbnail.html.erb @@ -50,6 +50,59 @@ Unless required by applicable law or agreed to in writing, software distributed let offset = '' let timeCheck = setInterval(enableCreateThumbnail, 500); + function handleCreateThumbnailModalShow() { + let currentPlayer = document.getElementById('iiif-media-player'); + let $imgPolaroid = document.getElementById('img-polaroid'); + offset = currentPlayer.player.currentTime(); + + canvasIndex = parseInt(currentPlayer.dataset.canvasindex); + const sectionId = sectionIds[canvasIndex]; + baseUrl = '/master_files/' + sectionId; + + if ($imgPolaroid) { + let src = baseUrl + '/poster?offset=' + offset + '&preview=true'; + + // Display a preview of thumbnail to user + $imgPolaroid.setAttribute('src', src); + $($imgPolaroid).fadeIn('slow'); + } + }; + + function handleUpdateThumbnail() { + let currentPlayer = document.getElementById('iiif-media-player'); + canvasIndex = parseInt(currentPlayer.dataset.canvasindex); + const sectionId = sectionIds[canvasIndex]; + baseUrl = '/master_files/' + sectionId; + offset = currentPlayer.player.currentTime(); + + const modalBody = document.getElementsByClassName('modal-body')[0]; + // Put in a loading spinner and disable buttons to prevent double clicks + modalBody.classList.add('spinner'); + $('#thumbnailModal') + .find('button') + .attr({ disabled: true }); + + $.ajax({ + url: baseUrl + '/still', + type: 'POST', + data: { + offset: offset + } + }) + .done(response => { + $('#thumbnailModal').modal('hide'); + }) + .fail(error => { + console.log(error); + }) + .always(() => { + modalBody.classList.remove('spinner'); + $('#thumbnailModal') + .find('button') + .attr({ disabled: false }); + }); + }; + function enableCreateThumbnail() { let player = document.getElementById('iiif-media-player'); @@ -85,53 +138,9 @@ Unless required by applicable law or agreed to in writing, software distributed } }); } - - $('#thumbnailModal').on('show.bs.modal', function(e) { - let currentPlayer = document.getElementById('iiif-media-player'); - let $imgPolaroid = document.getElementById('img-polaroid'); - offset = currentPlayer.player.currentTime(); - - canvasIndex = parseInt(currentPlayer.dataset.canvasindex); - const sectionId = sectionIds[canvasIndex]; - baseUrl = '/master_files/' + sectionId; - - if ($imgPolaroid) { - let src = baseUrl + '/poster?offset=' + offset + '&preview=true'; - - // Display a preview of thumbnail to user - $imgPolaroid.setAttribute('src', src); - $($imgPolaroid).fadeIn('slow'); - } - }); - - $('#create-thumbnail-submit-button').on('click', function(e) { - const modalBody = document.getElementsByClassName('modal-body')[0]; - // Put in a loading spinner and disable buttons to prevent double clicks - modalBody.classList.add('spinner'); - $('#thumbnailModal') - .find('button') - .attr({ disabled: true }); - - $.ajax({ - url: baseUrl + '/still', - type: 'POST', - data: { - offset: offset - } - }) - .done(response => { - $('#thumbnailModal').modal('hide'); - }) - .fail(error => { - console.log(error); - }) - .always(() => { - modalBody.classList.remove('spinner'); - $('#thumbnailModal') - .find('button') - .attr({ disabled: false }); - }); - }); + + document.getElementById('create-thumbnail-btn').addEventListener('click', handleCreateThumbnailModalShow); + document.getElementById('create-thumbnail-submit-button').addEventListener('click', handleUpdateThumbnail); }; }); From c07e9be8be44a4c90131b3ed8824e39e8d1e2cda Mon Sep 17 00:00:00 2001 From: dwithana Date: Fri, 12 Apr 2024 11:53:53 -0400 Subject: [PATCH 2/5] Ramp v3.1.3 tag for 7.7.2 release --- package.json | 2 +- yarn.lock | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f2a9cc741c..09b1ea8f57 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/preset-react": "^7.0.0", "@babel/runtime": "7", - "@samvera/ramp": "^3.1.0", + "@samvera/ramp": "https://github.com/samvera-labs/ramp.git#v3.1.3", "babel-plugin-macros": "^3.1.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "buffer": "^6.0.3", diff --git a/yarn.lock b/yarn.lock index 7516286e5b..35e82e9dc3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1440,10 +1440,9 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@samvera/ramp@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@samvera/ramp/-/ramp-3.1.0.tgz#6254646f34b9a434ff6e6046f1e013130d036e28" - integrity sha512-B5UiU0DDxi7Ub+DfbKC7j80zjMCmkuLnmDJNUqnftjO1L2gocdMOuUfYZ30pAh9SO9HbMCEtAFtLUHPlizPz3A== +"@samvera/ramp@https://github.com/samvera-labs/ramp.git#v3.1.3": + version "3.1.3" + resolved "https://github.com/samvera-labs/ramp.git#6c233c2cd668856b6bce1ce63076455a9e58b0f2" dependencies: "@rollup/plugin-json" "^6.0.1" "@silvermine/videojs-quality-selector" "^1.2.4" From f5d6bd2aab825a880c36f6db28c3f3a92e98985a Mon Sep 17 00:00:00 2001 From: cjcolvar Date: Fri, 12 Apr 2024 15:59:28 -0400 Subject: [PATCH 3/5] Bump version to 7.7.2 --- config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/application.rb b/config/application.rb index 9f78a4087f..562c2af5ae 100644 --- a/config/application.rb +++ b/config/application.rb @@ -8,7 +8,7 @@ Bundler.require(*Rails.groups) module Avalon - VERSION = '7.7.1' + VERSION = '7.7.2' class Application < Rails::Application require 'avalon/configuration' From cd8816a811768b8443cceb73eb76afd8f5ba47ce Mon Sep 17 00:00:00 2001 From: dwithana Date: Thu, 18 Apr 2024 11:10:35 -0400 Subject: [PATCH 4/5] Use player.src() instead of player.readyState() to enable button for iOS Safari --- .../media_objects/_add_to_playlist.html.erb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/app/views/media_objects/_add_to_playlist.html.erb b/app/views/media_objects/_add_to_playlist.html.erb index a08c60a1f6..f66ac4bd2a 100644 --- a/app/views/media_objects/_add_to_playlist.html.erb +++ b/app/views/media_objects/_add_to_playlist.html.erb @@ -202,8 +202,23 @@ Unless required by applicable law or agreed to in writing, software distributed function enableAddToPlaylist() { let player = document.getElementById('iiif-media-player'); let addToPlaylistBtn = document.getElementById('addToPlaylistBtn'); - if(addToPlaylistBtn && addToPlaylistBtn.disabled && player?.player.readyState() === 4) { - addToPlaylistBtn.disabled = false; + if(addToPlaylistBtn && addToPlaylistBtn.disabled) { + const USER_AGENT = window.navigator.userAgent; + const IS_MOBILE = (/Mobi/i).test(USER_AGENT); + const IS_SAFARI = (/Safari/i).test(USER_AGENT); + /* + For iOS Safari, player.readyState() never gets to 4 until media playback is + started. Therefore, use player.src() to check whether there's a playable media + loaded into the player instead of player.readyState(). + Keep the player.readyState() === 4 check for desktop browsers, because without + that check the add to playlist form populates NaN values for time fields when user + clicks the 'Add to Playlist' button immediately on page load, which does not + happen in mobile context. + */ + if((IS_MOBILE && IS_SAFARI && player?.player.src() != '') + || player?.player.readyState() === 4) { + addToPlaylistBtn.disabled = false; + } } if(!listenersAdded) { // Add 'Add new playlist' option to dropdown From 173ec1248b66cda577746514c8bca6fe8ae7aec5 Mon Sep 17 00:00:00 2001 From: Dananji Withana Date: Tue, 23 Apr 2024 09:44:59 -0400 Subject: [PATCH 5/5] Extend player status check for add to playlist to iPad Safari (#5799) * Extend player status check for add to playlist to iPad Safari * Add IS_MOBILE check back in --- app/views/media_objects/_add_to_playlist.html.erb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/views/media_objects/_add_to_playlist.html.erb b/app/views/media_objects/_add_to_playlist.html.erb index f66ac4bd2a..0bfcf77512 100644 --- a/app/views/media_objects/_add_to_playlist.html.erb +++ b/app/views/media_objects/_add_to_playlist.html.erb @@ -204,7 +204,11 @@ Unless required by applicable law or agreed to in writing, software distributed let addToPlaylistBtn = document.getElementById('addToPlaylistBtn'); if(addToPlaylistBtn && addToPlaylistBtn.disabled) { const USER_AGENT = window.navigator.userAgent; + // Identify both iPad and iPhone devices const IS_MOBILE = (/Mobi/i).test(USER_AGENT); + const IS_IPHONE = (/iPhone/i).test(USER_AGENT); + const IS_TOUCH_ONLY = navigator.maxTouchPoints && navigator.maxTouchPoints > 2 && !window.matchMedia("(pointer: fine").matches; + // Identify browser is Safari const IS_SAFARI = (/Safari/i).test(USER_AGENT); /* For iOS Safari, player.readyState() never gets to 4 until media playback is @@ -215,7 +219,7 @@ Unless required by applicable law or agreed to in writing, software distributed clicks the 'Add to Playlist' button immediately on page load, which does not happen in mobile context. */ - if((IS_MOBILE && IS_SAFARI && player?.player.src() != '') + if(((IS_TOUCH_ONLY || IS_IPHONE || IS_MOBILE) && IS_SAFARI && player?.player.src() != '') || player?.player.readyState() === 4) { addToPlaylistBtn.disabled = false; }