PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 All 141 releases
← All changes | assets/js/dist/frontend/single-course.js +188 -42 4.3.7 → 4.4.9 View file →
@@ -942,8 +942,9 @@
942 942 __webpack_require__.r(__webpack_exports__);
943 943 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
944 944 /* harmony export */ debounce: () => (/* binding */ debounce),
945 945 /* harmony export */ eventHandlers: () => (/* binding */ eventHandlers),
946 +/* harmony export */ fullScreenView: () => (/* binding */ fullScreenView),
946 947 /* harmony export */ getDataOfForm: () => (/* binding */ getDataOfForm),
947 948 /* harmony export */ getFieldKeysOfForm: () => (/* binding */ getFieldKeysOfForm),
948 949 /* harmony export */ listenElementCreated: () => (/* binding */ listenElementCreated),
949 950 /* harmony export */ listenElementViewed: () => (/* binding */ listenElementViewed),
@@ -955,9 +956,10 @@
955 956 /* harmony export */ lpOnElementReady: () => (/* binding */ lpOnElementReady),
956 957 /* harmony export */ lpSetLoadingEl: () => (/* binding */ lpSetLoadingEl),
957 958 /* harmony export */ lpShowHideEl: () => (/* binding */ lpShowHideEl),
958 959 /* harmony export */ mergeDataWithDatForm: () => (/* binding */ mergeDataWithDatForm),
959 -/* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse)
960 +/* harmony export */ toggleCollapse: () => (/* binding */ toggleCollapse),
961 +/* harmony export */ toggleEnable: () => (/* binding */ toggleEnable)
960 962 /* harmony export */ });
961 963 /**
962 964 * Utils functions
963 965 *
@@ -964,9 +966,9 @@
964 966 * @param url
965 967 * @param data
966 968 * @param functions
967 969 * @since 4.2.5.1
968 - * @version 1.0.6
970 + * @version 1.0.7
969 971 */
970 972 const lpClassName = {
971 973 hidden: 'lp-hidden',
972 974 loading: 'loading',
@@ -971,9 +973,12 @@
971 973 hidden: 'lp-hidden',
972 974 loading: 'loading',
973 975 elCollapse: 'lp-collapse',
974 976 elSectionToggle: '.lp-section-toggle',
975 - elTriggerToggle: '.lp-trigger-toggle'
977 + elTriggerToggle: '.lp-trigger-toggle',
978 + elBtnFullScreen: '.lp-btn-full-screen-view',
979 + elFullScreen: 'lp-full-screen-view',
980 + elBtnFullScreenClose: 'lp-full-screen-view__close'
976 981 };
977 982 const lpFetchAPI = (url, data = {}, functions = {}) => {
978 983 if ('function' === typeof functions.before) {
979 984 functions.before();
@@ -1291,8 +1296,141 @@
1291 1296 timer = setTimeout(() => func(args), wait);
1292 1297 };
1293 1298 };
1294 1299
1300 +/**
1301 + * Initialize lp-toggle-enable components.
1302 + *
1303 + * Finds all `.lp-toggle-enable` elements and wires up toggle behavior.
1304 + * Reads initial state from `data-enabled` attribute ("true"/"false").
1305 + * Calls `data-on-toggle` callback (if provided via options) on state change.
1306 + *
1307 + * HTML structure:
1308 + * <label class="lp-toggle-enable" data-enabled="true">
1309 + * <input type="checkbox" class="lp-toggle-enable__input" />
1310 + * <span class="lp-toggle-enable__track"></span>
1311 + * </label>
1312 + *
1313 + * @param {string} selector CSS selector for toggle elements (default: '.lp-toggle-enable')
1314 + * @param {Function} onToggle Optional callback( el, isEnabled ) called on state change
1315 + * @since 4.4.5
1316 + * @version 1.0.0
1317 + */
1318 +window.lpToggleEnableInit = 0;
1319 +const toggleEnable = (onToggle = null) => {
1320 + if (window.lpToggleEnableInit) {
1321 + return;
1322 + }
1323 + window.lpToggleEnableInit = 1;
1324 + const selector = '.lp-toggle-enable';
1325 + const updateUI = (toggle, isEnabled) => {
1326 + toggle.classList.toggle('is-enabled', isEnabled);
1327 + const input = toggle.querySelector('.lp-toggle-enable__input');
1328 + if (input) {
1329 + input.checked = isEnabled;
1330 + input.value = isEnabled ? '1' : '0';
1331 + }
1332 + };
1333 +
1334 + // Delegate click handling via eventHandlers.
1335 + eventHandlers('click', [{
1336 + selector,
1337 + callBack: args => {
1338 + const {
1339 + e,
1340 + target
1341 + } = args;
1342 + const toggle = target.closest(selector);
1343 + if (!toggle || toggle.classList.contains('is-disabled')) {
1344 + return;
1345 + }
1346 + e.preventDefault();
1347 + const isEnabled = !toggle.classList.contains('is-enabled');
1348 + updateUI(toggle, isEnabled);
1349 + if ('function' === typeof onToggle) {
1350 + onToggle(toggle, isEnabled);
1351 + }
1352 + }
1353 + }]);
1354 +};
1355 +
1356 +/**
1357 + * Initialize custom fullscreen view buttons.
1358 + *
1359 + * Delegates clicks on `.lp-btn-full-screen-view` buttons to
1360 + * `lpToggleFullscreenView`. Reads the `data-target` attribute to find the
1361 + * target element. Falls back to the button's parent element when
1362 + * `data-target` is not provided.
1363 + *
1364 + * @since 4.4.5
1365 + * @version 1.0.0
1366 + */
1367 +window.lpFullScreenViewInit = 0;
1368 +const fullScreenView = () => {
1369 + if (window.lpFullScreenViewInit) {
1370 + return;
1371 + }
1372 + window.lpFullScreenViewInit = 1;
1373 + let lastScrollY = 0;
1374 + const lpToggleFullscreenView = (elTarget, elBtnFullScreen = null) => {
1375 + const isFullscreen = elTarget.classList.contains(lpClassName.elFullScreen);
1376 + if (isFullscreen) {
1377 + elTarget.classList.remove(lpClassName.elFullScreen);
1378 + document.documentElement.classList.remove('lp-full-screen-active');
1379 + window.scrollTo(0, lastScrollY);
1380 + } else {
1381 + lastScrollY = window.scrollY;
1382 + elTarget.classList.add(lpClassName.elFullScreen);
1383 + document.documentElement.classList.add('lp-full-screen-active');
1384 + }
1385 + if (!isFullscreen) {
1386 + if (!elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`)) {
1387 + const closeButton = document.createElement('button');
1388 + closeButton.type = 'button';
1389 + closeButton.className = lpClassName.elBtnFullScreenClose;
1390 + closeButton.setAttribute('aria-label', 'Close');
1391 + closeButton.innerHTML = lpData.i18n.closeButtonFullScreen || 'Close &times;';
1392 + closeButton.addEventListener('click', e => {
1393 + e.preventDefault();
1394 + lpToggleFullscreenView(elTarget);
1395 + });
1396 + elTarget.appendChild(closeButton);
1397 + }
1398 + } else {
1399 + const closeButton = elTarget.querySelector(`.${lpClassName.elBtnFullScreenClose}`);
1400 + if (closeButton) {
1401 + closeButton.remove();
1402 + }
1403 + }
1404 + };
1405 + eventHandlers('click', [{
1406 + selector: lpClassName.elBtnFullScreen,
1407 + callBack: args => {
1408 + const {
1409 + e,
1410 + target
1411 + } = args;
1412 + const elBtnFullScreen = target.closest(lpClassName.elBtnFullScreen);
1413 + if (!elBtnFullScreen) {
1414 + console.log('No full screen button found');
1415 + return;
1416 + }
1417 + e.preventDefault();
1418 + let elTarget = null;
1419 + const targetSelector = elBtnFullScreen.dataset.targetFullscreen;
1420 + console.log(targetSelector);
1421 + if (targetSelector) {
1422 + elTarget = document.querySelector(targetSelector);
1423 + }
1424 + if (!elTarget) {
1425 + console.log('No target element found');
1426 + return;
1427 + }
1428 + lpToggleFullscreenView(elTarget, elBtnFullScreen);
1429 + }
1430 + }]);
1431 +};
1432 +
1295 1433 /***/ },
1296 1434
1297 1435 /***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/toastify-js/src/toastify.css"
1298 1436 /*!*****************************************************************************************!*\
@@ -2738,46 +2876,54 @@
2738 2876 });
2739 2877 };
2740 2878
2741 2879 // Rest API load content course progress - Nhamdv.
2742 -const courseProgress = () => {
2743 - const elements = document.querySelectorAll('.lp-course-progress-wrapper');
2744 - if (!elements.length) {
2745 - return;
2746 - }
2747 - if ('IntersectionObserver' in window) {
2748 - const eleObserver = new IntersectionObserver((entries, observer) => {
2749 - entries.forEach(entry => {
2750 - if (entry.isIntersecting) {
2751 - const ele = entry.target;
2752 - setTimeout(function () {
2753 - getResponse(ele);
2754 - }, 600);
2755 - eleObserver.unobserve(ele);
2756 - }
2757 - });
2758 - });
2759 - [...elements].map(ele => eleObserver.observe(ele));
2760 - }
2761 - const getResponse = async ele => {
2762 - let url = 'lp/v1/lazy-load/course-progress';
2763 - if (lpData.urlParams.hasOwnProperty('lang')) {
2764 - url += '?lang=' + lpData.urlParams.lang;
2765 - }
2766 - const response = await wp.apiFetch({
2767 - path: url,
2768 - method: 'POST',
2769 - data: {
2770 - courseId: lpGlobalSettings.post_id || '',
2771 - userId: lpData.user_id || ''
2772 - }
2773 - });
2774 - const {
2775 - data
2776 - } = response;
2777 - ele.innerHTML = data;
2778 - };
2779 -};
2880 +/*const courseProgress = () => {
2881 + const elements = document.querySelectorAll( '.lp-course-progress-wrapper' );
2882 +
2883 + if ( ! elements.length ) {
2884 + return;
2885 + }
2886 +
2887 + if ( 'IntersectionObserver' in window ) {
2888 + const eleObserver = new IntersectionObserver( ( entries, observer ) => {
2889 + entries.forEach( ( entry ) => {
2890 + if ( entry.isIntersecting ) {
2891 + const ele = entry.target;
2892 +
2893 + setTimeout( function() {
2894 + getResponse( ele );
2895 + }, 600 );
2896 +
2897 + eleObserver.unobserve( ele );
2898 + }
2899 + } );
2900 + } );
2901 +
2902 + [ ...elements ].map( ( ele ) => eleObserver.observe( ele ) );
2903 + }
2904 +
2905 + const getResponse = async ( ele ) => {
2906 + let url = 'lp/v1/lazy-load/course-progress';
2907 + if ( lpData.urlParams.hasOwnProperty( 'lang' ) ) {
2908 + url += '?lang=' + lpData.urlParams.lang;
2909 + }
2910 +
2911 + const response = await wp.apiFetch( {
2912 + path: url,
2913 + method: 'POST',
2914 + data: {
2915 + courseId: lpGlobalSettings.post_id || '',
2916 + userId: lpData.user_id || '',
2917 + },
2918 + } );
2919 +
2920 + const { data } = response;
2921 +
2922 + ele.innerHTML = data;
2923 + };
2924 +};*/
2925 +
2780 2926 const accordionExtraTab = () => {
2781 2927 const elements = document.querySelectorAll('.course-extra-box');
2782 2928 [...elements].map(ele => {
2783 2929 const title = ele.querySelector('.course-extra-box__title');
@@ -2836,9 +2982,9 @@
2836 2982 initCourseSidebar();
2837 2983 enrollCourse();
2838 2984 purchaseCourse();
2839 2985 retakeCourse();
2840 - courseProgress();
2986 + //courseProgress();
2841 2987 courseContinue();
2842 2988 _show_lp_overlay_complete_item__WEBPACK_IMPORTED_MODULE_2__["default"].init();
2843 2989 (0,_material__WEBPACK_IMPORTED_MODULE_5__["default"])();
2844 2990 //courseCurriculumSkeleton();