diff --git a/amd/build/activityhelp.min.js b/amd/build/activityhelp.min.js index a3dc794e34..a875b70b82 100644 --- a/amd/build/activityhelp.min.js +++ b/amd/build/activityhelp.min.js @@ -6,6 +6,6 @@ define("mod_moodleoverflow/activityhelp",["exports"],(function(_exports){Object. * @copyright 2023 Tamaro Walter * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -var Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=function(){document.addEventListener("click",(function(event){event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()}))}})); +const Selectors_actions={showHelpIcon:'[data-action="showhelpicon"]'};_exports.init=()=>{document.addEventListener("click",(event=>{event.target.closest(Selectors_actions.showHelpIcon)&&event.preventDefault()}))}})); //# sourceMappingURL=activityhelp.min.js.map \ No newline at end of file diff --git a/amd/build/activityhelp.min.js.map b/amd/build/activityhelp.min.js.map index 7bae1c7cab..64d79cd463 100644 --- a/amd/build/activityhelp.min.js.map +++ b/amd/build/activityhelp.min.js.map @@ -1 +1 @@ -{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.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 .\n\n/**\n * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;IAyBMA,kBACO,CACLC,aAAc,8CAOF,WAChBC,SAASC,iBAAiB,SAAS,SAAAC,OAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"} \ No newline at end of file +{"version":3,"file":"activityhelp.min.js","sources":["../src/activityhelp.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 .\n\n/**\n * Show a help string for the amount of activity column in userstats_table.php\n *\n * @module mod_moodleoverflow/activityhelp\n * @copyright 2023 Tamaro Walter\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n\n\nconst Selectors = {\n actions: {\n showHelpIcon: '[data-action=\"showhelpicon\"]',\n },\n};\n\n/**\n * Function that shows the help string.\n */\nexport const init = () => {\n document.addEventListener('click', event => {\n if (event.target.closest(Selectors.actions.showHelpIcon)) {\n event.preventDefault();\n }\n });\n};"],"names":["Selectors","showHelpIcon","document","addEventListener","event","target","closest","preventDefault"],"mappings":";;;;;;;;MAyBMA,kBACO,CACLC,aAAc,8CAOF,KAChBC,SAASC,iBAAiB,SAASC,QAC3BA,MAAMC,OAAOC,QAAQN,kBAAkBC,eACvCG,MAAMG"} \ No newline at end of file diff --git a/amd/build/rating.min.js b/amd/build/rating.min.js index 7a148eb2b0..0e51924c2d 100644 --- a/amd/build/rating.min.js +++ b/amd/build/rating.min.js @@ -1,3 +1,10 @@ -define("mod_moodleoverflow/rating",["exports","core/ajax","core/prefetch","core/str"],(function(_exports,_ajax,_prefetch,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _createForOfIteratorHelper(o,allowArrayLike){var it="undefined"!=typeof Symbol&&o[Symbol.iterator]||o["@@iterator"];if(!it){if(Array.isArray(o)||(it=function(o,minLen){if(!o)return;if("string"==typeof o)return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);"Object"===n&&o.constructor&&(n=o.constructor.name);if("Map"===n||"Set"===n)return Array.from(o);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen)}(o))||allowArrayLike&&o&&"number"==typeof o.length){it&&(o=it);var i=0,F=function(){};return{s:F,n:function(){return i>=o.length?{done:!0}:{done:!1,value:o[i++]}},e:function(_e){throw _e},f:F}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var err,normalCompletion=!0,didErr=!1;return{s:function(){it=it.call(o)},n:function(){var step=it.next();return normalCompletion=step.done,step},e:function(_e2){didErr=!0,err=_e2},f:function(){try{normalCompletion||null==it.return||it.return()}finally{if(didErr)throw err}}}}function _arrayLikeToArray(arr,len){(null==len||len>arr.length)&&(len=arr.length);for(var i=0,arr2=new Array(len);i{const actionElement=event.target.closest("[data-moodleoverflow-action]");if(!actionElement)return;const action=actionElement.getAttribute("data-moodleoverflow-action"),postElement=actionElement.closest("[data-moodleoverflow-postid]"),postid=null==postElement?void 0:postElement.getAttribute("data-moodleoverflow-postid");switch(action){case"upvote":case"downvote":{const isupvote="upvote"===action;if("clicked"===actionElement.getAttribute("data-moodleoverflow-state"))await sendVote(postid,isupvote?20:10,userid),actionElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_"+action,"mod_moodleoverflow");else{const otherAction=isupvote?"downvote":"upvote";await sendVote(postid,isupvote?2:1,userid),actionElement.setAttribute("data-moodleoverflow-state","clicked");const otherElement=postElement.querySelector('[data-moodleoverflow-action="'.concat(otherAction,'"]'));otherElement.setAttribute("data-moodleoverflow-state","notclicked"),actionElement.title=await(0,_str.get_string)("action_remove_"+action,"mod_moodleoverflow"),otherElement.title=await(0,_str.get_string)("action_"+otherAction,"mod_moodleoverflow")}}break;case"helpful":case"solved":{const isHelpful="helpful"===action,htmlclass=isHelpful?"markedhelpful":"markedsolution",shouldRemove=postElement.classList.contains(htmlclass),baseRating=isHelpful?4:3,rating=shouldRemove?10*baseRating:baseRating;if(await sendVote(postid,rating,userid),allowmultiplemarks)shouldRemove&&(postElement.classList.remove(htmlclass),actionElement.textContent=await(0,_str.get_string)("mark".concat(action),"mod_moodleoverflow"),changeStrings(htmlclass,action));else for(const el of root.querySelectorAll(".moodleoverflowpost."+htmlclass))el.classList.remove(htmlclass),el.querySelector('[data-moodleoverflow-action="'.concat(action,'"]')).textContent=await(0,_str.get_string)("mark".concat(action),"mod_moodleoverflow");shouldRemove||(postElement.classList.add(htmlclass),actionElement.textContent=await(0,_str.get_string)("marknot".concat(action),"mod_moodleoverflow"),allowmultiplemarks&&changeStrings(htmlclass,action))}}}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch);const root=document.getElementById("moodleoverflow-root");async function sendVote(postid,rating,userid){const response=await _ajax.default.call([{methodname:"mod_moodleoverflow_record_vote",args:{postid:postid,ratingid:rating}}])[0];return root.querySelectorAll('[data-moodleoverflow-userreputation="'.concat(userid,'"]')).forEach((i=>{i.textContent=response.raterreputation})),root.querySelectorAll('[data-moodleoverflow-userreputation="'.concat(response.ownerid,'"]')).forEach((i=>{i.textContent=response.ownerreputation})),root.querySelectorAll('[data-moodleoverflow-postreputation="'.concat(postid,'"]')).forEach((i=>{i.textContent=response.postrating})),response}async function changeStrings(htmlclass,action){_prefetch.default.prefetchStrings("mod_moodleoverflow",["marksolved","alsomarksolved","markhelpful","alsomarkhelpful"]);var othermarkedposts=!1;for(const el of root.querySelectorAll(".moodleoverflowpost"))if(el.classList.contains(htmlclass)){othermarkedposts=!0;break}for(const el of root.querySelectorAll(".moodleoverflowpost"))!el.classList.contains(htmlclass)&&el.querySelector('[data-moodleoverflow-action="'.concat(action,'"]'))&&(el.querySelector('[data-moodleoverflow-action="'.concat(action,'"]')).textContent=othermarkedposts?await(0,_str.get_string)("alsomark".concat(action),"mod_moodleoverflow"):await(0,_str.get_string)("mark".concat(action),"mod_moodleoverflow"))}})); //# sourceMappingURL=rating.min.js.map \ No newline at end of file diff --git a/amd/build/rating.min.js.map b/amd/build/rating.min.js.map index 6ca7b5f0bc..bd1b71de82 100644 --- a/amd/build/rating.min.js.map +++ b/amd/build/rating.min.js.map @@ -1 +1 @@ -{"version":3,"file":"rating.min.js","sources":["../src/rating.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 .\n\n/**\n * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if mulitplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["userid","allowmultiplemarks","prefetchStrings","root","onclick","event","actionElement","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","RATING_REMOVE_UPVOTE","RATING_REMOVE_DOWNVOTE","setAttribute","title","otherAction","RATING_UPVOTE","RATING_DOWNVOTE","otherElement","querySelector","htmlclass","isHelpful","shouldRemove","classList","contains","baseRating","RATING_HELPFUL","RATING_SOLVED","rating","querySelectorAll","el","remove","textContent","changeStrings","add","document","getElementById","Ajax","call","methodname","args","ratingid","response","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":"8kEAsEqBA,OAAQC,sCAChBC,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,yDAAU,iBAAMC,mQACXC,cAAgBD,MAAME,OAAOC,QAAQ,+FAKrCC,OAASH,cAAcI,aAAa,8BACpCC,YAAcL,cAAcE,QAAQ,gCACpCI,OAASD,yBAAAA,YAAaD,aAAa,0CAEjCD,qBACC,wBACA,2BAkBA,yBACA,6CAlBKI,SAAsB,WAAXJ,OAC+C,YAA5DH,cAAcI,aAAa,6EACrBI,SAASF,OAAQC,SAAWE,qBAAuBC,uBAAwBhB,uBACjFM,cAAcW,aAAa,4BAA6B,gCAC5B,mBAAU,UAAYR,OAAQ,8BAA1DH,cAAcY,0DAERC,YAAcN,SAAW,WAAa,0BACtCC,SAASF,OAAQC,SAAWO,cAAgBC,gBAAiBrB,uBACnEM,cAAcW,aAAa,4BAA6B,YAClDK,aAAeX,YAAYY,qDACGJ,oBACvBF,aAAa,4BAA6B,gCAC3B,mBAAU,iBAAmBR,OAAQ,qCAAjEH,cAAcY,sCACa,mBAAU,UAAYC,YAAa,8BAA9DG,aAAaJ,8EAOXM,WADAC,UAAuB,YAAXhB,QACY,gBAAkB,iBAC1CiB,aAAef,YAAYgB,UAAUC,SAASJ,WAC9CK,WAAaJ,UAAYK,eAAiBC,cAC1CC,OAASN,aAA4B,GAAbG,WAAkBA,4BAC1Cf,SAASF,OAAQoB,OAAQhC,mBAO1BC,gFAEgBE,KAAK8B,iBAAiB,uBAAyBT,gHAArDU,gBACJP,UAAUQ,OAAOX,6BAEV,iCAAiBf,QAAU,8BADrCyB,GAAGX,qDAA8Cd,cAAY2B,sRAK7DV,4CACAf,YAAYgB,UAAUQ,OAAOX,6BACK,iCAAiBf,QAAU,8BAA7DH,cAAc8B,0BACdC,cAAcb,UAAWf,mBAI5BiB,4CACDf,YAAYgB,UAAUW,IAAId,6BACQ,oCAAoBf,QAAU,8BAAhEH,cAAc8B,0BACVnC,oBACAoC,cAAcb,UAAWf,sOAjH3CY,gBAAkB,EAClBD,cAAgB,EAChBJ,uBAAyB,GACzBD,qBAAuB,GACvBgB,cAAgB,EAChBD,eAAiB,EAEjB3B,KAAOoC,SAASC,eAAe,gCAStB1B,6IAAf,kBAAwBF,OAAQoB,OAAQhC,qJACbyC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACFhC,OAAQA,OACRiC,SAAUb,WAEd,iBANEc,wBAON3C,KAAK8B,gEAAyDjC,cAAY+C,SAAQ,SAACC,GAC/EA,EAAEZ,YAAcU,SAASG,mBAE7B9C,KAAK8B,gEAAyDa,SAASI,eAAaH,SAAQ,SAACC,GACzFA,EAAEZ,YAAcU,SAASK,mBAE7BhD,KAAK8B,gEAAyDrB,cAAYmC,SAAQ,SAACC,GAC/EA,EAAEZ,YAAcU,SAASM,wCAEtBN,oGAgGIT,8JAAf,kBAA6Bb,UAAWf,+LAC3BP,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,oBAGhDmD,kBAAmB,wCACNlD,KAAK8B,iBAAiB,yIAC5BN,UAAUC,SAASJ,2CACtB6B,kBAAmB,sSAKVlD,KAAK8B,iBAAiB,8HAA5BC,kBACCP,UAAUC,SAASJ,aAAcU,IAAGX,qDAA8Cd,2CAClF4C,oEAEU,qCAAqB5C,QAAU,8BADzCyB,IAAGX,qDAA8Cd,cAAY2B,qFAInD,iCAAiB3B,QAAU,8BADrCyB,IAAGX,qDAA8Cd,cAAY2B"} \ No newline at end of file +{"version":3,"file":"rating.min.js","sources":["../src/rating.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 .\n\n/**\n * Implements rating functionality\n *\n * @module mod_moodleoverflow/rating\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport {get_string as getString} from 'core/str';\n\nconst RATING_DOWNVOTE = 1;\nconst RATING_UPVOTE = 2;\nconst RATING_REMOVE_DOWNVOTE = 10;\nconst RATING_REMOVE_UPVOTE = 20;\nconst RATING_SOLVED = 3;\nconst RATING_HELPFUL = 4;\n\nconst root = document.getElementById('moodleoverflow-root');\n\n/**\n * Send a vote via AJAX, then updates post and user ratings.\n * @param {int} postid\n * @param {int} rating\n * @param {int} userid\n * @returns {Promise<*>}\n */\nasync function sendVote(postid, rating, userid) {\n const response = await Ajax.call([{\n methodname: 'mod_moodleoverflow_record_vote',\n args: {\n postid: postid,\n ratingid: rating\n }\n }])[0];\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${userid}\"]`).forEach((i) => {\n i.textContent = response.raterreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-userreputation=\"${response.ownerid}\"]`).forEach((i) => {\n i.textContent = response.ownerreputation;\n });\n root.querySelectorAll(`[data-moodleoverflow-postreputation=\"${postid}\"]`).forEach((i) => {\n i.textContent = response.postrating;\n });\n return response;\n}\n\n\n/**\n * Init function.\n *\n * @param {int} userid\n * @param {boolean} allowmultiplemarks // true means allowed, false means not allowed.\n *\n */\nexport function init(userid, allowmultiplemarks) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'marknotsolved', 'markhelpful', 'marknothelpful',\n 'action_remove_upvote', 'action_upvote', 'action_remove_downvote', 'action_downvote']);\n\n root.onclick = async(event) => {\n const actionElement = event.target.closest('[data-moodleoverflow-action]');\n if (!actionElement) {\n return;\n }\n\n const action = actionElement.getAttribute('data-moodleoverflow-action');\n const postElement = actionElement.closest('[data-moodleoverflow-postid]');\n const postid = postElement?.getAttribute('data-moodleoverflow-postid');\n\n switch (action) {\n case 'upvote':\n case 'downvote': {\n const isupvote = action === 'upvote';\n if (actionElement.getAttribute('data-moodleoverflow-state') === 'clicked') {\n await sendVote(postid, isupvote ? RATING_REMOVE_UPVOTE : RATING_REMOVE_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_' + action, 'mod_moodleoverflow');\n } else {\n const otherAction = isupvote ? 'downvote' : 'upvote';\n await sendVote(postid, isupvote ? RATING_UPVOTE : RATING_DOWNVOTE, userid);\n actionElement.setAttribute('data-moodleoverflow-state', 'clicked');\n const otherElement = postElement.querySelector(\n `[data-moodleoverflow-action=\"${otherAction}\"]`);\n otherElement.setAttribute('data-moodleoverflow-state', 'notclicked');\n actionElement.title = await getString('action_remove_' + action, 'mod_moodleoverflow');\n otherElement.title = await getString('action_' + otherAction, 'mod_moodleoverflow');\n }\n }\n break;\n case 'helpful':\n case 'solved': {\n const isHelpful = action === 'helpful';\n const htmlclass = isHelpful ? 'markedhelpful' : 'markedsolution';\n const shouldRemove = postElement.classList.contains(htmlclass);\n const baseRating = isHelpful ? RATING_HELPFUL : RATING_SOLVED;\n const rating = shouldRemove ? baseRating * 10 : baseRating;\n await sendVote(postid, rating, userid);\n\n /* If multiplemarks are not allowed (that is the default mode): delete all marks.\n else: only delete the mark if the post is being unmarked.\n\n Add a mark, if the post is being marked.\n */\n if (!allowmultiplemarks) {\n // Delete all marks in the discussion\n for (const el of root.querySelectorAll('.moodleoverflowpost.' + htmlclass)) {\n el.classList.remove(htmlclass);\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n } else {\n // Remove only the mark of the unmarked post.\n if (shouldRemove) {\n postElement.classList.remove(htmlclass);\n actionElement.textContent = await getString(`mark${action}`, 'mod_moodleoverflow');\n changeStrings(htmlclass, action);\n }\n }\n // If the post is being marked, mark it.\n if (!shouldRemove) {\n postElement.classList.add(htmlclass);\n actionElement.textContent = await getString(`marknot${action}`, 'mod_moodleoverflow');\n if (allowmultiplemarks) {\n changeStrings(htmlclass, action);\n }\n }\n\n }\n }\n };\n\n}\n\n/**\n * Function to change the String of the post data-action button.\n * Only used if mulitplemarks are allowed.\n * @param {string} htmlclass the class where the String is being updated\n * @param {string} action helpful or solved mark\n */\nasync function changeStrings(htmlclass, action) {\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['marksolved', 'alsomarksolved', 'markhelpful', 'alsomarkhelpful',]);\n\n // 1. Step: Are there other posts in the Discussion, that are solved/helpful?\n var othermarkedposts = false;\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (el.classList.contains(htmlclass)) {\n othermarkedposts = true;\n break;\n }\n }\n // 2. Step: Change the strings of the action Button of the unmarked posts.\n for (const el of root.querySelectorAll('.moodleoverflowpost')) {\n if (!el.classList.contains(htmlclass) && el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`)) {\n if (othermarkedposts) {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`alsomark${action}`, 'mod_moodleoverflow');\n } else {\n el.querySelector(`[data-moodleoverflow-action=\"${action}\"]`).textContent =\n await getString(`mark${action}`, 'mod_moodleoverflow');\n }\n }\n }\n}"],"names":["userid","allowmultiplemarks","prefetchStrings","root","onclick","async","actionElement","event","target","closest","action","getAttribute","postElement","postid","isupvote","sendVote","setAttribute","title","otherAction","otherElement","querySelector","isHelpful","htmlclass","shouldRemove","classList","contains","baseRating","rating","remove","textContent","changeStrings","el","querySelectorAll","add","document","getElementById","response","Ajax","call","methodname","args","ratingid","forEach","i","raterreputation","ownerid","ownerreputation","postrating","othermarkedposts"],"mappings":";;;;;;;oFAsEqBA,OAAQC,sCAChBC,gBAAgB,qBACrB,CAAC,aAAc,gBAAiB,cAAe,iBAC3C,uBAAwB,gBAAiB,yBAA0B,oBAE3EC,KAAKC,QAAUC,MAAAA,cACLC,cAAgBC,MAAMC,OAAOC,QAAQ,oCACtCH,2BAICI,OAASJ,cAAcK,aAAa,8BACpCC,YAAcN,cAAcG,QAAQ,gCACpCI,OAASD,MAAAA,mBAAAA,YAAaD,aAAa,qCAEjCD,YACC,aACA,kBACKI,SAAsB,WAAXJ,UAC+C,YAA5DJ,cAAcK,aAAa,mCACrBI,SAASF,OAAQC,SA7Dd,GADE,GA8DsEd,QACjFM,cAAcU,aAAa,4BAA6B,cACxDV,cAAcW,YAAc,mBAAU,UAAYP,OAAQ,0BACvD,OACGQ,YAAcJ,SAAW,WAAa,eACtCC,SAASF,OAAQC,SApErB,EADE,EAqE+Dd,QACnEM,cAAcU,aAAa,4BAA6B,iBAClDG,aAAeP,YAAYQ,qDACGF,mBACpCC,aAAaH,aAAa,4BAA6B,cACvDV,cAAcW,YAAc,mBAAU,iBAAmBP,OAAQ,sBACjES,aAAaF,YAAc,mBAAU,UAAYC,YAAa,iCAIjE,cACA,gBACKG,UAAuB,YAAXX,OACZY,UAAYD,UAAY,gBAAkB,iBAC1CE,aAAeX,YAAYY,UAAUC,SAASH,WAC9CI,WAAaL,UA/EZ,EADD,EAiFAM,OAASJ,aAA4B,GAAbG,WAAkBA,oBAC1CX,SAASF,OAAQc,OAAQ3B,QAO1BC,mBASGsB,eACAX,YAAYY,UAAUI,OAAON,WAC7BhB,cAAcuB,kBAAoB,iCAAiBnB,QAAU,sBAC7DoB,cAAcR,UAAWZ,kBAVxB,MAAMqB,MAAM5B,KAAK6B,iBAAiB,uBAAyBV,WAC5DS,GAAGP,UAAUI,OAAON,WACpBS,GAAGX,qDAA8CV,cAAYmB,kBACnD,iCAAiBnB,QAAU,sBAWxCa,eACDX,YAAYY,UAAUS,IAAIX,WAC1BhB,cAAcuB,kBAAoB,oCAAoBnB,QAAU,sBAC5DT,oBACA6B,cAAcR,UAAWZ,mGA1G3CP,KAAO+B,SAASC,eAAe,sCAStBpB,SAASF,OAAQc,OAAQ3B,cAC9BoC,eAAiBC,cAAKC,KAAK,CAAC,CAC9BC,WAAY,iCACZC,KAAM,CACF3B,OAAQA,OACR4B,SAAUd,WAEd,UACJxB,KAAK6B,gEAAyDhC,cAAY0C,SAASC,IAC/EA,EAAEd,YAAcO,SAASQ,mBAE7BzC,KAAK6B,gEAAyDI,SAASS,eAAaH,SAASC,IACzFA,EAAEd,YAAcO,SAASU,mBAE7B3C,KAAK6B,gEAAyDnB,cAAY6B,SAASC,IAC/EA,EAAEd,YAAcO,SAASW,cAEtBX,wBAgGIN,cAAcR,UAAWZ,0BAC3BR,gBAAgB,qBACrB,CAAC,aAAc,iBAAkB,cAAe,wBAGhD8C,kBAAmB,MAClB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,0BAC/BD,GAAGP,UAAUC,SAASH,WAAY,CAClC0B,kBAAmB,YAKtB,MAAMjB,MAAM5B,KAAK6B,iBAAiB,wBAC9BD,GAAGP,UAAUC,SAASH,YAAcS,GAAGX,qDAA8CV,gBAElFqB,GAAGX,qDAA8CV,cAAYmB,YAD7DmB,uBAEU,qCAAqBtC,QAAU,4BAG/B,iCAAiBA,QAAU"} \ No newline at end of file diff --git a/amd/build/reviewing.min.js b/amd/build/reviewing.min.js index c811cbbdfd..7dc1ac1e4f 100644 --- a/amd/build/reviewing.min.js +++ b/amd/build/reviewing.min.js @@ -1,3 +1,10 @@ -define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],(function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg),value=info.value}catch(error){return void reject(error)}info.done?resolve(value):Promise.resolve(value).then(_next,_throw)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]),document.getElementById("moodleoverflow-posts").onclick=(fn=regeneratorRuntime.mark((function _callee(e){var action,post,reviewRow,postID,nextPostURL,message,rejectMessage,args,_nextPostURL,_message;return regeneratorRuntime.wrap((function(_context){for(;;)switch(_context.prev=_context.next){case 0:if(action=e.target.getAttribute("data-moodleoverflow-action")){_context.next=3;break}return _context.abrupt("return");case 3:if(post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid"),"approve"!==action){_context.next=33;break}return reviewRow.innerHTML=".",_context.next=10,_ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];case 10:return nextPostURL=_context.sent,_context.next=13,(0,_str.get_string)("post_was_approved","mod_moodleoverflow");case 13:if(_context.t0=_context.sent,message=_context.t0+" ",!nextPostURL){_context.next=25;break}return _context.t1=message,_context.t2=''),_context.next=20,(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow");case 20:_context.t3=_context.sent,_context.t4=_context.t2+_context.t3,message=_context.t1+=_context.t4+"",_context.next=29;break;case 25:return _context.t5=message,_context.next=28,(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow");case 28:message=_context.t5+=_context.sent;case 29:reviewRow.innerHTML=message,post.classList.remove("pendingreview"),_context.next=73;break;case 33:if("reject"!==action){_context.next=40;break}return reviewRow.innerHTML=".",_context.next=37,_templates.default.render("mod_moodleoverflow/reject_post_form",{});case 37:reviewRow.innerHTML=_context.sent,_context.next=73;break;case 40:if("reject-submit"!==action){_context.next=68;break}return rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim(),reviewRow.innerHTML=".",args={postid:postID,reason:rejectMessage||null},_context.next=46,_ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];case 46:return _nextPostURL=_context.sent,_context.next=49,(0,_str.get_string)("post_was_rejected","mod_moodleoverflow");case 49:if(_context.t6=_context.sent,_message=_context.t6+" ",!_nextPostURL){_context.next=61;break}return _context.t7=_message,_context.t8=''),_context.next=56,(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow");case 56:_context.t9=_context.sent,_context.t10=_context.t8+_context.t9,_message=_context.t7+=_context.t10+"",_context.next=65;break;case 61:return _context.t11=_message,_context.next=64,(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow");case 64:_message=_context.t11+=_context.sent;case 65:reviewRow.innerHTML=_message,_context.next=73;break;case 68:if("reject-cancel"!==action){_context.next=73;break}return reviewRow.innerHTML=".",_context.next=72,_templates.default.render("mod_moodleoverflow/review_buttons",{});case 72:reviewRow.innerHTML=_context.sent;case 73:case"end":return _context.stop()}}),_callee)})),_ref=function(){var self=this,args=arguments;return new Promise((function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(void 0)}))},function(_x){return _ref.apply(this,arguments)});var fn,_ref},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)})); +define("mod_moodleoverflow/reviewing",["exports","core/ajax","core/prefetch","core/templates","core/str"],(function(_exports,_ajax,_prefetch,_templates,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +/** + * Implements reviewing functionality + * + * @module mod_moodleoverflow/reviewing + * @copyright 2022 Justus Dieckmann WWU + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(){_prefetch.default.prefetchTemplates(["mod_moodleoverflow/reject_post_form","mod_moodleoverflow/review_buttons"]),_prefetch.default.prefetchStrings("mod_moodleoverflow",["post_was_approved","jump_to_next_post_needing_review","there_are_no_posts_needing_review","post_was_rejected"]);document.getElementById("moodleoverflow-posts").onclick=async e=>{const action=e.target.getAttribute("data-moodleoverflow-action");if(!action)return;const post=e.target.closest("*[data-moodleoverflow-postid]"),reviewRow=e.target.closest(".reviewrow"),postID=post.getAttribute("data-moodleoverflow-postid");if("approve"===action){reviewRow.innerHTML=".";const nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_approve_post",args:{postid:postID}}])[0];let message=await(0,_str.get_string)("post_was_approved","mod_moodleoverflow")+" ";message+=nextPostURL?'')+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message,post.classList.remove("pendingreview")}else if("reject"===action)reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/reject_post_form",{});else if("reject-submit"===action){const rejectMessage=post.querySelector("textarea.reject-reason").value.toString().trim();reviewRow.innerHTML=".";const args={postid:postID,reason:rejectMessage||null},nextPostURL=await _ajax.default.call([{methodname:"mod_moodleoverflow_review_reject_post",args:args}])[0];let message=await(0,_str.get_string)("post_was_rejected","mod_moodleoverflow")+" ";message+=nextPostURL?'')+await(0,_str.get_string)("jump_to_next_post_needing_review","mod_moodleoverflow")+"":await(0,_str.get_string)("there_are_no_posts_needing_review","mod_moodleoverflow"),reviewRow.innerHTML=message}else"reject-cancel"===action&&(reviewRow.innerHTML=".",reviewRow.innerHTML=await _templates.default.render("mod_moodleoverflow/review_buttons",{}))}},_ajax=_interopRequireDefault(_ajax),_prefetch=_interopRequireDefault(_prefetch),_templates=_interopRequireDefault(_templates)})); //# sourceMappingURL=reviewing.min.js.map \ No newline at end of file diff --git a/amd/build/reviewing.min.js.map b/amd/build/reviewing.min.js.map index d2b01e0044..d5002e736d 100644 --- a/amd/build/reviewing.min.js.map +++ b/amd/build/reviewing.min.js.map @@ -1 +1 @@ -{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.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 .\n\n/**\n * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["prefetchTemplates","prefetchStrings","document","getElementById","onclick","e","action","target","getAttribute","post","closest","reviewRow","postID","innerHTML","Ajax","call","methodname","args","postid","nextPostURL","message","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason"],"mappings":"8iBA+BaA,kBAAkB,CAAC,sCAAuC,wDAC1DC,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,qCAAU,iBAAMC,yMACXC,OAASD,EAAEE,OAAOC,aAAa,gGAM/BC,KAAOJ,EAAEE,OAAOG,QAAQ,iCACxBC,UAAYN,EAAEE,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,8BAElB,YAAXF,sCACAK,UAAUE,UAAY,qBACIC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQN,WAEZ,kBALEO,4CAOc,mBAAU,oBAAqB,2DAA/CC,oBAAuE,KACvED,uDACAC,uCAAuBD,oCACX,mBAAU,mCAAoC,4FAD1DC,iCAEM,yDAENA,0BAAiB,mBAAU,oCAAqC,8BAAhEA,2CAEJT,UAAUE,UAAYO,QACtBX,KAAKY,UAAUC,OAAO,mDACJ,WAAXhB,sCACPK,UAAUE,UAAY,qBACMU,mBAAUC,OAAO,sCAAuC,YAApFb,UAAUE,0DACQ,kBAAXP,sCACDmB,cAAgBhB,KAAKiB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFlB,UAAUE,UAAY,IAChBI,KAAO,CACTC,OAAQN,OACRkB,OAAQL,eAAgC,uBAElBX,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,kBAHEE,6CAKc,mBAAU,oBAAqB,2DAA/CC,qBAAuE,KACvED,wDACAC,wCAAuBD,qCACX,mBAAU,mCAAoC,6FAD1DC,mCAEM,0DAENA,2BAAiB,mBAAU,oCAAqC,8BAAhEA,6CAEJT,UAAUE,UAAYO,2CACJ,kBAAXd,sCACPK,UAAUE,UAAY,qBACMU,mBAAUC,OAAO,oCAAqC,YAAlFb,UAAUE"} \ No newline at end of file +{"version":3,"file":"reviewing.min.js","sources":["../src/reviewing.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 .\n\n/**\n * Implements reviewing functionality\n *\n * @module mod_moodleoverflow/reviewing\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport Ajax from 'core/ajax';\nimport Prefetch from 'core/prefetch';\nimport Templates from 'core/templates';\nimport {get_string as getString} from 'core/str';\n\n/**\n * Init function.\n */\nexport function init() {\n Prefetch.prefetchTemplates(['mod_moodleoverflow/reject_post_form', 'mod_moodleoverflow/review_buttons']);\n Prefetch.prefetchStrings('mod_moodleoverflow',\n ['post_was_approved', 'jump_to_next_post_needing_review', 'there_are_no_posts_needing_review', 'post_was_rejected']);\n\n const root = document.getElementById('moodleoverflow-posts');\n root.onclick = async(e) => {\n const action = e.target.getAttribute('data-moodleoverflow-action');\n\n if (!action) {\n return;\n }\n\n const post = e.target.closest('*[data-moodleoverflow-postid]');\n const reviewRow = e.target.closest('.reviewrow');\n const postID = post.getAttribute('data-moodleoverflow-postid');\n\n if (action === 'approve') {\n reviewRow.innerHTML = '.';\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_approve_post',\n args: {\n postid: postID,\n }\n }])[0];\n\n let message = await getString('post_was_approved', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n post.classList.remove(\"pendingreview\");\n } else if (action === 'reject') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/reject_post_form', {});\n } else if (action === 'reject-submit') {\n const rejectMessage = post.querySelector('textarea.reject-reason').value.toString().trim();\n reviewRow.innerHTML = '.';\n const args = {\n postid: postID,\n reason: rejectMessage ? rejectMessage : null\n };\n const nextPostURL = await Ajax.call([{\n methodname: 'mod_moodleoverflow_review_reject_post',\n args: args\n }])[0];\n\n let message = await getString('post_was_rejected', 'mod_moodleoverflow') + ' ';\n if (nextPostURL) {\n message += ``\n + await getString('jump_to_next_post_needing_review', 'mod_moodleoverflow')\n + \"\";\n } else {\n message += await getString('there_are_no_posts_needing_review', 'mod_moodleoverflow');\n }\n reviewRow.innerHTML = message;\n } else if (action === 'reject-cancel') {\n reviewRow.innerHTML = '.';\n reviewRow.innerHTML = await Templates.render('mod_moodleoverflow/review_buttons', {});\n }\n };\n}"],"names":["prefetchTemplates","prefetchStrings","document","getElementById","onclick","async","action","e","target","getAttribute","post","closest","reviewRow","postID","innerHTML","nextPostURL","Ajax","call","methodname","args","postid","message","classList","remove","Templates","render","rejectMessage","querySelector","value","toString","trim","reason"],"mappings":";;;;;;;wGA+BaA,kBAAkB,CAAC,sCAAuC,wDAC1DC,gBAAgB,qBACrB,CAAC,oBAAqB,mCAAoC,oCAAqC,sBAEtFC,SAASC,eAAe,wBAChCC,QAAUC,MAAAA,UACLC,OAASC,EAAEC,OAAOC,aAAa,kCAEhCH,oBAICI,KAAOH,EAAEC,OAAOG,QAAQ,iCACxBC,UAAYL,EAAEC,OAAOG,QAAQ,cAC7BE,OAASH,KAAKD,aAAa,iCAElB,YAAXH,OAAsB,CACtBM,UAAUE,UAAY,UAChBC,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,yCACZC,KAAM,CACFC,OAAQP,WAEZ,OAEAQ,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACW,mBAAYA,wBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,QACtBX,KAAKY,UAAUC,OAAO,sBACnB,GAAe,WAAXjB,OACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,sCAAuC,SACjF,GAAe,kBAAXnB,OAA4B,OAC7BoB,cAAgBhB,KAAKiB,cAAc,0BAA0BC,MAAMC,WAAWC,OACpFlB,UAAUE,UAAY,UAChBK,KAAO,CACTC,OAAQP,OACRkB,OAAQL,eAAgC,MAEtCX,kBAAoBC,cAAKC,KAAK,CAAC,CACjCC,WAAY,wCACZC,KAAMA,QACN,OAEAE,cAAgB,mBAAU,oBAAqB,sBAAwB,IAEvEA,SADAN,YACW,mBAAYA,wBACX,mBAAU,mCAAoC,sBACpD,aAEW,mBAAU,oCAAqC,sBAEpEH,UAAUE,UAAYO,YACJ,kBAAXf,SACPM,UAAUE,UAAY,IACtBF,UAAUE,gBAAkBU,mBAAUC,OAAO,oCAAqC"} \ No newline at end of file diff --git a/amd/build/warnmodechange.min.js b/amd/build/warnmodechange.min.js index 370da13a32..5042ba704b 100644 --- a/amd/build/warnmodechange.min.js +++ b/amd/build/warnmodechange.min.js @@ -1,3 +1,10 @@ -define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],(function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg),value=info.value}catch(error){return void reject(error)}info.done?resolve(value):Promise.resolve(value).then(_next,_throw)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);var form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=(fn=regeneratorRuntime.mark((function _callee(e){var value;return regeneratorRuntime.wrap((function(_context){for(;;)switch(_context.prev=_context.next){case 0:if((value=select.selectedOptions[0].value)!=previousSetting&&1!=value&&3!=value){_context.next=3;break}return _context.abrupt("return");case 3:return e.preventDefault(),_context.t0=_notification.default,_context.next=7,(0,_str.get_string)("confirm");case 7:return _context.t1=_context.sent,_context.next=10,(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow");case 10:return _context.t2=_context.sent,_context.next=13,(0,_str.get_string)("confirm");case 13:return _context.t3=_context.sent,_context.next=16,(0,_str.get_string)("cancel");case 16:return _context.t4=_context.sent,_context.t5=function(){form.onsubmit=void 0,form.requestSubmit(e.submitter)},_context.t6=void 0,_context.next=21,_context.t0.confirm.call(_context.t0,_context.t1,_context.t2,_context.t3,_context.t4,_context.t5,_context.t6);case 21:case"end":return _context.stop()}}),_callee)})),_ref=function(){var self=this,args=arguments;return new Promise((function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(void 0)}))},function(_x){return _ref.apply(this,arguments)});var fn,_ref},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)})); +define("mod_moodleoverflow/warnmodechange",["exports","core/str","core/notification","core/prefetch"],(function(_exports,_str,_notification,_prefetch){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}} +/** + * Warns on changing the subscription mode. + * + * @module mod_moodleoverflow/warnmodechange + * @copyright 2022 Justus Dieckmann WWU + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=function(previousSetting){_prefetch.default.prefetchStrings("mod_moodleoverflow",["switchtooptional","switchtoauto"]),_prefetch.default.prefetchStrings("moodle",["confirm","cancel"]);const form=document.querySelector("form.mform"),select=document.getElementById("id_forcesubscribe");form.onsubmit=async e=>{const value=select.selectedOptions[0].value;value!=previousSetting&&1!=value&&3!=value&&(e.preventDefault(),await _notification.default.confirm(await(0,_str.get_string)("confirm"),await(0,_str.get_string)(0==value?"switchtooptional":"switchtoauto","mod_moodleoverflow"),await(0,_str.get_string)("confirm"),await(0,_str.get_string)("cancel"),(()=>{form.onsubmit=void 0,form.requestSubmit(e.submitter)}),void 0))}},_notification=_interopRequireDefault(_notification),_prefetch=_interopRequireDefault(_prefetch)})); //# sourceMappingURL=warnmodechange.min.js.map \ No newline at end of file diff --git a/amd/build/warnmodechange.min.js.map b/amd/build/warnmodechange.min.js.map index f3c76304c1..70683e5540 100644 --- a/amd/build/warnmodechange.min.js.map +++ b/amd/build/warnmodechange.min.js.map @@ -1 +1 @@ -{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.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 .\n\n/**\n * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["previousSetting","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","e","value","selectedOptions","preventDefault","Notification","undefined","requestSubmit","submitter","confirm"],"mappings":"mhBA8BqBA,mCACRC,gBAAgB,qBAAsB,CAAC,mBAAoB,mCAC3DA,gBAAgB,SAAU,CAAC,UAAW,eACzCC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,sCAAW,iBAAMC,sHACZC,MAAQJ,OAAOK,gBAAgB,GAAGD,QAC3BT,iBAA4B,GAATS,OAAuB,GAATA,4EAG9CD,EAAEG,6BACIC,uCACI,mBAAU,qEACV,mBAAmB,GAATH,MAAa,mBAAqB,eAAgB,iFAC5D,mBAAU,sEACV,mBAAU,+DAChB,WAEIP,KAAKK,cAAWM,EAChBX,KAAKY,cAAcN,EAAEO,6BACtBF,+BATYG"} \ No newline at end of file +{"version":3,"file":"warnmodechange.min.js","sources":["../src/warnmodechange.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 .\n\n/**\n * Warns on changing the subscription mode.\n *\n * @module mod_moodleoverflow/warnmodechange\n * @copyright 2022 Justus Dieckmann WWU\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\nimport {get_string as getString} from 'core/str';\nimport Notification from 'core/notification';\nimport Prefetch from 'core/prefetch';\n\n/**\n * Init function.\n * @param {string} previousSetting\n */\nexport function init(previousSetting) {\n Prefetch.prefetchStrings('mod_moodleoverflow', ['switchtooptional', 'switchtoauto']);\n Prefetch.prefetchStrings('moodle', ['confirm', 'cancel']);\n const form = document.querySelector('form.mform');\n const select = document.getElementById('id_forcesubscribe');\n form.onsubmit = async(e) => {\n const value = select.selectedOptions[0].value;\n if (value == previousSetting || value == 1 || value == 3) {\n return;\n }\n e.preventDefault();\n await Notification.confirm(\n await getString('confirm'),\n await getString(value == 0 ? 'switchtooptional' : 'switchtoauto', 'mod_moodleoverflow'),\n await getString('confirm'),\n await getString('cancel'),\n () => {\n // Prevent this listener from preventing the event again.\n form.onsubmit = undefined;\n form.requestSubmit(e.submitter);\n }, undefined);\n };\n}"],"names":["previousSetting","prefetchStrings","form","document","querySelector","select","getElementById","onsubmit","async","value","selectedOptions","e","preventDefault","Notification","confirm","undefined","requestSubmit","submitter"],"mappings":";;;;;;;oFA8BqBA,mCACRC,gBAAgB,qBAAsB,CAAC,mBAAoB,mCAC3DA,gBAAgB,SAAU,CAAC,UAAW,iBACzCC,KAAOC,SAASC,cAAc,cAC9BC,OAASF,SAASG,eAAe,qBACvCJ,KAAKK,SAAWC,MAAAA,UACNC,MAAQJ,OAAOK,gBAAgB,GAAGD,MACpCA,OAAST,iBAA4B,GAATS,OAAuB,GAATA,QAG9CE,EAAEC,uBACIC,sBAAaC,cACT,mBAAU,iBACV,mBAAmB,GAATL,MAAa,mBAAqB,eAAgB,4BAC5D,mBAAU,iBACV,mBAAU,WAChB,KAEIP,KAAKK,cAAWQ,EAChBb,KAAKc,cAAcL,EAAEM,kBACtBF"} \ No newline at end of file diff --git a/classes/manager/mail_manager.php b/classes/manager/mail_manager.php index e822a01719..1c80659e88 100644 --- a/classes/manager/mail_manager.php +++ b/classes/manager/mail_manager.php @@ -324,7 +324,7 @@ private static function check_post($post, array &$mailcount, array &$users, arra * @param string $table * @param int $id * @param array $cache - * @param string $errorMessage + * @param string $errormessage * @param array $posts * @param int $postid * @param bool $fillsubscache If the subscription cache is being filled (only when checking discussion cache) diff --git a/classes/tables/userstats_table.php b/classes/tables/userstats_table.php index d88fa7ce21..ad663e6bc9 100644 --- a/classes/tables/userstats_table.php +++ b/classes/tables/userstats_table.php @@ -316,11 +316,10 @@ private function get_rating_data() { /** * Process the received votes for a student. - * @param $student - * @param $row - * @return void + * @param object $student + * @param object $row */ - private function process_received_votes(&$student, $row) { + private function process_received_votes(object $student, object $row) { // Only count received votes if the post is not anonymous (no anonymous setting or only questioner anonymous discussion). if ((($row->anonymoussetting == 0) || ($row->anonymoussetting == 1 && $row->postuserid != $row->discussuserid))) { if ($row->rating == RATING_UPVOTE) { @@ -333,11 +332,10 @@ private function process_received_votes(&$student, $row) { /** * Process the submitted ratings from a student. - * @param $student - * @param $row - * @return void + * @param object $student + * @param object $row */ - private function process_submitted_ratings(&$student, $row) { + private function process_submitted_ratings($student, $row) { // For solution marks: only count a solution if the discussion is not completely anonymous. // For helpful marks: only count helpful marks if the discussion is not any kind of anonymous. // Up and downvotes are always counted. @@ -356,11 +354,10 @@ private function process_submitted_ratings(&$student, $row) { /** * Process the written posts from a student for the activity. - * @param $student - * @param $row - * @return void + * @param object $student + * @param object $row */ - private function process_written_posts(&$student, $row) { + private function process_written_posts($student, $row) { // Only count a written post if: the post is not in an anonymous discussion: // or the post is in a partial anonymous discussion and the user is not the starter of the discussion. if (!array_key_exists($row->postid, $student->submittedposts) && @@ -374,12 +371,10 @@ private function process_written_posts(&$student, $row) { /** * Increments the forum activity of a student. - * @param $row - * @param $moodleoverflowid - * @param $forumactivity - * @return void + * @param object $student + * @param object $row */ - private function increment_forumactivity(&$student, $row) { + private function increment_forumactivity($student, $row) { if ($row->moodleoverflowid == $this->moodleoverflowid) { $student->forumactivity++; } diff --git a/db/upgradelib.php b/db/upgradelib.php index 9f772ae9f8..7f1cd5f32d 100644 --- a/db/upgradelib.php +++ b/db/upgradelib.php @@ -30,7 +30,7 @@ /** * Convert the draft file area URLs in some content to @@PLUGINFILE@@ tokens * ready to be saved in the database. Normally, this is done automatically by - * {@link file_save_draft_area_files()}. + * {@see file_save_draft_area_files()}. * * @category files * @param string $text the content to process. diff --git a/lib.php b/lib.php index 7d7bf7c73c..67210e8dc4 100644 --- a/lib.php +++ b/lib.php @@ -125,7 +125,7 @@ function moodleoverflow_supports($feature) { * of the new instance. * * @param stdClass $moodleoverflow Submitted data from the form in mod_form.php - * @param mod_moodleoverflow_mod_form $mform The form instance itself (if needed) + * @param ?mod_moodleoverflow_mod_form $mform The form instance itself (if needed) * * @return int The id of the newly inserted moodleoverflow record */ diff --git a/tests/behat/behat_mod_moodleoverflow.php b/tests/behat/behat_mod_moodleoverflow.php index 9fd2f80806..97c11f043b 100644 --- a/tests/behat/behat_mod_moodleoverflow.php +++ b/tests/behat/behat_mod_moodleoverflow.php @@ -45,12 +45,11 @@ class behat_mod_moodleoverflow extends behat_base { * Adds a new moodleoverflow to the specified course and section. * * @Given I add a moodleoverflow to course :coursefullname section :sectionnum and I fill the form with: - * @param $courseshortname - * @param $sectionnumber - * @param $data - * @return void + * @param string $courseshortname + * @param string $sectionnumber + * @param TableNode $data */ - public function i_add_a_moodleoverflow_to_course_section_and_fill_form($courseshortname, $sectionnumber, TableNode $data) { + public function i_add_a_moodleoverflow_to_course_section_and_fill_form(string $courseshortname, string $sectionnumber, TableNode $data) { global $CFG; if ($CFG->branch >= 404) { diff --git a/tests/behat/topicmove.feature b/tests/behat/topicmove.feature index b0cb7dbffa..0da6f119ee 100644 --- a/tests/behat/topicmove.feature +++ b/tests/behat/topicmove.feature @@ -62,5 +62,3 @@ Feature: Teachers can move a discussion in one moodleoverflow forum to another m And I should not see "Move discussion to public moodleoverflow two" And I should not see "Move discussion to question anonymous" And I should not see "Move discussion to everything anonymous" - - diff --git a/tests/behat/userstats.feature b/tests/behat/userstats.feature index 6e1ad6391c..8512cd075d 100644 --- a/tests/behat/userstats.feature +++ b/tests/behat/userstats.feature @@ -23,21 +23,20 @@ Feature: If the admin enabled user statistics, the teacher can see the activity | Message | This is a question | Scenario: Userstats are not enabled per default. The teacher should not see the user statistics - And I follow "Test Moodleoverflow" - Then I should not see "View user statistics" + And I follow "Test Moodleoverflow" + Then I should not see "View user statistics" Scenario: Userstats are enabled. The teacher should see the user statistics. The teacher should already have an acitivty point for writing a post. Given the following config values are set as admin: - | showuserstats | 1 | moodleoverflow | - And I follow "Test Moodleoverflow" - Then I should see "View user statistics" - When I press "View user statistics" - Then the following should exist in the "statisticstable" table: - | User full name | Received upvotes | Received downvotes | Activity (this forum) | Activity (coursewide) | - | Teacher 1 | 0 | 0 | 1 | 1 | - | Student 1 | 0 | 0 | 0 | 0 | - + | showuserstats | 1 | moodleoverflow | + And I follow "Test Moodleoverflow" + Then I should see "View user statistics" + When I press "View user statistics" + Then the following should exist in the "statisticstable" table: + | User full name | Received upvotes | Received downvotes | Activity (this forum) | Activity (coursewide) | + | Teacher 1 | 0 | 0 | 1 | 1 | + | Student 1 | 0 | 0 | 0 | 0 | Scenario: Test if reputation appears in the user statistics Given the following config values are set as admin: diff --git a/tests/ratings_test.php b/tests/ratings_test.php index e75c0eefb5..a1f8cf30ec 100644 --- a/tests/ratings_test.php +++ b/tests/ratings_test.php @@ -526,11 +526,10 @@ private function process_groups(String $group1, string $group2, array $orderpost /** * Sets a post to a group of mark. - * @param String $group Group can be: solved+helpful, solved, helpful, not marked - * @param $answer - * @return void + * @param string $group Group can be: solved+helpful, solved, helpful, not marked + * @param object $answer */ - private function set_group(String $group, $answer) { + private function set_group(string $group, object $answer) { switch($group) { case 'sh': $answer->markedhelpful = 1;