mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-63303 message: add message drawer (boost only)
This commit is contained in:
parent
3ea46c8e31
commit
5005d8cfb4
@ -22,13 +22,20 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['acceptandaddcontact'] = 'Accept and add to contacts';
|
||||
$string['addcontact'] = 'Add contact';
|
||||
$string['addcontactconfirm'] = 'Are you sure you want to add {$a} to your contacts?';
|
||||
$string['addtoyourcontacts'] = 'Add to your contacts';
|
||||
$string['addtoyourcontactsandmessage'] = 'Add to your contacts and message';
|
||||
$string['addtofavourites'] = 'Add to favourites';
|
||||
$string['ago'] = '{$a} ago';
|
||||
$string['allusers'] = 'All messages from all users';
|
||||
$string['backto'] = 'Back to {$a}';
|
||||
$string['backupmessageshelp'] = 'If enabled, then instant messages will be included in SITE automated backups';
|
||||
$string['blockcontact'] = 'Block contact';
|
||||
$string['blockedusers'] = 'Blocked users';
|
||||
$string['blockuser'] = 'Block user';
|
||||
$string['blockuserconfirm'] = 'Are you sure you want to block {$a}?';
|
||||
$string['blocknoncontacts'] = 'Prevent non-contacts from messaging me';
|
||||
$string['canceledit'] = 'Cancel editing messages';
|
||||
$string['contactableprivacy'] = 'Accept messages from:';
|
||||
@ -37,12 +44,16 @@ $string['contactableprivacy_coursemember'] = 'My contacts and anyone in my cours
|
||||
$string['contactableprivacy_site'] = 'Anyone on the site';
|
||||
$string['contactblocked'] = 'Contact blocked';
|
||||
$string['contactrequests'] = 'Contact requests';
|
||||
$string['contactrequestsent'] = 'Contact request sent';
|
||||
$string['contacts'] = 'Contacts';
|
||||
$string['decline'] = 'Decline';
|
||||
$string['defaultmessageoutputs'] = 'Default message outputs';
|
||||
$string['defaults'] = 'Defaults';
|
||||
$string['deleteallconfirm'] = "Are you sure you would like to delete this entire conversation?";
|
||||
$string['deleteallmessages'] = "Delete all messages";
|
||||
$string['deleteconversation'] = "Delete conversation";
|
||||
$string['deleteselectedmessages'] = 'Delete selected messages';
|
||||
$string['deleteselectedmessagesconfirm'] = 'Are you sure you would like to delete the selected messages?';
|
||||
$string['disableall'] = 'Disable notifications';
|
||||
$string['disabled'] = 'Messaging is disabled on this site';
|
||||
$string['disallowed'] = 'Disallowed';
|
||||
@ -64,8 +75,13 @@ $string['eventmessagesent'] = 'Message sent';
|
||||
$string['forced'] = 'Locked';
|
||||
$string['guestnoeditmessage'] = 'Guest user can not edit messaging options';
|
||||
$string['guestnoeditmessageother'] = 'Guest user can not edit other user messaging options';
|
||||
$string['groupinfo'] = 'Group info';
|
||||
$string['groupmessages'] = 'Group messages';
|
||||
$string['hidemessagewindow'] = 'Hide message window';
|
||||
$string['hidenotificationwindow'] = 'Hide notification window';
|
||||
$string['info'] = 'Info';
|
||||
$string['isnotinyourcontacts'] = '{$a} is not in your contacts';
|
||||
$string['loadmore'] = 'Load more';
|
||||
$string['loggedin'] = 'Online';
|
||||
$string['loggedin_help'] = 'Configure how you would like to receive notifications when you are logged into Moodle';
|
||||
$string['loggedindescription'] = 'When you are logged into Moodle';
|
||||
@ -78,24 +94,40 @@ $string['messagepreferences'] = 'Message preferences';
|
||||
$string['message'] = 'Message';
|
||||
$string['messagecontactrequestsnotification'] = '{$a} wants to be added as a contact';
|
||||
$string['messagecontactrequestsnotificationsubject'] = '{$a} wants to be added as a contact';
|
||||
$string['messagedrawerviewcontact'] = 'User details for {$a}';
|
||||
$string['messagedrawerviewcontacts'] = 'Message contacts';
|
||||
$string['messagedrawerviewconversation'] = 'Conversation with {$a}';
|
||||
$string['messagedrawerviewgroupinfo'] = 'Group details for {$a}';
|
||||
$string['messagedrawerviewoverview'] = 'Messages overview';
|
||||
$string['messagedrawerviewsearch'] = 'Messages search results for {$a}';
|
||||
$string['messagedrawerviewsettings'] = 'Message settings';
|
||||
$string['messagepreferences'] = 'Message preferences';
|
||||
$string['messages'] = 'Messages';
|
||||
$string['messagesselected:'] = 'Messages selected:';
|
||||
$string['messagingdatahasnotbeenmigrated'] = 'Your messages are temporarily unavailable due to upgrades in the messaging infrastructure. Please wait for them to be migrated.';
|
||||
$string['newonlymsg'] = 'Show only new';
|
||||
$string['newmessage'] = 'New message';
|
||||
$string['newmessagesearch'] = 'Select or search for a contact to send a new message.';
|
||||
$string['nofavourites'] = 'No favourites';
|
||||
$string['noframesjs'] = 'Use more accessible interface';
|
||||
$string['nocontactrequests'] = 'No contact requests';
|
||||
$string['nocontacts'] = 'No contacts';
|
||||
$string['nocontactsgetstarted'] = "Try searching for someone to add them as a contact";
|
||||
$string['nogroupmessages'] = 'No group messages';
|
||||
$string['nomessages'] = 'No messages';
|
||||
$string['nomessagesfound'] = 'No messages were found';
|
||||
$string['noreply'] = 'Do not reply to this message';
|
||||
$string['noncontacts'] = 'Non-contacts';
|
||||
$string['nonotifications'] = 'You have no notifications';
|
||||
$string['noparticipants'] = 'No participants';
|
||||
$string['notificationdatahasnotbeenmigrated'] = 'Your notifications are temporarily unavailable due to upgrades in the notification infrastructure. Please wait for them to be migrated.';
|
||||
$string['notificationwindow'] = 'Notification window';
|
||||
$string['notificationpreferences'] = 'Notification preferences';
|
||||
$string['notificationimage'] = 'Notification image';
|
||||
$string['notifications'] = 'Notifications';
|
||||
$string['notincontactsheading'] = '{$a} is not in your contacts';
|
||||
$string['notincontacts'] = 'You need to add {$a} to your contacts to be able to send them messages.';
|
||||
$string['numparticipants'] = '{$a} participants';
|
||||
$string['off'] = 'Off';
|
||||
$string['offline'] = 'Offline';
|
||||
$string['on'] = 'On';
|
||||
@ -105,7 +137,10 @@ $string['outputdoesnotexist'] = 'Message output does not exists';
|
||||
$string['outputenabled'] = 'Output enabled';
|
||||
$string['outputnotavailable'] = 'Not available';
|
||||
$string['outputnotconfigured'] = 'Not configured';
|
||||
$string['participants'] = 'Participants';
|
||||
$string['permitted'] = 'Permitted';
|
||||
$string['privacy'] = 'Privacy';
|
||||
$string['privacy_desc'] = 'You can restrict who can message you';
|
||||
$string['privacy:metadata:messages'] = 'Messages';
|
||||
$string['privacy:metadata:messages:conversationid'] = 'The ID of the conversation';
|
||||
$string['privacy:metadata:messages:fullmessage'] = 'The full message';
|
||||
@ -154,12 +189,18 @@ $string['privacy:metadata:preference:core_message_settings'] = 'Settings related
|
||||
$string['privacy:request:preference:set'] = 'The value of the setting \'{$a->name}\' was \'{$a->value}\'';
|
||||
$string['processorsettings'] = 'Processor settings';
|
||||
$string['removecontact'] = 'Remove contact';
|
||||
$string['removecontactconfirm'] = 'Are you sure you want to remove {$a} from your contacts?';
|
||||
$string['removecoursefilter'] = 'Remove filter for course {$a}';
|
||||
$string['removefromyourcontacts'] = 'Remove from your contacts';
|
||||
$string['removefromfavourites'] = 'Remove from favourites';
|
||||
$string['requirecontacttomessage'] = 'You need to request {$a} to add you as a contact to be able to message';
|
||||
$string['requiresconfiguration'] = 'Requires configuration';
|
||||
$string['searchforuser'] = 'Search for a user';
|
||||
$string['searchforuserorcourse'] = 'Search for a user or course';
|
||||
$string['searchmessages'] = 'Search messages';
|
||||
$string['searchnocontactsfound'] = 'No contacts found';
|
||||
$string['searchnomessagesfound'] = 'No messages found';
|
||||
$string['searchnononcontactsfound'] = 'No non contacts found';
|
||||
$string['searchcombined'] = 'Search people and messages';
|
||||
$string['seeall'] = 'See all';
|
||||
$string['selectmessagestodelete'] = 'Select messages to delete';
|
||||
@ -167,6 +208,7 @@ $string['selectnotificationtoview'] = 'Select from the list of notifications on
|
||||
$string['send'] = 'Send';
|
||||
$string['sendingvia'] = 'Sending "{$a->provider}" via "{$a->processor}"';
|
||||
$string['sendingviawhen'] = 'Sending "{$a->provider}" via "{$a->processor}" when {$a->state}';
|
||||
$string['sendcontactrequest'] = 'Send contact request';
|
||||
$string['sendmessage'] = 'Send message';
|
||||
$string['sendbulkmessage'] = 'Send message to {$a} people';
|
||||
$string['sendbulkmessagesingle'] = 'Send message to 1 person';
|
||||
@ -182,19 +224,29 @@ $string['shownotificationwindowwithcount'] = 'Show notification window with {$a}
|
||||
$string['togglenotificationmenu'] = 'Toggle notifications menu';
|
||||
$string['togglemessagemenu'] = 'Toggle messages menu';
|
||||
$string['touserdoesntexist'] = 'You can not send a message to a user id ({$a}) that doesn\'t exist';
|
||||
$string['unabletomessage'] = 'You are unable to message this user';
|
||||
$string['unblock'] = 'Unblock';
|
||||
$string['unblockcontact'] = 'Unblock contact';
|
||||
$string['unblockuser'] = 'Unblock user';
|
||||
$string['unblockuserconfirm'] = 'Are you sure you want to unblock {$a}?';
|
||||
$string['unknownuser'] = 'Unknown user';
|
||||
$string['unreadnotification'] = 'Unread notification: {$a}';
|
||||
$string['unreadnewgroupconversationmessage'] = 'New message from {$a->name} in {$a->conversationname}';
|
||||
$string['unreadnewmessage'] = 'New message from {$a}';
|
||||
$string['usercantbemessaged'] = 'You can\'t message {$a} due to their message preferences. Try adding them as a contact.';
|
||||
$string['userisblockingyou'] = 'This user has blocked you from sending messages to them';
|
||||
$string['userisblockingyounoncontact'] = '{$a} only accepts messages from their contacts.';
|
||||
$string['userwouldliketocontactyou'] = '{$a} would like to contact you';
|
||||
$string['viewfullnotification'] = 'View full notification';
|
||||
$string['viewinganotherusersmessagearea'] = 'You are viewing another user\'s message area.';
|
||||
$string['viewmessageswith'] = 'View messages with {$a}';
|
||||
$string['viewnotificationresource'] = 'Go to: {$a}';
|
||||
$string['viewunreadmessageswith'] = 'View unread messages with {$a}';
|
||||
$string['writeamessage'] = 'Write a message...';
|
||||
$string['wouldliketocontactyou'] = 'Would like to contact you';
|
||||
$string['you'] = 'You:';
|
||||
$string['youhaveblockeduser'] = 'You have blocked this user in the past';
|
||||
$string['yourcontactrequestpending'] = 'Your contact request is pending with {$a}';
|
||||
|
||||
// Deprecated since Moodle 3.6.
|
||||
$string['eventmessagecontactblocked'] = 'Message contact blocked';
|
||||
|
@ -808,6 +808,7 @@ $string['expandcategory'] = 'Expand {$a}';
|
||||
$string['explanation'] = 'Explanation';
|
||||
$string['explanationdigitalminor'] = 'This information is required to determine if your age is over the digital age of consent. This is the age when an individual can consent to terms and conditions and their data being legally stored and processed.';
|
||||
$string['extendperiod'] = 'Extended period';
|
||||
$string['favourites'] = 'Favourites';
|
||||
$string['failedloginattempts'] = '{$a->attempts} failed logins since your last login';
|
||||
$string['feedback'] = 'Feedback';
|
||||
$string['file'] = 'File';
|
||||
@ -1656,6 +1657,7 @@ $string['requestcourse'] = 'Request a course';
|
||||
$string['requestedby'] = 'Requested by';
|
||||
$string['requestedcourses'] = 'Requested courses';
|
||||
$string['requestreason'] = 'Reason for course request';
|
||||
$string['requests'] = 'Requests';
|
||||
$string['required'] = 'Required';
|
||||
$string['requirespayment'] = 'This course requires payment for access';
|
||||
$string['resendemail'] = 'Resend email';
|
||||
|
2
lib/amd/build/key_codes.min.js
vendored
2
lib/amd/build/key_codes.min.js
vendored
@ -1 +1 @@
|
||||
define(function(){return{tab:9,enter:13,escape:27,space:32,end:35,home:36,arrowLeft:37,arrowUp:38,arrowRight:39,arrowDown:40,8:56,asterix:106,pageUp:33,pageDown:34}});
|
||||
define(function(){return{tab:9,enter:13,shift:16,ctrl:17,alt:18,escape:27,space:32,end:35,home:36,arrowLeft:37,arrowUp:38,arrowRight:39,arrowDown:40,8:56,asterix:106,pageUp:33,pageDown:34}});
|
@ -28,6 +28,9 @@ define(function() {
|
||||
return /** @alias module:core/key_codes */ {
|
||||
'tab': 9,
|
||||
'enter': 13,
|
||||
'shift': 16,
|
||||
'ctrl': 17,
|
||||
'alt': 18,
|
||||
'escape': 27,
|
||||
'space': 32,
|
||||
'end': 35,
|
||||
|
@ -1571,6 +1571,7 @@ $functions = array(
|
||||
'classpath' => 'user/externallib.php',
|
||||
'description' => 'Return user preferences.',
|
||||
'type' => 'read',
|
||||
'ajax' => true,
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
),
|
||||
'core_user_update_picture' => array(
|
||||
|
@ -33,4 +33,4 @@
|
||||
Example context (json):
|
||||
{}
|
||||
}}
|
||||
<span class="loading-icon">{{#pix}} i/loading, core, {{#str}} loading {{/str}} {{/pix}}</span>
|
||||
<span class="loading-icon icon-no-margin">{{#pix}} i/loading, core, {{#str}} loading {{/str}} {{/pix}}</span>
|
||||
|
1
message/amd/build/message_drawer.min.js
vendored
Normal file
1
message/amd/build/message_drawer.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/custom_interaction_events","core/pubsub","core_message/message_drawer_view_contact","core_message/message_drawer_view_contacts","core_message/message_drawer_view_conversation","core_message/message_drawer_view_group_info","core_message/message_drawer_view_overview","core_message/message_drawer_view_search","core_message/message_drawer_view_settings","core_message/message_drawer_router","core_message/message_drawer_routes","core_message/message_drawer_events"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={VIEW_CONTACT:'[data-region="view-contact"]',VIEW_CONTACTS:'[data-region="view-contacts"]',VIEW_CONVERSATION:'[data-region="view-conversation"]',VIEW_GROUP_INFO:'[data-region="view-group-info"]',VIEW_OVERVIEW:'[data-region="view-overview"]',VIEW_SEARCH:'[data-region="view-search"]',VIEW_SETTINGS:'[data-region="view-settings"]',ROUTES:"[data-route]",ROUTES_BACK:"[data-route-back]",HEADER_CONTAINER:'[data-region="header-container"]',BODY_CONTAINER:'[data-region="body-container"]',FOOTER_CONTAINER:'[data-region="footer-container"]'},o=function(a,b){var c=a.children(),d=c.filter(n.HEADER_CONTAINER).find(b),e=c.filter(n.BODY_CONTAINER).find(b),f=c.filter(n.FOOTER_CONTAINER).find(b),g=[d,e,f].filter(function(a){return a.length});return g},p=[[l.VIEW_CONTACT,n.VIEW_CONTACT,d.show,d.description],[l.VIEW_CONTACTS,n.VIEW_CONTACTS,e.show,e.description],[l.VIEW_CONVERSATION,n.VIEW_CONVERSATION,f.show,f.description],[l.VIEW_GROUP_INFO,n.VIEW_GROUP_INFO,g.show,g.description],[l.VIEW_OVERVIEW,n.VIEW_OVERVIEW,h.show,h.description],[l.VIEW_SEARCH,n.VIEW_SEARCH,i.show,i.description],[l.VIEW_SETTINGS,n.VIEW_SETTINGS,j.show,j.description]],q=function(a){p.forEach(function(b){k.add(b[0],o(a,b[1]),b[2],b[3])})},r=function(a){a.attr("data-shown")||(k.go(l.VIEW_OVERVIEW),a.attr("data-shown",!0)),a.removeClass("hidden"),a.attr("aria-expanded",!0),a.attr("aria-hidden",!1)},s=function(a){a.addClass("hidden"),a.attr("aria-expanded",!1),a.attr("aria-hidden",!0)},t=function(a){return!a.hasClass("hidden")},u=function(d){b.define(d,[b.events.activate]);var e=/^data-route-param-?(\d*)$/;d.on(b.events.activate,n.ROUTES,function(b,c){for(var d=a(b.target).closest(n.ROUTES),f=d.attr("data-route"),g=[],h=0;h<d[0].attributes.length;h++)g.push(d[0].attributes[h]);var i=g.filter(function(a){var b=a.nodeName,c=e.test(b);return c});i.sort(function(a,b){var c=e.exec(a.nodeName),d=e.exec(b.nodeName),f=c.length>1?c[1]:0,g=d.length>1?d[1]:0;return f<g?-1:g<f?1:0});var j=i.map(function(a){return a.nodeValue}),l=[f].concat(j);k.go.apply(null,l),c.originalEvent.preventDefault()}),d.on(b.events.activate,n.ROUTES_BACK,function(a,b){k.back(),b.originalEvent.preventDefault()}),c.subscribe(m.SHOW,function(){r(d)}),c.subscribe(m.HIDE,function(){s(d)}),c.subscribe(m.TOGGLE_VISIBILITY,function(){t(d)?s(d):r(d)}),c.subscribe(m.SHOW_CONVERSATION,function(a){r(d),k.go(l.VIEW_CONVERSATION,a)}),c.subscribe(m.SHOW_SETTINGS,function(){r(d),k.go(l.VIEW_SETTINGS)})},v=function(b){b=a(b),q(b),u(b)};return{init:v}});
|
1
message/amd/build/message_drawer_events.min.js
vendored
Normal file
1
message/amd/build/message_drawer_events.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define([],function(){return{CONTACT_BLOCKED:"message-drawer-contact-blocked",CONTACT_UNBLOCKED:"message-drawer-contact-unblocked",CONTACT_ADDED:"message-drawer-contact-added",CONTACT_REMOVED:"message-drawer-contact-removed",CONTACT_REQUEST_ACCEPTED:"message-drawer-contact-request-accepted",CONTACT_REQUEST_DECLINED:"message-drawer-contact-request-declined",CONVERSATION_CREATED:"message-drawer-conversation-created",CONVERSATION_NEW_LAST_MESSAGE:"message-drawer-conversation-new-last-message",CONVERSATION_DELETED:"message-drawer-conversation-deleted",CONVERSATION_READ:"message-drawer-conversation-read",CONVERSATION_SET_FAVOURITE:"message-drawer-conversation-set-favourite",CONVERSATION_UNSET_FAVOURITE:"message-drawer-conversation-unset-favourite",ROUTE_CHANGED:"message-drawer-route-change",SHOW:"message-drawer-show",HIDE:"message-drawer-hide",TOGGLE_VISIBILITY:"message-drawer-toggle",SHOW_CONVERSATION:"message-drawer-show-conversation",SHOW_SETTINGS:"message-drawer-show-settings"}});
|
1
message/amd/build/message_drawer_helper.min.js
vendored
Normal file
1
message/amd/build/message_drawer_helper.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["core/pubsub","core_message/message_drawer_events"],function(a,b){var c=function(){a.publish(b.SHOW)},d=function(c){a.publish(b.SHOW_CONVERSATION,c)},e=function(){a.publish(b.SHOW_SETTINGS)};return{show:c,showConversation:d,showSettings:e}});
|
1
message/amd/build/message_drawer_lazy_load_list.min.js
vendored
Normal file
1
message/amd/build/message_drawer_lazy_load_list.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/custom_interaction_events"],function(a,b){var c={ROOT:'[data-region="lazy-load-list"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]',CONTENT_CONTAINER:'[data-region="content-container"]',EMPTY_MESSAGE:'[data-region="empty-message-container"]',PLACEHOLDER:'[data-region="placeholder-container"]'},d=function(a){a.attr("data-loading",!0)},e=function(a){a.attr("data-loading",!1)},f=function(a){return"true"===a.attr("data-loading")},g=function(a){return a.attr("data-user-id")},h=function(a){return a.find(c.CONTENT_CONTAINER)},i=function(a){return a.find(c.ROOT)},j=function(a){a.find(c.LOADING_ICON_CONTAINER).removeClass("hidden")},k=function(a){a.find(c.LOADING_ICON_CONTAINER).addClass("hidden")},l=function(a){a.find(c.EMPTY_MESSAGE).removeClass("hidden")},m=function(a){a.find(c.EMPTY_MESSAGE).addClass("hidden")},n=function(a){a.find(c.PLACEHOLDER).removeClass("hidden")},o=function(a){a.find(c.PLACEHOLDER).addClass("hidden")},p=function(a){h(a).removeClass("hidden")},q=function(a){h(a).addClass("hidden")},r=function(a){return"true"==a.attr("data-loaded-all")},s=function(a,b){a.attr("data-loaded-all",b)},t=function(a){return!r(a)&&!f(a)},u=function(a,b,c){var f=g(a);return d(a),b(a,f).then(function(b){if(b.length>0){var d=h(a);return c(d,b,f).then(function(){return b})}return b}).then(function(b){return e(a),a.attr("data-seen",!0),b.length||s(a,!0),b})["catch"](function(){e(a),a.attr("data-seen",!0)})},v=function(a,b,c){return h(a).empty(),n(a),q(a),u(a,b,c).then(function(b){o(a),b.length?p(a):l(a)})["catch"](function(){o(a),p(a)})},w=function(a,c,d){b.define(a,[b.events.scrollBottom]),a.on(b.events.scrollBottom,function(){t(a)&&(j(a),u(a,c,d).then(function(){return k(a)})["catch"](function(){return k(a)}))})},x=function(b,c,d){b=a(b),b.attr("data-init")||(w(b,c,d),v(b,c,d),b.attr("data-init",!0))};return{show:x,getContentContainer:h,getRoot:i,setLoadedAll:s,showEmptyMessage:l,hideEmptyMessage:m,showContent:p,hideContent:q}});
|
1
message/amd/build/message_drawer_router.min.js
vendored
Normal file
1
message/amd/build/message_drawer_router.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/pubsub","core/str","core_message/message_drawer_events"],function(a,b,c,d){var e={},f=[],g={CAN_RECEIVE_FOCUS:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',ROUTES_BACK:"[data-route-back]"},h=function(a,b,c,d){e[a]={elements:b,onGo:c,getDescription:d}},i=function(c){var f,h=[].slice.call(arguments,1),i=a.Deferred().resolve().promise();if(Object.keys(e).forEach(function(a){var b=e[a],d=a===c;d&&(f=b),b.elements.forEach(function(a){a.removeClass("previous"),d?(a.removeClass("hidden"),a.attr("aria-hidden",!1)):(a.addClass("hidden"),a.attr("aria-hidden",!0))})}),f&&f.onGo){i=f.onGo.apply(void 0,f.elements.concat(h));for(var j=a(document.activeElement),k=!1,l=0;l<f.elements.length;l++){var m=f.elements[l];if(m.has(j).length){k=!0;break}}k||f.elements[0].find(g.CAN_RECEIVE_FOCUS).first().focus()}var n={route:c,params:h,renderPromise:i};return b.publish(d.ROUTE_CHANGED,n),n},j=function(){var b=a(document.activeElement),d=i.apply(null,arguments),h=!1;f=f.reduce(function(a,b){return b.route===d.route&&(h=!0),h||a.push(b),a},[]);var j=f.length?f[f.length-1]:null;if(j){var k=e[j.route];k.elements.forEach(function(a){a.addClass("previous")}),j.focusElement=b,k.getDescription&&k.getDescription.apply(null,k.elements.concat(j.params)).then(function(a){return c.get_string("backto","core_message",a)}).then(function(a){return d.renderPromise.then(function(){e[d.route].elements.forEach(function(b){b.find(g.ROUTES_BACK).attr("aria-label",a)})})})["catch"](function(){})}return f.push(d),d},k=function(){if(f.length){f.pop();var a=f.pop();a&&(j.apply(void 0,[a.route].concat(a.params)),window.setTimeout(function(){a.focusElement.focus()},50))}};return{add:h,go:j,back:k}});
|
1
message/amd/build/message_drawer_routes.min.js
vendored
Normal file
1
message/amd/build/message_drawer_routes.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define([],function(){return{VIEW_CONTACT:"view-contact",VIEW_CONTACTS:"view-contacts",VIEW_CONVERSATION:"view-conversation",VIEW_GROUP_INFO:"view-group-info",VIEW_OVERVIEW:"view-overview",VIEW_SEARCH:"view-search",VIEW_SETTINGS:"view-settings"}});
|
1
message/amd/build/message_drawer_view_contact.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_contact.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/str","core/templates"],function(a,b,c){var d={CONTENT_CONTAINER:'[data-region="content-container"]'},e={CONTENT:"core_message/message_drawer_view_contact_body_content"},f=function(a){return a.find(d.CONTENT_CONTAINER)},g=function(a,b){return c.render(e.CONTENT,b).then(function(b){return f(a).append(b),b})},h=function(b,c){return b=a(b),f(b).empty(),g(b,c)},i=function(a,c){return b.get_string("messagedrawerviewcontact","core_message",c.fullname)};return{show:h,description:i}});
|
1
message/amd/build/message_drawer_view_contacts.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_contacts.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/pubsub","core/str","core_message/message_drawer_events","core_message/message_drawer_view_contacts_section_contacts","core_message/message_drawer_view_contacts_section_requests"],function(a,b,c,d,e,f){var g={ACTION_SHOW_CONTACTS_SECTION:'[data-action="show-contacts-section"]',ACTION_SHOW_REQUESTS_SECTION:'[data-action="show-requests-section"]',CONTACT_REQUEST_COUNT:'[data-region="contact-request-count"]',CONTACTS_SECTION_CONTAINER:'[data-section="contacts"]',REQUESTS_SECTION_CONTAINER:'[data-section="requests"]'},h=function(a){return a.find(g.CONTACTS_SECTION_CONTAINER)},i=function(a){return a.find(g.REQUESTS_SECTION_CONTAINER)},j=function(a){return a.hasClass("active")},k=function(a){return function(){var b=a.find(g.CONTACT_REQUEST_COUNT),c=parseInt(b.text(),10);c=isNaN(c)?0:c-1,c<=0?b.addClass("hidden"):b.text(c)}},l=function(a){var c=h(a),j=i(a),l=a.find(g.ACTION_SHOW_CONTACTS_SECTION),m=a.find(g.ACTION_SHOW_REQUESTS_SECTION);l.on("show.bs.tab",function(){e.show(c)}),m.on("show.bs.tab",function(){f.show(j)}),b.subscribe(d.CONTACT_REQUEST_ACCEPTED,k(a)),b.subscribe(d.CONTACT_REQUEST_DECLINED,k(a))},m=function(b,c){c=a(c),c.attr("data-contacts-init")||(l(c),c.attr("data-contacts-init",!0));var d=h(c),g=i(c);return j(d)?e.show(d):f.show(g),a.Deferred().resolve().promise()},n=function(){return c.get_string("messagedrawerviewcontacts","core_message")};return{show:m,description:n}});
|
1
message/amd/build/message_drawer_view_contacts_section.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_contacts_section.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/notification","core/pubsub","core/templates","core/custom_interaction_events","core_message/message_repository","core_message/message_drawer_events"],function(a,b,c,d,e,f,g){var h=100,i=0,j=0,k=!1,l=!1,m={BLOCK_ICON_CONTAINER:'[data-region="block-icon-container"]',CONTACTS:'[data-region="contacts-container"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]',CONTENT_CONTAINER:'[data-region="contacts-content-container"]',EMPTY_MESSAGE:'[data-region="empty-message-container"]',PLACEHOLDER:'[data-region="placeholder-container"]'},n={CONTACTS_LIST:"core_message/message_drawer_contacts_list"},o=function(a){a.find(m.LOADING_ICON_CONTAINER).removeClass("hidden")},p=function(a){a.find(m.LOADING_ICON_CONTAINER).addClass("hidden")},q=function(a){return a.find(m.CONTENT_CONTAINER)},r=function(a){return a.find(m.CONTACTS)},s=function(a){q(a).addClass("hidden"),a.find(m.EMPTY_MESSAGE).removeClass("hidden")},t=function(a){a.find(m.PLACEHOLDER).addClass("hidden")},u=function(a){q(a).removeClass("hidden")},v=function(a,b){return a.find('[data-contact-user-id="'+b+'"]')},w=function(a){return a.attr("data-user-id")},x=function(a,b){var c=q(a);return d.render(n.CONTACTS_LIST,{contacts:b}).then(function(b){return t(a),c.append(b),u(a),b})},y=function(a){var b=w(a);return f.getContacts(b,h+1,j).then(function(a){return a.contacts}).then(function(a){return a.length>h?a.pop():k=!0,a}).then(function(b){return 0==j&&0==b.length&&(t(a),s(a)),i+=b.length,j+=h,b.length>0?x(a,b):b})},z=function(a,b){v(a,b).remove()},A=function(a,b){var c=v(a,b);c.length&&c.find(m.BLOCK_ICON_CONTAINER).removeClass("hidden")},B=function(a,b){var c=v(a,b);c.length&&c.find(m.BLOCK_ICON_CONTAINER).addClass("hidden")},C=function(a){c.subscribe(g.CONTACT_ADDED,function(){j=0,k=!1,q(a).empty(),y(a)}),c.subscribe(g.CONTACT_REMOVED,function(b){z(a,b)}),c.subscribe(g.CONTACT_BLOCKED,function(b){A(a,b)}),c.subscribe(g.CONTACT_UNBLOCKED,function(b){B(a,b)});var d=r(a);e.define(d,[e.events.scrollBottom,e.events.scrollLock]),d.on(e.events.scrollBottom,function(c,d){var e=i>1;k||!e||l||(l=!0,o(a),y(a).then(function(){p(a),l=!1})["catch"](function(c){p(a),l=!1,b.exception(c)})),d.originalEvent.preventDefault()})},D=function(b,c){c=a(c),j=0,c.attr("data-contacts-init")||(C(c),c.attr("data-contacts-init",!0)),k||y(c)};return{show:D}});
|
1
message/amd/build/message_drawer_view_contacts_section_contacts.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_contacts_section_contacts.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/notification","core/pubsub","core/templates","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_lazy_load_list"],function(a,b,c,d,e,f,g){var h=100,i=0,j={BLOCK_ICON_CONTAINER:'[data-region="block-icon-container"]',CONTACT:'[data-region="contact"]',CONTENT_CONTAINER:'[data-region="contacts-content-container"]'},k={CONTACTS_LIST:"core_message/message_drawer_contacts_list"},l=function(a,b){return a.find('[data-contact-user-id="'+b+'"]')},m=function(c,e){var f=e.map(function(b){return a.extend(b,{id:b.userid})});return d.render(k.CONTACTS_LIST,{contacts:f}).then(function(a){return c.append(a),a})["catch"](b.exception)},n=function(a,c){return e.getContacts(c,h+1,i).then(function(a){return a.contacts}).then(function(b){return b.length>h?b.pop():g.setLoadedAll(a,!0),b}).then(function(a){return i+=h,a})["catch"](b.exception)},o=function(a,b){l(a,b).remove()},p=function(a,b){var c=l(a,b);c.length&&c.find(j.BLOCK_ICON_CONTAINER).removeClass("hidden")},q=function(a,b){var c=l(a,b);c.length&&c.find(j.BLOCK_ICON_CONTAINER).addClass("hidden")},r=function(a){c.subscribe(f.CONTACT_ADDED,function(b){var c=g.getContentContainer(a);m(c,[b]),g.hideEmptyMessage(a),g.showContent(a)}),c.subscribe(f.CONTACT_REMOVED,function(b){o(a,b);var c=a.find(j.CONTACT);c.length||(g.hideContent(a),g.showEmptyMessage(a))}),c.subscribe(f.CONTACT_BLOCKED,function(b){p(a,b)}),c.subscribe(f.CONTACT_UNBLOCKED,function(b){q(a,b)})},s=function(a){a.attr("data-contacts-init")||(r(a),a.attr("data-contacts-init",!0)),g.show(a,n,m)};return{show:s}});
|
1
message/amd/build/message_drawer_view_contacts_section_requests.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_contacts_section_requests.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/notification","core/pubsub","core/templates","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_lazy_load_list"],function(a,b,c,d,e,f,g){var h={CONTACT_REQUEST:'[data-region="contact-request"]'},i={REQUESTS_LIST:"core_message/message_drawer_view_contacts_body_section_requests_list"},j=function(a,c){var e=c.map(function(a){return{id:a.id,profileimageurl:a.profileimageurl,fullname:a.fullname}});return d.render(i.REQUESTS_LIST,{requests:e}).then(function(b){return a.append(b),b})["catch"](b.exception)},k=function(a,c){return e.getContactRequests(c).then(function(b){return g.setLoadedAll(a,!0),b})["catch"](b.exception)},l=function(a){return function(b){a.find('[data-request-id="'+b.userid+'"]').remove();var c=a.find(h.CONTACT_REQUEST);c.length||(g.showEmptyMessage(a),g.hideContent(a))}},m=function(a){c.subscribe(f.CONTACT_REQUEST_ACCEPTED,l(a)),c.subscribe(f.CONTACT_REQUEST_DECLINED,l(a))},n=function(a){a.attr("data-contacts-init")||(m(a),a.attr("data-contacts-init",!0)),g.show(a,k,j)};return{show:n}});
|
1
message/amd/build/message_drawer_view_conversation.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_conversation.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
message/amd/build/message_drawer_view_conversation_constants.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_conversation_constants.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define([],function(){var a={ACTION_ACCEPT_CONTACT_REQUEST:'[data-action="accept-contact-request"]',ACTION_CANCEL_CONFIRM:'[data-action="cancel-confirm"]',ACTION_CANCEL_EDIT_MODE:'[data-action="cancel-edit-mode"]',ACTION_CONFIRM_ADD_CONTACT:'[data-action="confirm-add-contact"]',ACTION_CONFIRM_BLOCK:'[data-action="confirm-block"]',ACTION_CONFIRM_DELETE_SELECTED_MESSAGES:'[data-action="confirm-delete-selected-messages"]',ACTION_CONFIRM_DELETE_CONVERSATION:'[data-action="confirm-delete-conversation"]',ACTION_CONFIRM_FAVOURITE:'[data-action="confirm-favourite"]',ACTION_CONFIRM_UNFAVOURITE:'[data-action="confirm-unfavourite"]',ACTION_CONFIRM_REMOVE_CONTACT:'[data-action="confirm-remove-contact"]',ACTION_CONFIRM_UNBLOCK:'[data-action="confirm-unblock"]',ACTION_DECLINE_CONTACT_REQUEST:'[data-action="decline-contact-request"]',ACTION_REQUEST_ADD_CONTACT:'[data-action="request-add-contact"]',ACTION_REQUEST_BLOCK:'[data-action="request-block"]',ACTION_REQUEST_DELETE_CONVERSATION:'[data-action="request-delete-conversation"]',ACTION_REQUEST_DELETE_SELECTED_MESSAGES:'[data-action="delete-selected-messages"]',ACTION_REQUEST_REMOVE_CONTACT:'[data-action="request-remove-contact"]',ACTION_REQUEST_UNBLOCK:'[data-action="request-unblock"]',ACTION_VIEW_CONTACT:'[data-action="view-contact"]',ACTION_VIEW_GROUP_INFO:'[data-action="view-group-info"]',CAN_RECEIVE_FOCUS:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',CONFIRM_DIALOGUE_BUTTON_TEXT:'[data-region="dialogue-button-text"]',CONFIRM_DIALOGUE_CANCEL_BUTTON:'[data-action="cancel-confirm"]',CONFIRM_DIALOGUE_CONTAINER:'[data-region="confirm-dialogue-container"]',CONFIRM_DIALOGUE_HEADER:'[data-region="dialogue-header"]',CONFIRM_DIALOGUE_TEXT:'[data-region="dialogue-text"]',CONTACT_REQUEST_SENT_MESSAGE_CONTAINER:'[data-region="contact-request-sent-message-container"]',CONTENT_PLACEHOLDER_CONTAINER:'[data-region="content-placeholder"]',CONTENT_CONTAINER:'[data-region="content-container"]',CONTENT_MESSAGES_CONTAINER:'[data-region="content-message-container"]',CONTENT_MESSAGES_FOOTER_CONTAINER:'[data-region="content-messages-footer-container"]',CONTENT_MESSAGES_FOOTER_EDIT_MODE_CONTAINER:'[data-region="content-messages-footer-edit-mode-container"]',CONTENT_MESSAGES_FOOTER_REQUIRE_CONTACT_CONTAINER:'[data-region="content-messages-footer-require-contact-container"]',CONTENT_MESSAGES_FOOTER_REQUIRE_UNBLOCK_CONTAINER:'[data-region="content-messages-footer-require-unblock-container"]',CONTENT_MESSAGES_FOOTER_UNABLE_TO_MESSAGE_CONTAINER:'[data-region="content-messages-footer-unable-to-message"]',DAY_MESSAGES_CONTAINER:'[data-region="day-messages-container"]',FAVOURITE_ICON_CONTAINER:'[data-region="favourite-icon-container"]',FOOTER_CONTAINER:'[data-region="content-messages-footer-container"]',HEADER:'[data-region="header-content"]',HEADER_EDIT_MODE:'[data-region="header-edit-mode"]',HEADER_PLACEHOLDER_CONTAINER:'[data-region="header-placeholder"]',LOADING_ICON_CONTAINER:'[data-region="loading-icon-container"]',MESSAGE:'[data-region="message"]',MESSAGE_NOT_SELECTED:'[data-region="message"][aria-checked="false"]',MESSAGE_NOT_SELECTED_ICON:'[data-region="not-selected-icon"]',MESSAGE_SELECTED_ICON:'[data-region="selected-icon"]',MESSAGES:'[data-region="content-message-container"]',MESSAGES_CONTAINER:'[data-region="content-message-container"]',MESSAGES_SELECTED_COUNT:'[data-region="message-selected-court"]',MESSAGE_TEXT_AREA:'[data-region="send-message-txt"]',MORE_MESSAGES_LOADING_ICON_CONTAINER:'[data-region="more-messages-loading-icon-container"]',PLACEHOLDER_CONTAINER:'[data-region="placeholder-container"]',SEND_MESSAGE_BUTTON:'[data-action="send-message"]',SEND_MESSAGE_ICON_CONTAINER:'[data-region="send-icon-container"]',TEXT:'[data-region="text"]',TITLE:'[data-region="title"]'},b={HEADER_PRIVATE:"core_message/message_drawer_view_conversation_header_content_type_private",HEADER_PRIVATE_NO_CONTROLS:"core_message/message_drawer_view_conversation_header_content_type_private_no_controls",HEADER_PUBLIC:"core_message/message_drawer_view_conversation_header_content_type_public",DAY:"core_message/message_drawer_view_conversation_body_day",MESSAGE:"core_message/message_drawer_view_conversation_body_message",MESSAGES:"core_message/message_drawer_view_conversation_body_messages"},c={PRIVATE:1,PUBLIC:2};return{SELECTORS:a,TEMPLATES:b,CONVERSATION_TYPES:c,NEWEST_MESSAGES_FIRST:!0,LOAD_MESSAGE_LIMIT:100,INITIAL_NEW_MESSAGE_POLL_TIMEOUT:1e3}});
|
1
message/amd/build/message_drawer_view_conversation_patcher.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_conversation_patcher.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
message/amd/build/message_drawer_view_conversation_renderer.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_conversation_renderer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
message/amd/build/message_drawer_view_conversation_state_manager.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_conversation_state_manager.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
message/amd/build/message_drawer_view_group_info.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_group_info.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/str","core/templates","core_message/message_repository","core_message/message_drawer_lazy_load_list"],function(a,b,c,d,e){var f=50,g={CONTENT_CONTAINER:'[data-region="group-info-content-container"]',MEMBERS_LIST:'[data-region="members-list"]'},h={CONTENT:"core_message/message_drawer_view_group_info_body_content",MEMBERS_LIST:"core_message/message_drawer_view_group_info_participants_list"},i=function(a){return a.find(g.CONTENT_CONTAINER)},j=function(a,b,d){var e=b.totalMemberCount>50?50:b.totalMemberCount,f=Array.apply(null,Array(e)).map(function(){return!0}),g={name:b.name,subname:b.subname,imageurl:b.imageUrl,placeholders:f,loggedinuser:{id:d}};return c.render(h.CONTENT,g).then(function(b){return i(a).append(b),b})},k=function(a,b,c){return function(f,g){return d.getConversationMembers(a.id,g,b+1,c).then(function(a){return a.length>b?a=a.slice(0,-1):e.setLoadedAll(f,!0),c+=b,a})}},l=function(a,b){return c.render(h.MEMBERS_LIST,{contacts:b}).then(function(b){return a.append(b),b})},m=function(b,c,d){return b=a(b),i(b).empty(),j(b,c,d).then(function(){var a=e.getRoot(b);e.show(a,k(c,f,0),l)})},n=function(a,c){return b.get_string("messagedrawerviewgroupinfo","core_message",c.name)};return{show:m,description:n}});
|
1
message/amd/build/message_drawer_view_overview.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_overview.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/key_codes","core/pubsub","core/str","core_message/message_drawer_view_overview_section_favourites","core_message/message_drawer_view_overview_section_group_messages","core_message/message_drawer_view_overview_section_messages","core_message/message_drawer_router","core_message/message_drawer_routes","core_message/message_drawer_events"],function(a,b,c,d,e,f,g,h,i,j){var k={CONTACT_REQUEST_COUNT:'[data-region="contact-request-count"]',FAVOURITES:'[data-region="view-overview-favourites"]',GROUP_MESSAGES:'[data-region="view-overview-group-messages"]',MESSAGES:'[data-region="view-overview-messages"]',SEARCH_INPUT:'[data-region="view-overview-search-input"]'},l=function(a){return a.find(k.SEARCH_INPUT)},m=function(a){return function(){var b=a.find(k.CONTACT_REQUEST_COUNT),c=parseInt(b.text(),10);c=isNaN(c)?0:c-1,c<=0?b.addClass("hidden"):b.text(c)}},n=function(a){var d=l(a),e=[b.tab,b.shift,b.ctrl,b.alt];d.on("click",function(){h.go(i.VIEW_SEARCH)}),d.on("keydown",function(a){e.indexOf(a.keyCode)<0&&"Meta"!=a.key&&h.go(i.VIEW_SEARCH)}),c.subscribe(j.CONTACT_REQUEST_ACCEPTED,m(a)),c.subscribe(j.CONTACT_REQUEST_DECLINED,m(a))},o=function(b,c){return b.attr("data-init")||(n(b),b.attr("data-init",!0)),l(b).val(""),a.when(e.show(c.find(k.FAVOURITES)),f.show(c.find(k.GROUP_MESSAGES)),g.show(c.find(k.MESSAGES)))},p=function(){return d.get_string("messagedrawerviewoverview","core_message")};return{show:o,description:p}});
|
1
message/amd/build/message_drawer_view_overview_section.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_overview_section.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
message/amd/build/message_drawer_view_overview_section_favourites.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_overview_section_favourites.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core_message/message_drawer_view_overview_section"],function(a,b){var c=null,d=!0,e=function(e){b.show(a(e),c,d)};return{show:e}});
|
1
message/amd/build/message_drawer_view_overview_section_group_messages.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_overview_section_group_messages.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core_message/message_drawer_view_overview_section"],function(a,b){var c=2,d=!1,e=function(e){e=a(e),b.show(a(e),c,d)};return{show:e}});
|
1
message/amd/build/message_drawer_view_overview_section_messages.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_overview_section_messages.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core_message/message_drawer_view_overview_section"],function(a,b){var c=1,d=!1,e=function(e){b.show(a(e),c,d)};return{show:e}});
|
1
message/amd/build/message_drawer_view_search.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_search.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
message/amd/build/message_drawer_view_settings.min.js
vendored
Normal file
1
message/amd/build/message_drawer_view_settings.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
define(["jquery","core/notification","core/str","core_message/message_repository","core/custom_interaction_events"],function(a,b,c,d,e){var f={SETTINGS:'[data-region="settings"]',PREFERENCE_CONTROL:'[data-region="preference-control"]',PRIVACY_PREFERENCE:'[data-preference="blocknoncontacts"] input[type="radio"]',EMAIL_ENABLED_PREFERENCE:'[data-preference="emailnotifications"] input[type="checkbox"]'},g={message_provider_moodle_instantmessage_loggedoff:{type:"emailnotifications",enabled:"email",disabled:"none"},message_provider_moodle_instantmessage_loggedin:{type:"emailnotifications",enabled:"email",disabled:"none"}},h=function(c,h){var i=c.find(f.SETTINGS);e.define(i,[e.events.activate]),i.on(e.events.activate,f.EMAIL_ENABLED_PREFERENCE,function(c){var e=a(c.target),i=e.closest(f.PREFERENCE_CONTROL),j=i.attr("data-preference"),k=e.prop("checked"),l=Object.keys(g).reduce(function(a,b){var c=g[b];return c.type===j&&a.push({type:b,value:k?c.enabled:c.disabled}),a},[]);d.savePreferences(h,l)["catch"](b.exception)}),i.on(e.events.activate,f.PRIVACY_PREFERENCE,function(c){var e=a(c.target).val(),f=[{type:"message_blocknoncontacts",value:e}];d.savePreferences(h,f)["catch"](b.exception)})},i=function(b,c,d){return c.attr("data-init")||(h(c,d),c.attr("data-init",!0)),a.Deferred().resolve().promise()},j=function(){return c.get_string("messagedrawerviewsettings","core_message")};return{show:i,description:j}});
|
243
message/amd/src/message_drawer.js
Normal file
243
message/amd/src/message_drawer.js
Normal file
@ -0,0 +1,243 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/custom_interaction_events',
|
||||
'core/pubsub',
|
||||
'core_message/message_drawer_view_contact',
|
||||
'core_message/message_drawer_view_contacts',
|
||||
'core_message/message_drawer_view_conversation',
|
||||
'core_message/message_drawer_view_group_info',
|
||||
'core_message/message_drawer_view_overview',
|
||||
'core_message/message_drawer_view_search',
|
||||
'core_message/message_drawer_view_settings',
|
||||
'core_message/message_drawer_router',
|
||||
'core_message/message_drawer_routes',
|
||||
'core_message/message_drawer_events'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
CustomEvents,
|
||||
PubSub,
|
||||
ViewContact,
|
||||
ViewContacts,
|
||||
ViewConversation,
|
||||
ViewGroupInfo,
|
||||
ViewOverview,
|
||||
ViewSearch,
|
||||
ViewSettings,
|
||||
Router,
|
||||
Routes,
|
||||
Events
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
VIEW_CONTACT: '[data-region="view-contact"]',
|
||||
VIEW_CONTACTS: '[data-region="view-contacts"]',
|
||||
VIEW_CONVERSATION: '[data-region="view-conversation"]',
|
||||
VIEW_GROUP_INFO: '[data-region="view-group-info"]',
|
||||
VIEW_OVERVIEW: '[data-region="view-overview"]',
|
||||
VIEW_SEARCH: '[data-region="view-search"]',
|
||||
VIEW_SETTINGS: '[data-region="view-settings"]',
|
||||
ROUTES: '[data-route]',
|
||||
ROUTES_BACK: '[data-route-back]',
|
||||
HEADER_CONTAINER: '[data-region="header-container"]',
|
||||
BODY_CONTAINER: '[data-region="body-container"]',
|
||||
FOOTER_CONTAINER: '[data-region="footer-container"]',
|
||||
};
|
||||
|
||||
/**
|
||||
* Get elements for route.
|
||||
*
|
||||
* @param {Object} root The message drawer container.
|
||||
* @param {string} selector The route container.
|
||||
*
|
||||
* @return {array} elements Found route container objects.
|
||||
*/
|
||||
var getElementsForRoute = function(root, selector) {
|
||||
var candidates = root.children();
|
||||
var header = candidates.filter(SELECTORS.HEADER_CONTAINER).find(selector);
|
||||
var body = candidates.filter(SELECTORS.BODY_CONTAINER).find(selector);
|
||||
var footer = candidates.filter(SELECTORS.FOOTER_CONTAINER).find(selector);
|
||||
var elements = [header, body, footer].filter(function(element) {
|
||||
return element.length;
|
||||
});
|
||||
|
||||
return elements;
|
||||
};
|
||||
|
||||
var routes = [
|
||||
[Routes.VIEW_CONTACT, SELECTORS.VIEW_CONTACT, ViewContact.show, ViewContact.description],
|
||||
[Routes.VIEW_CONTACTS, SELECTORS.VIEW_CONTACTS, ViewContacts.show, ViewContacts.description],
|
||||
[Routes.VIEW_CONVERSATION, SELECTORS.VIEW_CONVERSATION, ViewConversation.show, ViewConversation.description],
|
||||
[Routes.VIEW_GROUP_INFO, SELECTORS.VIEW_GROUP_INFO, ViewGroupInfo.show, ViewGroupInfo.description],
|
||||
[Routes.VIEW_OVERVIEW, SELECTORS.VIEW_OVERVIEW, ViewOverview.show, ViewOverview.description],
|
||||
[Routes.VIEW_SEARCH, SELECTORS.VIEW_SEARCH, ViewSearch.show, ViewSearch.description],
|
||||
[Routes.VIEW_SETTINGS, SELECTORS.VIEW_SETTINGS, ViewSettings.show, ViewSettings.description],
|
||||
];
|
||||
|
||||
/**
|
||||
* Create routes.
|
||||
*
|
||||
* @param {Object} root The message drawer container.
|
||||
*/
|
||||
var createRoutes = function(root) {
|
||||
routes.forEach(function(route) {
|
||||
Router.add(route[0], getElementsForRoute(root, route[1]), route[2], route[3]);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the message drawer.
|
||||
*
|
||||
* @param {Object} root The message drawer container.
|
||||
*/
|
||||
var show = function(root) {
|
||||
if (!root.attr('data-shown')) {
|
||||
Router.go(Routes.VIEW_OVERVIEW);
|
||||
root.attr('data-shown', true);
|
||||
}
|
||||
|
||||
root.removeClass('hidden');
|
||||
root.attr('aria-expanded', true);
|
||||
root.attr('aria-hidden', false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the message drawer.
|
||||
*
|
||||
* @param {Object} root The message drawer container.
|
||||
*/
|
||||
var hide = function(root) {
|
||||
root.addClass('hidden');
|
||||
root.attr('aria-expanded', false);
|
||||
root.attr('aria-hidden', true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the drawer is visible.
|
||||
*
|
||||
* @param {Object} root The message drawer container.
|
||||
* @return {bool}
|
||||
*/
|
||||
var isVisible = function(root) {
|
||||
return !root.hasClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen to and handle events for routing, showing and hiding the message drawer.
|
||||
*
|
||||
* @param {Object} root The message drawer container.
|
||||
*/
|
||||
var registerEventListeners = function(root) {
|
||||
CustomEvents.define(root, [CustomEvents.events.activate]);
|
||||
var paramRegex = /^data-route-param-?(\d*)$/;
|
||||
|
||||
root.on(CustomEvents.events.activate, SELECTORS.ROUTES, function(e, data) {
|
||||
var element = $(e.target).closest(SELECTORS.ROUTES);
|
||||
var route = element.attr('data-route');
|
||||
var attributes = [];
|
||||
|
||||
for (var i = 0; i < element[0].attributes.length; i++) {
|
||||
attributes.push(element[0].attributes[i]);
|
||||
}
|
||||
|
||||
var paramAttributes = attributes.filter(function(attribute) {
|
||||
var name = attribute.nodeName;
|
||||
var match = paramRegex.test(name);
|
||||
return match;
|
||||
});
|
||||
paramAttributes.sort(function(a, b) {
|
||||
var aParts = paramRegex.exec(a.nodeName);
|
||||
var bParts = paramRegex.exec(b.nodeName);
|
||||
var aIndex = aParts.length > 1 ? aParts[1] : 0;
|
||||
var bIndex = bParts.length > 1 ? bParts[1] : 0;
|
||||
|
||||
if (aIndex < bIndex) {
|
||||
return -1;
|
||||
} else if (bIndex < aIndex) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
var params = paramAttributes.map(function(attribute) {
|
||||
return attribute.nodeValue;
|
||||
});
|
||||
var routeParams = [route].concat(params);
|
||||
|
||||
Router.go.apply(null, routeParams);
|
||||
|
||||
data.originalEvent.preventDefault();
|
||||
});
|
||||
|
||||
root.on(CustomEvents.events.activate, SELECTORS.ROUTES_BACK, function(e, data) {
|
||||
Router.back();
|
||||
|
||||
data.originalEvent.preventDefault();
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.SHOW, function() {
|
||||
show(root);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.HIDE, function() {
|
||||
hide(root);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.TOGGLE_VISIBILITY, function() {
|
||||
if (isVisible(root)) {
|
||||
hide(root);
|
||||
} else {
|
||||
show(root);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.SHOW_CONVERSATION, function(conversationId) {
|
||||
show(root);
|
||||
Router.go(Routes.VIEW_CONVERSATION, conversationId);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.SHOW_SETTINGS, function() {
|
||||
show(root);
|
||||
Router.go(Routes.VIEW_SETTINGS);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the message drawer.
|
||||
*
|
||||
* @param {Object} root The message drawer container.
|
||||
*/
|
||||
var init = function(root) {
|
||||
root = $(root);
|
||||
createRoutes(root);
|
||||
registerEventListeners(root);
|
||||
};
|
||||
|
||||
return {
|
||||
init: init,
|
||||
};
|
||||
});
|
45
message/amd/src/message_drawer_events.js
Normal file
45
message/amd/src/message_drawer_events.js
Normal file
@ -0,0 +1,45 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Events for the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_events
|
||||
* @package message
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define([], function() {
|
||||
return {
|
||||
CONTACT_BLOCKED: 'message-drawer-contact-blocked',
|
||||
CONTACT_UNBLOCKED: 'message-drawer-contact-unblocked',
|
||||
CONTACT_ADDED: 'message-drawer-contact-added',
|
||||
CONTACT_REMOVED: 'message-drawer-contact-removed',
|
||||
CONTACT_REQUEST_ACCEPTED: 'message-drawer-contact-request-accepted',
|
||||
CONTACT_REQUEST_DECLINED: 'message-drawer-contact-request-declined',
|
||||
CONVERSATION_CREATED: 'message-drawer-conversation-created',
|
||||
CONVERSATION_NEW_LAST_MESSAGE: 'message-drawer-conversation-new-last-message',
|
||||
CONVERSATION_DELETED: 'message-drawer-conversation-deleted',
|
||||
CONVERSATION_READ: 'message-drawer-conversation-read',
|
||||
CONVERSATION_SET_FAVOURITE: 'message-drawer-conversation-set-favourite',
|
||||
CONVERSATION_UNSET_FAVOURITE: 'message-drawer-conversation-unset-favourite',
|
||||
ROUTE_CHANGED: 'message-drawer-route-change',
|
||||
SHOW: 'message-drawer-show',
|
||||
HIDE: 'message-drawer-hide',
|
||||
TOGGLE_VISIBILITY: 'message-drawer-toggle',
|
||||
SHOW_CONVERSATION: 'message-drawer-show-conversation',
|
||||
SHOW_SETTINGS: 'message-drawer-show-settings',
|
||||
};
|
||||
});
|
62
message/amd/src/message_drawer_helper.js
Normal file
62
message/amd/src/message_drawer_helper.js
Normal file
@ -0,0 +1,62 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Provides some helper functions to trigger actions in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_helper
|
||||
* @package message
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'core/pubsub',
|
||||
'core_message/message_drawer_events'
|
||||
],
|
||||
function(
|
||||
PubSub,
|
||||
MessageDrawerEvents
|
||||
) {
|
||||
|
||||
/**
|
||||
* Trigger an event to show the message drawer.
|
||||
*/
|
||||
var show = function() {
|
||||
PubSub.publish(MessageDrawerEvents.SHOW);
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger an event to show the given conversation.
|
||||
*
|
||||
* @param {int} conversationId Id for the conversation to show.
|
||||
*/
|
||||
var showConversation = function(conversationId) {
|
||||
PubSub.publish(MessageDrawerEvents.SHOW_CONVERSATION, conversationId);
|
||||
};
|
||||
|
||||
/**
|
||||
* Trigger an event to show messaging settings.
|
||||
*/
|
||||
var showSettings = function() {
|
||||
PubSub.publish(MessageDrawerEvents.SHOW_SETTINGS);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
showConversation: showConversation,
|
||||
showSettings: showSettings
|
||||
};
|
||||
});
|
327
message/amd/src/message_drawer_lazy_load_list.js
Normal file
327
message/amd/src/message_drawer_lazy_load_list.js
Normal file
@ -0,0 +1,327 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Lazy loaded list of items.
|
||||
*
|
||||
* @module core_message/message_drawer_lazy_load_list
|
||||
* @package message
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/custom_interaction_events'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
CustomEvents
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
ROOT: '[data-region="lazy-load-list"]',
|
||||
LOADING_ICON_CONTAINER: '[data-region="loading-icon-container"]',
|
||||
CONTENT_CONTAINER: '[data-region="content-container"]',
|
||||
EMPTY_MESSAGE: '[data-region="empty-message-container"]',
|
||||
PLACEHOLDER: '[data-region="placeholder-container"]'
|
||||
};
|
||||
|
||||
/**
|
||||
* Flag element as loading.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var startLoading = function(root) {
|
||||
root.attr('data-loading', true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Flag element as not loading.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var stopLoading = function(root) {
|
||||
root.attr('data-loading', false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the element is loading.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @return {Bool}
|
||||
*/
|
||||
var isLoading = function(root) {
|
||||
return root.attr('data-loading') === 'true';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get user id
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @return {Number} Logged in user id.
|
||||
*/
|
||||
var getUserId = function(root) {
|
||||
return root.attr('data-user-id');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the section content container element.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @return {Object} The section content container element.
|
||||
*/
|
||||
var getContentContainer = function(root) {
|
||||
return root.find(SELECTORS.CONTENT_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the root element.
|
||||
*
|
||||
* @param {Object} containerElement The container element to search in.
|
||||
* @return {Object} The list root element.
|
||||
*/
|
||||
var getRoot = function(containerElement) {
|
||||
return containerElement.find(SELECTORS.ROOT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the loading icon.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var showLoadingIcon = function(root) {
|
||||
root.find(SELECTORS.LOADING_ICON_CONTAINER).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the loading icon.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var hideLoadingIcon = function(root) {
|
||||
root.find(SELECTORS.LOADING_ICON_CONTAINER).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the empty message.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var showEmptyMessage = function(root) {
|
||||
root.find(SELECTORS.EMPTY_MESSAGE).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the empty message.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var hideEmptyMessage = function(root) {
|
||||
root.find(SELECTORS.EMPTY_MESSAGE).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the placeholder element.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var showPlaceholder = function(root) {
|
||||
root.find(SELECTORS.PLACEHOLDER).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the placeholder element.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var hidePlaceholder = function(root) {
|
||||
root.find(SELECTORS.PLACEHOLDER).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the section content container.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var showContent = function(root) {
|
||||
getContentContainer(root).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the section content container.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var hideContent = function(root) {
|
||||
getContentContainer(root).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* If the section has loaded all content.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @return {Bool}
|
||||
*/
|
||||
var hasLoadedAll = function(root) {
|
||||
return root.attr('data-loaded-all') == 'true';
|
||||
};
|
||||
|
||||
/**
|
||||
* If the section has loaded all content.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @param {Bool} value If all items have been loaded.
|
||||
*/
|
||||
var setLoadedAll = function(root, value) {
|
||||
root.attr('data-loaded-all', value);
|
||||
};
|
||||
|
||||
/**
|
||||
* If the section can load more items.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @return {Bool}
|
||||
*/
|
||||
var canLoadMore = function(root) {
|
||||
return !hasLoadedAll(root) && !isLoading(root);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load all items in this container from callback and render them.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @param {Function} loadCallback The callback to load items.
|
||||
* @param {Function} renderCallback The callback to render the results.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var loadAndRender = function(root, loadCallback, renderCallback) {
|
||||
var userId = getUserId(root);
|
||||
startLoading(root);
|
||||
|
||||
return loadCallback(root, userId)
|
||||
.then(function(items) {
|
||||
if (items.length > 0) {
|
||||
var contentContainer = getContentContainer(root);
|
||||
return renderCallback(contentContainer, items, userId)
|
||||
.then(function() {
|
||||
return items;
|
||||
});
|
||||
} else {
|
||||
return items;
|
||||
}
|
||||
})
|
||||
.then(function(items) {
|
||||
stopLoading(root);
|
||||
root.attr('data-seen', true);
|
||||
|
||||
if (!items.length) {
|
||||
setLoadedAll(root, true);
|
||||
}
|
||||
|
||||
return items;
|
||||
})
|
||||
.catch(function() {
|
||||
stopLoading(root);
|
||||
root.attr('data-seen', true);
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* First load of this section.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @param {Function} loadCallback The callback to load items.
|
||||
* @param {Function} renderCallback The callback to render the results.
|
||||
* @return {Object} promise
|
||||
*/
|
||||
var initialLoadAndRender = function(root, loadCallback, renderCallback) {
|
||||
getContentContainer(root).empty();
|
||||
showPlaceholder(root);
|
||||
hideContent(root);
|
||||
return loadAndRender(root, loadCallback, renderCallback)
|
||||
.then(function(items) {
|
||||
hidePlaceholder(root);
|
||||
|
||||
if (!items.length) {
|
||||
showEmptyMessage(root);
|
||||
} else {
|
||||
showContent(root);
|
||||
}
|
||||
|
||||
return;
|
||||
})
|
||||
.catch(function() {
|
||||
hidePlaceholder(root);
|
||||
showContent(root);
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen to, and handle events in this section.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @param {Function} loadCallback The callback to load items.
|
||||
* @param {Function} renderCallback The callback to render the results.
|
||||
*/
|
||||
var registerEventListeners = function(root, loadCallback, renderCallback) {
|
||||
CustomEvents.define(root, [
|
||||
CustomEvents.events.scrollBottom
|
||||
]);
|
||||
|
||||
root.on(CustomEvents.events.scrollBottom, function() {
|
||||
if (canLoadMore(root)) {
|
||||
showLoadingIcon(root);
|
||||
loadAndRender(root, loadCallback, renderCallback)
|
||||
.then(function() {
|
||||
return hideLoadingIcon(root);
|
||||
})
|
||||
.catch(function() {
|
||||
return hideLoadingIcon(root);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the section.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @param {Function} loadCallback The callback to load items.
|
||||
* @param {Function} renderCallback The callback to render the results.
|
||||
*/
|
||||
var show = function(root, loadCallback, renderCallback) {
|
||||
root = $(root);
|
||||
|
||||
if (!root.attr('data-init')) {
|
||||
registerEventListeners(root, loadCallback, renderCallback);
|
||||
initialLoadAndRender(root, loadCallback, renderCallback);
|
||||
root.attr('data-init', true);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
getContentContainer: getContentContainer,
|
||||
getRoot: getRoot,
|
||||
setLoadedAll: setLoadedAll,
|
||||
showEmptyMessage: showEmptyMessage,
|
||||
hideEmptyMessage: hideEmptyMessage,
|
||||
showContent: showContent,
|
||||
hideContent: hideContent
|
||||
};
|
||||
});
|
225
message/amd/src/message_drawer_router.js
Normal file
225
message/amd/src/message_drawer_router.js
Normal file
@ -0,0 +1,225 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* A simple router for the message drawer that allows navigating between
|
||||
* the "pages" in the drawer.
|
||||
*
|
||||
* This module will maintain a linear history of the unique pages access
|
||||
* to allow navigating back.
|
||||
*
|
||||
* @module core_message/message_drawer_router
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/pubsub',
|
||||
'core/str',
|
||||
'core_message/message_drawer_events'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
PubSub,
|
||||
Str,
|
||||
MessageDrawerEvents
|
||||
) {
|
||||
|
||||
/* @var {object} routes Message drawer route elements and callbacks. */
|
||||
var routes = {};
|
||||
|
||||
/* @var {array} history Store for route objects history. */
|
||||
var history = [];
|
||||
|
||||
var SELECTORS = {
|
||||
CAN_RECEIVE_FOCUS: 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
|
||||
ROUTES_BACK: '[data-route-back]'
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a route.
|
||||
*
|
||||
* @param {string} route Route config name.
|
||||
* @param {array} elements Route container objects.
|
||||
* @param {callback} onGo Route initialization function.
|
||||
* @param {callback} getDescription Route initialization function.
|
||||
*/
|
||||
var add = function(route, elements, onGo, getDescription) {
|
||||
routes[route] = {
|
||||
elements: elements,
|
||||
onGo: onGo,
|
||||
getDescription: getDescription
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Go to a defined route and run the route callbacks.
|
||||
*
|
||||
* @param {string} newRoute Route config name.
|
||||
* @return {object} record Current route record with route config name and parameters.
|
||||
*/
|
||||
var changeRoute = function(newRoute) {
|
||||
var newConfig;
|
||||
// Get the rest of the arguments, if any.
|
||||
var args = [].slice.call(arguments, 1);
|
||||
var renderPromise = $.Deferred().resolve().promise();
|
||||
|
||||
Object.keys(routes).forEach(function(route) {
|
||||
var config = routes[route];
|
||||
var isMatch = route === newRoute;
|
||||
|
||||
if (isMatch) {
|
||||
newConfig = config;
|
||||
}
|
||||
|
||||
config.elements.forEach(function(element) {
|
||||
element.removeClass('previous');
|
||||
|
||||
if (isMatch) {
|
||||
element.removeClass('hidden');
|
||||
element.attr('aria-hidden', false);
|
||||
} else {
|
||||
element.addClass('hidden');
|
||||
element.attr('aria-hidden', true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (newConfig) {
|
||||
if (newConfig.onGo) {
|
||||
renderPromise = newConfig.onGo.apply(undefined, newConfig.elements.concat(args));
|
||||
var currentFocusElement = $(document.activeElement);
|
||||
var hasFocus = false;
|
||||
|
||||
for (var i = 0; i < newConfig.elements.length; i++) {
|
||||
var element = newConfig.elements[i];
|
||||
|
||||
if (element.has(currentFocusElement).length) {
|
||||
hasFocus = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasFocus) {
|
||||
// This page doesn't have focus yet so focus the first focusable
|
||||
// element in the new view.
|
||||
newConfig.elements[0].find(SELECTORS.CAN_RECEIVE_FOCUS).first().focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var record = {
|
||||
route: newRoute,
|
||||
params: args,
|
||||
renderPromise: renderPromise
|
||||
};
|
||||
|
||||
PubSub.publish(MessageDrawerEvents.ROUTE_CHANGED, record);
|
||||
|
||||
return record;
|
||||
};
|
||||
|
||||
/**
|
||||
* Go to a defined route and store the route history.
|
||||
*
|
||||
* @param {string} newRoute Route config name.
|
||||
* @return {object} record Current route record with route config name and parameters.
|
||||
*/
|
||||
var go = function() {
|
||||
var currentFocusElement = $(document.activeElement);
|
||||
var record = changeRoute.apply(null, arguments);
|
||||
var inHistory = false;
|
||||
// History stores a unique list of routes. Check to see if the new route
|
||||
// is already in the history, if it is then forget all history after it.
|
||||
// This ensures there are no duplicate routes in history and that it represents
|
||||
// a linear path of routes (it never stores something like [foo, bar, foo])/
|
||||
history = history.reduce(function(carry, previous) {
|
||||
if (previous.route === record.route) {
|
||||
inHistory = true;
|
||||
}
|
||||
|
||||
if (!inHistory) {
|
||||
carry.push(previous);
|
||||
}
|
||||
|
||||
return carry;
|
||||
}, []);
|
||||
|
||||
var previousRecord = history.length ? history[history.length - 1] : null;
|
||||
|
||||
if (previousRecord) {
|
||||
var prevConfig = routes[previousRecord.route];
|
||||
prevConfig.elements.forEach(function(element) {
|
||||
element.addClass('previous');
|
||||
});
|
||||
|
||||
previousRecord.focusElement = currentFocusElement;
|
||||
|
||||
if (prevConfig.getDescription) {
|
||||
// If the route has a description then set it on the back button for
|
||||
// the new page we're displaying.
|
||||
prevConfig.getDescription.apply(null, prevConfig.elements.concat(previousRecord.params))
|
||||
.then(function(description) {
|
||||
return Str.get_string('backto', 'core_message', description);
|
||||
})
|
||||
.then(function(label) {
|
||||
// Wait for the new page to finish rendering so that we know
|
||||
// that the back button is visible.
|
||||
return record.renderPromise.then(function() {
|
||||
// Find the elements for the new route we displayed.
|
||||
routes[record.route].elements.forEach(function(element) {
|
||||
// Update the aria label for the back button.
|
||||
element.find(SELECTORS.ROUTES_BACK).attr('aria-label', label);
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(function() {
|
||||
// Silently ignore.
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
history.push(record);
|
||||
return record;
|
||||
};
|
||||
|
||||
/**
|
||||
* Go back to the previous route record stored in history.
|
||||
*/
|
||||
var back = function() {
|
||||
if (history.length) {
|
||||
// Remove the current route.
|
||||
history.pop();
|
||||
var previous = history.pop();
|
||||
|
||||
if (previous) {
|
||||
// If we have a previous route then show it.
|
||||
go.apply(undefined, [previous.route].concat(previous.params));
|
||||
// Delay the focus 50 milliseconds otherwise it doesn't correctly
|
||||
// focus the element for some reason...
|
||||
window.setTimeout(function() {
|
||||
previous.focusElement.focus();
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
add: add,
|
||||
go: go,
|
||||
back: back
|
||||
};
|
||||
});
|
33
message/amd/src/message_drawer_routes.js
Normal file
33
message/amd/src/message_drawer_routes.js
Normal file
@ -0,0 +1,33 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Available routes for the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_routes
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define([], function() {
|
||||
return {
|
||||
VIEW_CONTACT: 'view-contact',
|
||||
VIEW_CONTACTS: 'view-contacts',
|
||||
VIEW_CONVERSATION: 'view-conversation',
|
||||
VIEW_GROUP_INFO: 'view-group-info',
|
||||
VIEW_OVERVIEW: 'view-overview',
|
||||
VIEW_SEARCH: 'view-search',
|
||||
VIEW_SETTINGS: 'view-settings'
|
||||
};
|
||||
});
|
97
message/amd/src/message_drawer_view_contact.js
Normal file
97
message/amd/src/message_drawer_view_contact.js
Normal file
@ -0,0 +1,97 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the contact page in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_contact
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/str',
|
||||
'core/templates'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Str,
|
||||
Templates
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
CONTENT_CONTAINER: '[data-region="content-container"]'
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
CONTENT: 'core_message/message_drawer_view_contact_body_content'
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the content container of the contact view container.
|
||||
*
|
||||
* @param {Object} root Contact container element.
|
||||
* @returns {Object} jQuery object
|
||||
*/
|
||||
var getContentContainer = function(root) {
|
||||
return root.find(SELECTORS.CONTENT_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the contact profile in the content container.
|
||||
*
|
||||
* @param {Object} root Contact container element.
|
||||
* @param {Object} profile Contact profile details.
|
||||
* @returns {Object} jQuery promise
|
||||
*/
|
||||
var render = function(root, profile) {
|
||||
return Templates.render(TEMPLATES.CONTENT, profile)
|
||||
.then(function(html) {
|
||||
getContentContainer(root).append(html);
|
||||
return html;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the contact page.
|
||||
*
|
||||
* @param {Object} root Contact container element.
|
||||
* @param {Object} contact The contact object.
|
||||
* @returns {Object} jQuery promise
|
||||
*/
|
||||
var show = function(root, contact) {
|
||||
root = $(root);
|
||||
|
||||
getContentContainer(root).empty();
|
||||
return render(root, contact);
|
||||
};
|
||||
|
||||
/**
|
||||
* String describing this page used for aria-labels.
|
||||
*
|
||||
* @param {Object} root Contact container element.
|
||||
* @param {Object} contact The contact object.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var description = function(root, contact) {
|
||||
return Str.get_string('messagedrawerviewcontact', 'core_message', contact.fullname);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
description: description
|
||||
};
|
||||
});
|
163
message/amd/src/message_drawer_view_contacts.js
Normal file
163
message/amd/src/message_drawer_view_contacts.js
Normal file
@ -0,0 +1,163 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the contacts page of the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_contacts
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/pubsub',
|
||||
'core/str',
|
||||
'core_message/message_drawer_events',
|
||||
'core_message/message_drawer_view_contacts_section_contacts',
|
||||
'core_message/message_drawer_view_contacts_section_requests'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
PubSub,
|
||||
Str,
|
||||
MessageDrawerEvents,
|
||||
ContactsSection,
|
||||
RequestsSection
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
ACTION_SHOW_CONTACTS_SECTION: '[data-action="show-contacts-section"]',
|
||||
ACTION_SHOW_REQUESTS_SECTION: '[data-action="show-requests-section"]',
|
||||
CONTACT_REQUEST_COUNT: '[data-region="contact-request-count"]',
|
||||
CONTACTS_SECTION_CONTAINER: '[data-section="contacts"]',
|
||||
REQUESTS_SECTION_CONTAINER: '[data-section="requests"]',
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the container element for the contacts section.
|
||||
*
|
||||
* @param {Object} body Contacts page body element.
|
||||
* @return {Object}
|
||||
*/
|
||||
var getContactsSectionContainer = function(body) {
|
||||
return body.find(SELECTORS.CONTACTS_SECTION_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the container element for the requests section.
|
||||
*
|
||||
* @param {Object} body Contacts page body element.
|
||||
* @return {Object}
|
||||
*/
|
||||
var getRequestsSectionContainer = function(body) {
|
||||
return body.find(SELECTORS.REQUESTS_SECTION_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given section is visible.
|
||||
*
|
||||
* @param {Object} sectionRoot The root element for the section
|
||||
* @return {Bool}
|
||||
*/
|
||||
var isSectionVisible = function(sectionRoot) {
|
||||
return sectionRoot.hasClass('active');
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrement the contact request count. If the count is zero or below then
|
||||
* hide the count.
|
||||
*
|
||||
* @param {Object} body Conversation body container element.
|
||||
* @return {Function} A function to handle decrementing the count.
|
||||
*/
|
||||
var decrementContactRequestCount = function(body) {
|
||||
return function() {
|
||||
var countContainer = body.find(SELECTORS.CONTACT_REQUEST_COUNT);
|
||||
var count = parseInt(countContainer.text(), 10);
|
||||
count = isNaN(count) ? 0 : count - 1;
|
||||
|
||||
if (count <= 0) {
|
||||
countContainer.addClass('hidden');
|
||||
} else {
|
||||
countContainer.text(count);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen to and handle events for contacts.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var registerEventListeners = function(body) {
|
||||
var contactsSection = getContactsSectionContainer(body);
|
||||
var requestsSection = getRequestsSectionContainer(body);
|
||||
var showContactsAction = body.find(SELECTORS.ACTION_SHOW_CONTACTS_SECTION);
|
||||
var showRequestsAction = body.find(SELECTORS.ACTION_SHOW_REQUESTS_SECTION);
|
||||
|
||||
showContactsAction.on('show.bs.tab', function() {
|
||||
ContactsSection.show(contactsSection);
|
||||
});
|
||||
|
||||
showRequestsAction.on('show.bs.tab', function() {
|
||||
RequestsSection.show(requestsSection);
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_ACCEPTED, decrementContactRequestCount(body));
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_DECLINED, decrementContactRequestCount(body));
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the contact page.
|
||||
*
|
||||
* @param {Object} header Contacts header container element.
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var show = function(header, body) {
|
||||
body = $(body);
|
||||
|
||||
if (!body.attr('data-contacts-init')) {
|
||||
registerEventListeners(body);
|
||||
body.attr('data-contacts-init', true);
|
||||
}
|
||||
|
||||
var contactsSection = getContactsSectionContainer(body);
|
||||
var requestsSection = getRequestsSectionContainer(body);
|
||||
|
||||
if (isSectionVisible(contactsSection)) {
|
||||
ContactsSection.show(contactsSection);
|
||||
} else {
|
||||
RequestsSection.show(requestsSection);
|
||||
}
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
/**
|
||||
* String describing this page used for aria-labels.
|
||||
*
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var description = function() {
|
||||
return Str.get_string('messagedrawerviewcontacts', 'core_message');
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
description: description
|
||||
};
|
||||
});
|
317
message/amd/src/message_drawer_view_contacts_section.js
Normal file
317
message/amd/src/message_drawer_view_contacts_section.js
Normal file
@ -0,0 +1,317 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls a section on the contacts page of the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_contacts_section
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/notification',
|
||||
'core/pubsub',
|
||||
'core/templates',
|
||||
'core/custom_interaction_events',
|
||||
'core_message/message_repository',
|
||||
'core_message/message_drawer_events'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Notification,
|
||||
PubSub,
|
||||
Templates,
|
||||
CustomEvents,
|
||||
MessageRepository,
|
||||
Events
|
||||
) {
|
||||
|
||||
var LOAD_CONTACTS_LIMIT = 100;
|
||||
|
||||
var numContacts = 0;
|
||||
var contactsOffset = 0;
|
||||
var loadedAllContacts = false;
|
||||
var waitForScrollLoad = false;
|
||||
|
||||
var SELECTORS = {
|
||||
BLOCK_ICON_CONTAINER: '[data-region="block-icon-container"]',
|
||||
CONTACTS: '[data-region="contacts-container"]',
|
||||
LOADING_ICON_CONTAINER: '[data-region="loading-icon-container"]',
|
||||
CONTENT_CONTAINER: '[data-region="contacts-content-container"]',
|
||||
EMPTY_MESSAGE: '[data-region="empty-message-container"]',
|
||||
PLACEHOLDER: '[data-region="placeholder-container"]'
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
CONTACTS_LIST: 'core_message/message_drawer_contacts_list'
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the loading icon.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var startLoading = function(body) {
|
||||
body.find(SELECTORS.LOADING_ICON_CONTAINER).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the loading icon.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var stopLoading = function(body) {
|
||||
body.find(SELECTORS.LOADING_ICON_CONTAINER).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the content container of the contacts body container element.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @return {Object} jQuery element
|
||||
*/
|
||||
var getContentContainer = function(body) {
|
||||
return body.find(SELECTORS.CONTENT_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the contacts container of the contacts body container element.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @return {Object} jQuery element
|
||||
*/
|
||||
var getContactsContainer = function(body) {
|
||||
return body.find(SELECTORS.CONTACTS);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show a message when no contacts found.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var showEmptyMessage = function(body) {
|
||||
getContentContainer(body).addClass('hidden');
|
||||
body.find(SELECTORS.EMPTY_MESSAGE).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the placeholder image.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var hidePlaceholder = function(body) {
|
||||
body.find(SELECTORS.PLACEHOLDER).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the content container.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var showContent = function(body) {
|
||||
getContentContainer(body).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a contact element.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId User id of contact.
|
||||
* @return {Object} contact element.
|
||||
*/
|
||||
var findContact = function(body, userId) {
|
||||
return body.find('[data-contact-user-id="' + userId + '"]');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get logged in userid.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @return {Number} Logged in userid.
|
||||
*/
|
||||
var getLoggedInUserId = function(body) {
|
||||
return body.attr('data-user-id');
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the contacts in the content container.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Array} contacts List of contacts.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var render = function(body, contacts) {
|
||||
var contentContainer = getContentContainer(body);
|
||||
return Templates.render(TEMPLATES.CONTACTS_LIST, {contacts: contacts})
|
||||
.then(function(html) {
|
||||
hidePlaceholder(body);
|
||||
contentContainer.append(html);
|
||||
showContent(body);
|
||||
return html;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the user contacts and call the renderer.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var loadContacts = function(body) {
|
||||
var userId = getLoggedInUserId(body);
|
||||
return MessageRepository.getContacts(userId, (LOAD_CONTACTS_LIMIT + 1), contactsOffset)
|
||||
.then(function(result) {
|
||||
return result.contacts;
|
||||
})
|
||||
.then(function(contacts) {
|
||||
if (contacts.length > LOAD_CONTACTS_LIMIT) {
|
||||
contacts.pop();
|
||||
} else {
|
||||
loadedAllContacts = true;
|
||||
}
|
||||
return contacts;
|
||||
})
|
||||
.then(function(contacts) {
|
||||
if (contactsOffset == 0 && contacts.length == 0) {
|
||||
hidePlaceholder(body);
|
||||
showEmptyMessage(body);
|
||||
}
|
||||
|
||||
numContacts = numContacts + contacts.length;
|
||||
|
||||
contactsOffset = contactsOffset + LOAD_CONTACTS_LIMIT;
|
||||
if (contacts.length > 0) {
|
||||
return render(body, contacts);
|
||||
}
|
||||
|
||||
return contacts;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove contact from view.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId Contact userid.
|
||||
*/
|
||||
var removeContact = function(body, userId) {
|
||||
findContact(body, userId).remove();
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the contact has been blocked.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId Contact userid.
|
||||
*/
|
||||
var showContactBlocked = function(body, userId) {
|
||||
var contact = findContact(body, userId);
|
||||
if (contact.length) {
|
||||
contact.find(SELECTORS.BLOCK_ICON_CONTAINER).removeClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the contact has been unblocked.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId Contact userid.
|
||||
*/
|
||||
var showContactUnblocked = function(body, userId) {
|
||||
var contact = findContact(body, userId);
|
||||
if (contact.length) {
|
||||
contact.find(SELECTORS.BLOCK_ICON_CONTAINER).addClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen to and handle events for contacts.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var registerEventListeners = function(body) {
|
||||
PubSub.subscribe(Events.CONTACT_ADDED, function() {
|
||||
contactsOffset = 0;
|
||||
loadedAllContacts = false;
|
||||
getContentContainer(body).empty();
|
||||
loadContacts(body);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_REMOVED, function(userId) {
|
||||
removeContact(body, userId);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_BLOCKED, function(userId) {
|
||||
showContactBlocked(body, userId);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_UNBLOCKED, function(userId) {
|
||||
showContactUnblocked(body, userId);
|
||||
});
|
||||
|
||||
var contactsContainer = getContactsContainer(body);
|
||||
|
||||
CustomEvents.define(contactsContainer, [
|
||||
CustomEvents.events.scrollBottom,
|
||||
CustomEvents.events.scrollLock
|
||||
]);
|
||||
|
||||
contactsContainer.on(CustomEvents.events.scrollBottom, function(e, data) {
|
||||
var hasContacts = numContacts > 1;
|
||||
if (!loadedAllContacts && hasContacts && !waitForScrollLoad) {
|
||||
waitForScrollLoad = true;
|
||||
startLoading(body);
|
||||
loadContacts(body)
|
||||
.then(function() {
|
||||
stopLoading(body);
|
||||
waitForScrollLoad = false;
|
||||
return;
|
||||
})
|
||||
.catch(function(error) {
|
||||
stopLoading(body);
|
||||
waitForScrollLoad = false;
|
||||
Notification.exception(error);
|
||||
});
|
||||
}
|
||||
data.originalEvent.preventDefault();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the contact page.
|
||||
*
|
||||
* @param {Object} header Contacts header container element.
|
||||
* @param {Object} body Contacts body container element.
|
||||
*/
|
||||
var show = function(header, body) {
|
||||
body = $(body);
|
||||
contactsOffset = 0;
|
||||
|
||||
if (!body.attr('data-contacts-init')) {
|
||||
registerEventListeners(body);
|
||||
body.attr('data-contacts-init', true);
|
||||
}
|
||||
|
||||
if (!loadedAllContacts) {
|
||||
loadContacts(body);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
};
|
||||
});
|
200
message/amd/src/message_drawer_view_contacts_section_contacts.js
Normal file
200
message/amd/src/message_drawer_view_contacts_section_contacts.js
Normal file
@ -0,0 +1,200 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the contacts section of the contacts page.
|
||||
*
|
||||
* @module core_message/message_drawer_view_contacts_section_contacts
|
||||
* @package message
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/notification',
|
||||
'core/pubsub',
|
||||
'core/templates',
|
||||
'core_message/message_repository',
|
||||
'core_message/message_drawer_events',
|
||||
'core_message/message_drawer_lazy_load_list'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Notification,
|
||||
PubSub,
|
||||
Templates,
|
||||
MessageRepository,
|
||||
Events,
|
||||
LazyLoadList
|
||||
) {
|
||||
|
||||
var limit = 100;
|
||||
var offset = 0;
|
||||
|
||||
var SELECTORS = {
|
||||
BLOCK_ICON_CONTAINER: '[data-region="block-icon-container"]',
|
||||
CONTACT: '[data-region="contact"]',
|
||||
CONTENT_CONTAINER: '[data-region="contacts-content-container"]'
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
CONTACTS_LIST: 'core_message/message_drawer_contacts_list'
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a contact element.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId User id of contact.
|
||||
* @return {Object} contact element.
|
||||
*/
|
||||
var findContact = function(body, userId) {
|
||||
return body.find('[data-contact-user-id="' + userId + '"]');
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the contacts in the content container.
|
||||
*
|
||||
* @param {Object} contentContainer Content container element.
|
||||
* @param {Array} contacts List of contacts.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var render = function(contentContainer, contacts) {
|
||||
var formattedContacts = contacts.map(function(contact) {
|
||||
return $.extend(contact, {id: contact.userid});
|
||||
});
|
||||
return Templates.render(TEMPLATES.CONTACTS_LIST, {contacts: formattedContacts})
|
||||
.then(function(html) {
|
||||
contentContainer.append(html);
|
||||
return html;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the user contacts and call the renderer.
|
||||
*
|
||||
* @param {Object} listRoot The lazy loaded list root element
|
||||
* @param {Integer} userId The logged in user id.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var load = function(listRoot, userId) {
|
||||
return MessageRepository.getContacts(userId, (limit + 1), offset)
|
||||
.then(function(result) {
|
||||
return result.contacts;
|
||||
})
|
||||
.then(function(contacts) {
|
||||
if (contacts.length > limit) {
|
||||
contacts.pop();
|
||||
} else {
|
||||
LazyLoadList.setLoadedAll(listRoot, true);
|
||||
}
|
||||
return contacts;
|
||||
})
|
||||
.then(function(contacts) {
|
||||
offset = offset + limit;
|
||||
return contacts;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove contact from view.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId Contact userid.
|
||||
*/
|
||||
var removeContact = function(body, userId) {
|
||||
findContact(body, userId).remove();
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the contact has been blocked.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId Contact userid.
|
||||
*/
|
||||
var showContactBlocked = function(body, userId) {
|
||||
var contact = findContact(body, userId);
|
||||
if (contact.length) {
|
||||
contact.find(SELECTORS.BLOCK_ICON_CONTAINER).removeClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the contact has been unblocked.
|
||||
*
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @param {Number} userId Contact userid.
|
||||
*/
|
||||
var showContactUnblocked = function(body, userId) {
|
||||
var contact = findContact(body, userId);
|
||||
if (contact.length) {
|
||||
contact.find(SELECTORS.BLOCK_ICON_CONTAINER).addClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen to and handle events for contacts.
|
||||
*
|
||||
* @param {Object} root Contacts section container element.
|
||||
*/
|
||||
var registerEventListeners = function(root) {
|
||||
PubSub.subscribe(Events.CONTACT_ADDED, function(profile) {
|
||||
var listContentContainer = LazyLoadList.getContentContainer(root);
|
||||
render(listContentContainer, [profile]);
|
||||
LazyLoadList.hideEmptyMessage(root);
|
||||
LazyLoadList.showContent(root);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_REMOVED, function(userId) {
|
||||
removeContact(root, userId);
|
||||
var contacts = root.find(SELECTORS.CONTACT);
|
||||
|
||||
if (!contacts.length) {
|
||||
LazyLoadList.hideContent(root);
|
||||
LazyLoadList.showEmptyMessage(root);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_BLOCKED, function(userId) {
|
||||
showContactBlocked(root, userId);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_UNBLOCKED, function(userId) {
|
||||
showContactUnblocked(root, userId);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the contacts section.
|
||||
*
|
||||
* @param {Object} root Contacts section container.
|
||||
*/
|
||||
var show = function(root) {
|
||||
if (!root.attr('data-contacts-init')) {
|
||||
registerEventListeners(root);
|
||||
root.attr('data-contacts-init', true);
|
||||
}
|
||||
|
||||
// The root element is already the lazy loaded list root.
|
||||
LazyLoadList.show(root, load, render);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
};
|
||||
});
|
139
message/amd/src/message_drawer_view_contacts_section_requests.js
Normal file
139
message/amd/src/message_drawer_view_contacts_section_requests.js
Normal file
@ -0,0 +1,139 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the requests section of the contacts page.
|
||||
*
|
||||
* @module core_message/message_drawer_view_contacts_section_requests
|
||||
* @package message
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/notification',
|
||||
'core/pubsub',
|
||||
'core/templates',
|
||||
'core_message/message_repository',
|
||||
'core_message/message_drawer_events',
|
||||
'core_message/message_drawer_lazy_load_list'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Notification,
|
||||
PubSub,
|
||||
Templates,
|
||||
MessageRepository,
|
||||
MessageDrawerEvents,
|
||||
LazyLoadList
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
CONTACT_REQUEST: '[data-region="contact-request"]'
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
REQUESTS_LIST: 'core_message/message_drawer_view_contacts_body_section_requests_list'
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the requests in the content container.
|
||||
*
|
||||
* @param {Object} contentContainer List container element.
|
||||
* @param {Array} requests List of requests.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var render = function(contentContainer, requests) {
|
||||
var formattedRequests = requests.map(function(request) {
|
||||
return {
|
||||
// This is actually the user id.
|
||||
id: request.id,
|
||||
profileimageurl: request.profileimageurl,
|
||||
fullname: request.fullname
|
||||
};
|
||||
});
|
||||
return Templates.render(TEMPLATES.REQUESTS_LIST, {requests: formattedRequests})
|
||||
.then(function(html) {
|
||||
contentContainer.append(html);
|
||||
return html;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load the user contacts and call the renderer.
|
||||
*
|
||||
* @param {Object} listRoot The lazy loaded list root element
|
||||
* @param {Integer} userId The logged in user id.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var load = function(listRoot, userId) {
|
||||
return MessageRepository.getContactRequests(userId)
|
||||
.then(function(requests) {
|
||||
LazyLoadList.setLoadedAll(listRoot, true);
|
||||
return requests;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle when a contact request is accepted or declined by removing the contact
|
||||
* list from the page.
|
||||
*
|
||||
* @param {Object} root The section root element
|
||||
* @return {Function} The event handler function
|
||||
*/
|
||||
var handleContactRequestProcessed = function(root) {
|
||||
return function(request) {
|
||||
root.find('[data-request-id="' + request.userid + '"]').remove();
|
||||
var contactRequests = root.find(SELECTORS.CONTACT_REQUEST);
|
||||
|
||||
if (!contactRequests.length) {
|
||||
LazyLoadList.showEmptyMessage(root);
|
||||
LazyLoadList.hideContent(root);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen for any events that might affect the requests section.
|
||||
*
|
||||
* @param {Object} root The section root element
|
||||
*/
|
||||
var registerEventListeners = function(root) {
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_ACCEPTED, handleContactRequestProcessed(root));
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_DECLINED, handleContactRequestProcessed(root));
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the requests section.
|
||||
*
|
||||
* @param {Object} root Requests section container.
|
||||
*/
|
||||
var show = function(root) {
|
||||
if (!root.attr('data-contacts-init')) {
|
||||
registerEventListeners(root);
|
||||
root.attr('data-contacts-init', true);
|
||||
}
|
||||
|
||||
// The root element is already the lazy loaded list root.
|
||||
LazyLoadList.show(root, load, render);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
};
|
||||
});
|
1564
message/amd/src/message_drawer_view_conversation.js
Normal file
1564
message/amd/src/message_drawer_view_conversation.js
Normal file
File diff suppressed because it is too large
Load Diff
106
message/amd/src/message_drawer_view_conversation_constants.js
Normal file
106
message/amd/src/message_drawer_view_conversation_constants.js
Normal file
@ -0,0 +1,106 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Constant values for the conversation page in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_conversation_constants
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define([], function() {
|
||||
|
||||
var SELECTORS = {
|
||||
ACTION_ACCEPT_CONTACT_REQUEST: '[data-action="accept-contact-request"]',
|
||||
ACTION_CANCEL_CONFIRM: '[data-action="cancel-confirm"]',
|
||||
ACTION_CANCEL_EDIT_MODE: '[data-action="cancel-edit-mode"]',
|
||||
ACTION_CONFIRM_ADD_CONTACT: '[data-action="confirm-add-contact"]',
|
||||
ACTION_CONFIRM_BLOCK: '[data-action="confirm-block"]',
|
||||
ACTION_CONFIRM_DELETE_SELECTED_MESSAGES: '[data-action="confirm-delete-selected-messages"]',
|
||||
ACTION_CONFIRM_DELETE_CONVERSATION: '[data-action="confirm-delete-conversation"]',
|
||||
ACTION_CONFIRM_FAVOURITE: '[data-action="confirm-favourite"]',
|
||||
ACTION_CONFIRM_UNFAVOURITE: '[data-action="confirm-unfavourite"]',
|
||||
ACTION_CONFIRM_REMOVE_CONTACT: '[data-action="confirm-remove-contact"]',
|
||||
ACTION_CONFIRM_UNBLOCK: '[data-action="confirm-unblock"]',
|
||||
ACTION_DECLINE_CONTACT_REQUEST: '[data-action="decline-contact-request"]',
|
||||
ACTION_REQUEST_ADD_CONTACT: '[data-action="request-add-contact"]',
|
||||
ACTION_REQUEST_BLOCK: '[data-action="request-block"]',
|
||||
ACTION_REQUEST_DELETE_CONVERSATION: '[data-action="request-delete-conversation"]',
|
||||
ACTION_REQUEST_DELETE_SELECTED_MESSAGES: '[data-action="delete-selected-messages"]',
|
||||
ACTION_REQUEST_REMOVE_CONTACT: '[data-action="request-remove-contact"]',
|
||||
ACTION_REQUEST_UNBLOCK: '[data-action="request-unblock"]',
|
||||
ACTION_VIEW_CONTACT: '[data-action="view-contact"]',
|
||||
ACTION_VIEW_GROUP_INFO: '[data-action="view-group-info"]',
|
||||
CAN_RECEIVE_FOCUS: 'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',
|
||||
CONFIRM_DIALOGUE_BUTTON_TEXT: '[data-region="dialogue-button-text"]',
|
||||
CONFIRM_DIALOGUE_CANCEL_BUTTON: '[data-action="cancel-confirm"]',
|
||||
CONFIRM_DIALOGUE_CONTAINER: '[data-region="confirm-dialogue-container"]',
|
||||
CONFIRM_DIALOGUE_HEADER: '[data-region="dialogue-header"]',
|
||||
CONFIRM_DIALOGUE_TEXT: '[data-region="dialogue-text"]',
|
||||
CONTACT_REQUEST_SENT_MESSAGE_CONTAINER: '[data-region="contact-request-sent-message-container"]',
|
||||
CONTENT_PLACEHOLDER_CONTAINER: '[data-region="content-placeholder"]',
|
||||
CONTENT_CONTAINER: '[data-region="content-container"]',
|
||||
CONTENT_MESSAGES_CONTAINER: '[data-region="content-message-container"]',
|
||||
CONTENT_MESSAGES_FOOTER_CONTAINER: '[data-region="content-messages-footer-container"]',
|
||||
CONTENT_MESSAGES_FOOTER_EDIT_MODE_CONTAINER: '[data-region="content-messages-footer-edit-mode-container"]',
|
||||
CONTENT_MESSAGES_FOOTER_REQUIRE_CONTACT_CONTAINER: '[data-region="content-messages-footer-require-contact-container"]',
|
||||
CONTENT_MESSAGES_FOOTER_REQUIRE_UNBLOCK_CONTAINER: '[data-region="content-messages-footer-require-unblock-container"]',
|
||||
CONTENT_MESSAGES_FOOTER_UNABLE_TO_MESSAGE_CONTAINER: '[data-region="content-messages-footer-unable-to-message"]',
|
||||
DAY_MESSAGES_CONTAINER: '[data-region="day-messages-container"]',
|
||||
FAVOURITE_ICON_CONTAINER: '[data-region="favourite-icon-container"]',
|
||||
FOOTER_CONTAINER: '[data-region="content-messages-footer-container"]',
|
||||
HEADER: '[data-region="header-content"]',
|
||||
HEADER_EDIT_MODE: '[data-region="header-edit-mode"]',
|
||||
HEADER_PLACEHOLDER_CONTAINER: '[data-region="header-placeholder"]',
|
||||
LOADING_ICON_CONTAINER: '[data-region="loading-icon-container"]',
|
||||
MESSAGE: '[data-region="message"]',
|
||||
MESSAGE_NOT_SELECTED: '[data-region="message"][aria-checked="false"]',
|
||||
MESSAGE_NOT_SELECTED_ICON: '[data-region="not-selected-icon"]',
|
||||
MESSAGE_SELECTED_ICON: '[data-region="selected-icon"]',
|
||||
MESSAGES: '[data-region="content-message-container"]',
|
||||
MESSAGES_CONTAINER: '[data-region="content-message-container"]',
|
||||
MESSAGES_SELECTED_COUNT: '[data-region="message-selected-court"]',
|
||||
MESSAGE_TEXT_AREA: '[data-region="send-message-txt"]',
|
||||
MORE_MESSAGES_LOADING_ICON_CONTAINER: '[data-region="more-messages-loading-icon-container"]',
|
||||
PLACEHOLDER_CONTAINER: '[data-region="placeholder-container"]',
|
||||
SEND_MESSAGE_BUTTON: '[data-action="send-message"]',
|
||||
SEND_MESSAGE_ICON_CONTAINER: '[data-region="send-icon-container"]',
|
||||
TEXT: '[data-region="text"]',
|
||||
TITLE: '[data-region="title"]'
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
HEADER_PRIVATE: 'core_message/message_drawer_view_conversation_header_content_type_private',
|
||||
HEADER_PRIVATE_NO_CONTROLS: 'core_message/message_drawer_view_conversation_header_content_type_private_no_controls',
|
||||
HEADER_PUBLIC: 'core_message/message_drawer_view_conversation_header_content_type_public',
|
||||
DAY: 'core_message/message_drawer_view_conversation_body_day',
|
||||
MESSAGE: 'core_message/message_drawer_view_conversation_body_message',
|
||||
MESSAGES: 'core_message/message_drawer_view_conversation_body_messages'
|
||||
};
|
||||
|
||||
var CONVERSATION_TYPES = {
|
||||
PRIVATE: 1,
|
||||
PUBLIC: 2
|
||||
};
|
||||
|
||||
return {
|
||||
SELECTORS: SELECTORS,
|
||||
TEMPLATES: TEMPLATES,
|
||||
CONVERSATION_TYPES: CONVERSATION_TYPES,
|
||||
NEWEST_MESSAGES_FIRST: true,
|
||||
LOAD_MESSAGE_LIMIT: 100,
|
||||
INITIAL_NEW_MESSAGE_POLL_TIMEOUT: 1000
|
||||
};
|
||||
});
|
1160
message/amd/src/message_drawer_view_conversation_patcher.js
Normal file
1160
message/amd/src/message_drawer_view_conversation_patcher.js
Normal file
File diff suppressed because it is too large
Load Diff
1518
message/amd/src/message_drawer_view_conversation_renderer.js
Normal file
1518
message/amd/src/message_drawer_view_conversation_renderer.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,651 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* This module operates on the view states from the message_drawer_view_conversation module.
|
||||
* It exposes functions that can be used to generate new version of the state.
|
||||
*
|
||||
* Important notes for this module:
|
||||
* 1.) The existing state is always immutable. It should never be modified.
|
||||
* 2.) All functions that operate on the state should always clone the state and
|
||||
* modify the cloned state before returning it.
|
||||
*
|
||||
* It's important that the states remain immutable because they are diff'd in
|
||||
* the message_drawer_view_conversation_patcher module in order to work out what
|
||||
* has changed.
|
||||
*
|
||||
* @module core_message/message_drawer_view_conversation_state_manager
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(['jquery'], function($) {
|
||||
|
||||
/**
|
||||
* Clone a state, a state is a collection of information about the variables required to build
|
||||
* the conversation user interface.
|
||||
*
|
||||
* @param {Object} state State to clone
|
||||
* @return {Object} newstate A copy of the state to clone.
|
||||
*/
|
||||
var cloneState = function(state) {
|
||||
var newState = $.extend({}, state);
|
||||
newState.messages = state.messages.map(function(message) {
|
||||
return $.extend({}, message);
|
||||
});
|
||||
newState.members = Object.keys(state.members).reduce(function(carry, id) {
|
||||
carry[id] = $.extend({}, state.members[id]);
|
||||
carry[id].contactrequests = state.members[id].contactrequests.map(function(request) {
|
||||
return $.extend({}, request);
|
||||
});
|
||||
return carry;
|
||||
}, {});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Format messages to be used in a state.
|
||||
*
|
||||
* @param {Array} messages The messages to format.
|
||||
* @param {Number} loggedInUserId The logged in user id.
|
||||
* @param {Array} members The converstation members.
|
||||
* @return {Array} Formatted messages.
|
||||
*/
|
||||
var formatMessages = function(messages, loggedInUserId, members) {
|
||||
return messages.map(function(message) {
|
||||
var fromLoggedInUser = message.useridfrom == loggedInUserId;
|
||||
return {
|
||||
id: parseInt(message.id, 10),
|
||||
isRead: message.isread,
|
||||
fromLoggedInUser: fromLoggedInUser,
|
||||
userFrom: members[message.useridfrom],
|
||||
text: message.text,
|
||||
timeCreated: parseInt(message.timecreated, 10)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an initial (blank) state.
|
||||
*
|
||||
* @param {Number} midnight Midnight time.
|
||||
* @param {Number} loggedInUserId The logged in user id.
|
||||
* @param {Number} id The conversation id.
|
||||
* @return {Object} Initial state.
|
||||
*/
|
||||
var buildInitialState = function(midnight, loggedInUserId, id) {
|
||||
return {
|
||||
midnight: midnight,
|
||||
loggedInUserId: loggedInUserId,
|
||||
id: id,
|
||||
name: null,
|
||||
subname: null,
|
||||
type: null,
|
||||
totalMemberCount: null,
|
||||
imageUrl: null,
|
||||
isFavourite: null,
|
||||
members: {},
|
||||
messages: [],
|
||||
hasTriedToLoadMessages: false,
|
||||
loadingMessages: true,
|
||||
sendingMessage: false,
|
||||
loadingMembers: true,
|
||||
loadingConfirmAction: false,
|
||||
pendingBlockUserIds: [],
|
||||
pendingUnblockUserIds: [],
|
||||
pendingRemoveContactIds: [],
|
||||
pendingAddContactIds: [],
|
||||
pendingDeleteMessageIds: [],
|
||||
pendingDeleteConversation: false,
|
||||
selectedMessageIds: []
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Add messages to a state and sort them by timecreated.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} messages Messages to add to state.
|
||||
* @return {Object} state New state with added messages.
|
||||
*/
|
||||
var addMessages = function(state, messages) {
|
||||
var newState = cloneState(state);
|
||||
var formattedMessages = formatMessages(messages, state.loggedInUserId, state.members);
|
||||
var allMessages = state.messages.concat(formattedMessages);
|
||||
// Sort the messages. Oldest to newest.
|
||||
allMessages.sort(function(a, b) {
|
||||
if (a.timeCreated < b.timeCreated) {
|
||||
return -1;
|
||||
} else if (a.timeCreated > b.timeCreated) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
// Filter out any duplicate messages.
|
||||
newState.messages = allMessages.filter(function(message, index, sortedMessages) {
|
||||
return !index || message.id !== sortedMessages[index - 1].id;
|
||||
});
|
||||
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove messages from state.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} messages Messages to remove from state.
|
||||
* @return {Object} state New state with removed messages.
|
||||
*/
|
||||
var removeMessages = function(state, messages) {
|
||||
var newState = cloneState(state);
|
||||
var removeMessageIds = messages.map(function(message) {
|
||||
return message.id;
|
||||
});
|
||||
newState.messages = newState.messages.filter(function(message) {
|
||||
return removeMessageIds.indexOf(message.id) < 0;
|
||||
});
|
||||
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove messages from state by message id.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} messagesIds Message ids to remove from state.
|
||||
* @return {Object} state New state with removed messages.
|
||||
*/
|
||||
var removeMessagesById = function(state, messagesIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.messages = newState.messages.filter(function(message) {
|
||||
return messagesIds.indexOf(message.id) < 0;
|
||||
});
|
||||
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add conversation member to state.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} members Conversation members to be added to state.
|
||||
* @return {Object} New state with added members.
|
||||
*/
|
||||
var addMembers = function(state, members) {
|
||||
var newState = cloneState(state);
|
||||
members.forEach(function(member) {
|
||||
newState.members[member.id] = member;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove members from state.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} members Members to be removed from state.
|
||||
* @return {Object} New state with removed members.
|
||||
*/
|
||||
var removeMembers = function(state, members) {
|
||||
var newState = cloneState(state);
|
||||
members.forEach(function(member) {
|
||||
delete newState.members[member.id];
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state loading messages attribute.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Bool} value New loading messages value.
|
||||
* @return {Object} New state with loading messages attribute.
|
||||
*/
|
||||
var setLoadingMessages = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.loadingMessages = value;
|
||||
if (state.loadingMessages && !value) {
|
||||
// If we're going from loading to not loading then
|
||||
// it means we've tried to load.
|
||||
newState.hasTriedToLoadMessages = true;
|
||||
}
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state sending message attribute.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Bool} value New sending message value.
|
||||
* @return {Object} New state with sending message attribute.
|
||||
*/
|
||||
var setSendingMessage = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.sendingMessage = value;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state loading members attribute.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Bool} value New loading members value.
|
||||
* @return {Object} New state with loading members attribute.
|
||||
*/
|
||||
var setLoadingMembers = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.loadingMembers = value;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the conversation id.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {String} value The ID.
|
||||
* @return {Object} New state.
|
||||
*/
|
||||
var setId = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.id = value;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state name attribute.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {String} value New name value.
|
||||
* @return {Object} New state with name attribute.
|
||||
*/
|
||||
var setName = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.name = value;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state subname attribute.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {String} value New subname value.
|
||||
* @return {Object} New state.
|
||||
*/
|
||||
var setSubname = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.subname = value;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the conversation type.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Int} type Conversation type.
|
||||
* @return {Object} New state.
|
||||
*/
|
||||
var setType = function(state, type) {
|
||||
var newState = cloneState(state);
|
||||
newState.type = type;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether the conversation is a favourite conversation.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Bool} isFavourite If it's a favourite.
|
||||
* @return {Object} New state.
|
||||
*/
|
||||
var setIsFavourite = function(state, isFavourite) {
|
||||
var newState = cloneState(state);
|
||||
newState.isFavourite = isFavourite;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the total member count.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {String} count The count.
|
||||
* @return {Object} New state.
|
||||
*/
|
||||
var setTotalMemberCount = function(state, count) {
|
||||
var newState = cloneState(state);
|
||||
newState.totalMemberCount = count;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the conversation image url.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {String} url The url to the image.
|
||||
* @return {Object} New state.
|
||||
*/
|
||||
var setImageUrl = function(state, url) {
|
||||
var newState = cloneState(state);
|
||||
newState.imageUrl = url;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state loading confirm action attribute.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Bool} value New loading confirm action value.
|
||||
* @return {Object} New state with loading confirm action attribute.
|
||||
*/
|
||||
var setLoadingConfirmAction = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.loadingConfirmAction = value;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state pending delete conversation attribute.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Bool} value New pending delete conversation value.
|
||||
* @return {Object} New state with pending delete conversation attribute.
|
||||
*/
|
||||
var setPendingDeleteConversation = function(state, value) {
|
||||
var newState = cloneState(state);
|
||||
newState.pendingDeleteConversation = value;
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state pending block userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to block.
|
||||
* @return {Object} New state with array of pending block userids.
|
||||
*/
|
||||
var addPendingBlockUsersById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
userIds.forEach(function(id) {
|
||||
newState.pendingBlockUserIds.push(id);
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state pending remove userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to remove.
|
||||
* @return {Object} New state with array of pending remove userids.
|
||||
*/
|
||||
var addPendingRemoveContactsById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
userIds.forEach(function(id) {
|
||||
newState.pendingRemoveContactIds.push(id);
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state pending unblock userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to unblock.
|
||||
* @return {Object} New state with array of pending unblock userids.
|
||||
*/
|
||||
var addPendingUnblockUsersById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
userIds.forEach(function(id) {
|
||||
newState.pendingUnblockUserIds.push(id);
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state pending add users to contacts userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to add users to contacts.
|
||||
* @return {Object} New state with array of pending add users to contacts userids.
|
||||
*/
|
||||
var addPendingAddContactsById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
userIds.forEach(function(id) {
|
||||
newState.pendingAddContactIds.push(id);
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the state pending delete messages.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} messageIds Messages to delete.
|
||||
* @return {Object} New state with array of pending delete message ids.
|
||||
*/
|
||||
var addPendingDeleteMessagesById = function(state, messageIds) {
|
||||
var newState = cloneState(state);
|
||||
messageIds.forEach(function(id) {
|
||||
newState.pendingDeleteMessageIds.push(id);
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the state pending block userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to remove from the list of user ids to block.
|
||||
* @return {Object} New state with array of pending block userids.
|
||||
*/
|
||||
var removePendingBlockUsersById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.pendingBlockUserIds = newState.pendingBlockUserIds.filter(function(id) {
|
||||
return userIds.indexOf(id) < 0;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the state pending remove userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to remove from the list of user ids to remove.
|
||||
* @return {Object} New state with array of pending remove userids.
|
||||
*/
|
||||
var removePendingRemoveContactsById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.pendingRemoveContactIds = newState.pendingRemoveContactIds.filter(function(id) {
|
||||
return userIds.indexOf(id) < 0;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the state pending unblock userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to remove from the list of user ids to unblock.
|
||||
* @return {Object} New state with array of pending unblock userids.
|
||||
*/
|
||||
var removePendingUnblockUsersById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.pendingUnblockUserIds = newState.pendingUnblockUserIds.filter(function(id) {
|
||||
return userIds.indexOf(id) < 0;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the state pending add to contacts userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} userIds User ids to remove from the list of user ids to add to contacts.
|
||||
* @return {Object} New state with array of pending add to contacts userids.
|
||||
*/
|
||||
var removePendingAddContactsById = function(state, userIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.pendingAddContactIds = newState.pendingAddContactIds.filter(function(id) {
|
||||
return userIds.indexOf(id) < 0;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the state pending delete messages userids.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} messageIds Message ids to remove from the list of messages to delete.
|
||||
* @return {Object} New state with array of messages to delete.
|
||||
*/
|
||||
var removePendingDeleteMessagesById = function(state, messageIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.pendingDeleteMessageIds = newState.pendingDeleteMessageIds.filter(function(id) {
|
||||
return messageIds.indexOf(id) < 0;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add messages to state selected messages.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} messageIds Messages that are selected.
|
||||
* @return {Object} New state with array of not blocked members.
|
||||
*/
|
||||
var addSelectedMessagesById = function(state, messageIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.selectedMessageIds = newState.selectedMessageIds.concat(messageIds);
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove messages from the state selected messages.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} messageIds Messages to remove from selected messages.
|
||||
* @return {Object} New state with array of selected messages.
|
||||
*/
|
||||
var removeSelectedMessagesById = function(state, messageIds) {
|
||||
var newState = cloneState(state);
|
||||
newState.selectedMessageIds = newState.selectedMessageIds.filter(function(id) {
|
||||
return messageIds.indexOf(id) < 0;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark messages as read.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} readMessages Messages that are read.
|
||||
* @return {Object} New state with array of messages that have the isread attribute set.
|
||||
*/
|
||||
var markMessagesAsRead = function(state, readMessages) {
|
||||
var newState = cloneState(state);
|
||||
var readMessageIds = readMessages.map(function(message) {
|
||||
return message.id;
|
||||
});
|
||||
newState.messages = newState.messages.map(function(message) {
|
||||
if (readMessageIds.indexOf(message.id) >= 0) {
|
||||
message.isRead = true;
|
||||
}
|
||||
|
||||
return message;
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a contact request to each of the members that the request is for.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} requests The contact requests
|
||||
* @return {Object} New state
|
||||
*/
|
||||
var addContactRequests = function(state, requests) {
|
||||
var newState = cloneState(state);
|
||||
|
||||
requests.forEach(function(request) {
|
||||
var fromUserId = request.userid;
|
||||
var toUserId = request.requesteduserid;
|
||||
newState.members[fromUserId].contactrequests.push(request);
|
||||
newState.members[toUserId].contactrequests.push(request);
|
||||
});
|
||||
|
||||
return newState;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a contact request from the members of that request.
|
||||
*
|
||||
* @param {Object} state Current state.
|
||||
* @param {Array} requests The contact requests
|
||||
* @return {Object} New state
|
||||
*/
|
||||
var removeContactRequests = function(state, requests) {
|
||||
var newState = cloneState(state);
|
||||
requests.forEach(function(request) {
|
||||
var fromUserId = request.userid;
|
||||
var toUserId = request.requesteduserid;
|
||||
|
||||
newState.members[fromUserId].contactrequests = newState.members[fromUserId].contactrequests.filter(function(existing) {
|
||||
return existing.userid != fromUserId;
|
||||
});
|
||||
newState.members[toUserId].contactrequests = newState.members[toUserId].contactrequests.filter(function(existing) {
|
||||
return existing.requesteduserid != toUserId;
|
||||
});
|
||||
});
|
||||
|
||||
return newState;
|
||||
};
|
||||
|
||||
return {
|
||||
buildInitialState: buildInitialState,
|
||||
addMessages: addMessages,
|
||||
removeMessages: removeMessages,
|
||||
removeMessagesById: removeMessagesById,
|
||||
addMembers: addMembers,
|
||||
removeMembers: removeMembers,
|
||||
setLoadingMessages: setLoadingMessages,
|
||||
setSendingMessage: setSendingMessage,
|
||||
setLoadingMembers: setLoadingMembers,
|
||||
setId: setId,
|
||||
setName: setName,
|
||||
setSubname: setSubname,
|
||||
setType: setType,
|
||||
setIsFavourite: setIsFavourite,
|
||||
setTotalMemberCount: setTotalMemberCount,
|
||||
setImageUrl: setImageUrl,
|
||||
setLoadingConfirmAction: setLoadingConfirmAction,
|
||||
setPendingDeleteConversation: setPendingDeleteConversation,
|
||||
addPendingBlockUsersById: addPendingBlockUsersById,
|
||||
addPendingRemoveContactsById: addPendingRemoveContactsById,
|
||||
addPendingUnblockUsersById: addPendingUnblockUsersById,
|
||||
addPendingAddContactsById: addPendingAddContactsById,
|
||||
addPendingDeleteMessagesById: addPendingDeleteMessagesById,
|
||||
removePendingBlockUsersById: removePendingBlockUsersById,
|
||||
removePendingRemoveContactsById: removePendingRemoveContactsById,
|
||||
removePendingUnblockUsersById: removePendingUnblockUsersById,
|
||||
removePendingAddContactsById: removePendingAddContactsById,
|
||||
removePendingDeleteMessagesById: removePendingDeleteMessagesById,
|
||||
addSelectedMessagesById: addSelectedMessagesById,
|
||||
removeSelectedMessagesById: removeSelectedMessagesById,
|
||||
markMessagesAsRead: markMessagesAsRead,
|
||||
addContactRequests: addContactRequests,
|
||||
removeContactRequests: removeContactRequests
|
||||
};
|
||||
});
|
170
message/amd/src/message_drawer_view_group_info.js
Normal file
170
message/amd/src/message_drawer_view_group_info.js
Normal file
@ -0,0 +1,170 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the group info page of the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_group_info
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/str',
|
||||
'core/templates',
|
||||
'core_message/message_repository',
|
||||
'core_message/message_drawer_lazy_load_list',
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Str,
|
||||
Templates,
|
||||
Repository,
|
||||
LazyLoadList
|
||||
) {
|
||||
|
||||
var LOAD_MEMBERS_LIMIT = 50;
|
||||
|
||||
var SELECTORS = {
|
||||
CONTENT_CONTAINER: '[data-region="group-info-content-container"]',
|
||||
MEMBERS_LIST: '[data-region="members-list"]',
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
CONTENT: 'core_message/message_drawer_view_group_info_body_content',
|
||||
MEMBERS_LIST: 'core_message/message_drawer_view_group_info_participants_list'
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the content container of the group info view container.
|
||||
*
|
||||
* @param {Object} root Contact container element.
|
||||
* @return {Object} jQuery object
|
||||
*/
|
||||
var getContentContainer = function(root) {
|
||||
return root.find(SELECTORS.CONTENT_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the group info page.
|
||||
*
|
||||
* @param {Object} root Container element.
|
||||
* @param {Object} conversation The group conversation.
|
||||
* @param {Number} loggedInUserId The logged in user's id.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var render = function(root, conversation, loggedInUserId) {
|
||||
var placeholderCount = conversation.totalMemberCount > 50 ? 50 : conversation.totalMemberCount;
|
||||
var placeholders = Array.apply(null, Array(placeholderCount)).map(function() {
|
||||
return true;
|
||||
});
|
||||
var templateContext = {
|
||||
name: conversation.name,
|
||||
subname: conversation.subname,
|
||||
imageurl: conversation.imageUrl,
|
||||
placeholders: placeholders,
|
||||
loggedinuser: {
|
||||
id: loggedInUserId
|
||||
}
|
||||
};
|
||||
|
||||
return Templates.render(TEMPLATES.CONTENT, templateContext)
|
||||
.then(function(html) {
|
||||
getContentContainer(root).append(html);
|
||||
return html;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the callback to load members of the conversation.
|
||||
*
|
||||
* @param {Object} conversation The conversation
|
||||
* @param {Number} limit How many members to load
|
||||
* @param {Number} offset How many memebers to skip
|
||||
* @return {Function} the callback.
|
||||
*/
|
||||
var getLoadMembersCallback = function(conversation, limit, offset) {
|
||||
return function(root, userId) {
|
||||
return Repository.getConversationMembers(conversation.id, userId, limit + 1, offset)
|
||||
.then(function(members) {
|
||||
if (members.length > limit) {
|
||||
members = members.slice(0, -1);
|
||||
} else {
|
||||
LazyLoadList.setLoadedAll(root, true);
|
||||
}
|
||||
|
||||
offset = offset + limit;
|
||||
|
||||
return members;
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to render the members in the list.
|
||||
*
|
||||
* @param {Object} contentContainer The list content container.
|
||||
* @param {Array} members The list of members to render
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var renderMembersCallback = function(contentContainer, members) {
|
||||
return Templates.render(TEMPLATES.MEMBERS_LIST, {contacts: members})
|
||||
.then(function(html) {
|
||||
contentContainer.append(html);
|
||||
return html;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the contact page.
|
||||
*
|
||||
* @param {Object} root Contact container element.
|
||||
* @param {Number} conversation The conversation
|
||||
* @param {Number} loggedInUserId The logged in user id
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var show = function(root, conversation, loggedInUserId) {
|
||||
root = $(root);
|
||||
|
||||
getContentContainer(root).empty();
|
||||
return render(root, conversation, loggedInUserId)
|
||||
.then(function() {
|
||||
var listRoot = LazyLoadList.getRoot(root);
|
||||
LazyLoadList.show(
|
||||
listRoot,
|
||||
getLoadMembersCallback(conversation, LOAD_MEMBERS_LIMIT, 0),
|
||||
renderMembersCallback
|
||||
);
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* String describing this page used for aria-labels.
|
||||
*
|
||||
* @param {Object} root Contact container element.
|
||||
* @param {Number} conversation The conversation
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var description = function(root, conversation) {
|
||||
return Str.get_string('messagedrawerviewgroupinfo', 'core_message', conversation.name);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
description: description
|
||||
};
|
||||
});
|
145
message/amd/src/message_drawer_view_overview.js
Normal file
145
message/amd/src/message_drawer_view_overview.js
Normal file
@ -0,0 +1,145 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the overview page of the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_overview
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/key_codes',
|
||||
'core/pubsub',
|
||||
'core/str',
|
||||
'core_message/message_drawer_view_overview_section_favourites',
|
||||
'core_message/message_drawer_view_overview_section_group_messages',
|
||||
'core_message/message_drawer_view_overview_section_messages',
|
||||
'core_message/message_drawer_router',
|
||||
'core_message/message_drawer_routes',
|
||||
'core_message/message_drawer_events'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
KeyCodes,
|
||||
PubSub,
|
||||
Str,
|
||||
Favourites,
|
||||
GroupMessages,
|
||||
Messages,
|
||||
Router,
|
||||
Routes,
|
||||
MessageDrawerEvents
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
CONTACT_REQUEST_COUNT: '[data-region="contact-request-count"]',
|
||||
FAVOURITES: '[data-region="view-overview-favourites"]',
|
||||
GROUP_MESSAGES: '[data-region="view-overview-group-messages"]',
|
||||
MESSAGES: '[data-region="view-overview-messages"]',
|
||||
SEARCH_INPUT: '[data-region="view-overview-search-input"]'
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search input text element.
|
||||
*
|
||||
* @param {Object} header Overview header container element.
|
||||
* @return {Object} The search input element.
|
||||
*/
|
||||
var getSearchInput = function(header) {
|
||||
return header.find(SELECTORS.SEARCH_INPUT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrement the contact request count. If the count is zero or below then
|
||||
* hide the count.
|
||||
*
|
||||
* @param {Object} header Conversation header container element.
|
||||
* @return {Function} A function to handle decrementing the count.
|
||||
*/
|
||||
var decrementContactRequestCount = function(header) {
|
||||
return function() {
|
||||
var countContainer = header.find(SELECTORS.CONTACT_REQUEST_COUNT);
|
||||
var count = parseInt(countContainer.text(), 10);
|
||||
count = isNaN(count) ? 0 : count - 1;
|
||||
|
||||
if (count <= 0) {
|
||||
countContainer.addClass('hidden');
|
||||
} else {
|
||||
countContainer.text(count);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen to, and handle event in the overview header.
|
||||
*
|
||||
* @param {Object} header Conversation header container element.
|
||||
*/
|
||||
var registerEventListeners = function(header) {
|
||||
var searchInput = getSearchInput(header);
|
||||
var ignoredKeys = [KeyCodes.tab, KeyCodes.shift, KeyCodes.ctrl, KeyCodes.alt];
|
||||
|
||||
searchInput.on('click', function() {
|
||||
Router.go(Routes.VIEW_SEARCH);
|
||||
});
|
||||
searchInput.on('keydown', function(e) {
|
||||
if (ignoredKeys.indexOf(e.keyCode) < 0 && e.key != 'Meta') {
|
||||
Router.go(Routes.VIEW_SEARCH);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_ACCEPTED, decrementContactRequestCount(header));
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_REQUEST_DECLINED, decrementContactRequestCount(header));
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the overview page.
|
||||
*
|
||||
* @param {Object} header Overview header container element.
|
||||
* @param {Object} body Overview body container element.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var show = function(header, body) {
|
||||
if (!header.attr('data-init')) {
|
||||
registerEventListeners(header);
|
||||
header.attr('data-init', true);
|
||||
}
|
||||
|
||||
getSearchInput(header).val('');
|
||||
|
||||
return $.when(
|
||||
Favourites.show(body.find(SELECTORS.FAVOURITES)),
|
||||
GroupMessages.show(body.find(SELECTORS.GROUP_MESSAGES)),
|
||||
Messages.show(body.find(SELECTORS.MESSAGES))
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* String describing this page used for aria-labels.
|
||||
*
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var description = function() {
|
||||
return Str.get_string('messagedrawerviewoverview', 'core_message');
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
description: description
|
||||
};
|
||||
});
|
529
message/amd/src/message_drawer_view_overview_section.js
Normal file
529
message/amd/src/message_drawer_view_overview_section.js
Normal file
@ -0,0 +1,529 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls a section of the overview page in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_overview_section
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/custom_interaction_events',
|
||||
'core/notification',
|
||||
'core/pubsub',
|
||||
'core/str',
|
||||
'core/templates',
|
||||
'core/user_date',
|
||||
'core_message/message_repository',
|
||||
'core_message/message_drawer_events',
|
||||
'core_message/message_drawer_router',
|
||||
'core_message/message_drawer_routes',
|
||||
'core_message/message_drawer_lazy_load_list',
|
||||
'core_message/message_drawer_view_conversation_constants'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
CustomEvents,
|
||||
Notification,
|
||||
PubSub,
|
||||
Str,
|
||||
Templates,
|
||||
UserDate,
|
||||
MessageRepository,
|
||||
MessageDrawerEvents,
|
||||
MessageDrawerRouter,
|
||||
MessageDrawerRoutes,
|
||||
LazyLoadList,
|
||||
MessageDrawerViewConversationContants
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
TOGGLE: '[data-region="toggle"]',
|
||||
CONVERSATION: '[data-conversation-id]',
|
||||
BLOCKED_ICON_CONTAINER: '[data-region="contact-icon-blocked"]',
|
||||
LAST_MESSAGE: '[data-region="last-message"]',
|
||||
LAST_MESSAGE_DATE: '[data-region="last-message-date"]',
|
||||
UNREAD_COUNT: '[data-region="unread-count"]',
|
||||
SECTION_TOTAL_COUNT: '[data-region="section-total-count"]',
|
||||
SECTION_UNREAD_COUNT: '[data-region="section-unread-count"]'
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
CONVERSATIONS_LIST: 'core_message/message_drawer_conversations_list'
|
||||
};
|
||||
|
||||
var LOAD_LIMIT = 50;
|
||||
var loadedConversationsById = {};
|
||||
|
||||
/**
|
||||
* Get the section visibility status.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @return {Bool} Is section visible.
|
||||
*/
|
||||
var isVisible = function(root) {
|
||||
return LazyLoadList.getRoot(root).hasClass('show');
|
||||
};
|
||||
|
||||
/**
|
||||
* Set this section as expanded.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var setExpanded = function(root) {
|
||||
root.addClass('expanded');
|
||||
};
|
||||
|
||||
/**
|
||||
* Set this section as collapsed.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
*/
|
||||
var setCollapsed = function(root) {
|
||||
root.removeClass('expanded');
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the messages in the overview page.
|
||||
*
|
||||
* @param {Object} contentContainer Conversations content container.
|
||||
* @param {Array} conversations List of conversations to render.
|
||||
* @param {Number} userId Logged in user id.
|
||||
* @return {Object} jQuery promise.
|
||||
*/
|
||||
var render = function(contentContainer, conversations, userId) {
|
||||
var formattedConversations = conversations.map(function(conversation) {
|
||||
var lastMessage = conversation.messages.length ? conversation.messages[conversation.messages.length - 1] : null;
|
||||
var formattedConversation = {
|
||||
id: conversation.id,
|
||||
imageurl: conversation.imageurl,
|
||||
name: conversation.name,
|
||||
subname: conversation.subname,
|
||||
unreadcount: conversation.unreadcount,
|
||||
lastmessagedate: lastMessage ? lastMessage.timecreated : null,
|
||||
sentfromcurrentuser: lastMessage ? lastMessage.useridfrom == userId : null,
|
||||
lastmessage: lastMessage ? $(lastMessage.text).text() || lastMessage.text : null
|
||||
};
|
||||
|
||||
if (conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.PRIVATE) {
|
||||
var otherUser = conversation.members.reduce(function(carry, member) {
|
||||
if (!carry && member.id != userId) {
|
||||
carry = member;
|
||||
}
|
||||
return carry;
|
||||
}, null);
|
||||
|
||||
formattedConversation.showonlinestatus = otherUser.showonlinestatus;
|
||||
formattedConversation.isonline = otherUser.isosnline;
|
||||
formattedConversation.isblocked = otherUser.isblocked;
|
||||
}
|
||||
|
||||
return formattedConversation;
|
||||
});
|
||||
|
||||
return Templates.render(TEMPLATES.CONVERSATIONS_LIST, {conversations: formattedConversations})
|
||||
.then(function(html) {
|
||||
contentContainer.append(html);
|
||||
return html;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Build the callback to load conversations.
|
||||
*
|
||||
* @param {Number} type The conversation type.
|
||||
* @param {Bool} includeFavourites Include/exclude favourites.
|
||||
* @param {Number} offset Result offset
|
||||
* @return {Function}
|
||||
*/
|
||||
var getLoadCallback = function(type, includeFavourites, offset) {
|
||||
return function(root, userId) {
|
||||
return MessageRepository.getConversations(
|
||||
userId,
|
||||
type,
|
||||
LOAD_LIMIT + 1,
|
||||
offset,
|
||||
includeFavourites
|
||||
)
|
||||
.then(function(response) {
|
||||
var conversations = response.conversations;
|
||||
|
||||
if (conversations.length > LOAD_LIMIT) {
|
||||
conversations = conversations.slice(0, -1);
|
||||
} else {
|
||||
LazyLoadList.setLoadedAll(root, true);
|
||||
}
|
||||
|
||||
offset = offset + LOAD_LIMIT;
|
||||
|
||||
conversations.forEach(function(conversation) {
|
||||
loadedConversationsById[conversation.id] = conversation;
|
||||
});
|
||||
|
||||
return conversations;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the total count container element.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
* @return {Object} Total count container element.
|
||||
*/
|
||||
var getTotalConversationCountElement = function(root) {
|
||||
return root.find(SELECTORS.SECTION_TOTAL_COUNT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the unread conversations count container element.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
* @return {Object} Unread conversations count container element.
|
||||
*/
|
||||
var getTotalUnreadConversationCountElement = function(root) {
|
||||
return root.find(SELECTORS.SECTION_UNREAD_COUNT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Increment the total conversations count.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
*/
|
||||
var incrementTotalConversationCount = function(root) {
|
||||
var element = getTotalConversationCountElement(root);
|
||||
var count = parseInt(element.text());
|
||||
count = count + 1;
|
||||
element.text(count);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrement the total conversations count.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
*/
|
||||
var decrementTotalConversationCount = function(root) {
|
||||
var element = getTotalConversationCountElement(root);
|
||||
var count = parseInt(element.text());
|
||||
count = count - 1;
|
||||
element.text(count);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decrement the total unread conversations count.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
*/
|
||||
var decrementTotalUnreadConversationCount = function(root) {
|
||||
var element = getTotalUnreadConversationCountElement(root);
|
||||
var count = parseInt(element.text());
|
||||
count = count - 1;
|
||||
element.text(count);
|
||||
|
||||
if (count < 1) {
|
||||
element.addClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a contact / conversation element.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
* @param {Number} conversationId The conversation id.
|
||||
* @return {Object} Conversation element.
|
||||
*/
|
||||
var getConversationElement = function(root, conversationId) {
|
||||
return root.find('[data-conversation-id="' + conversationId + '"]');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the contact is blocked icon.
|
||||
*
|
||||
* @param {Object} conversationElement The conversation element.
|
||||
*/
|
||||
var blockContact = function(conversationElement) {
|
||||
conversationElement.find(SELECTORS.BLOCKED_ICON_CONTAINER).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the contact is blocked icon.
|
||||
*
|
||||
* @param {Object} conversationElement The conversation element.
|
||||
*/
|
||||
var unblockContact = function(conversationElement) {
|
||||
conversationElement.find(SELECTORS.BLOCKED_ICON_CONTAINER).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the last message from / to a contact.
|
||||
*
|
||||
* @param {Object} element Conversation element.
|
||||
* @param {Object} conversation The conversation.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var updateLastMessage = function(element, conversation) {
|
||||
var message = conversation.messages[conversation.messages.length - 1];
|
||||
var youString = '';
|
||||
var stringRequests = [
|
||||
{key: 'you', component: 'core_message'},
|
||||
{key: 'strftimetime24', component: 'core_langconfig'},
|
||||
];
|
||||
return Str.get_strings(stringRequests)
|
||||
.then(function(strings) {
|
||||
youString = strings[0];
|
||||
return UserDate.get([{timestamp: message.timeCreated, format: strings[1]}]);
|
||||
})
|
||||
.then(function(dates) {
|
||||
return dates[0];
|
||||
})
|
||||
.then(function(dateString) {
|
||||
var lastMessage = $(message.text).text();
|
||||
|
||||
if (message.fromLoggedInUser) {
|
||||
lastMessage = youString + ' ' + lastMessage;
|
||||
}
|
||||
|
||||
element.find(SELECTORS.LAST_MESSAGE).html(lastMessage);
|
||||
element.find(SELECTORS.LAST_MESSAGE_DATE).text(dateString).removeClass('hidden');
|
||||
return dateString;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an render new conversation element in the list of conversations.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
* @param {Object} conversation The conversation.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var createNewConversation = function(root, conversation) {
|
||||
var existingConversations = root.find(SELECTORS.CONVERSATION);
|
||||
var text = '';
|
||||
|
||||
if (!existingConversations.length) {
|
||||
// If we didn't have any conversations then we need to show
|
||||
// the content of the list and hide the empty message.
|
||||
var listRoot = LazyLoadList.getRoot(root);
|
||||
LazyLoadList.showContent(listRoot);
|
||||
LazyLoadList.hideEmptyMessage(listRoot);
|
||||
}
|
||||
|
||||
var messageCount = conversation.messages.length;
|
||||
var lastMessage = messageCount ? conversation.messages[messageCount - 1] : null;
|
||||
|
||||
if (lastMessage) {
|
||||
text = $(lastMessage.text).text() || lastMessage.text;
|
||||
}
|
||||
|
||||
var formattedConversation = {
|
||||
id: conversation.id,
|
||||
name: conversation.name,
|
||||
subname: conversation.subname,
|
||||
lastmessagedate: lastMessage ? lastMessage.timeCreated : null,
|
||||
sentfromcurrentuser: lastMessage ? lastMessage.fromLoggedInUser : null,
|
||||
lastmessage: text,
|
||||
imageurl: conversation.imageUrl,
|
||||
};
|
||||
|
||||
return Templates.render(TEMPLATES.CONVERSATIONS_LIST, {conversations: [formattedConversation]})
|
||||
.then(function(html) {
|
||||
var contentContainer = LazyLoadList.getContentContainer(root);
|
||||
return contentContainer.prepend(html);
|
||||
})
|
||||
.then(function() {
|
||||
return incrementTotalConversationCount(root);
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a conversation from the list of conversations.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
* @param {Object} conversationElement The conversation element.
|
||||
*/
|
||||
var deleteConversation = function(root, conversationElement) {
|
||||
conversationElement.remove();
|
||||
decrementTotalConversationCount(root);
|
||||
|
||||
var conversations = root.find(SELECTORS.CONVERSATION);
|
||||
if (!conversations.length) {
|
||||
// If we don't have any conversations then we need to hide
|
||||
// the content of the list and show the empty message.
|
||||
var listRoot = LazyLoadList.getRoot(root);
|
||||
LazyLoadList.hideContent(listRoot);
|
||||
LazyLoadList.showEmptyMessage(listRoot);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark a conversation as read.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
* @param {Object} conversationElement The conversation element.
|
||||
*/
|
||||
var markConversationAsRead = function(root, conversationElement) {
|
||||
var unreadCount = conversationElement.find(SELECTORS.UNREAD_COUNT);
|
||||
unreadCount.text('0');
|
||||
unreadCount.addClass('hidden');
|
||||
decrementTotalUnreadConversationCount(root);
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen to, and handle events in this section.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @param {Function} loadCallback The callback to load items.
|
||||
* @param {Number} type The conversation type for this section
|
||||
* @param {Bool} includeFavourites If this section includes favourites
|
||||
*/
|
||||
var registerEventListeners = function(root, loadCallback, type, includeFavourites) {
|
||||
var listRoot = LazyLoadList.getRoot(root);
|
||||
|
||||
// Set the minimum height of the section to the height of the toggle. This
|
||||
// smooths out the collapse animation.
|
||||
var toggle = root.find(SELECTORS.TOGGLE);
|
||||
root.css('min-height', toggle.outerHeight());
|
||||
|
||||
root.on('show.bs.collapse', function() {
|
||||
setExpanded(root);
|
||||
LazyLoadList.show(listRoot, loadCallback, render);
|
||||
});
|
||||
|
||||
root.on('hidden.bs.collapse', function() {
|
||||
setCollapsed(root);
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_BLOCKED, function(conversationId) {
|
||||
var conversationElement = getConversationElement(root, conversationId);
|
||||
if (conversationElement.length) {
|
||||
blockContact(conversationElement);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONTACT_UNBLOCKED, function(conversationId) {
|
||||
var conversationElement = getConversationElement(root, conversationId);
|
||||
if (conversationElement.length) {
|
||||
unblockContact(conversationElement);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONVERSATION_NEW_LAST_MESSAGE, function(conversation) {
|
||||
if (
|
||||
(type && conversation.type != type) ||
|
||||
(includeFavourites && !conversation.isFavourite) ||
|
||||
(!includeFavourites && conversation.isFavourite)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
var conversationId = conversation.id;
|
||||
var element = getConversationElement(root, conversationId);
|
||||
if (element.length) {
|
||||
updateLastMessage(element, conversation);
|
||||
} else {
|
||||
createNewConversation(root, conversation);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONVERSATION_DELETED, function(conversationId) {
|
||||
var conversationElement = getConversationElement(root, conversationId);
|
||||
if (conversationElement.length) {
|
||||
deleteConversation(root, conversationElement);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONVERSATION_READ, function(conversationId) {
|
||||
var conversationElement = getConversationElement(root, conversationId);
|
||||
if (conversationElement.length) {
|
||||
markConversationAsRead(root, conversationElement);
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONVERSATION_SET_FAVOURITE, function(conversation) {
|
||||
var conversationElement = null;
|
||||
if (includeFavourites && (!type || type == conversation.type)) {
|
||||
conversationElement = getConversationElement(root, conversation.id);
|
||||
if (!conversationElement.length) {
|
||||
createNewConversation(root, conversation);
|
||||
}
|
||||
} else if (type == conversation.type) {
|
||||
conversationElement = getConversationElement(root, conversation.id);
|
||||
if (conversationElement.length) {
|
||||
deleteConversation(root, conversationElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
PubSub.subscribe(MessageDrawerEvents.CONVERSATION_UNSET_FAVOURITE, function(conversation) {
|
||||
var conversationElement = null;
|
||||
if (includeFavourites) {
|
||||
conversationElement = getConversationElement(root, conversation.id);
|
||||
if (conversationElement.length) {
|
||||
deleteConversation(root, conversationElement);
|
||||
}
|
||||
} else if (type == conversation.type) {
|
||||
conversationElement = getConversationElement(root, conversation.id);
|
||||
if (!conversationElement.length) {
|
||||
createNewConversation(root, conversation);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CustomEvents.define(root, [CustomEvents.events.activate]);
|
||||
root.on(CustomEvents.events.activate, SELECTORS.CONVERSATION, function(e, data) {
|
||||
var conversationElement = $(e.target).closest(SELECTORS.CONVERSATION);
|
||||
var conversationId = conversationElement.attr('data-conversation-id');
|
||||
var conversation = loadedConversationsById[conversationId];
|
||||
MessageDrawerRouter.go(MessageDrawerRoutes.VIEW_CONVERSATION, conversation);
|
||||
|
||||
data.originalEvent.preventDefault();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the section.
|
||||
*
|
||||
* @param {Object} root The section container element.
|
||||
* @param {Number} type The conversation type for this section
|
||||
* @param {Bool} includeFavourites If this section includes favourites
|
||||
*/
|
||||
var show = function(root, type, includeFavourites) {
|
||||
root = $(root);
|
||||
|
||||
if (!root.attr('data-init')) {
|
||||
var loadCallback = getLoadCallback(type, includeFavourites, 0);
|
||||
registerEventListeners(root, loadCallback, type, includeFavourites);
|
||||
|
||||
if (isVisible(root)) {
|
||||
setExpanded(root);
|
||||
var listRoot = LazyLoadList.getRoot(root);
|
||||
LazyLoadList.show(listRoot, loadCallback, render);
|
||||
}
|
||||
|
||||
root.attr('data-init', true);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
show: show
|
||||
};
|
||||
});
|
@ -0,0 +1,48 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the favourites section of the overview page in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_overview_section_favourites
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core_message/message_drawer_view_overview_section'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Section
|
||||
) {
|
||||
// All conversation types.
|
||||
var CONVERSATION_TYPE = null;
|
||||
var INCLUDE_FAVOURITES = true;
|
||||
|
||||
/**
|
||||
* Show the overview page conversations.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
*/
|
||||
var show = function(root) {
|
||||
Section.show($(root), CONVERSATION_TYPE, INCLUDE_FAVOURITES);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
};
|
||||
});
|
@ -0,0 +1,49 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the group overview section of the overview page in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_overview_section_group_messages
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core_message/message_drawer_view_overview_section'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Section
|
||||
) {
|
||||
// Public conversations.
|
||||
var CONVERSATION_TYPE = 2;
|
||||
var INCLUDE_FAVOURITES = false;
|
||||
|
||||
/**
|
||||
* Show the overview page conversations.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
*/
|
||||
var show = function(root) {
|
||||
root = $(root);
|
||||
Section.show($(root), CONVERSATION_TYPE, INCLUDE_FAVOURITES);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
};
|
||||
});
|
@ -0,0 +1,48 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the messages section of the overview page in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_overview_section_messages
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core_message/message_drawer_view_overview_section'
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Section
|
||||
) {
|
||||
// Private conversations.
|
||||
var CONVERSATION_TYPE = 1;
|
||||
var INCLUDE_FAVOURITES = false;
|
||||
|
||||
/**
|
||||
* Show the overview page conversations.
|
||||
*
|
||||
* @param {Object} root Overview messages container element.
|
||||
*/
|
||||
var show = function(root) {
|
||||
Section.show($(root), CONVERSATION_TYPE, INCLUDE_FAVOURITES);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
};
|
||||
});
|
837
message/amd/src/message_drawer_view_search.js
Normal file
837
message/amd/src/message_drawer_view_search.js
Normal file
@ -0,0 +1,837 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the search page of the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_search
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/custom_interaction_events',
|
||||
'core/notification',
|
||||
'core/pubsub',
|
||||
'core/str',
|
||||
'core/templates',
|
||||
'core_message/message_repository',
|
||||
'core_message/message_drawer_events',
|
||||
],
|
||||
function(
|
||||
$,
|
||||
CustomEvents,
|
||||
Notification,
|
||||
PubSub,
|
||||
Str,
|
||||
Templates,
|
||||
Repository,
|
||||
Events
|
||||
) {
|
||||
|
||||
var MESSAGE_SEARCH_LIMIT = 50;
|
||||
var USERS_SEARCH_LIMIT = 50;
|
||||
var USERS_INITIAL_SEARCH_LIMIT = 3;
|
||||
|
||||
var SELECTORS = {
|
||||
BLOCK_ICON_CONTAINER: '[data-region="block-icon-container"]',
|
||||
CANCEL_SEARCH_BUTTON: '[data-action="cancel-search"]',
|
||||
CONTACTS_CONTAINER: '[data-region="contacts-container"]',
|
||||
CONTACTS_LIST: '[data-region="contacts-container"] [data-region="list"]',
|
||||
EMPTY_MESSAGE_CONTAINER: '[data-region="empty-message-container"]',
|
||||
LIST: '[data-region="list"]',
|
||||
LOADING_ICON_CONTAINER: '[data-region="loading-icon-container"]',
|
||||
LOADING_PLACEHOLDER: '[data-region="loading-placeholder"]',
|
||||
MESSAGES_LIST: '[data-region="messages-container"] [data-region="list"]',
|
||||
MESSAGES_CONTAINER: '[data-region="messages-container"]',
|
||||
NON_CONTACTS_CONTAINER: '[data-region="non-contacts-container"]',
|
||||
NON_CONTACTS_LIST: '[data-region="non-contacts-container"] [data-region="list"]',
|
||||
SEARCH_ICON_CONTAINER: '[data-region="search-icon-container"]',
|
||||
SEARCH_ACTION: '[data-action="search"]',
|
||||
SEARCH_INPUT: '[data-region="search-input"]',
|
||||
SEARCH_RESULTS_CONTAINER: '[data-region="search-results-container"]',
|
||||
LOAD_MORE_USERS: '[data-action="load-more-users"]',
|
||||
LOAD_MORE_MESSAGES: '[data-action="load-more-messages"]',
|
||||
BUTTON_TEXT: '[data-region="button-text"]',
|
||||
NO_RESULTS_CONTAINTER: '[data-region="no-results-container"]',
|
||||
};
|
||||
|
||||
var TEMPLATES = {
|
||||
CONTACTS_LIST: 'core_message/message_drawer_contacts_list',
|
||||
NON_CONTACTS_LIST: 'core_message/message_drawer_non_contacts_list',
|
||||
MESSAGES_LIST: 'core_message/message_drawer_messages_list'
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the logged in user id.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
* @return {Number} User id.
|
||||
*/
|
||||
var getLoggedInUserId = function(body) {
|
||||
return body.attr('data-user-id');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the no messages container element.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
* @return {Object} No messages container element.
|
||||
*/
|
||||
var getEmptyMessageContainer = function(body) {
|
||||
return body.find(SELECTORS.EMPTY_MESSAGE_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search loading icon.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
* @return {Object} Loading icon element.
|
||||
*/
|
||||
var getLoadingIconContainer = function(header) {
|
||||
return header.find(SELECTORS.LOADING_ICON_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the loading container element.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
* @return {Object} Loading container element.
|
||||
*/
|
||||
var getLoadingPlaceholder = function(body) {
|
||||
return body.find(SELECTORS.LOADING_PLACEHOLDER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search icon container.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
* @return {Object} Search icon container.
|
||||
*/
|
||||
var getSearchIconContainer = function(header) {
|
||||
return header.find(SELECTORS.SEARCH_ICON_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search input container.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
* @return {Object} Search input container.
|
||||
*/
|
||||
var getSearchInput = function(header) {
|
||||
return header.find(SELECTORS.SEARCH_INPUT);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search results container.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
* @return {Object} Search results container.
|
||||
*/
|
||||
var getSearchResultsContainer = function(body) {
|
||||
return body.find(SELECTORS.SEARCH_RESULTS_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search contacts container.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
* @return {Object} Search contacts container.
|
||||
*/
|
||||
var getContactsContainer = function(body) {
|
||||
return body.find(SELECTORS.CONTACTS_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search non contacts container.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
* @return {Object} Search non contacts container.
|
||||
*/
|
||||
var getNonContactsContainer = function(body) {
|
||||
return body.find(SELECTORS.NON_CONTACTS_CONTAINER);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the search messages container.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
* @return {Object} Search messages container.
|
||||
*/
|
||||
var getMessagesContainer = function(body) {
|
||||
return body.find(SELECTORS.MESSAGES_CONTAINER);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the messages empty container.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var showEmptyMessage = function(body) {
|
||||
getEmptyMessageContainer(body).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the messages empty container.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var hideEmptyMessage = function(body) {
|
||||
getEmptyMessageContainer(body).addClass('hidden');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show the loading icon.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
*/
|
||||
var showLoadingIcon = function(header) {
|
||||
getLoadingIconContainer(header).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the loading icon.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
*/
|
||||
var hideLoadingIcon = function(header) {
|
||||
getLoadingIconContainer(header).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show loading placeholder.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var showLoadingPlaceholder = function(body) {
|
||||
getLoadingPlaceholder(body).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide loading placeholder.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var hideLoadingPlaceholder = function(body) {
|
||||
getLoadingPlaceholder(body).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show search icon.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
*/
|
||||
var showSearchIcon = function(header) {
|
||||
getSearchIconContainer(header).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide search icon.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
*/
|
||||
var hideSearchIcon = function(header) {
|
||||
getSearchIconContainer(header).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show search results.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var showSearchResults = function(body) {
|
||||
getSearchResultsContainer(body).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide search results.
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var hideSearchResults = function(body) {
|
||||
getSearchResultsContainer(body).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable the search input.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
*/
|
||||
var disableSearchInput = function(header) {
|
||||
getSearchInput(header).prop('disabled', true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable the search input.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
*/
|
||||
var enableSearchInput = function(header) {
|
||||
getSearchInput(header).prop('disabled', false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear the search input.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
*/
|
||||
var clearSearchInput = function(header) {
|
||||
getSearchInput(header).val('');
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear all search results
|
||||
*
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var clearAllSearchResults = function(body) {
|
||||
body.find(SELECTORS.CONTACTS_LIST).empty();
|
||||
body.find(SELECTORS.NON_CONTACTS_LIST).empty();
|
||||
body.find(SELECTORS.MESSAGES_LIST).empty();
|
||||
body.find(SELECTORS.NO_RESULTS_CONTAINTER).addClass('hidden');
|
||||
showLoadMoreUsersButton(body);
|
||||
showLoadMoreMessagesButton(body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the body and header to indicate the search is loading.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var startLoading = function(header, body) {
|
||||
hideSearchIcon(header);
|
||||
hideEmptyMessage(body);
|
||||
hideSearchResults(body);
|
||||
showLoadingIcon(header);
|
||||
showLoadingPlaceholder(body);
|
||||
disableSearchInput(header);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the body and header to indicate the search has stopped loading.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var stopLoading = function(header, body) {
|
||||
showSearchIcon(header);
|
||||
hideEmptyMessage(body);
|
||||
showSearchResults(body);
|
||||
hideLoadingIcon(header);
|
||||
hideLoadingPlaceholder(body);
|
||||
enableSearchInput(header);
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the more users loading icon.
|
||||
*
|
||||
* @param {Object} root The more users container element.
|
||||
*/
|
||||
var showUsersLoadingIcon = function(root) {
|
||||
var button = root.find(SELECTORS.LOAD_MORE_USERS);
|
||||
button.prop('disabled', true);
|
||||
button.find(SELECTORS.BUTTON_TEXT).addClass('hidden');
|
||||
button.find(SELECTORS.LOADING_ICON_CONTAINER).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the more users loading icon.
|
||||
*
|
||||
* @param {Object} root The more users container element.
|
||||
*/
|
||||
var hideUsersLoadingIcon = function(root) {
|
||||
var button = root.find(SELECTORS.LOAD_MORE_USERS);
|
||||
button.prop('disabled', false);
|
||||
button.find(SELECTORS.BUTTON_TEXT).removeClass('hidden');
|
||||
button.find(SELECTORS.LOADING_ICON_CONTAINER).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the load more users button.
|
||||
*
|
||||
* @param {Object} root The users container element.
|
||||
*/
|
||||
var showLoadMoreUsersButton = function(root) {
|
||||
root.find(SELECTORS.LOAD_MORE_USERS).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the load more users button.
|
||||
*
|
||||
* @param {Object} root The users container element.
|
||||
*/
|
||||
var hideLoadMoreUsersButton = function(root) {
|
||||
root.find(SELECTORS.LOAD_MORE_USERS).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the messages are loading icon.
|
||||
*
|
||||
* @param {Object} root Messages root element.
|
||||
*/
|
||||
var showMessagesLoadingIcon = function(root) {
|
||||
var button = root.find(SELECTORS.LOAD_MORE_MESSAGES);
|
||||
button.prop('disabled', true);
|
||||
button.find(SELECTORS.BUTTON_TEXT).addClass('hidden');
|
||||
button.find(SELECTORS.LOADING_ICON_CONTAINER).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the messages are loading icon.
|
||||
*
|
||||
* @param {Object} root Messages root element.
|
||||
*/
|
||||
var hideMessagesLoadingIcon = function(root) {
|
||||
var button = root.find(SELECTORS.LOAD_MORE_MESSAGES);
|
||||
button.prop('disabled', false);
|
||||
button.find(SELECTORS.BUTTON_TEXT).removeClass('hidden');
|
||||
button.find(SELECTORS.LOADING_ICON_CONTAINER).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the load more messages button.
|
||||
*
|
||||
* @param {Object} root The messages container element.
|
||||
*/
|
||||
var showLoadMoreMessagesButton = function(root) {
|
||||
root.find(SELECTORS.LOAD_MORE_MESSAGES).removeClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the load more messages button.
|
||||
*
|
||||
* @param {Object} root The messages container element.
|
||||
*/
|
||||
var hideLoadMoreMessagesButton = function(root) {
|
||||
root.find(SELECTORS.LOAD_MORE_MESSAGES).addClass('hidden');
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a contact in the search results.
|
||||
*
|
||||
* @param {Object} root Search results container element.
|
||||
* @param {Number} userId User id.
|
||||
* @return {Object} User container element.
|
||||
*/
|
||||
var findContact = function(root, userId) {
|
||||
return root.find('[data-contact-user-id="' + userId + '"]');
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a contact to the search results.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Object} contact User in contacts list.
|
||||
*/
|
||||
var addContact = function(root, contact) {
|
||||
var nonContactsContainer = getNonContactsContainer(root);
|
||||
var nonContact = findContact(nonContactsContainer, contact.userid);
|
||||
|
||||
if (nonContact.length) {
|
||||
nonContact.remove();
|
||||
var contactsContainer = getContactsContainer(root);
|
||||
contactsContainer.removeClass('hidden');
|
||||
contactsContainer.find(SELECTORS.LIST).append(nonContact);
|
||||
}
|
||||
|
||||
if (!nonContactsContainer.find(SELECTORS.LIST).children().length) {
|
||||
nonContactsContainer.addClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a contact from the contacts results.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Object} userId Contact user id.
|
||||
*/
|
||||
var removeContact = function(root, userId) {
|
||||
var contactsContainer = getContactsContainer(root);
|
||||
var contact = findContact(contactsContainer, userId);
|
||||
|
||||
if (contact.length) {
|
||||
contact.remove();
|
||||
var nonContactsContainer = getNonContactsContainer(root);
|
||||
nonContactsContainer.removeClass('hidden');
|
||||
nonContactsContainer.find(SELECTORS.LIST).append(contact);
|
||||
}
|
||||
|
||||
if (!contactsContainer.find(SELECTORS.LIST).children().length) {
|
||||
contactsContainer.addClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the contact is blocked icon.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Object} userId Contact user id.
|
||||
*/
|
||||
var blockContact = function(root, userId) {
|
||||
var contact = findContact(root, userId);
|
||||
if (contact.length) {
|
||||
contact.find(SELECTORS.BLOCK_ICON_CONTAINER).removeClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the contact is blocked icon.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Object} userId Contact user id.
|
||||
*/
|
||||
var unblockContact = function(root, userId) {
|
||||
var contact = findContact(root, userId);
|
||||
if (contact.length) {
|
||||
contact.find(SELECTORS.BLOCK_ICON_CONTAINER).addClass('hidden');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Render contacts in the contacts search results.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Array} contacts List of contacts.
|
||||
* @return {Promise} Renderer promise.
|
||||
*/
|
||||
var renderContacts = function(root, contacts) {
|
||||
var container = getContactsContainer(root);
|
||||
var list = container.find(SELECTORS.LIST);
|
||||
|
||||
if (!contacts.length && !list.children().length) {
|
||||
var noResultsContainer = container.find(SELECTORS.NO_RESULTS_CONTAINTER);
|
||||
noResultsContainer.removeClass('hidden');
|
||||
return $.Deferred().resolve('').promise();
|
||||
} else {
|
||||
return Templates.render(TEMPLATES.CONTACTS_LIST, {contacts: contacts})
|
||||
.then(function(html) {
|
||||
list.append(html);
|
||||
return html;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Render non contacts in the contacts search results.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Array} nonContacts List of non contacts.
|
||||
* @return {Promise} Renderer promise.
|
||||
*/
|
||||
var renderNonContacts = function(root, nonContacts) {
|
||||
var container = getNonContactsContainer(root);
|
||||
var list = container.find(SELECTORS.LIST);
|
||||
|
||||
if (!nonContacts.length && !list.children().length) {
|
||||
var noResultsContainer = container.find(SELECTORS.NO_RESULTS_CONTAINTER);
|
||||
noResultsContainer.removeClass('hidden');
|
||||
return $.Deferred().resolve('').promise();
|
||||
} else {
|
||||
return Templates.render(TEMPLATES.NON_CONTACTS_LIST, {noncontacts: nonContacts})
|
||||
.then(function(html) {
|
||||
list.append(html);
|
||||
return html;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Render messages in the messages search results.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Array} messages List of messages.
|
||||
* @return {Promise} Renderer promise.
|
||||
*/
|
||||
var renderMessages = function(root, messages) {
|
||||
var container = getMessagesContainer(root);
|
||||
var list = container.find(SELECTORS.LIST);
|
||||
|
||||
if (!messages.length && !list.children().length) {
|
||||
var noResultsContainer = container.find(SELECTORS.NO_RESULTS_CONTAINTER);
|
||||
noResultsContainer.removeClass('hidden');
|
||||
return $.Deferred().resolve('').promise();
|
||||
} else {
|
||||
return Templates.render(TEMPLATES.MESSAGES_LIST, {messages: messages})
|
||||
.then(function(html) {
|
||||
list.append(html);
|
||||
return html;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load more users from the repository and render the results into the users search results.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Number} loggedInUserId Current logged in user.
|
||||
* @param {String} text Search text.
|
||||
* @param {Number} limit Number of users to get.
|
||||
* @param {Number} offset Load users from
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var loadMoreUsers = function(root, loggedInUserId, text, limit, offset) {
|
||||
var loadedAll = false;
|
||||
showUsersLoadingIcon(root);
|
||||
return Repository.searchUsers(loggedInUserId, text, limit + 1, offset)
|
||||
.then(function(results) {
|
||||
var contacts = results.contacts;
|
||||
var noncontacts = results.noncontacts;
|
||||
|
||||
if (contacts.length <= limit && noncontacts.length <= limit) {
|
||||
loadedAll = true;
|
||||
return {
|
||||
contacts: contacts,
|
||||
noncontacts: noncontacts
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
contacts: contacts.slice(0, limit),
|
||||
noncontacts: noncontacts.slice(0, limit)
|
||||
};
|
||||
}
|
||||
})
|
||||
.then(function(results) {
|
||||
return $.when(
|
||||
renderContacts(root, results.contacts),
|
||||
renderNonContacts(root, results.noncontacts)
|
||||
);
|
||||
})
|
||||
.then(function() {
|
||||
hideUsersLoadingIcon(root);
|
||||
|
||||
if (loadedAll) {
|
||||
hideLoadMoreUsersButton(root);
|
||||
}
|
||||
|
||||
return;
|
||||
})
|
||||
.catch(function(error) {
|
||||
hideUsersLoadingIcon(root);
|
||||
// Rethrow error for other handlers.
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Load more messages from the repository and render the results into the messages search results.
|
||||
*
|
||||
* @param {Object} root Search results container.
|
||||
* @param {Number} loggedInUserId Current logged in user.
|
||||
* @param {String} text Search text.
|
||||
* @param {Number} limit Number of messages to get.
|
||||
* @param {Number} offset Load messages from
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var loadMoreMessages = function(root, loggedInUserId, text, limit, offset) {
|
||||
var loadedAll = false;
|
||||
showMessagesLoadingIcon(root);
|
||||
return Repository.searchMessages(loggedInUserId, text, limit + 1, offset)
|
||||
.then(function(results) {
|
||||
var messages = results.contacts;
|
||||
|
||||
if (messages.length <= limit) {
|
||||
loadedAll = true;
|
||||
return messages;
|
||||
} else {
|
||||
return messages.slice(0, limit);
|
||||
}
|
||||
})
|
||||
.then(function(messages) {
|
||||
return renderMessages(root, messages);
|
||||
})
|
||||
.then(function() {
|
||||
hideMessagesLoadingIcon(root);
|
||||
|
||||
if (loadedAll) {
|
||||
hideLoadMoreMessagesButton(root);
|
||||
}
|
||||
|
||||
return;
|
||||
})
|
||||
.catch(function(error) {
|
||||
hideMessagesLoadingIcon(root);
|
||||
// Rethrow error for other handlers.
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Search for users and messages.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
* @param {Object} body Search body container element.
|
||||
* @param {String} searchText Search text.
|
||||
* @param {Number} usersLimit The users limit.
|
||||
* @param {Number} usersOffset The users offset.
|
||||
* @param {Number} messagesLimit The message limit.
|
||||
* @param {Number} messagesOffset The message offset.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var search = function(header, body, searchText, usersLimit, usersOffset, messagesLimit, messagesOffset) {
|
||||
var loggedInUserId = getLoggedInUserId(body);
|
||||
startLoading(header, body);
|
||||
clearAllSearchResults(body);
|
||||
|
||||
return $.when(
|
||||
loadMoreUsers(body, loggedInUserId, searchText, usersLimit, usersOffset),
|
||||
loadMoreMessages(body, loggedInUserId, searchText, messagesLimit, messagesOffset)
|
||||
)
|
||||
.then(function() {
|
||||
stopLoading(header, body);
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Listen to and handle events for searching.
|
||||
*
|
||||
* @param {Object} header Search header container element.
|
||||
* @param {Object} body Search body container element.
|
||||
*/
|
||||
var registerEventListeners = function(header, body) {
|
||||
var loggedInUserId = getLoggedInUserId(body);
|
||||
var searchInput = getSearchInput(header);
|
||||
var searchText = '';
|
||||
var messagesOffset = 0;
|
||||
var usersOffset = 0;
|
||||
|
||||
var searchEventHandler = function(e, data) {
|
||||
searchText = searchInput.val().trim();
|
||||
|
||||
if (searchText !== '') {
|
||||
messagesOffset = 0;
|
||||
usersOffset = 0;
|
||||
search(
|
||||
header,
|
||||
body,
|
||||
searchText,
|
||||
USERS_INITIAL_SEARCH_LIMIT,
|
||||
usersOffset,
|
||||
MESSAGE_SEARCH_LIMIT,
|
||||
messagesOffset
|
||||
)
|
||||
.then(function() {
|
||||
searchInput.focus();
|
||||
usersOffset = usersOffset + USERS_INITIAL_SEARCH_LIMIT;
|
||||
messagesOffset = messagesOffset + MESSAGE_SEARCH_LIMIT;
|
||||
return;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
}
|
||||
|
||||
data.originalEvent.preventDefault();
|
||||
};
|
||||
|
||||
CustomEvents.define(searchInput, [CustomEvents.events.enter]);
|
||||
CustomEvents.define(header, [CustomEvents.events.activate]);
|
||||
CustomEvents.define(body, [CustomEvents.events.activate]);
|
||||
|
||||
searchInput.on(CustomEvents.events.enter, searchEventHandler);
|
||||
|
||||
header.on(CustomEvents.events.activate, SELECTORS.SEARCH_ACTION, searchEventHandler);
|
||||
|
||||
body.on(CustomEvents.events.activate, SELECTORS.LOAD_MORE_MESSAGES, function(e, data) {
|
||||
if (searchText !== '') {
|
||||
loadMoreMessages(body, loggedInUserId, searchText, MESSAGE_SEARCH_LIMIT, messagesOffset)
|
||||
.then(function() {
|
||||
messagesOffset = messagesOffset + MESSAGE_SEARCH_LIMIT;
|
||||
return;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
}
|
||||
data.originalEvent.preventDefault();
|
||||
});
|
||||
|
||||
body.on(CustomEvents.events.activate, SELECTORS.LOAD_MORE_USERS, function(e, data) {
|
||||
if (searchText !== '') {
|
||||
loadMoreUsers(body, loggedInUserId, searchText, USERS_SEARCH_LIMIT, usersOffset)
|
||||
.then(function() {
|
||||
usersOffset = usersOffset + USERS_SEARCH_LIMIT;
|
||||
return;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
}
|
||||
data.originalEvent.preventDefault();
|
||||
});
|
||||
|
||||
header.on(CustomEvents.events.activate, SELECTORS.CANCEL_SEARCH_BUTTON, function() {
|
||||
clearSearchInput(header);
|
||||
showEmptyMessage(body);
|
||||
showSearchIcon(header);
|
||||
hideSearchResults(body);
|
||||
hideLoadingIcon(header);
|
||||
hideLoadingPlaceholder(body);
|
||||
usersOffset = 0;
|
||||
messagesOffset = 0;
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_ADDED, function(userId) {
|
||||
addContact(body, userId);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_REMOVED, function(userId) {
|
||||
removeContact(body, userId);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_BLOCKED, function(userId) {
|
||||
blockContact(body, userId);
|
||||
});
|
||||
|
||||
PubSub.subscribe(Events.CONTACT_UNBLOCKED, function(userId) {
|
||||
unblockContact(body, userId);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the search page.
|
||||
*
|
||||
* @param {Object} header Contacts header container element.
|
||||
* @param {Object} body Contacts body container element.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var show = function(header, body) {
|
||||
if (!body.attr('data-init')) {
|
||||
registerEventListeners(header, body);
|
||||
body.attr('data-init', true);
|
||||
}
|
||||
|
||||
var searchInput = getSearchInput(header);
|
||||
searchInput.focus();
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
/**
|
||||
* String describing this page used for aria-labels.
|
||||
*
|
||||
* @param {Object} header Contacts header container element.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var description = function(header) {
|
||||
var searchInput = getSearchInput(header);
|
||||
var searchText = searchInput.val().trim();
|
||||
return Str.get_string('messagedrawerviewsearch', 'core_message', searchText);
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
description: description
|
||||
};
|
||||
});
|
142
message/amd/src/message_drawer_view_settings.js
Normal file
142
message/amd/src/message_drawer_view_settings.js
Normal file
@ -0,0 +1,142 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* Controls the settings page in the message drawer.
|
||||
*
|
||||
* @module core_message/message_drawer_view_settings
|
||||
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'jquery',
|
||||
'core/notification',
|
||||
'core/str',
|
||||
'core_message/message_repository',
|
||||
'core/custom_interaction_events',
|
||||
],
|
||||
function(
|
||||
$,
|
||||
Notification,
|
||||
Str,
|
||||
Repository,
|
||||
CustomEvents
|
||||
) {
|
||||
|
||||
var SELECTORS = {
|
||||
SETTINGS: '[data-region="settings"]',
|
||||
PREFERENCE_CONTROL: '[data-region="preference-control"]',
|
||||
PRIVACY_PREFERENCE: '[data-preference="blocknoncontacts"] input[type="radio"]',
|
||||
EMAIL_ENABLED_PREFERENCE: '[data-preference="emailnotifications"] input[type="checkbox"]'
|
||||
};
|
||||
|
||||
var PREFERENCES_EMAIL = {
|
||||
'message_provider_moodle_instantmessage_loggedoff': {
|
||||
type: 'emailnotifications',
|
||||
enabled: 'email',
|
||||
disabled: 'none'
|
||||
},
|
||||
'message_provider_moodle_instantmessage_loggedin': {
|
||||
type: 'emailnotifications',
|
||||
enabled: 'email',
|
||||
disabled: 'none'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create all of the event listeners for the message preferences page.
|
||||
*
|
||||
* @method registerEventListeners
|
||||
* @param {Object} body The settings body element.
|
||||
* @param {Number} loggedInUserId The logged in user id.
|
||||
*/
|
||||
var registerEventListeners = function(body, loggedInUserId) {
|
||||
var settingsContainer = body.find(SELECTORS.SETTINGS);
|
||||
|
||||
CustomEvents.define(settingsContainer, [
|
||||
CustomEvents.events.activate
|
||||
]);
|
||||
|
||||
settingsContainer.on(CustomEvents.events.activate, SELECTORS.EMAIL_ENABLED_PREFERENCE, function(e) {
|
||||
var checkbox = $(e.target);
|
||||
var setting = checkbox.closest(SELECTORS.PREFERENCE_CONTROL);
|
||||
var type = setting.attr('data-preference');
|
||||
var isEnabled = checkbox.prop('checked');
|
||||
var preferences = Object.keys(PREFERENCES_EMAIL).reduce(function(carry, preference) {
|
||||
var config = PREFERENCES_EMAIL[preference];
|
||||
|
||||
if (config.type === type) {
|
||||
carry.push({
|
||||
type: preference,
|
||||
value: isEnabled ? config.enabled : config.disabled
|
||||
});
|
||||
}
|
||||
|
||||
return carry;
|
||||
}, []);
|
||||
|
||||
Repository.savePreferences(loggedInUserId, preferences)
|
||||
.catch(Notification.exception);
|
||||
}
|
||||
);
|
||||
|
||||
settingsContainer.on(CustomEvents.events.activate, SELECTORS.PRIVACY_PREFERENCE, function(e) {
|
||||
var newValue = $(e.target).val();
|
||||
var preferences = [
|
||||
{
|
||||
type: 'message_blocknoncontacts',
|
||||
value: newValue
|
||||
}
|
||||
];
|
||||
|
||||
Repository.savePreferences(loggedInUserId, preferences)
|
||||
.catch(Notification.exception);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the settings page by adding event listeners to
|
||||
* the checkboxes.
|
||||
*
|
||||
* @param {Object} header The settings header element.
|
||||
* @param {Object} body The settings body element.
|
||||
* @param {Number} loggedInUserId The logged in user id.
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var show = function(header, body, loggedInUserId) {
|
||||
if (!body.attr('data-init')) {
|
||||
registerEventListeners(body, loggedInUserId);
|
||||
body.attr('data-init', true);
|
||||
}
|
||||
|
||||
return $.Deferred().resolve().promise();
|
||||
};
|
||||
|
||||
/**
|
||||
* String describing this page used for aria-labels.
|
||||
*
|
||||
* @return {Object} jQuery promise
|
||||
*/
|
||||
var description = function() {
|
||||
return Str.get_string('messagedrawerviewsettings', 'core_message');
|
||||
};
|
||||
|
||||
return {
|
||||
show: show,
|
||||
description: description,
|
||||
};
|
||||
});
|
106
message/lib.php
106
message/lib.php
@ -763,3 +763,109 @@ function core_message_user_preferences() {
|
||||
});
|
||||
return $preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the message drawer to be included in the top of the body of
|
||||
* each page.
|
||||
*
|
||||
* @return string HTML
|
||||
*/
|
||||
function core_message_before_standard_top_of_body_html() {
|
||||
global $USER, $CFG, $PAGE;
|
||||
|
||||
// Early bail out conditions.
|
||||
if (empty($CFG->messaging) || !isloggedin() || isguestuser() || user_not_fully_set_up($USER) ||
|
||||
get_user_preferences('auth_forcepasswordchange') ||
|
||||
(!$USER->policyagreed && !is_siteadmin() &&
|
||||
($manager = new \core_privacy\local\sitepolicy\manager()) && $manager->is_defined())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$renderer = $PAGE->get_renderer('core');
|
||||
$unreadconversationcount = \core_message\api::count_unread_conversations($USER);
|
||||
$individualconversationcount = \core_message\api::count_conversations(
|
||||
$USER,
|
||||
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
|
||||
true
|
||||
);
|
||||
$groupconversationcount = \core_message\api::count_conversations(
|
||||
$USER,
|
||||
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
|
||||
true
|
||||
);
|
||||
$systemcontext = \context_system::instance();
|
||||
$usercontext = \context_user::instance($USER->id);
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
|
||||
$favouriteconversationcount = $ufservice->count_favourites_by_type('core_message', 'message_conversations', $systemcontext);
|
||||
$requestcount = \core_message\api::count_received_contact_requests($USER);
|
||||
$contactscount = \core_message\api::count_contacts($USER->id);
|
||||
|
||||
// Get the privacy settings options for being messaged.
|
||||
$privacysetting = \core_message\api::get_user_privacy_messaging_preference($USER->id);
|
||||
$choices = [];
|
||||
$choices[] = [
|
||||
'value' => \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
|
||||
'text' => get_string('contactableprivacy_onlycontacts', 'message'),
|
||||
'checked' => ($privacysetting == \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS)
|
||||
];
|
||||
$choices[] = [
|
||||
'value' => \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
|
||||
'text' => get_string('contactableprivacy_coursemember', 'message'),
|
||||
'checked' => ($privacysetting == \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER)
|
||||
];
|
||||
if (!empty($CFG->messagingallusers)) {
|
||||
// Add the MESSAGE_PRIVACY_SITE option when site-wide messaging between users is enabled.
|
||||
$choices[] = [
|
||||
'value' => \core_message\api::MESSAGE_PRIVACY_SITE,
|
||||
'text' => get_string('contactableprivacy_site', 'message'),
|
||||
'checked' => ($privacysetting == \core_message\api::MESSAGE_PRIVACY_SITE)
|
||||
];
|
||||
}
|
||||
// Email settings.
|
||||
$emailloggedin = get_user_preferences('message_provider_moodle_instantmessage_loggedin', 'none', $USER->id);
|
||||
$emailloggedoff = get_user_preferences('message_provider_moodle_instantmessage_loggedoff', 'none', $USER->id);
|
||||
$emailenabled = $emailloggedin == 'email' && $emailloggedoff == 'email';
|
||||
|
||||
return $renderer->render_from_template('core_message/message_drawer', [
|
||||
'contactrequestcount' => $requestcount,
|
||||
'loggedinuser' => [
|
||||
'id' => $USER->id,
|
||||
'midnight' => usergetmidnight(time())
|
||||
],
|
||||
'overview' => [
|
||||
'messages' => [
|
||||
'expanded' => false,
|
||||
'count' => [
|
||||
'unread' => $unreadconversationcount,
|
||||
'total' => $individualconversationcount
|
||||
],
|
||||
'placeholders' => array_fill(0, $individualconversationcount, true)
|
||||
],
|
||||
'groupmessages' => [
|
||||
'expanded' => false,
|
||||
'count' => [
|
||||
'unread' => 0, // TODO: fix me.
|
||||
'total' => $groupconversationcount
|
||||
],
|
||||
'placeholders' => array_fill(0, $groupconversationcount, true)
|
||||
],
|
||||
'favourites' => [
|
||||
'expanded' => true,
|
||||
'count' => [
|
||||
'unread' => 0, // TODO: fix me.
|
||||
'total' => $favouriteconversationcount
|
||||
],
|
||||
'placeholders' => array_fill(0, $favouriteconversationcount, true)
|
||||
],
|
||||
],
|
||||
'contacts' => [
|
||||
'sectioncontacts' => [
|
||||
'placeholders' => array_fill(0, $contactscount > 50 ? 50 : $contactscount, true)
|
||||
]
|
||||
],
|
||||
'settings' => [
|
||||
'privacy' => $choices,
|
||||
'emailenabled' => $emailenabled
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
70
message/templates/message_drawer.mustache
Normal file
70
message/templates/message_drawer.mustache
Normal file
@ -0,0 +1,70 @@
|
||||
{{!
|
||||
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 core_message/message_drawer
|
||||
|
||||
This template will render the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div
|
||||
id="message-drawer-{{uniqid}}"
|
||||
class="message-drawer bg-light hidden"
|
||||
aria-expanded="false"
|
||||
aria-hidden="true"
|
||||
data-region="message-drawer"
|
||||
role="region"
|
||||
>
|
||||
<div class="header-container position-relative" data-region="header-container">
|
||||
{{> core_message/message_drawer_view_contacts_header }}
|
||||
{{> core_message/message_drawer_view_conversation_header }}
|
||||
{{> core_message/message_drawer_view_overview_header }}
|
||||
{{> core_message/message_drawer_view_search_header }}
|
||||
{{> core_message/message_drawer_view_settings_header }}
|
||||
</div>
|
||||
<div class="body-container position-relative" data-region="body-container">
|
||||
{{> core_message/message_drawer_view_contact_body }}
|
||||
{{> core_message/message_drawer_view_contacts_body }}
|
||||
{{> core_message/message_drawer_view_conversation_body }}
|
||||
{{> core_message/message_drawer_view_group_info_body }}
|
||||
{{> core_message/message_drawer_view_overview_body }}
|
||||
{{> core_message/message_drawer_view_search_body }}
|
||||
{{> core_message/message_drawer_view_settings_body }}
|
||||
</div>
|
||||
<div class="footer-container position-relative" data-region="footer-container">
|
||||
{{> core_message/message_drawer_view_conversation_footer }}
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
require(['jquery', 'core_message/message_drawer'], function($, MessageDrawer) {
|
||||
var root = $('#message-drawer-{{uniqid}}');
|
||||
MessageDrawer.init(root);
|
||||
});
|
||||
{{/js}}
|
71
message/templates/message_drawer_contacts_list.mustache
Normal file
71
message/templates/message_drawer_contacts_list.mustache
Normal file
@ -0,0 +1,71 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_contacts_list
|
||||
|
||||
This template will render a list of contacts for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
{{#contacts}}
|
||||
<a
|
||||
href="#"
|
||||
class="p-2 d-flex list-group-item list-group-item-action border-0"
|
||||
data-route="view-conversation"
|
||||
{{#conversationid}}
|
||||
data-route-param-1="{{.}}"
|
||||
{{/conversationid}}
|
||||
{{^conversationid}}
|
||||
data-route-param-1="false"
|
||||
data-route-param-2="create"
|
||||
data-route-param-3="{{id}}"
|
||||
{{/conversationid}}
|
||||
data-contact-user-id="{{id}}"
|
||||
data-region="contact"
|
||||
>
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{profileimageurl}}}"
|
||||
alt="{{fullname}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
{{#showonlinestatus}}
|
||||
<span class="contact-status {{#isonline}}online{{/isonline}}"></span>
|
||||
{{/showonlinestatus}}
|
||||
<h6 class="ml-2" data-region="searchable">{{fullname}}</h6>
|
||||
<div
|
||||
class="ml-auto align-self-end {{^isblocked}}hidden{{/isblocked}}"
|
||||
data-region="block-icon-container"
|
||||
>
|
||||
{{#pix}} t/block, core, {{#str}} contactblocked, message {{/str}} {{/pix}}
|
||||
</div>
|
||||
</a>
|
||||
{{/contacts}}
|
@ -0,0 +1,48 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_contacts_list_item_placeholder
|
||||
|
||||
This template will render a placeholder loading item for a contact in
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="p-1 d-flex list-group-item border-0" data-region="placeholder">
|
||||
<div
|
||||
class="rounded-circle bg-pulse-grey"
|
||||
style="height: 38px; width: 38px"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 bg-pulse-grey w-50"
|
||||
style="height: 20px;"
|
||||
>
|
||||
</div>
|
||||
</div>
|
90
message/templates/message_drawer_conversations_list.mustache
Normal file
90
message/templates/message_drawer_conversations_list.mustache
Normal file
@ -0,0 +1,90 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_conversations_list
|
||||
|
||||
This template will render a list of conversations for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
{{#conversations}}
|
||||
<a
|
||||
href="#"
|
||||
class="p-2 d-flex list-group-item list-group-item-action border-0 align-items-center"
|
||||
data-conversation-id="{{id}}"
|
||||
>
|
||||
{{#imageurl}}
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{.}}}"
|
||||
alt="{{name}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
{{/imageurl}}
|
||||
{{#showonlinestatus}}
|
||||
<span class="contact-status {{#isonline}}online{{/isonline}}"></span>
|
||||
{{/showonlinestatus}}
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0 text-truncate">{{name}}</strong>
|
||||
<span class="{{^isblocked}}hidden{{/isblocked}}" data-region="contact-icon-blocked">
|
||||
{{#pix}} t/block, core, {{#str}} contactblocked, message {{/str}} {{/pix}}
|
||||
</span>
|
||||
<div
|
||||
class="ml-auto small {{^lastmessagedate}}hidden{{/lastmessagedate}}"
|
||||
data-region="last-message-date"
|
||||
>
|
||||
{{#lastmessagedate}}
|
||||
{{#userdate}} {{.}}, {{#str}} strftimetime24, core_langconfig {{/str}} {{/userdate}}
|
||||
{{/lastmessagedate}}
|
||||
</div>
|
||||
</div>
|
||||
{{#subname}}
|
||||
<p class="m-0 text-truncate">{{.}}</p>
|
||||
{{/subname}}
|
||||
<p class="m-0 font-weight-light text-truncate" data-region="last-message">
|
||||
{{#sentfromcurrentuser}}{{#str}} you, core_message {{/str}}{{/sentfromcurrentuser}}
|
||||
{{lastmessage}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<span
|
||||
class="badge badge-pill badge-primary bg-primary rounded-circle {{^unreadcount}}hidden{{/unreadcount}}"
|
||||
data-region="unread-count"
|
||||
>
|
||||
{{unreadcount}}
|
||||
</span>
|
||||
|
||||
<div class="text-muted">
|
||||
{{> core_message/message_drawer_icon_forward }}
|
||||
</div>
|
||||
</a>
|
||||
{{/conversations}}
|
@ -0,0 +1,65 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_conversations_list_item_placeholder
|
||||
|
||||
This template will render a placeholder loading element for a message in
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="p-1 d-flex list-group-item border-0" data-region="placeholder">
|
||||
<div
|
||||
class="rounded-circle bg-pulse-grey"
|
||||
style="height: 38px; width: 38px"
|
||||
>
|
||||
</div>
|
||||
<div class="ml-2 align-self-center" style="flex: 1">
|
||||
<div
|
||||
class="bg-pulse-grey w-50"
|
||||
style="height: 15px;"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="bg-pulse-grey mt-1"
|
||||
style="height: 15px; width: 90%"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-pulse-grey align-self-center"
|
||||
style="height: 15px; width: 15px"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 bg-pulse-grey align-self-center"
|
||||
style="height: 15px; width: 15px"
|
||||
>
|
||||
</div>
|
||||
</div>
|
37
message/templates/message_drawer_icon_back.mustache
Normal file
37
message/templates/message_drawer_icon_back.mustache
Normal file
@ -0,0 +1,37 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_icon_back
|
||||
|
||||
This template will render the back icon for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<span class="dir-rtl-hide">{{#pix}} i/previous, core {{/pix}}</span>
|
||||
<span class="dir-ltr-hide">{{#pix}} i/next, core {{/pix}}</span>
|
37
message/templates/message_drawer_icon_forward.mustache
Normal file
37
message/templates/message_drawer_icon_forward.mustache
Normal file
@ -0,0 +1,37 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_icon_forward
|
||||
|
||||
This template will render the forward icon for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<span class="dir-rtl-hide">{{#pix}} i/next, core {{/pix}}</span>
|
||||
<span class="dir-ltr-hide">{{#pix}} i/previous, core {{/pix}}</span>
|
58
message/templates/message_drawer_lazy_load_list.mustache
Normal file
58
message/templates/message_drawer_lazy_load_list.mustache
Normal file
@ -0,0 +1,58 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_lazy_load_list
|
||||
|
||||
This template will render a lazy loaded list for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div
|
||||
class="{{$rootclasses}}{{/rootclasses}}"
|
||||
style="overflow-y: auto"
|
||||
aria-live="polite"
|
||||
data-region="lazy-load-list"
|
||||
data-user-id="{{loggedinuser.id}}"
|
||||
{{$rootattributes}}{{/rootattributes}}
|
||||
>
|
||||
<div class="hidden text-center p-2" data-region="empty-message-container">
|
||||
<p class="text-muted mt-2">
|
||||
{{$emptymessage}}{{/emptymessage}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="hidden list-group" data-region="content-container">
|
||||
{{$content}}{{/content}}
|
||||
</div>
|
||||
<div class="list-group" data-region="placeholder-container">
|
||||
{{$placeholder}}{{/placeholder}}
|
||||
</div>
|
||||
<div class="w-100 text-center p-3 hidden" data-region="loading-icon-container" >
|
||||
{{> core/loading }}
|
||||
</div>
|
||||
</div>
|
97
message/templates/message_drawer_messages_list.mustache
Normal file
97
message/templates/message_drawer_messages_list.mustache
Normal file
@ -0,0 +1,97 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_messages_list
|
||||
|
||||
This template will render a list of messages for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
{{#messages}}
|
||||
<a
|
||||
href="#"
|
||||
class="p-2 d-flex list-group-item list-group-item-action border-0 align-items-center"
|
||||
data-route="view-conversation"
|
||||
{{#conversationid}}
|
||||
data-route-param-1="{{.}}"
|
||||
{{/conversationid}}
|
||||
{{^conversationid}}
|
||||
data-route-param-1="false"
|
||||
data-route-param-2="create"
|
||||
data-route-param-3="{{userid}}"
|
||||
{{/conversationid}}
|
||||
data-conversation-id="{{conversationid}}"
|
||||
>
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{profileimageurl}}}"
|
||||
alt="{{fullname}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
{{#showonlinestatus}}
|
||||
<span class="contact-status {{#isonline}}online{{/isonline}}"></span>
|
||||
{{/showonlinestatus}}
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0">
|
||||
{{fullname}}
|
||||
|
||||
<span class="{{^isblocked}}hidden{{/isblocked}}" data-region="contact-icon-blocked">
|
||||
{{#pix}} t/block, core, {{#str}} contactblocked, message {{/str}} {{/pix}}
|
||||
</span>
|
||||
</strong>
|
||||
<div
|
||||
class="ml-auto small {{^lastmessagedate}}hidden{{/lastmessagedate}}"
|
||||
data-region="last-message-date"
|
||||
>
|
||||
{{#lastmessagedate}}
|
||||
{{#userdate}} {{.}}, {{#str}} strftimetime24, core_langconfig {{/str}} {{/userdate}}
|
||||
{{/lastmessagedate}}
|
||||
</div>
|
||||
</div>
|
||||
<p class="m-0 font-weight-light text-truncate" data-region="last-message">
|
||||
{{#sentfromcurrentuser}}{{#str}} you, core_message {{/str}}{{/sentfromcurrentuser}}
|
||||
{{lastmessage}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<span
|
||||
class="badge badge-pill badge-primary bg-primary rounded-circle {{^unreadcount}}hidden{{/unreadcount}}"
|
||||
data-region="unread-count"
|
||||
>
|
||||
{{unreadcount}}
|
||||
</span>
|
||||
|
||||
<div class="text-muted">
|
||||
{{> core_message/message_drawer_icon_forward }}
|
||||
</div>
|
||||
</a>
|
||||
{{/messages}}
|
@ -0,0 +1,65 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_messages_list_item_placeholder
|
||||
|
||||
This template will render a placeholder loading element for a message in
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="p-1 d-flex list-group-item border-0" data-region="placeholder">
|
||||
<div
|
||||
class="rounded-circle bg-pulse-grey"
|
||||
style="height: 38px; width: 38px"
|
||||
>
|
||||
</div>
|
||||
<div class="ml-2 align-self-center" style="flex: 1">
|
||||
<div
|
||||
class="bg-pulse-grey w-50"
|
||||
style="height: 15px;"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="bg-pulse-grey mt-1"
|
||||
style="height: 15px; width: 90%"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="bg-pulse-grey align-self-center"
|
||||
style="height: 15px; width: 15px"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 bg-pulse-grey align-self-center"
|
||||
style="height: 15px; width: 15px"
|
||||
>
|
||||
</div>
|
||||
</div>
|
65
message/templates/message_drawer_non_contacts_list.mustache
Normal file
65
message/templates/message_drawer_non_contacts_list.mustache
Normal file
@ -0,0 +1,65 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_non_contacts_list
|
||||
|
||||
This template will render a list of non contacts for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
{{#noncontacts}}
|
||||
<a
|
||||
href="#"
|
||||
class="p-2 d-flex list-group-item list-group-item-action border-0"
|
||||
data-route="view-conversation"
|
||||
{{#conversationid}}
|
||||
data-route-param-1="{{.}}"
|
||||
{{/conversationid}}
|
||||
{{^conversationid}}
|
||||
data-route-param-1="false"
|
||||
data-route-param-2="create"
|
||||
data-route-param-3="{{id}}"
|
||||
{{/conversationid}}
|
||||
>
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{profileimageurl}}}"
|
||||
alt="{{fullname}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
<h6 class="ml-2" data-region="searchable">{{fullname}}</h6>
|
||||
{{#isblocked}}
|
||||
<div class="ml-auto align-self-end">
|
||||
{{#pix}} t/block, core, {{#str}} contactblocked, message {{/str}} {{/pix}}
|
||||
</div>
|
||||
{{/isblocked}}
|
||||
</a>
|
||||
{{/noncontacts}}
|
44
message/templates/message_drawer_view_contact_body.mustache
Normal file
44
message/templates/message_drawer_view_contact_body.mustache
Normal file
@ -0,0 +1,44 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_contact_body
|
||||
|
||||
This template will render the body section of the contact page in the
|
||||
message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div
|
||||
class="hidden"
|
||||
data-region="view-contact"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="p-2 pt-3" data-region="content-container"></div>
|
||||
</div>
|
@ -0,0 +1,95 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_contact_body_content
|
||||
|
||||
This template will render the content for the body section of the contact
|
||||
page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<a class="align-self-center" href="#" data-route-back>
|
||||
{{> core_message/message_drawer_icon_back }}
|
||||
</a>
|
||||
<div class="px-3 pb-3">
|
||||
<div class="text-center">
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{profileimageurl}}"
|
||||
aria-hidden="true"
|
||||
alt="{{#str}} pictureof, moodle, {{fullname}} {{/str}}"
|
||||
title="{{#str}} pictureof, moodle, {{fullname}} {{/str}}"
|
||||
style="height: 100px; width: 100px"
|
||||
>
|
||||
</div>
|
||||
<h2 class="mt-2 text-center text-truncate">{{fullname}}</h2>
|
||||
<div class="px-4 mt-4">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-block {{^isblocked}}hidden{{/isblocked}}"
|
||||
data-route="view-conversation"
|
||||
data-route-param-1=""
|
||||
data-route-param-2="unblock"
|
||||
data-route-param-3="{{userid}}"
|
||||
>
|
||||
{{#str}}unblockuser, message{{/str}}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-danger btn-block {{#isblocked}}hidden{{/isblocked}}"
|
||||
data-route="view-conversation"
|
||||
data-route-param-1=""
|
||||
data-route-param-2="block"
|
||||
data-route-param-3="{{userid}}"
|
||||
>
|
||||
{{#str}}blockuser, message{{/str}}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-danger btn-block {{^iscontact}}hidden{{/iscontact}}"
|
||||
data-route="view-conversation"
|
||||
data-route-param-1=""
|
||||
data-route-param-2="remove-contact"
|
||||
data-route-param-3="{{userid}}"
|
||||
>
|
||||
{{#str}}removefromyourcontacts, message{{/str}}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-block {{#iscontact}}hidden{{/iscontact}}"
|
||||
data-route="view-conversation"
|
||||
data-route-param-1=""
|
||||
data-route-param-2="add-contact"
|
||||
data-route-param-3="{{userid}}"
|
||||
>
|
||||
{{#str}}addtoyourcontacts, message{{/str}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
96
message/templates/message_drawer_view_contacts_body.mustache
Normal file
96
message/templates/message_drawer_view_contacts_body.mustache
Normal file
@ -0,0 +1,96 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_contacts_body
|
||||
|
||||
This template will render the body content of the contacts page in the
|
||||
message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="hidden h-100" data-region="view-contacts" aria-hidden="true" data-user-id="{{loggedinuser.id}}">
|
||||
<div class="d-flex flex-column h-100">
|
||||
<div class="p-3 border-bottom">
|
||||
<ul class="nav nav-pills nav-fill" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
id="contacts-tab-{{uniqid}}"
|
||||
class="nav-link active"
|
||||
href="#contacts-tab-panel-{{uniqid}}"
|
||||
data-toggle="tab"
|
||||
data-action="show-contacts-section"
|
||||
role="tab"
|
||||
aria-controls="contacts-tab-panel-{{uniqid}}"
|
||||
aria-selected="true"
|
||||
>
|
||||
{{#str}} contacts, core_message {{/str}}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
id="requests-tab-{{uniqid}}"
|
||||
class="nav-link"
|
||||
href="#requests-tab-panel-{{uniqid}}"
|
||||
data-toggle="tab"
|
||||
data-action="show-requests-section"
|
||||
role="tab"
|
||||
aria-controls="requests-tab-panel-{{uniqid}}"
|
||||
aria-selected="false"
|
||||
>
|
||||
{{#str}} requests {{/str}}
|
||||
<span class="badge bg-primary ml-2 {{^contactrequestcount}}hidden{{/contactrequestcount}}" data-region="contact-request-count">
|
||||
{{contactrequestcount}}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content d-flex flex-column">
|
||||
{{< core_message/message_drawer_view_contacts_body_section_contacts }}
|
||||
{{$rootclasses}}tab-pane fade show active h-100{{/rootclasses}}
|
||||
{{$rootattributes}}
|
||||
id="contacts-tab-panel-{{uniqid}}"
|
||||
data-section="contacts"
|
||||
role="tabpanel"
|
||||
aria-labelledby="contacts-tab-{{uniqid}}"
|
||||
{{/rootattributes}}
|
||||
{{/ core_message/message_drawer_view_contacts_body_section_contacts }}
|
||||
|
||||
{{< core_message/message_drawer_view_contacts_body_section_requests }}
|
||||
{{$rootclasses}}tab-pane fade h-100{{/rootclasses}}
|
||||
{{$rootattributes}}
|
||||
id="requests-tab-panel-{{uniqid}}"
|
||||
data-section="requests"
|
||||
role="tabpanel"
|
||||
aria-labelledby="requests-tab-{{uniqid}}"
|
||||
{{/rootattributes}}
|
||||
{{/ core_message/message_drawer_view_contacts_body_section_requests }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,48 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_contacts_body_section_contacts
|
||||
|
||||
This template will render the contacts section of the body of the contacts
|
||||
page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
{{< core_message/message_drawer_lazy_load_list }}
|
||||
{{$emptymessage}}{{#str}} nocontactsgetstarted, core_message {{/str}}{{/emptymessage}}
|
||||
{{$placeholder}}
|
||||
{{#contacts}}
|
||||
{{#sectioncontacts}}
|
||||
{{#placeholders}}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{/placeholders}}
|
||||
{{/sectioncontacts}}
|
||||
{{/contacts}}
|
||||
{{/placeholder}}
|
||||
{{/ core_message/message_drawer_lazy_load_list }}
|
@ -0,0 +1,81 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_contacts_body_section_requests
|
||||
|
||||
This template will render the the requests section of the body of the contacts
|
||||
page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
{{< core_message/message_drawer_lazy_load_list }}
|
||||
{{$emptymessage}}{{#str}} nocontactrequests, core_message {{/str}}{{/emptymessage}}
|
||||
{{$placeholder}}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{> core_message/message_drawer_contacts_list_item_placeholder }}
|
||||
{{/placeholder}}
|
||||
{{/ core_message/message_drawer_lazy_load_list }}
|
@ -0,0 +1,71 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_contacts_list
|
||||
|
||||
This template will render a list of contacts for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
{{#requests}}
|
||||
<a
|
||||
href="#"
|
||||
class="p-2 d-flex list-group-item list-group-item-action border-0 align-items-center"
|
||||
data-route="view-conversation"
|
||||
{{#conversationid}}
|
||||
data-route-param-1="{{.}}"
|
||||
{{/conversationid}}
|
||||
{{^conversationid}}
|
||||
data-route-param-1="false"
|
||||
data-route-param-2="create"
|
||||
data-route-param-3="{{id}}"
|
||||
{{/conversationid}}
|
||||
data-request-id="{{id}}"
|
||||
data-region="contact-request"
|
||||
>
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{profileimageurl}}}"
|
||||
alt="{{fullname}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0">
|
||||
{{fullname}}
|
||||
</strong>
|
||||
</div>
|
||||
<p class="m-0 font-weight-light text-truncate">
|
||||
{{#str}} wouldliketocontactyou, core_message {{/str}}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
{{/requests}}
|
@ -0,0 +1,53 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_contacts_header
|
||||
|
||||
This template will render the header for the contacts page of
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="hidden border-bottom px-2 py-3" aria-hidden="true" data-region="view-contacts">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="align-self-stretch">
|
||||
<a class="h-100 d-flex align-items-center mr-2" href="#" data-route-back>
|
||||
{{> core_message/message_drawer_icon_back }}
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
{{#str}} contacts, core_message {{/str}}
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<a href="#" data-route="view-search">
|
||||
{{#pix}} a/search, core {{/pix}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,56 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_contacts_section
|
||||
|
||||
This template will render a generic "section" on the contacts page of
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div
|
||||
data-region="{{$region}}{{/region}}"
|
||||
data-user-id="{{loggedinuser.id}}"
|
||||
>
|
||||
<div
|
||||
id="{{$region}}{{/region}}-target"
|
||||
aria-labelledby="{{$region}}{{/region}}"
|
||||
>
|
||||
<div class="hidden text-center p-2" data-region="empty-message-container">
|
||||
{{$emptymessage}}{{/emptymessage}}
|
||||
</div>
|
||||
<div class="hidden list-group" data-region="contacts-content-container">
|
||||
{{$content}}{{/content}}
|
||||
</div>
|
||||
<div class="list-group" data-region="placeholder-container">
|
||||
{{$placeholder}}{{/placeholder}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,60 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_conversation_body
|
||||
|
||||
This template will render the body container for the conversation page in
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
*
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div
|
||||
class="view-conversation hidden h-100"
|
||||
aria-hidden="true"
|
||||
data-region="view-conversation"
|
||||
data-user-id="{{loggedinuser.id}}"
|
||||
data-midnight="{{loggedinuser.midnight}}"
|
||||
style="overflow-y: auto; overflow-x: hidden"
|
||||
>
|
||||
<div class="position-relative h-100" data-region="content-container" style="overflow-y: auto; overflow-x: hidden">
|
||||
<div class="p-3 text-center hidden" data-region="contact-request-sent-message-container">
|
||||
<p class="m-0">{{#str}} contactrequestsent, core_message {{/str}}</p>
|
||||
<p class="font-italic font-weight-light" data-region="text"></p>
|
||||
</div>
|
||||
<div class="content-message-container hidden h-100 px-2 pb-2 pt-0" data-region="content-message-container" role="log" style="overflow-y: auto; overflow-x: hidden">
|
||||
<div class="hidden text-center p-3" data-region="more-messages-loading-icon-container">{{> core/loading }}</div>
|
||||
</div>
|
||||
<div class="p-4 w-100 h-100 hidden position-absolute" data-region="confirm-dialogue-container" style="top: 0; background: rgba(0,0,0,0.3);">
|
||||
{{> core_message/message_drawer_view_conversation_body_confirm_dialogue }}
|
||||
</div>
|
||||
<div class="px-2 pb-2 pt-0" data-region="content-placeholder">
|
||||
{{> core_message/message_drawer_view_conversation_body_placeholder }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,78 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_body_confirm_dialogue
|
||||
|
||||
This template will render the confirmation dialogue inside the conversation page of
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="p-3 bg-white" data-region="confirm-dialogue" role="alert">
|
||||
<h3 class="h6 hidden" data-region="dialogue-header"></h3>
|
||||
<p class="text-muted" data-region="dialogue-text"></p>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="confirm-block">
|
||||
<span data-region="dialogue-button-text">{{#str}} block, core {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="confirm-unblock">
|
||||
<span data-region="dialogue-button-text">{{#str}} unblock, core_message {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="confirm-remove-contact">
|
||||
<span data-region="dialogue-button-text">{{#str}} remove, core {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="confirm-add-contact">
|
||||
<span data-region="dialogue-button-text">{{#str}} add, core {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="confirm-delete-selected-messages">
|
||||
<span data-region="dialogue-button-text">{{#str}} delete, core {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="confirm-delete-conversation">
|
||||
<span data-region="dialogue-button-text">{{#str}} delete, core {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="request-add-contact">
|
||||
<span data-region="dialogue-button-text">{{#str}} sendcontactrequest, core_message {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-primary btn-block hidden" data-action="accept-contact-request">
|
||||
<span data-region="dialogue-button-text">{{#str}} acceptandaddcontact, core_message {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary btn-block hidden" data-action="decline-contact-request">
|
||||
<span data-region="dialogue-button-text">{{#str}} decline, core_message {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary btn-block" data-action="cancel-confirm">{{#str}} cancel, core {{/str}}</button>
|
||||
</div>
|
@ -0,0 +1,40 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_body_day
|
||||
|
||||
This template will render a day's worth of messages in the body of the
|
||||
conversation page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="mt-4" data-region="day-container" data-day-id="{{timestamp}}">
|
||||
<h6 class="text-center mb-4">{{#userdate}} {{timestamp}}, {{#str}} strftimedateshort, core_langconfig {{/str}} {{/userdate}}</h6>
|
||||
{{> core_message/message_drawer_view_conversation_body_messages }}
|
||||
</div>
|
@ -0,0 +1,83 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_covnersation_body_day_placeholder
|
||||
|
||||
This template will render the loading placeholder elements for a day of messages
|
||||
in the conversation page of the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="mt-4">
|
||||
<div class="mb-4">
|
||||
<div class="mx-auto bg-white" style="height: 25px; width: 100px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column p-2 bg-white rounded mb-2">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="mr-2">
|
||||
<div class="rounded-circle bg-pulse-grey" style="height: 35px; width: 35px"></div>
|
||||
</div>
|
||||
<div class="mr-4 w-75 bg-pulse-grey" style="height: 16px"></div>
|
||||
<div class="ml-auto bg-pulse-grey" style="width: 35px; height: 16px"></div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey w-100" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-75 mt-2" style="height: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column p-2 bg-white rounded mb-2">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="mr-2">
|
||||
<div class="rounded-circle bg-pulse-grey" style="height: 35px; width: 35px"></div>
|
||||
</div>
|
||||
<div class="mr-4 w-75 bg-pulse-grey" style="height: 16px"></div>
|
||||
<div class="ml-auto bg-pulse-grey" style="width: 35px; height: 16px"></div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey w-100" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-75 mt-2" style="height: 16px"></div>
|
||||
</div>
|
||||
<div class="d-flex flex-column p-2 bg-white rounded mb-2">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<div class="mr-2">
|
||||
<div class="rounded-circle bg-pulse-grey" style="height: 35px; width: 35px"></div>
|
||||
</div>
|
||||
<div class="mr-4 w-75 bg-pulse-grey" style="height: 16px"></div>
|
||||
<div class="ml-auto bg-pulse-grey" style="width: 35px; height: 16px"></div>
|
||||
</div>
|
||||
<div class="bg-pulse-grey w-100" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-100 mt-2" style="height: 16px"></div>
|
||||
<div class="bg-pulse-grey w-75 mt-2" style="height: 16px"></div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,70 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_body_message
|
||||
|
||||
This template will render a single message for the body of the conversation page
|
||||
in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div
|
||||
class="message clickable d-flex flex-column p-2 {{#fromloggedinuser}}bg-secondary{{/fromloggedinuser}}{{^fromloggedinuser}}bg-white{{/fromloggedinuser}} rounded mb-2"
|
||||
data-region="message"
|
||||
data-message-id="{{id}}"
|
||||
role="checkbox"
|
||||
aria-checked="false"
|
||||
tabindex="0"
|
||||
>
|
||||
<div class="d-flex align-items-center {{^fromloggedinuser}}pb-2{{/fromloggedinuser}}">
|
||||
{{^fromloggedinuser}}
|
||||
<div>
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{userfrom.profileimageurl}}}"
|
||||
alt="{{userfrom.fullname}}"
|
||||
aria-hidden="true"
|
||||
style="height: 30px"
|
||||
>
|
||||
</div>
|
||||
<div class="pl-2 pr-2">
|
||||
<h6 class="text-truncate m-0">{{userfrom.fullname}}</h6>
|
||||
</div>
|
||||
{{/fromloggedinuser}}
|
||||
<div
|
||||
class="ml-auto small text-right text-muted"
|
||||
style="flex-shrink: 0"
|
||||
>
|
||||
{{formattedtime}}
|
||||
</div>
|
||||
<span class="hidden ml-2 small text-primary" data-region="not-selected-icon">{{#pix}} i/unchecked, core {{/pix}}</span>
|
||||
<span class="hidden ml-2 small text-primary" data-region="selected-icon">{{#pix}} i/checked, core {{/pix}}</span>
|
||||
</div>
|
||||
<div>{{{text}}}</div>
|
||||
</div>
|
@ -0,0 +1,41 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_body_messages
|
||||
|
||||
This template will render the list of messages in the body of the conversation
|
||||
page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div data-region="day-messages-container">
|
||||
{{#messages}}
|
||||
{{> core_message/message_drawer_view_conversation_body_message }}
|
||||
{{/messages}}
|
||||
</div>
|
@ -0,0 +1,48 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_body_placeholder
|
||||
|
||||
This template will render the loading placeholder elements for the body of
|
||||
the conversation page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="h-100 d-flex flex-column">
|
||||
<div
|
||||
class="px-2 pb-2 pt-0 bg-light h-100"
|
||||
style="overflow-y: auto"
|
||||
>
|
||||
{{> core_message/message_drawer_view_conversation_body_day_placeholder }}
|
||||
{{> core_message/message_drawer_view_conversation_body_day_placeholder }}
|
||||
{{> core_message/message_drawer_view_conversation_body_day_placeholder }}
|
||||
{{> core_message/message_drawer_view_conversation_body_day_placeholder }}
|
||||
{{> core_message/message_drawer_view_conversation_body_day_placeholder }}
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,66 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_footer
|
||||
|
||||
This template will render the footer container for the conversation page
|
||||
in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div
|
||||
class="hidden border-top bg-white position-relative"
|
||||
aria-hidden="true"
|
||||
data-region="view-conversation"
|
||||
>
|
||||
<div class="hidden p-2" data-region="content-messages-footer-container">
|
||||
{{> core_message/message_drawer_view_conversation_footer_content }}
|
||||
</div>
|
||||
<div class="hidden p-2" data-region="content-messages-footer-edit-mode-container">
|
||||
{{> core_message/message_drawer_view_conversation_footer_edit_mode }}
|
||||
</div>
|
||||
<div class="hidden bg-secondary p-3" data-region="content-messages-footer-require-contact-container">
|
||||
{{> core_message/message_drawer_view_conversation_footer_require_contact }}
|
||||
</div>
|
||||
<div class="hidden bg-secondary p-3" data-region="content-messages-footer-require-unblock-container">
|
||||
{{> core_message/message_drawer_view_conversation_footer_require_unblock }}
|
||||
</div>
|
||||
<div class="hidden bg-secondary p-3" data-region="content-messages-footer-unable-to-message">
|
||||
{{> core_message/message_drawer_view_conversation_footer_unable_to_message }}
|
||||
</div>
|
||||
<div class="p-2" data-region="placeholder-container">
|
||||
{{> core_message/message_drawer_view_conversation_footer_placeholder }}
|
||||
</div>
|
||||
<div
|
||||
class="hidden position-absolute"
|
||||
data-region="confirm-dialogue-container"
|
||||
style="top: -1px; bottom: 0; right: 0; left: 0; background: rgba(0,0,0,0.3);"
|
||||
></div>
|
||||
</div>
|
@ -0,0 +1,59 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_covnersation_footer_content
|
||||
|
||||
This template will render the footer content for the conversation page in
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="d-flex mt-1">
|
||||
<textarea
|
||||
data-region="send-message-txt"
|
||||
class="form-control bg-light"
|
||||
rows="3"
|
||||
data-auto-rows
|
||||
data-min-rows="3"
|
||||
data-max-rows="5"
|
||||
role="textbox"
|
||||
aria-label="{{#str}} writeamessage, core_message {{/str}}"
|
||||
placeholder="{{#str}} writeamessage, core_message {{/str}}"
|
||||
style="resize: none"
|
||||
></textarea>
|
||||
<button
|
||||
class="btn btn-link btn-icon icon-size-3 ml-1 mt-auto"
|
||||
aria-label="{{#str}} sendmessage, core_message {{/str}}"
|
||||
data-action="send-message"
|
||||
>
|
||||
<span data-region="send-icon-container">{{#pix}} i/sendmessage, core {{/pix}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,50 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_footer_edit_mode
|
||||
|
||||
This template will render the foot while the conversation page is in edit mode
|
||||
in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="d-flex p-3">
|
||||
<button
|
||||
class="btn btn-link btn-icon my-1 icon-size-4"
|
||||
data-action="delete-selected-messages"
|
||||
data-toggle="tooltip"
|
||||
data-placement="top"
|
||||
title="{{#str}} deleteselectedmessages, core_message {{/str}}"
|
||||
>
|
||||
<span data-region="icon-container">{{#pix}} i/delete, core {{/pix}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
<span class="sr-only">{{#str}} deleteselectedmessages, core_message {{/str}}</span>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,40 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_footer_placeholder
|
||||
|
||||
This template will render the loading placeholder elements in the footer of
|
||||
the conversation page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="d-flex">
|
||||
<div class="bg-pulse-grey w-100" style="height: 80px"></div>
|
||||
<div class="mx-2 mb-2 align-self-end bg-pulse-grey" style="height: 20px; width: 20px"></div>
|
||||
</div>
|
@ -0,0 +1,45 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_footer_require_contact
|
||||
|
||||
This template will render the footer when the user must add the other user as
|
||||
a contact in a conversation in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="p-3 bg-white">
|
||||
<p data-region="title"></p>
|
||||
<p class="text-muted" data-region="text"></p>
|
||||
<button type="button" class="btn btn-primary btn-block" data-action="request-add-contact">
|
||||
<span data-region="dialogue-button-text">{{#str}} sendcontactrequest, core_message {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,44 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_footer_require_unblock
|
||||
|
||||
This template will render the footer content when the user must unblock the other
|
||||
user in a conversation in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="p-3 bg-white">
|
||||
<p class="text-muted" data-region="text">{{#str}} youhaveblockeduser, core_message {{/str}}</p>
|
||||
<button type="button" class="btn btn-primary btn-block" data-action="request-unblock">
|
||||
<span data-region="dialogue-button-text">{{#str}} unblockuser, core_message {{/str}}</span>
|
||||
<span class="hidden" data-region="loading-icon-container">{{> core/loading }}</span>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,40 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_unable_to_message
|
||||
|
||||
This template will render the footer content when the user is unable to message
|
||||
in a conversation in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="p-3 bg-white">
|
||||
<p class="text-muted" data-region="text">{{#str}} unabletomessage, core_message {{/str}}</p>
|
||||
</div>
|
@ -0,0 +1,54 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_header
|
||||
|
||||
This template will render the header for the conversation page of the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div
|
||||
class="hidden bg-white position-relative border-bottom px-2 py-3"
|
||||
aria-hidden="true"
|
||||
data-region="view-conversation"
|
||||
>
|
||||
<div class="hidden" data-region="header-content"></div>
|
||||
<div class="hidden" data-region="header-edit-mode">
|
||||
{{> core_message/message_drawer_view_conversation_header_edit_mode }}
|
||||
</div>
|
||||
<div data-region="header-placeholder">
|
||||
{{> core_message/message_drawer_view_conversation_header_placeholder }}
|
||||
</div>
|
||||
<div
|
||||
class="hidden position-absolute"
|
||||
data-region="confirm-dialogue-container"
|
||||
style="top: 0; bottom: -1px; right: 0; left: 0; background: rgba(0,0,0,0.3);"
|
||||
></div>
|
||||
</div>
|
@ -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 core_message/message_drawer_view_conversation_heeader_content
|
||||
|
||||
This template will render the header content of the conversation page in
|
||||
the message message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="align-self-stretch" >
|
||||
<a class="h-100 mr-2 d-flex align-items-center" href="#" data-route-back>
|
||||
{{> core_message/message_drawer_icon_back }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="d-flex text-truncate">
|
||||
<a class="d-flex text-truncate" href="#" data-action="view-contact">
|
||||
{{#imageurl}}
|
||||
<div class="d-flex align-items-center">
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{.}}}"
|
||||
alt="{{name}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
</div>
|
||||
{{/imageurl}}
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0 text-truncate">{{name}}</strong>
|
||||
<span class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary" data-region="favourite-icon-container">
|
||||
{{#pix}} i/star-rating, core {{/pix}}
|
||||
</span>
|
||||
</div>
|
||||
{{#showonlinestatus}}
|
||||
<p class="m-0 font-weight-light text-truncate">
|
||||
{{#isonline}}{{#str}} loggedin, core_message {{/str}}{{/isonline}}
|
||||
{{^isonline}}{{#str}} loggedoff, core_message {{/str}}{{/isonline}}
|
||||
</p>
|
||||
{{/showonlinestatus}}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ml-auto dropdown">
|
||||
<button class="btn btn-link btn-icon icon-size-3" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{#pix}} i/moremenu, core {{/pix}}
|
||||
</button>
|
||||
<div class="dropdown-menu pull-right">
|
||||
<a class="dropdown-item" href="#" data-action="view-contact">
|
||||
{{#str}} info, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{#isfavourite}}hidden{{/isfavourite}}" href="#" data-action="confirm-favourite">
|
||||
{{#str}} addtofavourites, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{^isfavourite}}hidden{{/isfavourite}}" href="#" data-action="confirm-unfavourite">
|
||||
{{#str}} removefromfavourites, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{#isblocked}}hidden{{/isblocked}}" href="#" data-action="request-block">
|
||||
{{#str}} blockuser, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{^isblocked}}hidden{{/isblocked}}" href="#" data-action="request-unblock">
|
||||
{{#str}} unblockuser, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-action="request-delete-conversation">
|
||||
{{#str}} deleteconversation, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{#iscontact}}hidden{{/iscontact}}" href="#" data-action="request-add-contact">
|
||||
{{#str}} addtoyourcontacts, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{^iscontact}}hidden{{/iscontact}}" href="#" data-action="request-remove-contact">
|
||||
{{#str}} removefromyourcontacts, core_message {{/str}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,71 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_heeader_content_type_private_no_controls
|
||||
|
||||
This template will render the header content of the conversation page without controls in
|
||||
the message message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="align-self-stretch" >
|
||||
<a class="h-100 mr-2 d-flex align-items-center" href="#" data-route-back>
|
||||
{{> core_message/message_drawer_icon_back }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="d-flex text-truncate">
|
||||
{{#imageurl}}
|
||||
<div class="d-flex align-items-center">
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{.}}}"
|
||||
alt="{{name}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
</div>
|
||||
{{/imageurl}}
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0 text-truncate">{{name}}</strong>
|
||||
<span class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary" data-region="favourite-icon-container">
|
||||
{{#pix}} i/star-rating, core {{/pix}}
|
||||
</span>
|
||||
</div>
|
||||
{{#showonlinestatus}}
|
||||
<p class="m-0 font-weight-light text-truncate">
|
||||
{{#isonline}}{{#str}} loggedin, core_message {{/str}}{{/isonline}}
|
||||
{{^isonline}}{{#str}} loggedoff, core_message {{/str}}{{/isonline}}
|
||||
</p>
|
||||
{{/showonlinestatus}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,87 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_heeader_content
|
||||
|
||||
This template will render the header content of the conversation page in
|
||||
the message message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="align-self-stretch" >
|
||||
<a class="h-100 mr-2 d-flex align-items-center" href="#" data-route-back>
|
||||
{{> core_message/message_drawer_icon_back }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="d-flex text-truncate">
|
||||
<a class="d-flex text-truncate" href="#" data-action="view-group-info">
|
||||
{{#imageurl}}
|
||||
<div class="d-flex align-items-center">
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{.}}}"
|
||||
alt="{{name}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
</div>
|
||||
{{/imageurl}}
|
||||
<div class="w-100 text-truncate ml-2">
|
||||
<div class="d-flex">
|
||||
<strong class="m-0 text-truncate">{{name}}</strong>
|
||||
<span class="{{^isfavourite}}hidden{{/isfavourite}} ml-1 text-primary" data-region="favourite-icon-container">
|
||||
{{#pix}} i/star-rating, core {{/pix}}
|
||||
</span>
|
||||
</div>
|
||||
<p class="m-0 text-truncate">{{subname}}</p>
|
||||
<p class="m-0 font-weight-light text-truncate">
|
||||
{{#str}} numparticipants, core_message, {{totalmembercount}} {{/str}}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ml-auto dropdown">
|
||||
<button class="btn btn-link btn-icon icon-size-3" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{#pix}} i/moremenu, core {{/pix}}
|
||||
</button>
|
||||
<div class="dropdown-menu pull-right">
|
||||
<a class="dropdown-item" href="#" data-action="view-group-info">
|
||||
{{#str}} groupinfo, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{#isfavourite}}hidden{{/isfavourite}}" href="#" data-action="confirm-favourite">
|
||||
{{#str}} addtofavourites, core_message {{/str}}
|
||||
</a>
|
||||
<a class="dropdown-item {{^isfavourite}}hidden{{/isfavourite}}" href="#" data-action="confirm-unfavourite">
|
||||
{{#str}} removefromfavourites, core_message {{/str}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,44 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_header_edit_mode
|
||||
|
||||
This template will render the header while the conversation is in edit mode on
|
||||
the conversation page of the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div class="d-flex p-2 align-items-center">
|
||||
{{#str}} messagesselected:, core_message {{/str}}
|
||||
<span class="ml-1" data-region="message-selected-court">1</span>
|
||||
<button type="button" class="ml-auto close" aria-label="" data-action="cancel-edit-mode">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
@ -0,0 +1,60 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_conversation_header_placeholder
|
||||
|
||||
This template will render the loading placeholder elements for the header
|
||||
of the conversation page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="d-flex">
|
||||
<div class="align-self-stretch" >
|
||||
<a class="h-100 mr-2 d-flex align-items-center" href="#" data-route-back>
|
||||
{{> core_message/message_drawer_icon_back }}
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 rounded-circle bg-pulse-grey align-self-center"
|
||||
style="height: 38px; width: 38px"
|
||||
>
|
||||
</div>
|
||||
<div class="ml-2 " style="flex: 1">
|
||||
<div
|
||||
class="mt-1 bg-pulse-grey w-75"
|
||||
style="height: 16px;"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 bg-pulse-grey align-self-center"
|
||||
style="height: 16px; width: 20px"
|
||||
>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,48 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_group_info_body
|
||||
|
||||
This template will render the body section of the group info page in the
|
||||
message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<div
|
||||
class="hidden"
|
||||
aria-hidden="true"
|
||||
data-region="view-group-info"
|
||||
>
|
||||
<div
|
||||
class="pt-3 h-100 d-flex flex-column"
|
||||
data-region="group-info-content-container"
|
||||
style="overflow-y: auto"
|
||||
></div>
|
||||
</div>
|
@ -0,0 +1,70 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_group_info_body_content
|
||||
|
||||
This template will render the content for the body section of the group
|
||||
info page in the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
<a class="px-2 align-self-start" href="#" data-route-back>
|
||||
{{> core_message/message_drawer_icon_back }}
|
||||
</a>
|
||||
<div class="px-2">
|
||||
<div class="text-center">
|
||||
{{#imageurl}}
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{.}}"
|
||||
aria-hidden="true"
|
||||
alt="{{#str}} pictureof, moodle, {{name}} {{/str}}"
|
||||
title="{{#str}} pictureof, moodle, {{name}} {{/str}}"
|
||||
style="height: 100px; width: 100px"
|
||||
>
|
||||
{{/imageurl}}
|
||||
</div>
|
||||
<h2 class="mt-2 mb-0 text-center text-truncate h4">{{name}}</h2>
|
||||
{{#subname}}<h3 class="mt-2 mb-0 text-center text-truncate h5">{{.}}</h3>{{/subname}}
|
||||
</div>
|
||||
<h3 class="border-bottom h6 mt-3 px-3 py-2 mb-0 font-weight-bold">{{#str}} participants, core_message {{/str}}</h3>
|
||||
<div class="pt-1 bg-white" data-region="members-list-container" style="overflow-y: auto">
|
||||
{{< core_message/message_drawer_lazy_load_list }}
|
||||
{{$rootattributes}}
|
||||
data-region="members-list"
|
||||
{{/rootattributes}}
|
||||
{{$emptymessage}}{{#str}} noparticipants, core_message {{/str}}{{/emptymessage}}
|
||||
{{$placeholder}}
|
||||
{{#placeholders}}
|
||||
{{> core_message/message_drawer_view_group_info_participants_list_item_placeholder }}
|
||||
{{/placeholders}}
|
||||
{{/placeholder}}
|
||||
{{/ core_message/message_drawer_lazy_load_list }}
|
||||
</div>
|
@ -0,0 +1,71 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_group_info_participants_list
|
||||
|
||||
This template will render a list of contacts for the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
|
||||
{{#contacts}}
|
||||
<a
|
||||
href="#"
|
||||
class="p-2 d-flex list-group-item list-group-item-action border-0"
|
||||
data-route="view-conversation"
|
||||
{{#conversationid}}
|
||||
data-route-param-1="{{.}}"
|
||||
{{/conversationid}}
|
||||
{{^conversationid}}
|
||||
data-route-param-1="false"
|
||||
data-route-param-2="create"
|
||||
data-route-param-3="{{id}}"
|
||||
{{/conversationid}}
|
||||
data-contact-user-id="{{id}}"
|
||||
data-region="contact"
|
||||
>
|
||||
<img
|
||||
class="rounded-circle"
|
||||
src="{{{profileimageurl}}}"
|
||||
alt="{{fullname}}"
|
||||
aria-hidden="true"
|
||||
style="height: 38px"
|
||||
>
|
||||
{{#showonlinestatus}}
|
||||
<span class="contact-status {{#isonline}}online{{/isonline}}"></span>
|
||||
{{/showonlinestatus}}
|
||||
<h6 class="ml-2" data-region="searchable">{{fullname}}</h6>
|
||||
<div
|
||||
class="ml-auto align-self-end {{^isblocked}}hidden{{/isblocked}}"
|
||||
data-region="block-icon-container"
|
||||
>
|
||||
{{#pix}} t/block, core, {{#str}} contactblocked, message {{/str}} {{/pix}}
|
||||
</div>
|
||||
</a>
|
||||
{{/contacts}}
|
@ -0,0 +1,48 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_group_info_participants_list_item_placeholder
|
||||
|
||||
This template will render a placeholder loading item for a contact in
|
||||
the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="p-1 d-flex list-group-item border-0" data-region="placeholder">
|
||||
<div
|
||||
class="rounded-circle bg-pulse-grey"
|
||||
style="height: 38px; width: 38px"
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 bg-pulse-grey w-50"
|
||||
style="height: 20px;"
|
||||
>
|
||||
</div>
|
||||
</div>
|
48
message/templates/message_drawer_view_overview_body.mustache
Normal file
48
message/templates/message_drawer_view_overview_body.mustache
Normal file
@ -0,0 +1,48 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_overview_body
|
||||
|
||||
This template will render the body of the overview section of the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="h-100 view-overview-body" aria-hidden="false" data-region="view-overview">
|
||||
<div id="message-drawer-view-overview-container" class="d-flex flex-column h-100" style="overflow-y: auto">
|
||||
{{#overview.favourites}}
|
||||
{{> core_message/message_drawer_view_overview_section_favourites }}
|
||||
{{/overview.favourites}}
|
||||
{{#overview.groupmessages}}
|
||||
{{> core_message/message_drawer_view_overview_section_group_messages }}
|
||||
{{/overview.groupmessages}}
|
||||
{{#overview.messages}}
|
||||
{{> core_message/message_drawer_view_overview_section_messages }}
|
||||
{{/overview.messages}}
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,71 @@
|
||||
{{!
|
||||
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 core_message/message_drawer_view_overview_header
|
||||
|
||||
This template will render the header for the overview page of the message drawer.
|
||||
|
||||
Classes required for JS:
|
||||
* none
|
||||
|
||||
Data attributes required for JS:
|
||||
* All data attributes are required
|
||||
|
||||
Context variables required for this template:
|
||||
* userid The logged in user id
|
||||
* urls The URLs for the popover
|
||||
|
||||
Example context (json):
|
||||
{}
|
||||
|
||||
}}
|
||||
<div class="border-bottom px-2 py-3" aria-hidden="false" data-region="view-overview">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text pr-0 bg-white">
|
||||
{{#pix}} a/search, core {{/pix}}
|
||||
</span>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control border-left-0"
|
||||
placeholder="{{#str}} search, core_search {{/str}}"
|
||||
aria-label="{{#str}} search, core_search {{/str}}"
|
||||
data-region="view-overview-search-input"
|
||||
>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<a
|
||||
href="#"
|
||||
data-route="view-settings"
|
||||
data-route-param="{{loggedinuser.id}}"
|
||||
>
|
||||
{{#pix}} t/edit, core {{/pix}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right mt-3">
|
||||
<a href="#" data-route="view-contacts">
|
||||
{{#pix}} i/user, core {{/pix}}
|
||||
{{#str}} contacts, core_message {{/str}}
|
||||
<span class="badge bg-primary ml-2 {{^contactrequestcount}}hidden{{/contactrequestcount}}" data-region="contact-request-count">
|
||||
{{contactrequestcount}}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user