Skip to content

Commit

Permalink
Merge pull request #545 from themeum/dev
Browse files Browse the repository at this point in the history
v2.2.4 merge to master.
  • Loading branch information
harunollyo authored Aug 29, 2023
2 parents ccbda39 + 2645a54 commit 877715d
Show file tree
Hide file tree
Showing 41 changed files with 1,099 additions and 223 deletions.
12 changes: 11 additions & 1 deletion assets/react/admin-dashboard/tutor-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,5 +503,15 @@ jQuery(document).ready(function($) {
}
});
}


/**
* Fix - Table last row context menu hidden.
*
* @since 2.2.4
*/
let tableDropdown = jQuery('.tutor-table-responsive .tutor-table .tutor-dropdown')
if (tableDropdown.length) {
let tableHeight = jQuery('.tutor-table-responsive .tutor-table').height()
jQuery('.tutor-table-responsive').css('min-height', tableHeight + 110)
}
});
11 changes: 11 additions & 0 deletions assets/react/front/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,15 @@ document.addEventListener('DOMContentLoaded', function() {
document.getElementById('tutor-frontend-course-builder').submit();
};
}

/**
* Fix - Table last row context menu hidden for frontend dashboard.
*
* @since 2.2.4
*/
let tableDropdown = jQuery('.tutor-table-responsive .tutor-table .tutor-dropdown')
if (tableDropdown.length) {
let tableHeight = jQuery('.tutor-table-responsive .tutor-table').height()
jQuery('.tutor-table-responsive').css('min-height', tableHeight + 110)
}
});
9 changes: 9 additions & 0 deletions assets/react/front/dashboard/settings/profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,15 @@ window.jQuery(document).ready(($) => {
var data = form.serializeObject();
let phone = document.querySelector('[name=phone_number]');

/**
* Basic markup for profile bio
* @since 2.2.4
*/
if (window.tinyMCE !== undefined) {
let editor = tinyMCE.get('tutor_profile_bio');
data.tutor_profile_bio = editor.getContent({ format: 'html' });
}

if (data.phone_number && !data.phone_number.match(/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im)) {
phone.classList.add('invalid');
tutor_toast('Invalid', 'Invalid phone number', 'error');
Expand Down
117 changes: 108 additions & 9 deletions assets/react/front/tutor-front.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,29 +129,59 @@ jQuery(document).ready(function($) {
ajaxurl: window._tutorobject.ajaxurl,
nonce_key: window._tutorobject.nonce_key,
played_once: false,
max_seek_time: 0,
video_data: function() {
const video_track_data = $('#tutor_video_tracking_information').val();
return video_track_data ? JSON.parse(video_track_data) : {};
},
track_player: function() {
const that = this;
if (typeof Plyr !== 'undefined') {
const player = new Plyr(this.player_DOM);
const video_data = that.video_data();
const player = new Plyr(this.player_DOM, {
keyboard: {
focused: that.isRequiredPercentage() ? false : true,
global: false,
},
listeners: {
...(that.isRequiredPercentage() && {
seek(e) {
const newTime = that.getTargetTime(player, e);
const currentTime = player.currentTime;
const max_seek_time = currentTime > that.max_seek_time ? currentTime : that.max_seek_time;
// Disallow moving forward
if (newTime > max_seek_time) {
e.preventDefault();
tutor_toast(__('Warning', 'tutor'), __(`Forward seeking is disabled.`, 'tutor'), 'error');
return false;
}
return true;
},
}),
}
});
player.on('ready', function(event) {
const instance = event.detail.plyr;
const { best_watch_time = 0 } = video_data || {};
if (
best_watch_time > 0 &&
instance.duration > Math.round(best_watch_time)
) {
instance.media.currentTime = best_watch_time;
if (_tutorobject.tutor_pro_url && best_watch_time > 0) {
var previous_duration = Math.round(best_watch_time);
var previousTimeSetter = setTimeout(function(){
if (player.playing !== true && player.currentTime !== previous_duration) {
if (instance.provider === 'youtube') {
instance.embed.seekTo(best_watch_time);
} else {
instance.media.currentTime = previous_duration;
}
} else {
clearTimeout(previousTimeSetter);
}
});
}
that.sync_time(instance);
});

let tempTimeNow = 0;
let intervalSeconds = 30; //Send to tutor backend about video playing time in this interval
let intervalSeconds = 10; //Send to tutor backend about video playing time in this interval
player.on('timeupdate', function(event) {
const instance = event.detail.plyr;
const tempTimeNowInSec = tempTimeNow / 4; //timeupdate firing 250ms interval
Expand Down Expand Up @@ -182,20 +212,33 @@ jQuery(document).ready(function($) {
}
},
sync_time: function(instance, options) {
const post_id = this.video_data().post_id;
const video_data = this.video_data();
if (!video_data) {
return;
}

if (this.isRequiredPercentage()) {
this.enable_complete_lesson_btn(instance);
}

//TUTOR is sending about video playback information to server.
let data = {
action: 'sync_video_playback',
currentTime: instance.currentTime,
duration: instance.duration,
post_id,
post_id: video_data.post_id,
};
data[this.nonce_key] = _tutorobject[this.nonce_key];
let data_send = data;
if (options) {
data_send = Object.assign(data, options);
}
$.post(this.ajaxurl, data_send);

const seekTime = video_data.best_watch_time > instance.currentTime ? video_data.best_watch_time : instance.currentTime;
if (seekTime > this.max_seek_time) {
this.max_seek_time = seekTime;
}
},
autoload_content: function() {
console.log('Autoloader called');
Expand All @@ -209,9 +252,65 @@ jQuery(document).ready(function($) {
}
});
},
isRequiredPercentage: function() {
const video_data = this.video_data();
if (!video_data) {
return false;
}

const { strict_mode, control_video_lesson_completion, lesson_completed, is_enrolled } = video_data;
if (_tutorobject.tutor_pro_url && is_enrolled && !lesson_completed && strict_mode && control_video_lesson_completion) {
return true;
}
return false;
},
enable_complete_lesson_btn: function(instance) {
const complete_lesson_btn = $('button[name="complete_lesson_btn"]');
const video_data = this.video_data();
const completedPercentage = this.getPercentage(Number(instance.currentTime), Number(instance.duration));

if (completedPercentage >= video_data.required_percentage) {
complete_lesson_btn.attr('disabled', false);
complete_lesson_btn.next().remove();
}
},
disable_complete_lesson_btn: function() {
const video_data = this.video_data();
if (!video_data) {
return;
}

const { best_watch_time, video_duration, required_percentage } = video_data;
const completedPercentage = this.getPercentage(Number(best_watch_time), Number(video_duration));

if (completedPercentage < required_percentage) {
const complete_lesson_btn = $('button[name="complete_lesson_btn"]');
complete_lesson_btn.attr('disabled', true);
complete_lesson_btn.wrap('<div class="tooltip-wrap"></div>').after(`<span class="tooltip-txt tooltip-bottom">Watch at least ${video_data.required_percentage}% to complete the lesson.</span>`);
}
},
getPercentage: function(value, total) {
if (value > 0 && total > 0) {
return Math.round((value / total) * 100);
}
return 0;
},
getTargetTime: function(player, input) {
if (
typeof input === "object" &&
(input.type === "input" || input.type === "change")
) {
return input.target.value / input.target.max * player.media.duration;
} else {
return Number(input);
}
},
init: function(element) {
this.player_DOM = element;
this.track_player();
if (this.isRequiredPercentage()) {
this.disable_complete_lesson_btn();
}
},
};

Expand Down
30 changes: 22 additions & 8 deletions assets/react/lib/media-chooser.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,45 @@ window.jQuery(document).ready(function ($) {
multiple: false, // Set to true to allow multiple files to be selected
});
frame.on('select', function () {
var attachment = frame.state().get('selection').first().toJSON();
let attachment = frame.state().get('selection').first().toJSON(),
inputEl = wrapper.find('input[type="hidden"].tutor-tumbnail-id-input');

wrapper.find('img').attr('src', attachment.url);
wrapper.find('input[type="hidden"].tutor-tumbnail-id-input').val(attachment.id);
inputEl.val(attachment.id);
wrapper.find('.delete-btn').show();

$('#save_tutor_option').prop('disabled', false);

document.querySelector('.tutor-option-form .tutor-thumbnail-uploader')
.dispatchEvent(new CustomEvent('tutor_settings_media_selected', {
detail: {
wrapper: wrapper,
settingsName: inputEl.attr('name').replace(/.*\[(.*?)\]/, '$1'),
attachment: attachment
}
}));

});
frame.open();
});

/**
* Thumbnail Delete
* @since v.1.5.6
* @since 1.5.6
*/
$(document).on('click', '.tutor-thumbnail-uploader .delete-btn', function (e) {
e.preventDefault();

var $that = $(this);
var wrapper = $that.closest('.tutor-thumbnail-uploader');
var img = wrapper.find('img');
var placeholder = img.data('placeholder') || '';
let $that = $(this),
wrapper = $that.closest('.tutor-thumbnail-uploader'),
img = wrapper.find('img'),
placeholder = img.data('placeholder') || '';

wrapper.find('input[type="hidden"].tutor-tumbnail-id-input').val('');
img.attr('src', placeholder);

$that.hide();

// Enable save button after thumbnail remove.
$('#save_tutor_option').prop('disabled', false);
});
});
22 changes: 22 additions & 0 deletions assets/react/lib/tutor.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,28 @@ window.tutor_toast = function( title, description, type, autoClose = true ) {
}
};

/**
* Escape HTML and return safe HTML
*
* @since 2.2.4
*
* @param {string} unsafeText HTML string
* @returns string
*/
window.tutor_esc_html = function (unsafeText) {
let safeHTML = ''
let div = document.createElement('div');
/**
* When set an HTML string to an element's innerText
* the browser automatically escapes any HTML tags and
* treats the content as plain text.
*/
div.innerText = unsafeText;
safeHTML = div.innerHTML;
div.remove()

return safeHTML;
}

// enable custom selector when modal opens
window.addEventListener('tutor_modal_shown', (e) => {
Expand Down
Loading

0 comments on commit 877715d

Please sign in to comment.