Proyectos de Subversion Moodle

Rev

Rev 4 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
5 ariadna 1
{"version":3,"file":"script_point_view.min.js","sources":["../src/script_point_view.js"],"sourcesContent":["// This file is part of Moodle - https://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 * Module to display and manage reactions and difficulty tracks on course page.\n * @copyright  2020 Quentin Fombaron, 2021 Astor Bizard\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/ajax', 'core/notification'], function($, ajax, notification) {\n\n    /**\n     * Call a function each time a course section is loaded.\n     * @param {Function} call Function to call.\n     */\n    function callOnModulesListLoad(call) {\n        call();\n\n        // The following listener is needed for the Tiles course format, where sections are loaded on demand.\n        $(document).ajaxComplete(function(event, xhr, settings) {\n            if (typeof (settings.data) !== 'string') {\n                return;\n            }\n            try {\n                var data = JSON.parse(settings.data);\n                if (data.length == 0 || typeof (data[0].methodname) === 'undefined') {\n                    return;\n                }\n                if (data[0].methodname == 'format_tiles_get_single_section_page_html' // Tile load.\n                    || data[0].methodname == 'format_tiles_log_tile_click') { // Tile load, cached.\n                    call();\n                }\n            } catch (e) {\n                // Something went wrong, it may not even be JSON. It is fine, this means it was not the call we were expecting.\n                return;\n            }\n        });\n    }\n\n    /**\n     * Set up difficulty tracks on course modules.\n     * @param {Array} difficultyLevels Array of difficulty tracks, one entry for each course module.\n     * @param {Array} trackColors Tracks colors, from block plugin configuration.\n     */\n    function setUpDifficultyTracks(difficultyLevels, trackColors) {\n        difficultyLevels.forEach(function(module) {\n            var difficultyLevel = parseInt(module.difficultyLevel);\n            var title = '';\n            if (difficultyLevel > 0) {\n                var track = ['greentrack', 'bluetrack', 'redtrack', 'blacktrack'][difficultyLevel - 1];\n                title = M.util.get_string(track, 'block_point_view');\n            }\n            var $track = $('<div>', {\n                'class': 'block_point_view track',\n                'title': title,\n                'style': 'background-color: ' + trackColors[difficultyLevel] + ';'\n            });\n            // Decide where to put the track.\n            var $container = $('#module-' + module.id + ' .mod-indent-outer');\n\n            // Add the track.\n            if ($container.find('.block_point_view.track').length === 0) {\n                $container.prepend($track);\n            }\n            // If there is indentation, move the track after it.\n            $container.find('.mod-indent').after($track);\n\n        });\n    }\n\n\n    /**\n     * Get a jQuery object in reaction zone for given module ID.\n     * @param {Number} moduleId Module ID.\n     * @param {String} selector (optional) Sub-selector.\n     * @return {jQuery} If selector was provided, the corresponding jQuery object within the reaction zone.\n     *  If not, the reaction zone jQuery object.\n     */\n    function $get(moduleId, selector) {\n        var $element = $('#module-' + moduleId + ' .block_point_view.reactions-container');\n        if (typeof (selector) === 'undefined') {\n            return $element;\n        } else {\n            return $element.find(selector);\n        }\n    }\n\n    // Enumeration of the possible reactions.\n    var Reactions = {\n            none: 0,\n            easy: 1,\n            better: 2,\n            hard: 3\n    };\n\n    // Array of Reaction of the user for the activity.\n    var reactionVotedArray = {};\n\n    /**\n     * Set up difficulty tracks on course modules.\n     * @param {Number} courseId Course ID.\n     * @param {Array} modulesWithReactions Array of reactions state, one entry for each course module with reactions enabled.\n     * @param {String} reactionsHtml HTML fragment for reactions.\n     * @param {Array} pixSrc Array of pictures sources for group images.\n     */\n    function setUpReactions(courseId, modulesWithReactions, reactionsHtml, pixSrc) {\n        // For each selected module, create a reaction zone.\n        modulesWithReactions.forEach(function(module) {\n            var moduleId = parseInt(module.cmid);\n            var uservote = parseInt(module.uservote);\n\n            // Initialise reactionVotedArray.\n            reactionVotedArray[moduleId] = uservote;\n\n            if ($('#module-' + moduleId).length === 1 && $get(moduleId).length === 0) {\n\n                // Add the reaction zone to the module.\n                $('#module-' + moduleId).prepend(reactionsHtml);\n\n                // Setup reaction change.\n                var reactionsLock = false;\n                $get(moduleId, '.reaction img')\n                .click(function() {\n                    // Use a mutex to avoid query / display inconsistencies.\n                    // This is not a perfect mutex, but is actually enough for our needs.\n                    if (reactionsLock === false) {\n                        reactionsLock = true;\n                        reactionChange(courseId, moduleId, $(this).data('reactionname'))\n                        .always(function() {\n                            reactionsLock = false;\n                            updateGroupImgAndNb(moduleId, pixSrc);\n                        });\n                    }\n                });\n\n                // Initialize reactions state.\n                $get(moduleId, '.reactionnb').each(function() {\n                    var reactionName = $(this).data('reactionname');\n                    var reactionNb = parseInt(module['total' + reactionName]);\n                    updateReactionNb(moduleId, reactionName, reactionNb, uservote === Reactions[reactionName]);\n                });\n                updateGroupImgAndNb(moduleId, pixSrc);\n\n                // Setup animations.\n                setupReactionsAnimation(moduleId, pixSrc);\n            }\n        });\n    }\n\n    /**\n     * Manage a reaction change (user added, removed or updated their vote).\n     * @param {Number} courseId Course ID.\n     * @param {Number} moduleId Module ID.\n     * @param {String} reactionName The reaction being clicked.\n     * @returns {Promise} A promise, result of the change operations (ajax call and UI update).\n     */\n    function reactionChange(courseId, moduleId, reactionName) {\n\n        var reactionSelect = Reactions[reactionName];\n        var previousReaction = reactionVotedArray[moduleId];\n\n        // If the reaction being clicked is the current one, it is a vote remove.\n        var newVote = (reactionSelect === previousReaction) ? Reactions.none : reactionSelect;\n\n        return ajax.call([\n            {\n                methodname: 'block_point_view_update_db',\n                args: {\n                    func: 'update',\n                    courseid: courseId,\n                    cmid: moduleId,\n                    vote: newVote\n                }\n            }\n        ])[0]\n        .done(function() {\n            reactionVotedArray[moduleId] = newVote; // Set current reaction.\n            if (previousReaction !== Reactions.none) {\n                // User canceled their vote (or updated to another one).\n                var previousReactionName = ['', 'easy', 'better', 'hard'][previousReaction];\n                updateReactionNb(moduleId, previousReactionName, -1, false);\n            }\n            if (newVote !== Reactions.none) {\n                // User added or updated their vote.\n                updateReactionNb(moduleId, reactionName, +1, true); // Add new vote.\n            }\n        })\n        .fail(notification.exception);\n    }\n\n    /**\n     * Update the reactions group image and total number according to current votes.\n     * @param {Number} moduleId Module ID.\n     * @param {Array} pix Array of pictures sources for group images.\n     */\n    function updateGroupImgAndNb(moduleId, pix) {\n        // Build group image name.\n        var groupImg = 'group_';\n        var totalNb = 0;\n        $get(moduleId, '.reactionnb').each(function() {\n            var reactionNb = parseInt($(this).text());\n            if (reactionNb > 0) {\n                groupImg += $(this).data('reactionname').toUpperCase().charAt(0); // Add E, B or H.\n            }\n            totalNb += reactionNb;\n        });\n        // Modify the image source of the reaction group.\n        $get(moduleId, '.group_img').attr('src', pix[groupImg]);\n\n        // Update the total number of votes.\n        var $groupNbWrapper = $get(moduleId, '.group_nb');\n        var $groupNb = $groupNbWrapper.find('span');\n\n        $groupNb\n        .text(totalNb)\n        .attr('title', M.util.get_string('totalreactions', 'block_point_view', totalNb));\n\n        $groupNbWrapper\n        .toggleClass('invisible', totalNb === 0)\n        .toggleClass('voted', reactionVotedArray[moduleId] !== Reactions.none);\n\n        // Adjust the size to fit within a fixed space (useful for the green dot).\n        var digits = Math.min(('' + totalNb).length, 5);\n        $groupNb.css({\n            'right': Math.max(0.25 * (digits - 2), 0) + 'em',\n            'transform': 'scaleX(' + (1.0 + 0.03 * digits * digits - 0.35 * digits + 0.34) + ')'\n        });\n    }\n\n    /**\n     * Update a reaction number of votes.\n     * @param {Number} moduleId Module ID.\n     * @param {String} reactionName The reaction to update the number of.\n     * @param {Number} diff Difference to apply (e.g. +1 for adding a vote, -1 for removing a vote).\n     * @param {Boolean} isSelected Whether the reaction we are updating is the one now selected by user.\n     */\n    function updateReactionNb(moduleId, reactionName, diff, isSelected) {\n        var $reactionNb = $get(moduleId, '.reactionnb[data-reactionname=\"' + reactionName + '\"]');\n        var nbReaction = parseInt($reactionNb.text()) + diff;\n        $reactionNb\n        .text(nbReaction)\n        .toggleClass('nbselected', isSelected);\n\n        $get(moduleId, '.reaction img[data-reactionname=\"' + reactionName + '\"]')\n        .toggleClass('novote', nbReaction === 0);\n    }\n\n    /**\n     * Set up animations to swap between reactions preview and vote interface.\n     * @param {Number} moduleId Module ID.\n     */\n    function setupReactionsAnimation(moduleId) {\n\n        // Helpers to resize images for animations.\n        var reactionImageSizeForRatio = function(ratio) {\n            return {\n                top: 15 - (10 * ratio),\n                left: 10 - (10 * ratio),\n                height: 20 * ratio\n            };\n        };\n        var groupImageSizeForRatio = function(ratio) {\n            return {\n                left: -10 + (10 * ratio),\n                height: 20 * ratio\n            };\n        };\n\n        // Animation sequence to hide reactions preview and show vote interface.\n        var showReactions = function(moduleId) {\n            $get(moduleId, '.reactions').removeClass('invisible');\n\n            $get(moduleId, '.group_img')\n            .css({'pointer-events': 'none'})\n            .animate(groupImageSizeForRatio(0), 300)\n            .hide(0);\n\n            $get(moduleId, '.group_nb').delay(200).hide(300);\n\n            $('#module-' + moduleId + ' .actions').delay(200).hide(300);\n\n            ['easy', 'better', 'hard'].forEach(function(reaction, index) {\n                var delay = 50 + 150 * index; // Easy: 50, better: 200, hard: 350.\n\n                $get(moduleId, '.reaction img[data-reactionname=\"' + reaction + '\"]')\n                .delay(delay).animate(reactionImageSizeForRatio(1), 300)\n                .css({'pointer-events': 'auto'});\n\n                $get(moduleId, '.reactionnb[data-reactionname=\"' + reaction + '\"]')\n                .delay(delay + 300)\n                .queue(function(next) {\n                    $(this).removeClass('invisible');\n                    next();\n                });\n            });\n        };\n\n        // Animation sequence to hide vote interface and show reaction preview.\n        var hideReactions = function(moduleId) {\n            ['hard', 'better', 'easy'].forEach(function(reaction, index) {\n                var delay = 50 + 250 * index; // Hard: 50, better: 300, easy: 550.\n                $get(moduleId, '.reaction img[data-reactionname=\"' + reaction + '\"]')\n                .css({'pointer-events': 'none'})\n                .delay(delay).animate(reactionImageSizeForRatio(0), 500);\n\n                $get(moduleId, '.reactionnb[data-reactionname=\"' + reaction + '\"]')\n                .delay(delay)\n                .queue(function(next) {\n                    $(this).addClass('invisible');\n                    next();\n                });\n            });\n\n            // Show the reaction group image with nice animation.\n            $get(moduleId, '.group_img')\n            .delay(500)\n            .show(0)\n            .animate(groupImageSizeForRatio(1), 300)\n            .queue(function(next) {\n                $get(moduleId, '.reactions').addClass('invisible');\n                next();\n            })\n            .css({'pointer-events': 'auto'});\n\n            $get(moduleId, '.group_nb').delay(600).show(0);\n\n            $('#module-' + moduleId + ' .actions').delay(600).show(300);\n        };\n\n        // Setup some timeouts and locks to trigger animations.\n        var reactionsVisible = false;\n        var groupTimeout = null;\n        var reactionsTimeout = null;\n\n        var triggerHideReactions = function() {\n            reactionsTimeout = null;\n            reactionsVisible = false;\n            hideReactions(moduleId);\n        };\n\n        var triggerShowReactions = function() {\n            groupTimeout = null;\n            reactionsVisible = true;\n            showReactions(moduleId);\n            clearTimeout(reactionsTimeout);\n            reactionsTimeout = setTimeout(triggerHideReactions, 2000); // Hide reactions after 2 seconds if mouse is already out.\n        };\n\n        // Reactions preview interactions.\n        $get(moduleId, '.group_img')\n        .mouseover(function() {\n            $(this).stop().animate(groupImageSizeForRatio(1.15), 100); // Widen image a little on hover.\n            groupTimeout = setTimeout(triggerShowReactions, 300); // Show vote interface after 0.3s hover.\n        })\n        .mouseout(function() {\n            if (!reactionsVisible) {\n                // Cancel mouseover actions.\n                clearTimeout(groupTimeout);\n                $(this).stop().animate(groupImageSizeForRatio(1), 100);\n            }\n        })\n        .click(triggerShowReactions); // Show vote interface instantly on click.\n\n        // Reactions images interactions.\n        $get(moduleId, '.reaction img')\n        .mouseover(function() {\n            $(this).stop().animate(reactionImageSizeForRatio(2), 100); // Widen image a little on hover.\n        })\n        .mouseout(function() {\n            $(this).stop().animate(reactionImageSizeForRatio(1), 100);\n        });\n\n        // Vote interface zone interactions\n        $get(moduleId, '.reactions')\n        .mouseout(function() {\n            clearTimeout(reactionsTimeout);\n            reactionsTimeout = setTimeout(triggerHideReactions, 1000); // Hide vote interface after 1s out of it.\n        })\n        .mouseover(function() {\n            clearTimeout(reactionsTimeout);\n        });\n    }\n\n    return {\n        init: function(courseId) {\n\n            // Wait that the DOM is fully loaded.\n            $(function() {\n\n                var blockData = $('.block_point_view[data-blockdata]').data('blockdata');\n\n                callOnModulesListLoad(function() {\n                    setUpDifficultyTracks(blockData.difficultylevels, blockData.trackcolors);\n                    setUpReactions(courseId, blockData.moduleswithreactions, blockData.reactionstemplate, blockData.pix);\n                });\n\n            });\n        }\n    };\n});"],"names":["define","$","ajax","notification","$get","moduleId","selector","$element","find","Reactions","none","easy","better","hard","reactionVotedArray","setUpReactions","courseId","modulesWithReactions","reactionsHtml","pixSrc","forEach","module","parseInt","cmid","uservote","length","prepend","reactionsLock","click","reactionName","reactionSelect","previousReaction","newVote","call","methodname","args","func","courseid","vote","done","updateReactionNb","fail","exception","reactionChange","this","data","always","updateGroupImgAndNb","each","reactionNb","reactionImageSizeForRatio","ratio","top","left","height","groupImageSizeForRatio","showReactions","removeClass","css","animate","hide","delay","reaction","index","queue","next","hideReactions","addClass","show","reactionsVisible","groupTimeout","reactionsTimeout","triggerHideReactions","triggerShowReactions","clearTimeout","setTimeout","mouseover","stop","mouseout","setupReactionsAnimation","pix","groupImg","totalNb","text","toUpperCase","charAt","attr","$groupNbWrapper","$groupNb","M","util","get_string","toggleClass","digits","Math","min","right","max","transform","diff","isSelected","$reactionNb","nbReaction","init","blockData","difficultyLevels","trackColors","difficultylevels","trackcolors","difficultyLevel","title","track","$track","class","style","$container","id","after","moduleswithreactions","reactionstemplate","document","ajaxComplete","event","xhr","settings","JSON","parse","e"],"mappings":"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"}