Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fixes for persisting user edits and enable/disable current track option in add to playlist #5465

Merged
merged 2 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 73 additions & 14 deletions app/assets/javascripts/ramp_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@
* --- END LICENSE_HEADER BLOCK ---
*/

/** Get the current active structure item from DOM */
function getActiveItem() {
/**
* Get the current active structure item(s) from DOM
* @param {Boolean} checkSection flag to indicate current section as active
* @returns {Object} active track information
*/
function getActiveItem(checkSection = true) {
let currentPlayer = document.getElementById('iiif-media-player');
let duration = currentPlayer.player.duration();
let currentStructureItem = $('li[class="ramp--structured-nav__list-item active"]');
Expand All @@ -40,7 +44,8 @@ function getActiveItem() {
end: parseFloat(timeHash.split(',')[1]) || duration
},
tags: ['current-track', 'current-section'],
streamId: itemId.split('/').pop()
streamId: itemId.split('/').pop(),
sectionLabel: label,
}
}

Expand All @@ -53,9 +58,15 @@ function getActiveItem() {
end: parseFloat(timeHash.split(',')[1]) || duration
}
let streamId = item.pathname.split('/').pop();
return { label, times, tags: ['current-track'], streamId };
return {
label,
times,
tags: ['current-track'],
streamId,
sectionLabel: currentSection[0].dataset.label,
};
}
} else if (currentSection?.length > 0) {
} else if (currentSection?.length > 0 && checkSection) {
/** When the structured navigation doesn't have an active timespan
* get the current active section to populate the timeline and add
* to playlist options */
Expand All @@ -68,6 +79,7 @@ function getActiveItem() {
},
tags: ['current-section'],
streamId: '',
sectionLabel: label,
}
}
}
Expand All @@ -89,10 +101,8 @@ function getTimelineScopes() {
if(activeItem != undefined) {
streamId = activeItem.streamId;
scopes.push({
label: activeItem.label,
...activeItem,
tracks: trackCount,
times: activeItem.times,
tags: activeItem.tags,
});
}

Expand Down Expand Up @@ -171,10 +181,59 @@ function collapseMultiItemCheck () {

/** Collapse title and description forms */
function collapseMoreDetails() {
$('#moreDetails').collapse('show');
$('#multiItemCheck').collapse('hide');
let currentTrackName = $('#current-track-name').text();
$('#playlist_item_title').val(currentTrackName);
if(!$('#moreDetails').hasClass('show')) {
$('#moreDetails').collapse('show');
$('#multiItemCheck').collapse('hide');
// When the title field is empty fill it with either
// current track or current section name
if($('#playlist_item_title').val() == '') {
$('#playlist_item_title').val(
$('#current-track-name').text() || $('#current-section-name').text()
);
}
}
}

/**
* Enable or disable the 'Current Track' option based on the current time of
* the player. When the current time is not included within an active timespan
* disable the option otherwise enable it.
* @param {Object} activeTrack JSON object for the active timespans
* @param {Number} currentTime player's playhead position
* @param {Boolean} isSeeked flag to indicate player 'seeked' event happened/not
* @param {String} sectionTitle name of the current section
*/
function disableEnableCurrentTrack(activeTrack, currentTime, isSeeked, sectionTitle) {
let title = sectionTitle;
if(activeTrack != undefined) {
streamId = activeTrack.streamId;
let { label, times, sectionLabel } = activeTrack;
let starttime = currentTime || times.begin;
$('#playlist_item_start').val(createTimestamp(starttime, true));
$('#playlist_item_end').val(createTimestamp(times.end, true));
title = `${sectionLabel} - ${label}`;
$('#current-track-name').text(title);
// When player's currentTime is in between the activeTrack's begin and
// end times, enable the current track option
if(times.begin <= starttime && starttime <= times.end) {
$('#playlistitem_scope_track')[0].disabled = false;
$('#current-track-text').removeClass('disabled-option');
}
} else {
// Whena activeTrack is undefined, disable the current track option
$('#playlistitem_scope_track')[0].disabled = true;
$('#current-track-name').text('');
$('#current-track-text').addClass('disabled-option');
if($('#playlistitem_scope_track')[0].checked) {
$('#moreDetails').collapse('hide');
$('#playlistitem_scope_track').prop('checked', false);
}
}
// Only change the title when user actively seeked to a different timestamp,
// persisting the user changes to the field unless the active track is changed
if(isSeeked && sectionTitle != undefined) {
$('#playlist_item_title').val(title);
}
}

/** AJAX request for add to playlist for submission for playlist item for
Expand Down Expand Up @@ -258,8 +317,8 @@ function handleAddError(error) {

/** Reset add to playlist form */
function resetAddToPlaylistForm() {
$('#playlist_item_description').value = '';
$('#playlist_item_title').value = '';
$('#playlist_item_description').val('');
$('#playlist_item_title').val('');
$('input[name="post[playlistitem_scope]"]').prop('checked', false);
$('#playlistitem_scope_structure').prop('checked', false);
$('#moreDetails').collapse('hide');
Expand Down
9 changes: 9 additions & 0 deletions app/assets/stylesheets/avalon/_form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@ label {
padding-bottom: 0.1rem;
}

.form-check-label {
cursor: pointer;

.disabled-option {
cursor: not-allowed;
color: $gray;
}
}

#playlist_item_end, #playlist_item_start {
border-radius: 0.25rem;
border: 1px solid $gray;
Expand Down
79 changes: 39 additions & 40 deletions app/views/media_objects/_add_to_playlist.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ Unless required by applicable law or agreed to in writing, software distributed
</div>

<div id="add-to-playlist-form-group" class="mb-4">
<div class="form-check" onclick="collapseMoreDetails()">
<label class="form-check-label">
<div class="form-check">
<label class="form-check-label" onclick="collapseMoreDetails()">
<input type="radio" name="post[playlistitem_scope]" id="playlistitem_scope_track" aria-label="playlist item current track">
Current Track (<span id="current-track-name"></span>)
<span id="current-track-text">Current Track (<span id="current-track-name"></span>)</span>
</label>
</div>
<div class="form-check">
Expand All @@ -52,14 +52,14 @@ Unless required by applicable law or agreed to in writing, software distributed
to
<input type="text" name="playlist_item_end" id="playlist_item_end" pattern="(\d+:){0,2}\d+(\.\d+)?" value="" aria-label="end time">
</div>
<div class="form-check" onclick="collapseMultiItemCheck()" >
<label class="form-check-label">
<div class="form-check">
<label class="form-check-label" onclick="collapseMultiItemCheck()">
<input type="radio" name="post[playlistitem_scope]" id="playlistitem_scope_section" aria-label="playlist item current section">
Current Section (<span id="current-section-name"></span>)
</label>
</div>
<div class="form-check" onclick="collapseMultiItemCheck()">
<label class="form-check-label">
<div class="form-check">
<label class="form-check-label" onclick="collapseMultiItemCheck()">
<input type="radio" name="post[playlistitem_scope]" id="playlistitem_scope_item" aria-label="playlist item current item">
All Sections
</label>
Expand Down Expand Up @@ -147,11 +147,11 @@ Unless required by applicable law or agreed to in writing, software distributed
let mediaObjectId, streamId, mediaObjectTitle;
let listenersAdded = false;
let activeTrack = null;
let currentSectionLabel = undefined;
// Enable add to playlist button after derivative is loaded
let timeCheck = setInterval(initAddToPlaylist, 500);
function initAddToPlaylist() {
let player = document.getElementById('iiif-media-player');
let scopes = [];
if(player) {
addPlayerEventListeners(player.player, () => {
clearInterval(timeCheck);
Expand All @@ -163,25 +163,17 @@ Unless required by applicable law or agreed to in writing, software distributed
player.on('loadedmetadata', () => {
enableAddToPlaylist();
});
player.on('timeupdate', () => {
player.on('seeked', () => {
if(getActiveItem() != undefined) {
let { label, times, streamId } = getActiveItem();
let starttime = player.currentTime() || times.begin;
$('#playlist_item_start').val(createTimestamp(starttime, true));
$('#playlist_item_end').val(createTimestamp(times.end, true));
$('#playlist_item_title').val(`${mediaObjectTitle} - ${label}`);
$('#current-track-name').text(`${mediaObjectTitle} - ${label}`);
// When player's currentTime equals the active item's begin, then
// playhead is not encompassed within an active track. When this happens
// disable the current track option
if(times.begin === starttime) {
$('#playlistitem_scope_track')[0].disabled = true;
} else {
$('#playlistitem_scope_track')[0].disabled = false;
activeTrack = getActiveItem(false);
if(activeTrack != undefined) {
streamId = activeTrack.streamId;
}
disableEnableCurrentTrack(activeTrack, player.currentTime(), true, currentSectionLabel);
}
});
player.on('dispose', () => {
currentSectionLabel = undefined;
$('#addToPlaylistPanel').collapse('hide');
resetAddToPlaylistForm();
addToPlaylistBtn.disabled = true;
Expand All @@ -198,7 +190,7 @@ Unless required by applicable law or agreed to in writing, software distributed
}
}

function addListeners() {
function addListeners() {
$('#addToPlaylistPanel').on('show.bs.collapse', function (e) {
// Hide add to playlist alert on panel show
$('#add_to_playlist_alert').slideUp(0);
Expand All @@ -212,10 +204,10 @@ Unless required by applicable law or agreed to in writing, software distributed

// For custom scope set start, end times as current time and media duration respectively
let currentPlayer = document.getElementById('iiif-media-player');
let start, end = 0;
let start, end, currentTime, duration = 0;
if(currentPlayer && currentPlayer.player) {
start = currentPlayer.player.currentTime();
end = currentPlayer.player.duration();
currentTime = currentPlayer.player.currentTime();
duration = currentPlayer.player.duration();
}
// Add 'Add new playlist' option to dropdown
window.add_new_playlist_option();
Expand All @@ -224,34 +216,41 @@ Unless required by applicable law or agreed to in writing, software distributed
mediaObjectTitle = playlistForm.dataset.title;
mediaObjectId = playlistForm.dataset.moid;
let timelineScopes = getTimelineScopes();
scopes = timelineScopes.scopes;
let scopes = timelineScopes.scopes;
streamId = timelineScopes.streamId || sectionIds[canvasIndex];
currentSectionLabel = `${mediaObjectTitle || mediaObjectId} - ${streamId}`;

// Fill in the current track and section titles and custom scope times
if(scopes?.length > 0) {
let sectionInfo = scopes.filter(s => s.tags.includes('current-section'));
let currentSectionLabel = mediaObjectTitle;
if(sectionInfo?.length > 0) {
currentSectionLabel = sectionInfo[0].label || currentSectionLabel;
$('#current-section-name').text(currentSectionLabel);
}

let trackInfo = scopes.filter(s => s.tags.includes('current-track'));
if(trackInfo.length > 0) {
activeTrack = trackInfo[0];
let trackName = `${currentSectionLabel} - ${activeTrack.label || streamId}`;
let trackName = activeTrack.tags.includes('current-section')
? activeTrack.label || streamId
: `${currentSectionLabel} - ${activeTrack.label || streamId}`;
Comment on lines +233 to +235
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is kind of a lot going on here logically. Would it make sense to break this down into multiple lines?

$('#current-track-name').text(trackName);
// Update start, end times for custom scope from the active timespan
start = activeTrack.times.begin;
end = activeTrack.times.end;
$('#playlistitem_scope_track')[0].disabled = false;
} else {
activeTrack = null;
$('#playlistitem_scope_track')[0].disabled = true;
activeTrack = undefined;
}
}
$('#playlist_item_start').val(createTimestamp(start, true));
$('#playlist_item_end').val(createTimestamp(end, true));

disableEnableCurrentTrack(
activeTrack,
currentTime,
false,
$('#playlist_item_title').val() || currentSectionLabel // Preserve user edits for the title when available
);
$('#current-section-name').text(currentSectionLabel);
$('#playlist_item_start').val(createTimestamp(start || currentTime, true));
$('#playlist_item_end').val(createTimestamp(duration || end, true));

// Show add to playlist form on show and reset initially
$('#add_to_playlist_form_group').slideDown();
Expand All @@ -261,13 +260,13 @@ Unless required by applicable law or agreed to in writing, software distributed
e.preventDefault();
let playlistId = $('#post_playlist_id').val();
let label, t, id;
if ($('#playlistitem_timeselection')[0].checked || $('#playlistitem_scope_track')[0].checked) {
if($('#playlistitem_scope_track')[0].checked) {
let starttime = createTimestamp(activeTrack.times.begin, true);
let endtime = createTimestamp(activeTrack.times.end, true);
addPlaylistItem(playlistId, streamId, starttime, endtime);
} else if ($('#playlistitem_timeselection')[0].checked) {
let starttime = $('#playlist_item_start').val();
let endtime = $('#playlist_item_end').val();
if(activeTrack) {
starttime = createTimestamp(activeTrack.times.begin, true);
endtime = createTimestamp(activeTrack.times.end, true);
}
addPlaylistItem(playlistId, streamId, starttime, endtime);
} else if ($('#playlistitem_scope_section')[0].checked) {
let multiItemCheck = $('#playlistitem_scope_structure')[0].checked;
Expand Down