Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"version":3,"file":"main.min.js","sources":["../src/main.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript to initialise the Recently accessed courses block.\n *\n * @module     block_recentlyaccessedcourses/main\n * @copyright  2018 Victor Deniz <victor@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(\n    [\n        'jquery',\n        'core/custom_interaction_events',\n        'core/notification',\n        'core/pubsub',\n        'core/paged_content_paging_bar',\n        'core/templates',\n        'core_course/events',\n        'core_course/repository',\n        'core/aria',\n    ],\n    function(\n        $,\n        CustomEvents,\n        Notification,\n        PubSub,\n        PagedContentPagingBar,\n        Templates,\n        CourseEvents,\n        CoursesRepository,\n        Aria\n    ) {\n\n        // Constants.\n        var NUM_COURSES_TOTAL = 10;\n        var SELECTORS = {\n            BLOCK_CONTAINER: '[data-region=\"recentlyaccessedcourses\"]',\n            CARD_CONTAINER: '[data-region=\"card-deck\"]',\n            COURSE_IS_FAVOURITE: '[data-region=\"is-favourite\"]',\n            CONTENT: '[data-region=\"view-content\"]',\n            EMPTY_MESSAGE: '[data-region=\"empty-message\"]',\n            LOADING_PLACEHOLDER: '[data-region=\"loading-placeholder\"]',\n            PAGING_BAR: '[data-region=\"paging-bar\"]',\n            PAGING_BAR_NEXT: '[data-control=\"next\"]',\n            PAGING_BAR_PREVIOUS: '[data-control=\"previous\"]'\n        };\n        // Module variables.\n        var contentLoaded = false;\n        var allCourses = [];\n        var visibleCoursesId = null;\n        var cardWidth = null;\n        var viewIndex = 0;\n        var availableVisibleCards = 1;\n\n        /**\n         * Show the empty message when no course are found.\n         *\n         * @param {object} root The root element for the courses view.\n         */\n        var showEmptyMessage = function(root) {\n            root.find(SELECTORS.EMPTY_MESSAGE).removeClass('hidden');\n            root.find(SELECTORS.LOADING_PLACEHOLDER).addClass('hidden');\n            root.find(SELECTORS.CONTENT).addClass('hidden');\n        };\n\n        /**\n         * Show the empty message when no course are found.\n         *\n         * @param {object} root The root element for the courses view.\n         */\n        var showContent = function(root) {\n            root.find(SELECTORS.CONTENT).removeClass('hidden');\n            root.find(SELECTORS.EMPTY_MESSAGE).addClass('hidden');\n            root.find(SELECTORS.LOADING_PLACEHOLDER).addClass('hidden');\n        };\n\n        /**\n         * Show the paging bar.\n         *\n         * @param {object} root The root element for the courses view.\n         */\n        var showPagingBar = function(root) {\n            var pagingBar = root.find(SELECTORS.PAGING_BAR);\n            pagingBar.css('opacity', 1);\n            pagingBar.css('visibility', 'visible');\n            Aria.unhide(pagingBar);\n        };\n\n        /**\n         * Hide the paging bar.\n         *\n         * @param {object} root The root element for the courses view.\n         */\n        var hidePagingBar = function(root) {\n            var pagingBar = root.find(SELECTORS.PAGING_BAR);\n            pagingBar.css('opacity', 0);\n            pagingBar.css('visibility', 'hidden');\n            Aria.hide(pagingBar);\n        };\n\n        /**\n         * Show the favourite indicator for the given course (if it's in the list).\n         *\n         * @param {object} root The root element for the courses view.\n         * @param {number} courseId The id of the course to be favourited.\n         */\n        var favouriteCourse = function(root, courseId) {\n            allCourses.forEach(function(course) {\n                if (course.attr('data-course-id') == courseId) {\n                    course.find(SELECTORS.COURSE_IS_FAVOURITE).removeClass('hidden');\n                }\n            });\n        };\n\n        /**\n         * Hide the favourite indicator for the given course (if it's in the list).\n         *\n         * @param {object} root The root element for the courses view.\n         * @param {number} courseId The id of the course to be unfavourited.\n         */\n        var unfavouriteCourse = function(root, courseId) {\n            allCourses.forEach(function(course) {\n                if (course.attr('data-course-id') == courseId) {\n                    course.find(SELECTORS.COURSE_IS_FAVOURITE).addClass('hidden');\n                }\n            });\n        };\n\n        /**\n         * Render the a list of courses.\n         *\n         * @param {array} courses containing array of courses.\n         * @return {promise} Resolved with list of rendered courses as jQuery objects.\n         */\n        var renderAllCourses = function(courses) {\n            var showcoursecategory = $(SELECTORS.BLOCK_CONTAINER).data('displaycoursecategory');\n            var promises = courses.map(function(course) {\n                course.showcoursecategory = showcoursecategory;\n                return Templates.render('block_recentlyaccessedcourses/course-card', course);\n            });\n\n            return $.when.apply(null, promises).then(function() {\n                var renderedCourses = [];\n\n                promises.forEach(function(promise) {\n                    promise.then(function(html) {\n                        renderedCourses.push($(html));\n                        return;\n                    })\n                    .catch(Notification.exception);\n                });\n\n                return renderedCourses;\n            });\n        };\n\n        /**\n         * Fetch user's recently accessed courses and reload the content of the block.\n         *\n         * @param {int} userid User whose courses will be shown\n         * @returns {promise} The updated content for the block.\n         */\n        var loadContent = function(userid) {\n            return CoursesRepository.getLastAccessedCourses(userid, NUM_COURSES_TOTAL)\n                .then(function(courses) {\n                    return renderAllCourses(courses);\n                });\n        };\n\n        /**\n         * Recalculate the number of courses that should be visible.\n         *\n         * @param {object} root The root element for the courses view.\n         */\n        var recalculateVisibleCourses = function(root) {\n            var container = root.find(SELECTORS.CONTENT).find(SELECTORS.CARD_CONTAINER);\n            var availableWidth = parseFloat(root.css('width'));\n            var numberOfCourses = allCourses.length;\n            var start = 0;\n\n            if (!cardWidth) {\n                container.html(allCourses[0]);\n                // Render one card initially to calculate the width of the cards\n                // including the margins.\n                cardWidth = allCourses[0].outerWidth(true);\n            }\n\n            availableVisibleCards = Math.floor(availableWidth / cardWidth);\n\n            if (viewIndex + availableVisibleCards < numberOfCourses) {\n                start = viewIndex;\n            } else {\n                var overflow = (viewIndex + availableVisibleCards) - numberOfCourses;\n                start = viewIndex - overflow;\n                start = start >= 0 ? start : 0;\n            }\n\n            // At least show one card.\n            if (availableVisibleCards === 0) {\n                availableVisibleCards = 1;\n            }\n\n            var coursesToShow = allCourses.slice(start, start + availableVisibleCards);\n            // Create an id for the list of courses we expect to be displayed.\n            var newVisibleCoursesId = coursesToShow.reduce(function(carry, course) {\n                return carry + course.attr('data-course-id');\n            }, '');\n\n            // Centre the courses if we have an overflow of courses.\n            if (allCourses.length > coursesToShow.length) {\n                container.addClass('justify-content-center');\n                container.removeClass('justify-content-start');\n            } else {\n                container.removeClass('justify-content-center');\n                container.addClass('justify-content-start');\n            }\n\n            // Don't bother updating the DOM unless the visible courses have changed.\n            if (visibleCoursesId != newVisibleCoursesId) {\n                var pagingBar = root.find(PagedContentPagingBar.rootSelector);\n                container.html(coursesToShow);\n                visibleCoursesId = newVisibleCoursesId;\n\n                if (availableVisibleCards >= allCourses.length) {\n                    hidePagingBar(root);\n                } else {\n                    showPagingBar(root);\n\n                    if (viewIndex === 0) {\n                        PagedContentPagingBar.disablePreviousControlButtons(pagingBar);\n                    } else {\n                        PagedContentPagingBar.enablePreviousControlButtons(pagingBar);\n                    }\n\n                    if (viewIndex + availableVisibleCards >= allCourses.length) {\n                        PagedContentPagingBar.disableNextControlButtons(pagingBar);\n                    } else {\n                        PagedContentPagingBar.enableNextControlButtons(pagingBar);\n                    }\n                }\n            }\n        };\n\n        /**\n         * Register event listeners for the block.\n         *\n         * @param {object} root The root element for the recentlyaccessedcourses block.\n         */\n        var registerEventListeners = function(root) {\n            var resizeTimeout = null;\n            var drawerToggling = false;\n\n            PubSub.subscribe(CourseEvents.favourited, function(courseId) {\n                favouriteCourse(root, courseId);\n            });\n\n            PubSub.subscribe(CourseEvents.unfavorited, function(courseId) {\n                unfavouriteCourse(root, courseId);\n            });\n\n            PubSub.subscribe('nav-drawer-toggle-start', function() {\n                if (!contentLoaded || !allCourses.length || drawerToggling) {\n                    // Nothing to recalculate.\n                    return;\n                }\n\n                drawerToggling = true;\n                var recalculationCount = 0;\n                // This function is going to recalculate the number of courses while\n                // the nav drawer is opening or closes (up to a maximum of 5 recalcs).\n                var doRecalculation = function() {\n                    setTimeout(function() {\n                        recalculateVisibleCourses(root);\n                        recalculationCount++;\n\n                        if (recalculationCount < 5 && drawerToggling) {\n                            // If we haven't done too many recalculations and the drawer\n                            // is still toggling then recurse.\n                            doRecalculation();\n                        }\n                    }, 100);\n                };\n\n                // Start the recalculations.\n                doRecalculation(root);\n            });\n\n            PubSub.subscribe('nav-drawer-toggle-end', function() {\n                drawerToggling = false;\n            });\n\n            $(window).on('resize', function() {\n                if (!contentLoaded || !allCourses.length) {\n                    // Nothing to reclculate.\n                    return;\n                }\n\n                // Resize events fire rapidly so recalculating the visible courses each\n                // time can be expensive. Let's debounce them,\n                if (!resizeTimeout) {\n                    resizeTimeout = setTimeout(function() {\n                        resizeTimeout = null;\n                        recalculateVisibleCourses(root);\n                    // The recalculateVisibleCourses function will execute at a rate of 15fps.\n                    }, 66);\n                }\n            });\n\n            CustomEvents.define(root, [CustomEvents.events.activate]);\n            root.on(CustomEvents.events.activate, SELECTORS.PAGING_BAR_NEXT, function(e, data) {\n                var button = $(e.target).closest(SELECTORS.PAGING_BAR_NEXT);\n                if (!button.hasClass('disabled')) {\n                    viewIndex = viewIndex + availableVisibleCards;\n                    recalculateVisibleCourses(root);\n                }\n\n                data.originalEvent.preventDefault();\n            });\n\n            root.on(CustomEvents.events.activate, SELECTORS.PAGING_BAR_PREVIOUS, function(e, data) {\n                var button = $(e.target).closest(SELECTORS.PAGING_BAR_PREVIOUS);\n                if (!button.hasClass('disabled')) {\n                    viewIndex = viewIndex - availableVisibleCards;\n                    viewIndex = viewIndex < 0 ? 0 : viewIndex;\n                    recalculateVisibleCourses(root);\n                }\n\n                data.originalEvent.preventDefault();\n            });\n        };\n\n        /**\n         * Get and show the recent courses into the block.\n         *\n         * @param {int} userid User from which the courses will be obtained\n         * @param {object} root The root element for the recentlyaccessedcourses block.\n         */\n        var init = function(userid, root) {\n            root = $(root);\n\n            registerEventListeners(root);\n            loadContent(userid)\n                .then(function(renderedCourses) {\n                    allCourses = renderedCourses;\n                    contentLoaded = true;\n\n                    if (allCourses.length) {\n                        showContent(root);\n                        recalculateVisibleCourses(root);\n                    } else {\n                        showEmptyMessage(root);\n                    }\n\n                    return;\n                })\n                .catch(Notification.exception);\n        };\n\n        return {\n            init: init\n        };\n    });\n"],"names":["define","$","CustomEvents","Notification","PubSub","PagedContentPagingBar","Templates","CourseEvents","CoursesRepository","Aria","SELECTORS","contentLoaded","allCourses","visibleCoursesId","cardWidth","viewIndex","availableVisibleCards","loadContent","userid","getLastAccessedCourses","then","courses","showcoursecategory","data","promises","map","course","render","when","apply","renderedCourses","forEach","promise","html","push","catch","exception","renderAllCourses","recalculateVisibleCourses","root","container","find","availableWidth","parseFloat","css","numberOfCourses","length","start","outerWidth","Math","floor","coursesToShow","slice","newVisibleCoursesId","reduce","carry","attr","addClass","removeClass","pagingBar","rootSelector","hide","hidePagingBar","unhide","showPagingBar","disablePreviousControlButtons","enablePreviousControlButtons","disableNextControlButtons","enableNextControlButtons","registerEventListeners","resizeTimeout","drawerToggling","subscribe","favourited","courseId","favouriteCourse","unfavorited","unfavouriteCourse","recalculationCount","doRecalculation","setTimeout","window","on","events","activate","e","target","closest","hasClass","originalEvent","preventDefault","init","showContent","showEmptyMessage"],"mappings":"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"}