MDL-64821 mod_forum: add in page reply to modern display mode
This commit is contained in:
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("mod_forum/discussion_modern",["exports","jquery","mod_forum/discussion","mod_forum/lock_toggle","mod_forum/favourite_toggle","mod_forum/pin_toggle"],function(a,b,c,d,e,f){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=g(b);c=g(c);d=g(d);e=g(e);f=g(f);function g(a){return a&&a.__esModule?a:{default:a}}var h=function(a){c.default.init(a);var g=(0,b.default)("[data-container=\"discussion-tools\"]");d.default.init(g);e.default.init(g);f.default.init(g)};a.init=h});
|
||||
define ("mod_forum/discussion_modern",["exports","jquery","core/auto_rows","core/custom_interaction_events","core/notification","core/templates","mod_forum/discussion","mod_forum/inpage_reply","mod_forum/lock_toggle","mod_forum/favourite_toggle","mod_forum/pin_toggle","mod_forum/selectors"],function(a,b,c,d,f,g,h,i,j,k,l,m){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=n(b);c=n(c);d=n(d);f=n(f);g=n(g);h=n(h);i=n(i);j=n(j);k=n(k);l=n(l);m=n(m);function n(a){return a&&a.__esModule?a:{default:a}}function o(a,b,c,d,e,f,g){try{var h=a[f](g),i=h.value}catch(a){c(a);return}if(h.done){b(i)}else{Promise.resolve(i).then(d,e)}}function p(a){return function(){var b=this,c=arguments;return new Promise(function(d,e){var h=a.apply(b,c);function f(a){o(h,d,e,f,g,"next",a)}function g(a){o(h,d,e,f,g,"throw",a)}f(void 0)})}}function q(a){for(var b=1;b<arguments.length;b++){var c=null!=arguments[b]?arguments[b]:{},d=Object.keys(c);if("function"==typeof Object.getOwnPropertySymbols){d=d.concat(Object.getOwnPropertySymbols(c).filter(function(a){return Object.getOwnPropertyDescriptor(c,a).enumerable}))}d.forEach(function(b){r(a,b,c[b])})}return a}function r(a,b,c){if(b in a){Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0})}else{a[b]=c}return a}var s=function(a){return a.closest(m.default.post.post)},t=function(a){return a.children().not(m.default.post.repliesContainer).find(m.default.post.forumCoreContent)},u=function(a){return a.children().filter(m.default.post.inpageReplyContainer)},v=function(a,b){var c=a.find(m.default.post.inpageReplyContent);c.slideDown({duration:150,queue:!1,complete:b}).css("display","none").fadeIn(150)},w=function(a,b){var c=a.find(m.default.post.inpageReplyContent);c.slideUp({duration:150,queue:!1,complete:b}).fadeOut(200)},x=function(a){return 0<a.find(m.default.post.inpageReplyContent).length},y=function(a,b,c){var d=t(c),e=d.find(m.default.post.forumSubject).text(),f=d.find(m.default.post.authorName).text(),h=q({postid:c.data("post-id"),reply_url:b.attr("data-href"),sesskey:M.cfg.sesskey,parentsubject:e,parentauthorname:f,canreplyprivately:b.data("can-reply-privately"),postformat:i.default.CONTENT_FORMATS.MOODLE},a);return g.default.render("mod_forum/inpage_reply_modern",h)},z=function(a,h){d.default.define(a,[d.default.events.activate]);c.default.init(a);a.on(d.default.events.activate,m.default.post.inpageReplyCreateButton,function(){var a=p(regeneratorRuntime.mark(function a(c,d){var e,i,j,k;return regeneratorRuntime.wrap(function(a){while(1){switch(a.prev=a.next){case 0:d.originalEvent.preventDefault();e=(0,b.default)(c.currentTarget);i=s(e);j=u(i);if(x(j)){a.next=15;break}a.prev=5;a.next=8;return y(h,e,i);case 8:k=a.sent;g.default.appendNodeContents(j,k,"");a.next=15;break;case 12:a.prev=12;a.t0=a["catch"](5);f.default.exception(a.t0);case 15:e.fadeOut(150,function(){v(j,function(){j.find(m.default.post.inpageReplyContent).find("textarea").focus()})});case 16:case"end":return a.stop();}}},a,null,[[5,12]])}));return function(){return a.apply(this,arguments)}}());a.on(d.default.events.activate,m.default.post.inpageReplyCancelButton,function(a,c){c.originalEvent.preventDefault();var d=(0,b.default)(a.currentTarget),e=s(d),f=t(e),g=u(e),h=f.find(m.default.post.inpageReplyCreateButton);w(g,function(){h.fadeIn(150)})})},A=function(a,b){z(a,b);h.default.init(a);i.default.init(a);var c=a.find("[data-container=\"discussion-tools\"]");j.default.init(c);k.default.init(c);l.default.init(c)};a.init=A});
|
||||
//# sourceMappingURL=discussion_modern.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("mod_forum/inpage_reply",["jquery","core/templates","core/notification","mod_forum/repository","mod_forum/selectors"],function(a,b,c,d,f){var g={THREADED:2,NESTED:3,FLAT_OLDEST_FIRST:1,FLAT_NEWEST_FIRST:-1},h={MOODLE:0},i=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer),d=a.outerWidth();a.css("width",d);b.addClass("hidden");c.removeClass("hidden")},j=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer);a.css("width","");b.removeClass("hidden");c.addClass("hidden")},k=function(k){k.on("click",f.post.inpageSubmitBtn,function(l){l.preventDefault();var e=a(l.currentTarget),m=e.parent().find(f.post.inpageReplyButton),n=e.parents(f.post.inpageReplyForm).get(0),o=n.elements.post.value.trim(),p=h.MOODLE,q=n.elements.reply.value,r=n.elements.subject.value,s=e.parents(f.post.forumContent),t=n.elements.privatereply!=void 0?n.elements.privatereply.checked:!1,u=parseInt(k.find(f.post.modeSelect).get(0).value),v;if(o.length){i(e);m.prop("disabled",!0);d.addDiscussionPost(q,r,o,p,t,!0).then(function(a){var b=a.messages.reduce(function(a,b){if("success"==b.type){a+="<p>"+b.message+"</p>"}return a},"");c.addNotification({message:b,type:"success"});return a}).then(function(a){n.reset();var c=a.post;v=c.id;switch(u){case g.THREADED:return b.render("mod_forum/forum_discussion_threaded_post",c);case g.NESTED:return b.render("mod_forum/forum_discussion_nested_post",c);default:return b.render("mod_forum/forum_discussion_post",c);}}).then(function(a,c){var d;if(u==g.FLAT_OLDEST_FIRST||u==g.FLAT_NEWEST_FIRST){d=s.parents(f.post.repliesContainer).children().get(0)}if(d==void 0){d=s.siblings(f.post.repliesContainer).children().get(0)}if(u==g.FLAT_NEWEST_FIRST){return b.prependNodeContents(d,a,c)}else{return b.appendNodeContents(d,a,c)}}).then(function(){j(e);m.prop("disabled",!1);return s.find(f.post.inpageReplyContent).hide()}).then(function(){location.href="#p"+v}).catch(function(a){j(e);m.prop("disabled",!1);return c.exception(a)})}})};return{init:function init(a){k(a)},CONTENT_FORMATS:h}});
|
||||
define ("mod_forum/inpage_reply",["jquery","core/templates","core/notification","mod_forum/repository","mod_forum/selectors"],function(a,b,c,d,f){var g={MODERN:4,THREADED:2,NESTED:3,FLAT_OLDEST_FIRST:1,FLAT_NEWEST_FIRST:-1},h={MOODLE:0},i=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer),d=a.outerWidth();a.css("width",d);b.addClass("hidden");c.removeClass("hidden")},j=function(a){var b=a.find(f.post.inpageSubmitBtnText),c=a.find(f.post.loadingIconContainer);a.css("width","");b.removeClass("hidden");c.addClass("hidden")},k=function(k){k.on("click",f.post.inpageSubmitBtn,function(l){l.preventDefault();var e=a(l.currentTarget),m=e.parent().find(f.post.inpageReplyButton),n=e.parents(f.post.inpageReplyForm).get(0),o=n.elements.post.value.trim(),p=h.MOODLE,q=n.elements.reply.value,r=n.elements.subject.value,s=e.closest(f.post.post),t=n.elements.privatereply!=void 0?n.elements.privatereply.checked:!1,u=k.find(f.post.modeSelect),v=u.length?parseInt(u.get(0).value):null,w;if(o.length){i(e);m.prop("disabled",!0);d.addDiscussionPost(q,r,o,p,t,!0).then(function(a){var b=a.messages.reduce(function(a,b){if("success"==b.type){a+="<p>"+b.message+"</p>"}return a},"");c.addNotification({message:b,type:"success"});return a}).then(function(a){n.reset();var c=a.post;w=c.id;switch(v){case g.MODERN:var d=c.capabilities;c.showactionmenu=d.controlreadstatus||d.edit||d.split||d.delete||d.export||c.urls.viewparent;return b.render("mod_forum/forum_discussion_modern_post_reply",c);case g.THREADED:return b.render("mod_forum/forum_discussion_threaded_post",c);case g.NESTED:return b.render("mod_forum/forum_discussion_nested_post",c);default:return b.render("mod_forum/forum_discussion_post",c);}}).then(function(a,c){var d=s.find(f.post.repliesContainer).first();if(v==g.FLAT_NEWEST_FIRST){return b.prependNodeContents(d,a,c)}else{return b.appendNodeContents(d,a,c)}}).then(function(){j(e);m.prop("disabled",!1);return s.find(f.post.inpageReplyContent).hide()}).then(function(){location.href="#p"+w}).catch(function(a){j(e);m.prop("disabled",!1);return c.exception(a)})}})};return{init:function init(a){k(a)},CONTENT_FORMATS:h}});
|
||||
//# sourceMappingURL=inpage_reply.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1,2 +1,2 @@
|
||||
define ("mod_forum/selectors",[],function(){return{subscription:{toggle:"[data-type='subscription-toggle'][data-action='toggle']"},summary:{actions:"[data-container='discussion-summary-actions']"},post:{post:"[data-region=\"post\"]",action:"[data-region=\"post-action\"]",actionsContainer:"[data-region=\"post-actions-container\"]",forumCoreContent:"[data-region-content='forum-post-core']",forumContent:"[data-content='forum-post']",forumSubject:"[data-region-content='forum-post-core-subject']",inpageReplyButton:"button",inpageReplyLink:"[data-action='collapsible-link']",inpageReplyContent:"[data-content='inpage-reply-content']",inpageReplyForm:"form[data-content='inpage-reply-form']",inpageSubmitBtn:"[data-action='forum-inpage-submit']",inpageSubmitBtnText:"[data-region='submit-text']",loadingIconContainer:"[data-region='loading-icon-container']",repliesContainer:"[data-region='replies-container']",modeSelect:"select[name='mode']"},lock:{toggle:"[data-action='toggle'][data-type='lock-toggle']",icon:"[data-region='locked-icon']"},favourite:{toggle:"[data-type='favorite-toggle'][data-action='toggle']"},pin:{toggle:"[data-type='pin-toggle'][data-action='toggle']"}}});
|
||||
define ("mod_forum/selectors",[],function(){return{subscription:{toggle:"[data-type='subscription-toggle'][data-action='toggle']"},summary:{actions:"[data-container='discussion-summary-actions']"},post:{post:"[data-region=\"post\"]",action:"[data-region=\"post-action\"]",actionsContainer:"[data-region=\"post-actions-container\"]",authorName:"[data-region=\"author-name\"]",forumCoreContent:"[data-region-content='forum-post-core']",forumContent:"[data-content='forum-post']",forumSubject:"[data-region-content='forum-post-core-subject']",inpageReplyButton:"button",inpageReplyLink:"[data-action='collapsible-link']",inpageReplyCancelButton:"[data-action='cancel-inpage-reply']",inpageReplyCreateButton:"[data-action='create-inpage-reply']",inpageReplyContainer:"[data-region=\"inpage-reply-container\"]",inpageReplyContent:"[data-content='inpage-reply-content']",inpageReplyForm:"form[data-content='inpage-reply-form']",inpageSubmitBtn:"[data-action='forum-inpage-submit']",inpageSubmitBtnText:"[data-region='submit-text']",loadingIconContainer:"[data-region='loading-icon-container']",repliesContainer:"[data-region='replies-container']",modeSelect:"select[name='mode']"},lock:{toggle:"[data-action='toggle'][data-type='lock-toggle']",icon:"[data-region='locked-icon']"},favourite:{toggle:"[data-type='favorite-toggle'][data-action='toggle']"},pin:{toggle:"[data-type='pin-toggle'][data-action='toggle']"}}});
|
||||
//# sourceMappingURL=selectors.min.js.map
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["../src/selectors.js"],"names":["define","subscription","toggle","summary","actions","post","action","actionsContainer","forumCoreContent","forumContent","forumSubject","inpageReplyButton","inpageReplyLink","inpageReplyContent","inpageReplyForm","inpageSubmitBtn","inpageSubmitBtnText","loadingIconContainer","repliesContainer","modeSelect","lock","icon","favourite","pin"],"mappings":"AAuBAA,OAAM,uBAAC,EAAD,CAAK,UAAW,CAClB,MAAO,CACHC,YAAY,CAAE,CACVC,MAAM,CAAE,yDADE,CADX,CAIHC,OAAO,CAAE,CACLC,OAAO,CAAE,+CADJ,CAJN,CAOHC,IAAI,CAAE,CACFA,IAAI,CAAE,wBADJ,CAEFC,MAAM,CAAE,+BAFN,CAGFC,gBAAgB,CAAE,0CAHhB,CAIFC,gBAAgB,CAAE,yCAJhB,CAKFC,YAAY,CAAE,6BALZ,CAMFC,YAAY,CAAE,iDANZ,CAOFC,iBAAiB,CAAE,QAPjB,CAQFC,eAAe,CAAE,kCARf,CASFC,kBAAkB,CAAE,uCATlB,CAUFC,eAAe,CAAE,wCAVf,CAWFC,eAAe,CAAE,qCAXf,CAYFC,mBAAmB,CAAE,6BAZnB,CAaFC,oBAAoB,CAAE,wCAbpB,CAcFC,gBAAgB,CAAE,mCAdhB,CAeFC,UAAU,CAAE,qBAfV,CAPH,CAwBHC,IAAI,CAAE,CACFlB,MAAM,CAAE,iDADN,CAEFmB,IAAI,CAAE,6BAFJ,CAxBH,CA4BHC,SAAS,CAAE,CACPpB,MAAM,CAAE,qDADD,CA5BR,CA+BHqB,GAAG,CAAE,CACDrB,MAAM,CAAE,gDADP,CA/BF,CAmCV,CApCK,CAAN","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 * Common CSS selectors for the forum UI.\n *\n * @module mod_forum/selectors\n * @package mod_forum\n * @copyright 2019 Andrew Nicols <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([], function() {\n return {\n subscription: {\n toggle: \"[data-type='subscription-toggle'][data-action='toggle']\",\n },\n summary: {\n actions: \"[data-container='discussion-summary-actions']\"\n },\n post: {\n post: '[data-region=\"post\"]',\n action: '[data-region=\"post-action\"]',\n actionsContainer: '[data-region=\"post-actions-container\"]',\n forumCoreContent: \"[data-region-content='forum-post-core']\",\n forumContent: \"[data-content='forum-post']\",\n forumSubject: \"[data-region-content='forum-post-core-subject']\",\n inpageReplyButton: \"button\",\n inpageReplyLink: \"[data-action='collapsible-link']\",\n inpageReplyContent: \"[data-content='inpage-reply-content']\",\n inpageReplyForm: \"form[data-content='inpage-reply-form']\",\n inpageSubmitBtn: \"[data-action='forum-inpage-submit']\",\n inpageSubmitBtnText: \"[data-region='submit-text']\",\n loadingIconContainer: \"[data-region='loading-icon-container']\",\n repliesContainer: \"[data-region='replies-container']\",\n modeSelect: \"select[name='mode']\"\n },\n lock: {\n toggle: \"[data-action='toggle'][data-type='lock-toggle']\",\n icon: \"[data-region='locked-icon']\"\n },\n favourite: {\n toggle: \"[data-type='favorite-toggle'][data-action='toggle']\",\n },\n pin: {\n toggle: \"[data-type='pin-toggle'][data-action='toggle']\",\n },\n };\n});\n"],"file":"selectors.min.js"}
|
||||
{"version":3,"sources":["../src/selectors.js"],"names":["define","subscription","toggle","summary","actions","post","action","actionsContainer","authorName","forumCoreContent","forumContent","forumSubject","inpageReplyButton","inpageReplyLink","inpageReplyCancelButton","inpageReplyCreateButton","inpageReplyContainer","inpageReplyContent","inpageReplyForm","inpageSubmitBtn","inpageSubmitBtnText","loadingIconContainer","repliesContainer","modeSelect","lock","icon","favourite","pin"],"mappings":"AAuBAA,OAAM,uBAAC,EAAD,CAAK,UAAW,CAClB,MAAO,CACHC,YAAY,CAAE,CACVC,MAAM,CAAE,yDADE,CADX,CAIHC,OAAO,CAAE,CACLC,OAAO,CAAE,+CADJ,CAJN,CAOHC,IAAI,CAAE,CACFA,IAAI,CAAE,wBADJ,CAEFC,MAAM,CAAE,+BAFN,CAGFC,gBAAgB,CAAE,0CAHhB,CAIFC,UAAU,CAAE,+BAJV,CAKFC,gBAAgB,CAAE,yCALhB,CAMFC,YAAY,CAAE,6BANZ,CAOFC,YAAY,CAAE,iDAPZ,CAQFC,iBAAiB,CAAE,QARjB,CASFC,eAAe,CAAE,kCATf,CAUFC,uBAAuB,CAAE,qCAVvB,CAWFC,uBAAuB,CAAE,qCAXvB,CAYFC,oBAAoB,CAAE,0CAZpB,CAaFC,kBAAkB,CAAE,uCAblB,CAcFC,eAAe,CAAE,wCAdf,CAeFC,eAAe,CAAE,qCAff,CAgBFC,mBAAmB,CAAE,6BAhBnB,CAiBFC,oBAAoB,CAAE,wCAjBpB,CAkBFC,gBAAgB,CAAE,mCAlBhB,CAmBFC,UAAU,CAAE,qBAnBV,CAPH,CA4BHC,IAAI,CAAE,CACFtB,MAAM,CAAE,iDADN,CAEFuB,IAAI,CAAE,6BAFJ,CA5BH,CAgCHC,SAAS,CAAE,CACPxB,MAAM,CAAE,qDADD,CAhCR,CAmCHyB,GAAG,CAAE,CACDzB,MAAM,CAAE,gDADP,CAnCF,CAuCV,CAxCK,CAAN","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 * Common CSS selectors for the forum UI.\n *\n * @module mod_forum/selectors\n * @package mod_forum\n * @copyright 2019 Andrew Nicols <[email protected]>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([], function() {\n return {\n subscription: {\n toggle: \"[data-type='subscription-toggle'][data-action='toggle']\",\n },\n summary: {\n actions: \"[data-container='discussion-summary-actions']\"\n },\n post: {\n post: '[data-region=\"post\"]',\n action: '[data-region=\"post-action\"]',\n actionsContainer: '[data-region=\"post-actions-container\"]',\n authorName: '[data-region=\"author-name\"]',\n forumCoreContent: \"[data-region-content='forum-post-core']\",\n forumContent: \"[data-content='forum-post']\",\n forumSubject: \"[data-region-content='forum-post-core-subject']\",\n inpageReplyButton: \"button\",\n inpageReplyLink: \"[data-action='collapsible-link']\",\n inpageReplyCancelButton: \"[data-action='cancel-inpage-reply']\",\n inpageReplyCreateButton: \"[data-action='create-inpage-reply']\",\n inpageReplyContainer: '[data-region=\"inpage-reply-container\"]',\n inpageReplyContent: \"[data-content='inpage-reply-content']\",\n inpageReplyForm: \"form[data-content='inpage-reply-form']\",\n inpageSubmitBtn: \"[data-action='forum-inpage-submit']\",\n inpageSubmitBtnText: \"[data-region='submit-text']\",\n loadingIconContainer: \"[data-region='loading-icon-container']\",\n repliesContainer: \"[data-region='replies-container']\",\n modeSelect: \"select[name='mode']\"\n },\n lock: {\n toggle: \"[data-action='toggle'][data-type='lock-toggle']\",\n icon: \"[data-region='locked-icon']\"\n },\n favourite: {\n toggle: \"[data-type='favorite-toggle'][data-action='toggle']\",\n },\n pin: {\n toggle: \"[data-type='pin-toggle'][data-action='toggle']\",\n },\n };\n});\n"],"file":"selectors.min.js"}
|
||||
@@ -14,23 +14,191 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Module for viewing a discussion.
|
||||
* Module for viewing a discussion in modern view.
|
||||
*
|
||||
* @module mod_forum/discussion_new
|
||||
* @package mod_forum
|
||||
* @copyright 2019 Ryan Wyllie <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
import $ from 'jquery';
|
||||
import AutoRows from 'core/auto_rows';
|
||||
import CustomEvents from 'core/custom_interaction_events';
|
||||
import Notification from 'core/notification';
|
||||
import Templates from 'core/templates';
|
||||
import Discussion from 'mod_forum/discussion';
|
||||
import InPageReply from 'mod_forum/inpage_reply';
|
||||
import LockToggle from 'mod_forum/lock_toggle';
|
||||
import FavouriteToggle from 'mod_forum/favourite_toggle';
|
||||
import Pin from 'mod_forum/pin_toggle';
|
||||
import Selectors from 'mod_forum/selectors';
|
||||
|
||||
export const init = (root) => {
|
||||
const ANIMATION_DURATION = 150;
|
||||
|
||||
/**
|
||||
* Get the closest post container element from the given element.
|
||||
*
|
||||
* @param {Object} element jQuery element to search from
|
||||
* @return {Object} jQuery element
|
||||
*/
|
||||
const getPostContainer = (element) => {
|
||||
return element.closest(Selectors.post.post);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the post content container element from the post container element.
|
||||
*
|
||||
* @param {Object} postContainer jQuery element for the post container
|
||||
* @return {Object} jQuery element
|
||||
*/
|
||||
const getPostContentContainer = (postContainer) => {
|
||||
return postContainer.children().not(Selectors.post.repliesContainer).find(Selectors.post.forumCoreContent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the in page reply container element from the post container element.
|
||||
*
|
||||
* @param {Object} postContainer jQuery element for the post container
|
||||
* @return {Object} jQuery element
|
||||
*/
|
||||
const getInPageReplyContainer = (postContainer) => {
|
||||
return postContainer.children().filter(Selectors.post.inpageReplyContainer);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the in page reply form in the given in page reply container. The form
|
||||
* display will be animated.
|
||||
*
|
||||
* @param {Object} inPageReplyContainer jQuery element for the in page reply container
|
||||
* @param {Function} afterAnimationCallback Callback after animation completes
|
||||
*/
|
||||
const showInPageReplyForm = (inPageReplyContainer, afterAnimationCallback) => {
|
||||
const form = inPageReplyContainer.find(Selectors.post.inpageReplyContent);
|
||||
|
||||
form.slideDown({
|
||||
duration: ANIMATION_DURATION,
|
||||
queue: false,
|
||||
complete: afterAnimationCallback
|
||||
}).css('display', 'none').fadeIn(ANIMATION_DURATION);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the in page reply form in the given in page reply container. The form
|
||||
* display will be animated.
|
||||
*
|
||||
* @param {Object} inPageReplyContainer jQuery element for the in page reply container
|
||||
* @param {Function} afterAnimationCallback Callback after animation completes
|
||||
*/
|
||||
const hideInPageReplyForm = (inPageReplyContainer, afterAnimationCallback) => {
|
||||
const form = inPageReplyContainer.find(Selectors.post.inpageReplyContent);
|
||||
|
||||
form.slideUp({
|
||||
duration: ANIMATION_DURATION,
|
||||
queue: false,
|
||||
complete: afterAnimationCallback
|
||||
}).fadeOut(200);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the in page reply container contains the in page reply form.
|
||||
*
|
||||
* @param {Object} inPageReplyContainer jQuery element for the in page reply container
|
||||
* @return {Bool}
|
||||
*/
|
||||
const hasInPageReplyForm = (inPageReplyContainer) => {
|
||||
return inPageReplyContainer.find(Selectors.post.inpageReplyContent).length > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the template to generate the in page reply form HTML.
|
||||
*
|
||||
* @param {Object} additionalTemplateContext Additional render context for the in page reply template
|
||||
* @param {Object} button jQuery element for the reply button that was clicked
|
||||
* @param {Object} postContainer jQuery element for the post container
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
const renderInPageReplyTemplate = (additionalTemplateContext, button, postContainer) => {
|
||||
const postContentContainer = getPostContentContainer(postContainer);
|
||||
const currentSubject = postContentContainer.find(Selectors.post.forumSubject).text();
|
||||
const currentAuthorName = postContentContainer.find(Selectors.post.authorName).text();
|
||||
const context = {
|
||||
postid: postContainer.data('post-id'),
|
||||
"reply_url": button.attr('data-href'),
|
||||
sesskey: M.cfg.sesskey,
|
||||
parentsubject: currentSubject,
|
||||
parentauthorname: currentAuthorName,
|
||||
canreplyprivately: button.data('can-reply-privately'),
|
||||
postformat: InPageReply.CONTENT_FORMATS.MOODLE,
|
||||
...additionalTemplateContext
|
||||
};
|
||||
|
||||
return Templates.render('mod_forum/inpage_reply_modern', context);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create all of the event listeners for the discussion.
|
||||
*
|
||||
* @param {Object} root jQuery element for the discussion container
|
||||
* @param {Object} additionalTemplateContext Additional render context for the in page reply template
|
||||
*/
|
||||
const registerEventListeners = (root, additionalTemplateContext) => {
|
||||
CustomEvents.define(root, [CustomEvents.events.activate]);
|
||||
// Auto expanding text area for in page reply.
|
||||
AutoRows.init(root);
|
||||
|
||||
// Reply button is clicked.
|
||||
root.on(CustomEvents.events.activate, Selectors.post.inpageReplyCreateButton, async (e, data) => {
|
||||
data.originalEvent.preventDefault();
|
||||
|
||||
const button = $(e.currentTarget);
|
||||
const postContainer = getPostContainer(button);
|
||||
const inPageReplyContainer = getInPageReplyContainer(postContainer);
|
||||
|
||||
if (!hasInPageReplyForm(inPageReplyContainer)) {
|
||||
try {
|
||||
const html = await renderInPageReplyTemplate(additionalTemplateContext, button, postContainer);
|
||||
Templates.appendNodeContents(inPageReplyContainer, html, '');
|
||||
} catch (e) {
|
||||
Notification.exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
button.fadeOut(ANIMATION_DURATION, () => {
|
||||
showInPageReplyForm(inPageReplyContainer, () => {
|
||||
inPageReplyContainer.find(Selectors.post.inpageReplyContent).find('textarea').focus();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Cancel in page reply button.
|
||||
root.on(CustomEvents.events.activate, Selectors.post.inpageReplyCancelButton, (e, data) => {
|
||||
data.originalEvent.preventDefault();
|
||||
|
||||
const button = $(e.currentTarget);
|
||||
const postContainer = getPostContainer(button);
|
||||
const postContentContainer = getPostContentContainer(postContainer);
|
||||
const inPageReplyContainer = getInPageReplyContainer(postContainer);
|
||||
const inPageReplyCreateButton = postContentContainer.find(Selectors.post.inpageReplyCreateButton);
|
||||
hideInPageReplyForm(inPageReplyContainer, () => {
|
||||
inPageReplyCreateButton.fadeIn(ANIMATION_DURATION);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the javascript for the discussion in modern display mode.
|
||||
*
|
||||
* @param {Object} root jQuery element for the discussion container
|
||||
* @param {Object} context Additional render context for the in page reply template
|
||||
*/
|
||||
export const init = (root, context) => {
|
||||
// Add discussion event listeners.
|
||||
registerEventListeners(root, context);
|
||||
// Add default discussion javascript (keyboard nav etc).
|
||||
Discussion.init(root);
|
||||
// Add in page reply javascript.
|
||||
InPageReply.init(root);
|
||||
|
||||
var discussionToolsContainer = $('[data-container="discussion-tools"]');
|
||||
// Initialise the settings menu javascript.
|
||||
const discussionToolsContainer = root.find('[data-container="discussion-tools"]');
|
||||
LockToggle.init(discussionToolsContainer);
|
||||
FavouriteToggle.init(discussionToolsContainer);
|
||||
Pin.init(discussionToolsContainer);
|
||||
|
||||
@@ -36,6 +36,7 @@ define([
|
||||
) {
|
||||
|
||||
var DISPLAYCONSTANTS = {
|
||||
MODERN: 4,
|
||||
THREADED: 2,
|
||||
NESTED: 3,
|
||||
FLAT_OLDEST_FIRST: 1,
|
||||
@@ -97,9 +98,10 @@ define([
|
||||
var topreferredformat = true;
|
||||
var postid = form.elements.reply.value;
|
||||
var subject = form.elements.subject.value;
|
||||
var currentRoot = submitButton.parents(Selectors.post.forumContent);
|
||||
var currentRoot = submitButton.closest(Selectors.post.post);
|
||||
var isprivatereply = form.elements.privatereply != undefined ? form.elements.privatereply.checked : false;
|
||||
var mode = parseInt(root.find(Selectors.post.modeSelect).get(0).value);
|
||||
var modeSelector = root.find(Selectors.post.modeSelect);
|
||||
var mode = modeSelector.length ? parseInt(modeSelector.get(0).value) : null;
|
||||
var newid;
|
||||
|
||||
if (message.length) {
|
||||
@@ -125,7 +127,17 @@ define([
|
||||
form.reset();
|
||||
var post = context.post;
|
||||
newid = post.id;
|
||||
|
||||
switch (mode) {
|
||||
case DISPLAYCONSTANTS.MODERN:
|
||||
var capabilities = post.capabilities;
|
||||
post.showactionmenu = capabilities.controlreadstatus ||
|
||||
capabilities.edit ||
|
||||
capabilities.split ||
|
||||
capabilities.delete ||
|
||||
capabilities.export ||
|
||||
post.urls.viewparent;
|
||||
return Templates.render('mod_forum/forum_discussion_modern_post_reply', post);
|
||||
case DISPLAYCONSTANTS.THREADED:
|
||||
return Templates.render('mod_forum/forum_discussion_threaded_post', post);
|
||||
case DISPLAYCONSTANTS.NESTED:
|
||||
@@ -135,16 +147,7 @@ define([
|
||||
}
|
||||
})
|
||||
.then(function(html, js) {
|
||||
var repliesnode;
|
||||
|
||||
// Try and get the replies-container which can either be a sibling OR parent if it's flat
|
||||
if (mode == DISPLAYCONSTANTS.FLAT_OLDEST_FIRST || mode == DISPLAYCONSTANTS.FLAT_NEWEST_FIRST) {
|
||||
repliesnode = currentRoot.parents(Selectors.post.repliesContainer).children().get(0);
|
||||
}
|
||||
|
||||
if (repliesnode == undefined) {
|
||||
repliesnode = currentRoot.siblings(Selectors.post.repliesContainer).children().get(0);
|
||||
}
|
||||
var repliesnode = currentRoot.find(Selectors.post.repliesContainer).first();
|
||||
|
||||
if (mode == DISPLAYCONSTANTS.FLAT_NEWEST_FIRST) {
|
||||
return Templates.prependNodeContents(repliesnode, html, js);
|
||||
|
||||
@@ -33,11 +33,15 @@ define([], function() {
|
||||
post: '[data-region="post"]',
|
||||
action: '[data-region="post-action"]',
|
||||
actionsContainer: '[data-region="post-actions-container"]',
|
||||
authorName: '[data-region="author-name"]',
|
||||
forumCoreContent: "[data-region-content='forum-post-core']",
|
||||
forumContent: "[data-content='forum-post']",
|
||||
forumSubject: "[data-region-content='forum-post-core-subject']",
|
||||
inpageReplyButton: "button",
|
||||
inpageReplyLink: "[data-action='collapsible-link']",
|
||||
inpageReplyCancelButton: "[data-action='cancel-inpage-reply']",
|
||||
inpageReplyCreateButton: "[data-action='create-inpage-reply']",
|
||||
inpageReplyContainer: '[data-region="inpage-reply-container"]',
|
||||
inpageReplyContent: "[data-content='inpage-reply-content']",
|
||||
inpageReplyForm: "form[data-content='inpage-reply-form']",
|
||||
inpageSubmitBtn: "[data-action='forum-inpage-submit']",
|
||||
|
||||
@@ -184,7 +184,6 @@ class discussion {
|
||||
$capabilitymanager = $this->capabilitymanager;
|
||||
$urlfactory = $this->urlfactory;
|
||||
$entityfactory = $this->entityfactory;
|
||||
$loggedinauthor = $entityfactory->get_author_from_stdClass($user);
|
||||
|
||||
// Make sure we can render.
|
||||
if (!$capabilitymanager->can_view_discussions($user)) {
|
||||
@@ -205,11 +204,6 @@ class discussion {
|
||||
$hasanyactions = $hasanyactions || $capabilitymanager->can_manage_forum($user);
|
||||
|
||||
$exporteddiscussion = array_merge($exporteddiscussion, [
|
||||
'loggedinuser' => [
|
||||
'firstname' => $loggedinauthor->get_first_name(),
|
||||
'fullname' => $loggedinauthor->get_full_name(),
|
||||
'profileimageurl' => ($urlfactory->get_author_profile_image_url($loggedinauthor, null))->out(false)
|
||||
],
|
||||
'notifications' => $this->get_notifications($user),
|
||||
'html' => [
|
||||
'hasanyactions' => $hasanyactions,
|
||||
@@ -233,6 +227,15 @@ class discussion {
|
||||
$exporteddiscussion['html']['movediscussion'] = $this->get_move_discussion_html();
|
||||
}
|
||||
|
||||
if (!empty($user->id)) {
|
||||
$loggedinuser = $entityfactory->get_author_from_stdClass($user);
|
||||
$exporteddiscussion['loggedinuser'] = [
|
||||
'firstname' => $loggedinuser->get_first_name(),
|
||||
'fullname' => $loggedinuser->get_full_name(),
|
||||
'profileimageurl' => ($urlfactory->get_author_profile_image_url($loggedinuser, null))->out(false)
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->displaymode === FORUM_MODE_MODERN) {
|
||||
$template = 'mod_forum/forum_discussion_modern';
|
||||
} else {
|
||||
|
||||
@@ -59,6 +59,7 @@ $string['blogforum'] = 'Standard forum displayed in a blog-like format';
|
||||
$string['bynameondate'] = 'by {$a->name} - {$a->date}';
|
||||
$string['cachedef_forum_is_tracked'] = 'Forum tracking status for user';
|
||||
$string['calendardue'] = '{$a} is due';
|
||||
$string['cancelreply'] = 'Cancel reply';
|
||||
$string['cannotadd'] = 'Could not add the discussion for this forum';
|
||||
$string['cannotadddiscussion'] = 'Adding discussions to this forum requires group membership.';
|
||||
$string['cannotadddiscussionall'] = 'You do not have permission to add a new discussion topic for all participants.';
|
||||
@@ -555,6 +556,8 @@ $string['replies'] = 'Replies';
|
||||
$string['repliesmany'] = '{$a} replies so far';
|
||||
$string['repliesone'] = '{$a} reply so far';
|
||||
$string['reply'] = 'Reply';
|
||||
$string['replyauthorself'] = '{$a} (you)';
|
||||
$string['replyingtoauthor'] = 'Replying to {$a}...';
|
||||
$string['replyplaceholder'] = 'Write your reply...';
|
||||
$string['replyforum'] = 'Reply to forum';
|
||||
$string['replytopostbyemail'] = 'You can reply to this via email.';
|
||||
|
||||
@@ -57,6 +57,14 @@
|
||||
{{#js}}
|
||||
require(['jquery', 'mod_forum/discussion_modern'], function($, Discussion) {
|
||||
var root = $('#discussion-container-{{uniqid}}');
|
||||
Discussion.init(root);
|
||||
Discussion.init(root, {
|
||||
{{#loggedinuser}}
|
||||
loggedinuser: {
|
||||
profileimageurl: '{{{profileimageurl}}}',
|
||||
fullname: '{{fullname}}',
|
||||
firstname: '{{firstname}}'
|
||||
}
|
||||
{{/loggedinuser}}
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
|
||||
@@ -325,7 +325,7 @@
|
||||
class="btn btn-primary btn-lg"
|
||||
data-href="{{{urls.reply}}}"
|
||||
data-post-id="{{id}}"
|
||||
data-action="collapsible-link"
|
||||
data-action="create-inpage-reply"
|
||||
data-can-reply-privately="{{capabilities.canreplyprivately}}"
|
||||
>
|
||||
{{#str}} reply, mod_forum {{/str}}
|
||||
@@ -354,9 +354,7 @@
|
||||
<div class="indent replies-container" data-region="replies-container">
|
||||
{{#hasreplies}}
|
||||
{{#replies}}
|
||||
<div class="mt-4">
|
||||
{{> mod_forum/forum_discussion_modern_post_reply }}
|
||||
</div>
|
||||
{{> mod_forum/forum_discussion_modern_post_reply }}
|
||||
{{/replies}}
|
||||
{{/hasreplies}}
|
||||
</div>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
}}
|
||||
{{< mod_forum/forum_discussion_post }}
|
||||
{{$replies}}
|
||||
<div class="indent">
|
||||
<div class="indent" data-region="replies-container">
|
||||
{{#replies}}
|
||||
{{> mod_forum/forum_discussion_nested_post }}
|
||||
{{/replies}}
|
||||
|
||||
@@ -314,15 +314,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-region="replies-container">
|
||||
{{$replies}}
|
||||
<div>
|
||||
{{#hasreplies}}
|
||||
{{#replies}}
|
||||
{{> mod_forum/forum_discussion_post }}
|
||||
{{/replies}}
|
||||
{{/hasreplies}}
|
||||
<div data-region="replies-container">
|
||||
{{#hasreplies}}
|
||||
{{#replies}}
|
||||
{{> mod_forum/forum_discussion_post }}
|
||||
{{/replies}}
|
||||
{{/hasreplies}}
|
||||
</div>
|
||||
{{/replies}}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
{{< mod_forum/forum_discussion_post }}
|
||||
{{$replies}}
|
||||
<!-- The forumthread class is only added for behat -->
|
||||
<div class="indent forumthread post-replies">
|
||||
<div class="indent forumthread post-replies" data-region="replies-container">
|
||||
{{#replies}}
|
||||
{{> mod_forum/forum_discussion_threaded_post }}
|
||||
{{/replies}}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template mod_forum/inpage_reply_modern
|
||||
|
||||
In page reply HTML for the "modern" discussion display mode.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* none
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"postid": 0,
|
||||
"reply_url": "",
|
||||
"sesskey": "",
|
||||
"parentsubject": ""
|
||||
}
|
||||
}}
|
||||
<div
|
||||
class="mt-4 mb-4"
|
||||
data-content="inpage-reply-content"
|
||||
style="display: none;"
|
||||
>
|
||||
<div class="d-flex">
|
||||
<div class="author-image-container">
|
||||
{{#loggedinuser}}
|
||||
<img
|
||||
class="rounded-circle w-100"
|
||||
src="{{{profileimageurl}}}"
|
||||
alt="{{#str}} pictureof, core, {{fullname}} {{/str}}"
|
||||
aria-hidden="true"
|
||||
>
|
||||
{{/loggedinuser}}
|
||||
</div>
|
||||
<div class="w-100">
|
||||
{{#loggedinuser}}
|
||||
<h4 class="h5 font-weight-bold reply-author">{{#str}} replyauthorself, mod_forum, {{firstname}}{{/str}}</h4>
|
||||
{{/loggedinuser}}
|
||||
<form data-post-id="{{postid}}" data-content="inpage-reply-form" action="{{{reply_url}}}">
|
||||
<textarea
|
||||
name="post"
|
||||
rows="3"
|
||||
class="w-100"
|
||||
{{#parentauthorname}}
|
||||
placeholder="{{#str}} replyingtoauthor, forum, {{.}} {{/str}}"
|
||||
{{/parentauthorname}}
|
||||
{{^parentauthorname}}
|
||||
placeholder="{{#str}} replyplaceholder, forum {{/str}}"
|
||||
{{/parentauthorname}}
|
||||
data-auto-rows
|
||||
data-min-rows="3"
|
||||
data-max-rows="10"
|
||||
></textarea>
|
||||
<input type="hidden" name="postformat" value="{{postformat}}"/>
|
||||
<input type="hidden" name="subject" value="{{#str}} inpagereplysubject, forum, {{parentsubject}} {{/str}}"/>
|
||||
<input type="hidden" name="reply" value="{{postid}}"/>
|
||||
<input type="hidden" name="sesskey" value="{{sesskey}}"/>
|
||||
<div class="d-flex mt-3 align-items-center flex-wrap">
|
||||
<button class="btn btn-primary" data-action="forum-inpage-submit">
|
||||
<span data-region="submit-text">{{#str}} post, core {{/str}}</span>
|
||||
<span data-region="loading-icon-container" class="hidden">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button data-action="forum-advanced-reply" class="btn btn-link mr-auto" type="submit">
|
||||
{{#str}} advanced, core {{/str}}
|
||||
</button>
|
||||
{{#canreplyprivately}}
|
||||
<div class="form-check form-check-inline">
|
||||
<span class="switch">
|
||||
<input name="privatereply" type="checkbox" id="private-reply-checkbox-{{uniqid}}">
|
||||
<label class="mb-0" for="private-reply-checkbox-{{uniqid}}">
|
||||
{{#str}} privatereply, forum {{/str}}
|
||||
</label>
|
||||
</span>
|
||||
</div>
|
||||
{{/canreplyprivately}}
|
||||
<button
|
||||
class="btn btn-icon icon-no-margin icon-size-4 text-muted"
|
||||
title="{{#str}} cancelreply, mod_forum {{/str}}"
|
||||
data-action="cancel-inpage-reply"
|
||||
>
|
||||
{{#pix}} i/delete, core {{/pix}}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user