From 734b198fd36c273f2412bb47ffbc7c1c75079391 Mon Sep 17 00:00:00 2001 From: Sara Arjona Date: Wed, 6 Mar 2019 21:26:29 +0100 Subject: [PATCH] MDL-64715 message: add support for self conversations Added new MESSAGE_CONVERSATION_TYPE_SELF type for self-conversations and upgraded legacy self-conversations to the new type, removing repeated members in the message_conversation_members table. Besides, from now, a self-conversation will be created by default for all the existing users. All the self-conversations have been also starred and a default message will be displayed always to explain how to use them. --- lang/en/message.php | 4 + lib/classes/message/manager.php | 6 + lib/db/services.php | 9 + lib/db/upgrade.php | 184 +++++++++ lib/messagelib.php | 32 +- lib/tests/messagelib_test.php | 53 +++ lib/upgrade.txt | 8 + .../message_drawer_view_conversation.min.js | 2 +- ..._drawer_view_conversation_constants.min.js | 2 +- ...ge_drawer_view_conversation_patcher.min.js | 2 +- ...e_drawer_view_conversation_renderer.min.js | 2 +- .../build/message_drawer_view_overview.min.js | 2 +- ...essage_drawer_view_overview_section.min.js | 2 +- message/amd/build/message_repository.min.js | 2 +- .../src/message_drawer_view_conversation.js | 146 +++++-- ...sage_drawer_view_conversation_constants.js | 15 +- ...essage_drawer_view_conversation_patcher.js | 64 ++- ...ssage_drawer_view_conversation_renderer.js | 77 +++- .../amd/src/message_drawer_view_overview.js | 28 +- .../message_drawer_view_overview_section.js | 33 +- message/amd/src/message_repository.js | 66 +++- message/classes/api.php | 196 +++++---- message/classes/privacy/provider.php | 19 +- message/classes/task/migrate_message_data.php | 13 +- message/externallib.php | 106 ++++- ...age_drawer_view_conversation_body.mustache | 4 + ...ersation_header_content_type_self.mustache | 91 +++++ message/tests/api_test.php | 373 +++++++++++++++--- message/tests/externallib_test.php | 167 +++++--- message/tests/messagelib_test.php | 13 +- message/upgrade.txt | 3 + user/lib.php | 4 + version.php | 2 +- 33 files changed, 1449 insertions(+), 281 deletions(-) create mode 100644 message/templates/message_drawer_view_conversation_header_content_type_self.mustache diff --git a/lang/en/message.php b/lang/en/message.php index 8ce4b5949ca..e3a2fb759a7 100644 --- a/lang/en/message.php +++ b/lang/en/message.php @@ -52,9 +52,11 @@ $string['defaultmessageoutputs'] = 'Notification settings'; $string['defaults'] = 'Defaults'; $string['deleteallconfirm'] = "Are you sure you would like to delete this entire conversation? This will not delete it for other conversation participants."; $string['deleteallmessages'] = "Delete all messages"; +$string['deleteallselfconfirm'] = "Are you sure you would like to delete this entire personal conversation?"; $string['deleteconversation'] = "Delete conversation"; $string['deleteselectedmessages'] = 'Delete selected messages'; $string['deleteselectedmessagesconfirm'] = 'Are you sure you would like to delete the selected messages? This will not delete them for other conversation participants.'; +$string['deleteselectedmessagesconfirmselfconversation'] = 'Are you sure you would like to delete the selected personal messages?'; $string['disableall'] = 'Disable notifications'; $string['disabled'] = 'Messaging is disabled on this site'; $string['disallowed'] = 'Disallowed'; @@ -211,6 +213,8 @@ $string['searchcombined'] = 'Search people and messages'; $string['seeall'] = 'See all'; $string['selectmessagestodelete'] = 'Select messages to delete'; $string['selectnotificationtoview'] = 'Select from the list of notifications on the side to view more details'; +$string['selfconversation'] = 'Personal space'; +$string['selfconversationdefaultmessage'] = 'Save draft messages, links, notes etc. to access later.'; $string['send'] = 'Send'; $string['sender'] = '{$a}:'; $string['sendingvia'] = 'Sending "{$a->provider}" via "{$a->processor}"'; diff --git a/lib/classes/message/manager.php b/lib/classes/message/manager.php index b35c1eda0db..321802814fb 100644 --- a/lib/classes/message/manager.php +++ b/lib/classes/message/manager.php @@ -109,6 +109,12 @@ class manager { // Get conversation type and name. We'll use this to determine which message subject to generate, depending on type. $conv = $DB->get_record('message_conversations', ['id' => $eventdata->convid], 'id, type, name'); + // For now Self conversations are not processed because users are aware of the messages sent by themselves, so we + // can return early. + if ($conv->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF) { + return $savemessage->id; + } + // We treat individual conversations the same as any direct message with 'userfrom' and 'userto' specified. // We know the other user, so set the 'userto' field so that the event code will get access to this field. // If this was a legacy caller (eventdata->userto is set), then use that instead, as we want to use the fields specified diff --git a/lib/db/services.php b/lib/db/services.php index 95a17be3db9..0eaab66f337 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -1170,6 +1170,15 @@ $functions = array( 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), 'ajax' => true ), + 'core_message_get_self_conversation' => array( + 'classname' => 'core_message_external', + 'methodname' => 'get_self_conversation', + 'classpath' => 'message/externallib.php', + 'description' => 'Retrieve a self-conversation for a user', + 'type' => 'read', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), + 'ajax' => true + ), 'core_message_get_messages' => array( 'classname' => 'core_message_external', 'methodname' => 'get_messages', diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 8bf80630525..719dd5c94d0 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -2988,5 +2988,189 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2019041000.02); } + if ($oldversion < 2019041300.01) { + // STEP 1. For the existing and migrated self-conversations, set the type to the new MESSAGE_CONVERSATION_TYPE_SELF, update + // the convhash and star them. + $sql = "SELECT mcm.conversationid, mcm.userid, MAX(mcm.id) as maxid + FROM {message_conversation_members} mcm + GROUP BY mcm.conversationid, mcm.userid + HAVING COUNT(*) > 1"; + $selfconversationsrs = $DB->get_recordset_sql($sql); + $maxids = []; + foreach ($selfconversationsrs as $selfconversation) { + $DB->update_record('message_conversations', + ['id' => $selfconversation->conversationid, + 'type' => \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, + 'convhash' => \core_message\helper::get_conversation_hash([$selfconversation->userid]) + ] + ); + + // Star the existing self-conversation. + $favouriterecord = new \stdClass(); + $favouriterecord->component = 'core_message'; + $favouriterecord->itemtype = 'message_conversations'; + $favouriterecord->itemid = $selfconversation->conversationid; + $userctx = \context_user::instance($selfconversation->userid); + $favouriterecord->contextid = $userctx->id; + $favouriterecord->userid = $selfconversation->userid; + $favouriterecord->timecreated = time(); + $favouriterecord->timemodified = $favouriterecord->timecreated; + + $DB->insert_record('favourite', $favouriterecord); + + // Set the self-conversation member with maxid to remove it later. + $maxids[] = $selfconversation->maxid; + } + $selfconversationsrs->close(); + + // Remove the repeated member with the higher id for all the existing self-conversations. + if (!empty($maxids)) { + list($insql, $inparams) = $DB->get_in_or_equal($maxids); + $DB->delete_records_select('message_conversation_members', "id $insql", $inparams); + } + + // STEP 2. Migrate existing self-conversation relying on old message tables, setting the type to the new + // MESSAGE_CONVERSATION_TYPE_SELF and the convhash to the proper one. Star them also. + + // On the messaging legacy tables, self-conversations are only present in the 'message_read' table, so we don't need to + // check the content in the 'message' table. + $select = 'useridfrom = useridto AND notification = 0'; + $legacyselfmessagesrs = $DB->get_recordset_select('message_read', $select); + foreach ($legacyselfmessagesrs as $message) { + // Get the self-conversation or create and star it if doesn't exist. + $conditions = [ + 'type' => \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, + 'convhash' => \core_message\helper::get_conversation_hash([$message->useridfrom]) + ]; + $selfconversation = $DB->get_record('message_conversations', $conditions); + if (empty($selfconversation)) { + // Create the self-conversation. + $selfconversation = new \stdClass(); + $selfconversation->type = \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF; + $selfconversation->convhash = \core_message\helper::get_conversation_hash([$message->useridfrom]); + $selfconversation->enabled = 1; + $selfconversation->timecreated = time(); + $selfconversation->timemodified = $selfconversation->timecreated; + + $selfconversation->id = $DB->insert_record('message_conversations', $selfconversation); + + // Add user to this self-conversation. + $member = new \stdClass(); + $member->conversationid = $selfconversation->id; + $member->userid = $message->useridfrom; + $member->timecreated = time(); + + $member->id = $DB->insert_record('message_conversation_members', $member); + + // Star the self-conversation. + $favouriterecord = new \stdClass(); + $favouriterecord->component = 'core_message'; + $favouriterecord->itemtype = 'message_conversations'; + $favouriterecord->itemid = $selfconversation->id; + $userctx = \context_user::instance($message->useridfrom); + $favouriterecord->contextid = $userctx->id; + $favouriterecord->userid = $message->useridfrom; + $favouriterecord->timecreated = time(); + $favouriterecord->timemodified = $favouriterecord->timecreated; + + $DB->insert_record('favourite', $favouriterecord); + } + + // Create the object we will be inserting into the database. + $tabledata = new \stdClass(); + $tabledata->useridfrom = $message->useridfrom; + $tabledata->conversationid = $selfconversation->id; + $tabledata->subject = $message->subject; + $tabledata->fullmessage = $message->fullmessage; + $tabledata->fullmessageformat = $message->fullmessageformat ?? FORMAT_MOODLE; + $tabledata->fullmessagehtml = $message->fullmessagehtml; + $tabledata->smallmessage = $message->smallmessage; + $tabledata->timecreated = $message->timecreated; + + $messageid = $DB->insert_record('messages', $tabledata); + + // Check if we need to mark this message as deleted (self-conversations add this information on the + // timeuserfromdeleted field. + if ($message->timeuserfromdeleted) { + $mua = new \stdClass(); + $mua->userid = $message->useridfrom; + $mua->messageid = $messageid; + $mua->action = \core_message\api::MESSAGE_ACTION_DELETED; + $mua->timecreated = $message->timeuserfromdeleted; + + $DB->insert_record('message_user_actions', $mua); + } + + // Mark this message as read. + $mua = new \stdClass(); + $mua->userid = $message->useridto; + $mua->messageid = $messageid; + $mua->action = \core_message\api::MESSAGE_ACTION_READ; + $mua->timecreated = $message->timeread; + + $DB->insert_record('message_user_actions', $mua); + } + $legacyselfmessagesrs->close(); + + // We can now delete the records from legacy table because the self-conversations have been migrated from the legacy tables. + $DB->delete_records_select('message_read', $select); + + // STEP 3. For existing users without self-conversations, create and star it. + + // Get all the users without a self-conversation. + $sql = "SELECT u.id + FROM {user} u + WHERE u.id NOT IN (SELECT mcm.userid + FROM {message_conversation_members} mcm + INNER JOIN mdl_message_conversations mc + ON mc.id = mcm.conversationid AND mc.type = ? + )"; + $useridsrs = $DB->get_recordset_sql($sql, [\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF]); + // Create the self-conversation for all these users. + foreach ($useridsrs as $user) { + $conditions = [ + 'type' => \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, + 'convhash' => \core_message\helper::get_conversation_hash([$user->id]) + ]; + $selfconversation = $DB->get_record('message_conversations', $conditions); + if (empty($selfconversation)) { + // Create the self-conversation. + $selfconversation = new \stdClass(); + $selfconversation->type = \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF; + $selfconversation->convhash = \core_message\helper::get_conversation_hash([$user->id]); + $selfconversation->enabled = 1; + $selfconversation->timecreated = time(); + $selfconversation->timemodified = $selfconversation->timecreated; + + $selfconversation->id = $DB->insert_record('message_conversations', $selfconversation); + + // Add user to this self-conversation. + $member = new \stdClass(); + $member->conversationid = $selfconversation->id; + $member->userid = $user->id; + $member->timecreated = time(); + + $member->id = $DB->insert_record('message_conversation_members', $member); + + // Star the self-conversation. + $favouriterecord = new \stdClass(); + $favouriterecord->component = 'core_message'; + $favouriterecord->itemtype = 'message_conversations'; + $favouriterecord->itemid = $selfconversation->id; + $userctx = \context_user::instance($user->id); + $favouriterecord->contextid = $userctx->id; + $favouriterecord->userid = $user->id; + $favouriterecord->timecreated = time(); + $favouriterecord->timemodified = $favouriterecord->timecreated; + + $DB->insert_record('favourite', $favouriterecord); + } + } + $useridsrs->close(); + + // Main savepoint reached. + upgrade_main_savepoint(true, 2019041300.01); + } + return true; } diff --git a/lib/messagelib.php b/lib/messagelib.php index 2f3b4174c0b..1dcc437c2e1 100644 --- a/lib/messagelib.php +++ b/lib/messagelib.php @@ -118,18 +118,30 @@ function message_send(\core\message\message $eventdata) { return false; } - if (!$conversationid = \core_message\api::get_conversation_between_users([$eventdata->userfrom->id, - $eventdata->userto->id])) { - $conversation = \core_message\api::create_conversation( - \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, - [ - $eventdata->userfrom->id, - $eventdata->userto->id - ] - ); + if ($eventdata->userfrom->id == $eventdata->userto->id) { + // It's a self conversation. + $conversation = \core_message\api::get_self_conversation($eventdata->userfrom->id); + if (empty($conversation)) { + $conversation = \core_message\api::create_conversation( + \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, + [$eventdata->userfrom->id] + ); + } + } else { + if (!$conversationid = \core_message\api::get_conversation_between_users([$eventdata->userfrom->id, + $eventdata->userto->id])) { + // It's a private conversation between users. + $conversation = \core_message\api::create_conversation( + \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, + [ + $eventdata->userfrom->id, + $eventdata->userto->id + ] + ); + } } // We either have found a conversation, or created one. - $conversationid = $conversationid ? $conversationid : $conversation->id; + $conversationid = !empty($conversationid) ? $conversationid : $conversation->id; $eventdata->convid = $conversationid; } diff --git a/lib/tests/messagelib_test.php b/lib/tests/messagelib_test.php index 489a4852978..e4ee895bd77 100644 --- a/lib/tests/messagelib_test.php +++ b/lib/tests/messagelib_test.php @@ -819,6 +819,59 @@ class core_messagelib_testcase extends advanced_testcase { $sink->clear(); } + /** + * Tests calling message_send() with $eventdata representing a message to a self-conversation. + * + * This test will verify: + * - that the 'messages' record is created. + * - that the processors is not called (for now self-conversations are not processed). + * - the a single event will be generated - 'message_sent' + * + * Note: We won't redirect/capture messages in this test because doing so causes message_send() to return early, before + * processors and events code is called. We need to test this code here, as we generally redirect messages elsewhere and we + * need to be sure this is covered. + */ + public function test_message_send_to_self_conversation() { + global $DB; + $this->preventResetByRollback(); + $this->resetAfterTest(); + + // Create some users and a conversation between them. + $user1 = $this->getDataGenerator()->create_user(array('maildisplay' => 1)); + set_config('allowedemaildomains', 'example.com'); + $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, + [$user1->id]); + + // Generate the message. + $message = new \core\message\message(); + $message->courseid = 1; + $message->component = 'moodle'; + $message->name = 'instantmessage'; + $message->userfrom = $user1; + $message->convid = $conversation->id; + $message->subject = 'message subject 1'; + $message->fullmessage = 'message body'; + $message->fullmessageformat = FORMAT_MARKDOWN; + $message->fullmessagehtml = '

message body

'; + $message->smallmessage = 'small message'; + $message->notification = '0'; + + // Content specific to the email processor. + $content = array('*' => array('header' => ' test ', 'footer' => ' test ')); + $message->set_additional_content('email', $content); + + // Ensure we're going to hit the email processor for this user. + $DB->set_field_select('message_processors', 'enabled', 0, "name <> 'email'"); + set_user_preference('message_provider_moodle_instantmessage_loggedoff', 'email', $user1); + + // Now, send a message and verify the message processors are empty (self-conversations are not processed for now). + $sink = $this->redirectEmails(); + $messageid = message_send($message); + $emails = $sink->get_messages(); + $this->assertCount(0, $emails); + $sink->clear(); + } + /** * Tests calling message_send() with $eventdata representing a message to an group conversation. * diff --git a/lib/upgrade.txt b/lib/upgrade.txt index f1bbeceee21..da93514e83d 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -30,6 +30,14 @@ attribute on forms to avoid collisions in forms loaded in AJAX requests. in this category. To work with list of courses use API methods in core_course_category and also 'course' form element. * It is possible to pass additional conditions to get_courses_search(); core_course_category::search_courses() now allows to search only among courses with completion enabled. +* A new conversation type has been created for self-conversations. During the upgrading process: + - Firstly, the existing self-conversations will be starred and migrated to the new type, removing the duplicated members in the + message_conversation_members table. + - Secondly, the legacy self conversations will be migrated from the legacy 'message_read' table. They will be created using the + new conversation type and will be favourited. + - Finally, the self-conversations for all remaining users without them will be created and starred. +Besides, from now, a self-conversation will be created and starred by default to all the new users (even when $CFG->messaging +is disabled). === 3.6 === diff --git a/message/amd/build/message_drawer_view_conversation.min.js b/message/amd/build/message_drawer_view_conversation.min.js index 6d5e118dbe3..f681f92188d 100644 --- a/message/amd/build/message_drawer_view_conversation.min.js +++ b/message/amd/build/message_drawer_view_conversation.min.js @@ -1 +1 @@ -define(["jquery","core/auto_rows","core/backoff_timer","core/custom_interaction_events","core/notification","core/pubsub","core/str","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_view_conversation_constants","core_message/message_drawer_view_conversation_patcher","core_message/message_drawer_view_conversation_renderer","core_message/message_drawer_view_conversation_state_manager","core_message/message_drawer_router","core_message/message_drawer_routes"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q=null,r=!1,s=0,t=null,u=!0,v=!1,w=null,x=[],y=j.NEWEST_MESSAGES_FIRST,z=j.LOAD_MESSAGE_LIMIT,A=j.INITIAL_NEW_MESSAGE_POLL_TIMEOUT,B=j.SELECTORS,C=j.CONVERSATION_TYPES,D=function(){if(!q||q.type!=C.PRIVATE)return null;var a=q.loggedInUserId,b=Object.keys(q.members).filter(function(b){return a!=b});return b.length?b[0]:null},E=function(a){return Object.keys(p).reduce(function(b,c){if(!b){var d=p[c].state;d.type==C.PRIVATE&&a in d.members&&(b=d.id)}return b},null)},F=function(a){return{id:parseInt(a.attr("data-user-id"),10),fullname:null,profileimageurl:null,profileimageurlsmall:null,isonline:null,showonlinestatus:null,isblocked:null,iscontact:null,isdeleted:null,canmessage:null,requirescontact:null,contactrequests:[]}},G=function(){return s},H=function(a){s=a,p[q.id].messagesOffset=a},I=function(){return r},J=function(a){r=a,p[q.id].loadedAllMessages=a},K=function(a){return a.find(B.MESSAGES_CONTAINER)},L=function(b){return{id:b.id,name:b.name,subname:b.subname,imageUrl:b.imageUrl,isFavourite:b.isFavourite,isMuted:b.isMuted,type:b.type,totalMemberCount:b.totalMemberCount,loggedInUserId:b.loggedInUserId,messages:b.messages.map(function(b){return a.extend({},b)}),members:Object.keys(b.members).reduce(function(c,d){return c[d]=a.extend({},b.members[d]),c[d].contactrequests=b.members[d].contactrequests.map(function(b){return a.extend({},b)}),c},{})}},M=function(a,b){var c=a.id,d=m.setLoadingMembers(q,!0);return d=m.setLoadingMessages(d,!0),w(d).then(function(){return h.getMemberInfo(c,[b],!0,!0)}).then(function(a){if(a.length)return a[0];throw new Error("Unable to load other user profile")}).then(function(b){var c=m.addMembers(q,[b,a]);return c=m.setLoadingMembers(c,!1),c=m.setLoadingMessages(c,!1),c=m.setName(c,b.fullname),c=m.setType(c,1),c=m.setImageUrl(c,b.profileimageurl),c=m.setTotalMemberCount(c,2),w(c).then(function(){return b})})["catch"](function(a){var b=m.setLoadingMembers(q,!1);w(b),e.exception(a)})},N=function(a,b){var c=a.members.filter(function(a){return a.id!=b}),d=c.length?c[0]:null,e=a.name,f=a.imageurl;a.type==C.PRIVATE&&(e=e||d?d.fullname:"",f=f||d?d.profileimageurl:"");var g=m.addMembers(q,a.members);return g=m.setName(g,e),g=m.setSubname(g,a.subname),g=m.setType(g,a.type),g=m.setImageUrl(g,f),g=m.setTotalMemberCount(g,a.membercount),g=m.setIsFavourite(g,a.isfavourite),g=m.setIsMuted(g,a.ismuted),g=m.addMessages(g,a.messages)},O=function(a,b,c,d,f){var g=b.id,i=m.setLoadingMembers(q,!0);return i=m.setLoadingMessages(i,!0),w(i).then(function(){return h.getConversation(g,a,!0,!0,0,0,c+1,d,f)}).then(function(a){return a.messages.length>c?a.messages=a.messages.slice(1):J(!0),H(d+c),a}).then(function(a){var c=a.members.filter(function(a){return a.id==b.id});c.length<1&&(a.members=a.members.concat([b]));var d=N(a,b.id);return d=m.setLoadingMembers(d,!1),d=m.setLoadingMessages(d,!1),w(d).then(function(){return a})}).then(function(){return S(a)})["catch"](function(a){var b=m.setLoadingMembers(q,!1);b=m.setLoadingMessages(b,!1),w(b),e.exception(a)})},P=function(a,b,c,d){var f=a.members.filter(function(a){return a.id==b.id});f.length<1&&(a.members=a.members.concat([b]));var g=N(a,b.id);g=m.setLoadingMembers(g,!1),g=m.setLoadingMessages(g,!0);var h=a.messages.length;return w(g).then(function(){if(hb?a.messages=a.messages.slice(0,-1):J(!0),a):a}).then(function(a){var b=a.members.filter(function(a){return!(a.id in q.members)}),c=m.addMembers(q,b);return c=m.addMessages(c,a.messages),c=m.setLoadingMessages(c,!1),w(c).then(function(){return a})})["catch"](function(a){var b=m.setLoadingMessages(q,!1);throw w(b),a})},R=function(b,c){return function(){var d=q.messages,e=d.length?d[d.length-1]:null;if(e&&!u&&!v){for(var g=[],h=d.length-1;h>=0;h--){var j=d[h];if(j.timeCreated!==e.timeCreated)break;g.push(j.id)}return Q(b,0,0,c,g,e.timeCreated).then(function(a){if(a.messages.length){t.restart();var c=L(q);return f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c),S(b)}return a})}return a.Deferred().resolve().promise()}},S=function(a){var b=q.loggedInUserId;return h.markAllConversationMessagesAsRead(b,a).then(function(){var b=m.markMessagesAsRead(q,q.messages);return f.publish(i.CONVERSATION_READ,a),w(b)})},T=function(a){return ha(a).then(function(){var b=m.addPendingBlockUsersById(q,[a]);return w(b)})},U=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.blockUser(q.loggedInUserId,a)}).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingBlockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_BLOCKED,a),w(c)})},V=function(a){return ha(a).then(function(){var b=m.addPendingUnblockUsersById(q,[a]);return w(b)})},W=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.unblockUser(q.loggedInUserId,a)}).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingUnblockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_UNBLOCKED,a),w(c)})},X=function(a){return ha(a).then(function(){var b=m.addPendingRemoveContactsById(q,[a]);return w(b)})},Y=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.deleteContacts(q.loggedInUserId,[a])}).then(function(b){var c=m.addMembers(q,b);return c=m.removePendingRemoveContactsById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_REMOVED,a),w(c)})},Z=function(a){return ha(a).then(function(){var b=m.addPendingAddContactsById(q,[a]);return w(b)})},$=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.createContactRequest(q.loggedInUserId,a)}).then(function(a){if(!a.request)throw new Error(a.warnings[0].message);return a.request}).then(function(b){var c=m.removePendingAddContactsById(q,[a]);return c=m.addContactRequests(c,[b]),c=m.setLoadingConfirmAction(c,!1),w(c)})},_=function(){var a=q.loggedInUserId,b=q.id;return h.setFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!0);return w(a)}).then(function(){return f.publish(i.CONVERSATION_SET_FAVOURITE,L(q))})},aa=function(){var a=q.loggedInUserId,b=q.id;return h.unsetFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!1);return w(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_FAVOURITE,L(q))})},ba=function(){var a=q.loggedInUserId,b=q.id;return h.setMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!0);return w(a)}).then(function(){return f.publish(i.CONVERSATION_SET_MUTED,L(q))})},ca=function(){var a=q.loggedInUserId,b=q.id;return h.unsetMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!1);return w(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_MUTED,L(q))})},da=function(a){var b=q.selectedMessageIds;return ha(a).then(function(){var a=m.addPendingDeleteMessagesById(q,b);return w(a)})},ea=function(){var a=q.pendingDeleteMessageIds,b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.deleteMessages(q.loggedInUserId,a)}).then(function(){var b=m.removeMessagesById(q,a);b=m.removePendingDeleteMessagesById(b,a),b=m.removeSelectedMessagesById(b,a),b=m.setLoadingConfirmAction(b,!1);var c=q.messages[q.messages.length-1],d=b.messages.length?b.messages[b.messages.length-1]:null;if(d&&d.id!=c.id){var e=L(b);f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,e)}else b.messages.length||f.publish(i.CONVERSATION_DELETED,b.id);return w(b)})},fa=function(a){return ha(a).then(function(){var a=m.setPendingDeleteConversation(q,!0);return w(a)})},ga=function(){var a=m.setLoadingConfirmAction(q,!0);return w(a).then(function(){return h.deleteConversation(q.loggedInUserId,q.id)}).then(function(){var a=m.removeMessages(q,q.messages);return a=m.removeSelectedMessagesById(a,q.selectedMessageIds),a=m.setPendingDeleteConversation(a,!1),a=m.setLoadingConfirmAction(a,!1),f.publish(i.CONVERSATION_DELETED,a.id),w(a)})},ha=function(a){var b=q.pendingDeleteMessageIds,c=m.removePendingAddContactsById(q,[a]);return c=m.removePendingRemoveContactsById(c,[a]),c=m.removePendingUnblockUsersById(c,[a]),c=m.removePendingBlockUsersById(c,[a]),c=m.removePendingDeleteMessagesById(c,b),c=m.setPendingDeleteConversation(c,!1),w(c)},ia=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return w(e).then(function(){return h.acceptContactRequest(a,b)}).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),w(b)}).then(function(){f.publish(i.CONTACT_ADDED,q.members[a]),f.publish(i.CONTACT_REQUEST_ACCEPTED,d)})},ja=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return w(e).then(function(){return h.declineContactRequest(a,b)}).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),w(b)}).then(function(){f.publish(i.CONTACT_REQUEST_DECLINED,d)})},ka=function(a,b){v=!0;var c=m.setSendingMessage(q,!0),d=null;return w(c).then(function(){if(a||q.type!=C.PRIVATE)return h.sendMessageToConversation(a,b);var c=D();return h.sendMessageToUser(c,b).then(function(a){return d=parseInt(a.conversationid,10),a})}).then(function(a){var b=m.addMessages(q,[a]);b=m.setSendingMessage(b,!1);var c=L(b);return b.id||(b=m.setId(b,d),c.id=d,za(d),f.publish(i.CONVERSATION_CREATED,c)),w(b).then(function(){v=!1,f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c)})})["catch"](function(a){v=!1;var b=m.setSendingMessage(q,!1);w(b),e.exception(a)})},la=function(a){var b=q;return b=q.selectedMessageIds.indexOf(a)>-1?m.removeSelectedMessagesById(q,[a]):m.addSelectedMessagesById(q,[a]),w(b)},ma=function(){return ha(D()).then(function(){var a=m.removeSelectedMessagesById(q,q.selectedMessageIds);return w(a)})},na=function(b,c,d,e){var f=function(a){return l.render(b,c,d,a)};if(!e){var g=m.buildInitialState(q.midnight,q.loggedInUserId,q.id),h=k.buildPatch(g,q);f(h)}return x.push(f),function(b){var c=k.buildPatch(q,b),d=x.map(function(a){return a(c)});return a.when.apply(null,d).then(function(){q=b,b.id&&(p[b.id]={state:b,messagesOffset:G(),loadedAllMessages:I()})})}},oa=function(a){return function(b,c){q.loadingConfirmAction||a(D())["catch"](function(a){var b=m.setLoadingConfirmAction(q,!1);w(b),e.exception(a)}),c.originalEvent.preventDefault()}},pa=function(b,c){var d=a(b.target),e=d.closest(B.FOOTER_CONTAINER),f=e.find(B.MESSAGE_TEXT_AREA),g=f.val().trim();""!==g&&ka(q.id,g),c.originalEvent.preventDefault()},qa=function(b,c){var d=window.getSelection(),f=a(b.target);if(""==d.toString()&&!f.is("a")){var g=f.closest(B.MESSAGE),h=parseInt(g.attr("data-message-id"),10);la(h)["catch"](e.exception),c.originalEvent.preventDefault()}},ra=function(a,b){ma()["catch"](e.exception),b.originalEvent.preventDefault()},sa=function(a){return function(b,c){var d=D(),e=q.members[d];n.go(a,o.VIEW_CONTACT,e),c.originalEvent.preventDefault()}},ta=function(a,b){_()["catch"](e.exception),b.originalEvent.preventDefault()},ua=function(a,b){aa()["catch"](e.exception),b.originalEvent.preventDefault()},va=function(a,b){ba()["catch"](e.exception),b.originalEvent.preventDefault()},wa=function(a,b){ca()["catch"](e.exception),b.originalEvent.preventDefault()},xa=function(a){return function(b,c){n.go(a,o.VIEW_GROUP_INFO,{id:q.id,name:q.name,subname:q.subname,imageUrl:q.imageUrl,totalMemberCount:q.totalMemberCount},q.loggedInUserId),c.originalEvent.preventDefault()}},ya=function(a,c,g,h){var j=!1,k=K(g),l=[[B.ACTION_REQUEST_BLOCK,oa(T)],[B.ACTION_REQUEST_UNBLOCK,oa(V)],[B.ACTION_REQUEST_ADD_CONTACT,oa(Z)],[B.ACTION_REQUEST_REMOVE_CONTACT,oa(X)],[B.ACTION_REQUEST_DELETE_CONVERSATION,oa(fa)],[B.ACTION_CANCEL_EDIT_MODE,ra],[B.ACTION_VIEW_CONTACT,sa(a)],[B.ACTION_VIEW_GROUP_INFO,xa(a)],[B.ACTION_CONFIRM_FAVOURITE,ta],[B.ACTION_CONFIRM_MUTE,va],[B.ACTION_CONFIRM_UNFAVOURITE,ua],[B.ACTION_CONFIRM_UNMUTE,wa]],n=[[B.ACTION_CANCEL_CONFIRM,oa(ha)],[B.ACTION_CONFIRM_BLOCK,oa(U)],[B.ACTION_CONFIRM_UNBLOCK,oa(W)],[B.ACTION_CONFIRM_ADD_CONTACT,oa($)],[B.ACTION_CONFIRM_REMOVE_CONTACT,oa(Y)],[B.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES,oa(ea)],[B.ACTION_CONFIRM_DELETE_CONVERSATION,oa(ga)],[B.ACTION_REQUEST_ADD_CONTACT,oa(Z)],[B.ACTION_ACCEPT_CONTACT_REQUEST,oa(ia)],[B.ACTION_DECLINE_CONTACT_REQUEST,oa(ja)],[B.MESSAGE,qa]],p=[[B.SEND_MESSAGE_BUTTON,pa],[B.ACTION_REQUEST_DELETE_SELECTED_MESSAGES,oa(da)],[B.ACTION_REQUEST_ADD_CONTACT,oa(Z)],[B.ACTION_REQUEST_UNBLOCK,oa(V)]];b.init(h),d.define(c,[d.events.activate]),d.define(g,[d.events.activate]),d.define(h,[d.events.activate,d.events.enter]),d.define(k,[d.events.scrollTop,d.events.scrollLock]),k.on(d.events.scrollTop,function(a,b){var c=Object.keys(q.members).length>1;if(!u&&!j&&!I()&&c){j=!0;var d=m.setLoadingMessages(q,!0);w(d).then(function(){return Q(q.id,z,G(),y,[])}).then(function(){j=!1,H(G()+z)})["catch"](function(a){j=!1,e.exception(a)})}b.originalEvent.preventDefault()}),l.forEach(function(a){var b=a[0],e=a[1];c.on(d.events.activate,b,e)}),n.forEach(function(a){var b=a[0],c=a[1];g.on(d.events.activate,b,c)}),p.forEach(function(a){var b=a[0],c=a[1];h.on(d.events.activate,b,c)}),h.on(d.events.enter,B.MESSAGE_TEXT_AREA,function(a,b){var c=h.attr("data-enter-to-send");c&&"false"!=c&&"0"!=c&&pa(a,b)}),f.subscribe(i.ROUTE_CHANGED,function(a){t&&a.route!=o.VIEW_CONVERSATION&&t.stop()})},za=function(a){t&&t.stop(),t=new c(R(a,y),function(a){return a?2*a:A}),t.start()},Aa=function(a,b,c){var d=c.id,e=parseInt(a.attr("data-midnight"),10),f=m.buildInitialState(e,d,b);return q||(q=f),t&&t.stop(),w(f)},Ba=function(a,b,c){return Aa(a,null,b).then(function(){return h.getConversationBetweenUsers(b.id,c,!0,!0,0,0,z,0,y).then(function(c){return Da(a,c,b)})["catch"](function(){return M(b,c)})})},Ca=function(a,b,c){var d=null;return b in p&&(d=p[b]),Aa(a,b,c).then(function(){if(d){var a=d.state;return a=m.setLoadingMessages(a,!1),a=m.setLoadingMembers(a,!1),H(d.messagesOffset),J(d.loadedAllMessages),w(a)}return O(b,c,z,0,y)}).then(function(){return za(b)})},Da=function(a,b,c){var d=null;return b.id in p&&(d=p[b.id]),Aa(a,b.id,c).then(function(){if(d){var a=d.state;return a=m.setLoadingMessages(a,!1),a=m.setLoadingMembers(a,!1),H(d.messagesOffset),J(d.loadedAllMessages),w(a)}return P(b,c,z,y)}).then(function(){return za(b.id)})},Ea=function(b,c,d,f,g,h,i){var k=null,l=null;g&&null!==g&&"object"==typeof g?(k=g,l=parseInt(k.id,10)):(k=null,l=parseInt(g,10),l=isNaN(l)?null:l),!l&&h&&i&&(l=E(i));var m=!q||q.id!=l||i&&i!=D();if(d.attr("data-init")||(w=na(c,d,f,m),ya(b,c,d,f),d.attr("data-init",!0)),m){u=!0;var n=null,o=F(d);return n=k?Da(d,k,o,i):l?Ca(d,l,o,i):Ba(d,o,i),n.then(function(){u=!1,c.find(j.SELECTORS.CAN_RECEIVE_FOCUS).first().focus()})["catch"](function(a){u=!1,e.exception(a)})}if(za(l),q.type==C.PRIVATE&&h){var p=D();switch(h){case"block":return T(p);case"unblock":return V(p);case"add-contact":return Z(p);case"remove-contact":return X(p)}}return a.Deferred().resolve().promise()},Fa=function(){return g.get_string("messagedrawerviewconversation","core_message",q.name)};return{show:Ea,description:Fa}}); \ No newline at end of file +define(["jquery","core/auto_rows","core/backoff_timer","core/custom_interaction_events","core/notification","core/pubsub","core/str","core_message/message_repository","core_message/message_drawer_events","core_message/message_drawer_view_conversation_constants","core_message/message_drawer_view_conversation_patcher","core_message/message_drawer_view_conversation_renderer","core_message/message_drawer_view_conversation_state_manager","core_message/message_drawer_router","core_message/message_drawer_routes"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o){var p={},q=null,r=!1,s=0,t=null,u=!0,v=!1,w=null,x=[],y=j.NEWEST_MESSAGES_FIRST,z=j.LOAD_MESSAGE_LIMIT,A=j.INITIAL_NEW_MESSAGE_POLL_TIMEOUT,B=j.SELECTORS,C=j.CONVERSATION_TYPES,D=function(){if(!q||q.type!=C.PRIVATE&&q.type!=C.SELF)return null;var a=q.loggedInUserId;if(q.type==C.SELF)return a;var b=Object.keys(q.members).filter(function(b){return a!=b});return b.length?b[0]:null},E=function(a){return Object.keys(p).reduce(function(b,c){if(!b){var d=p[c].state;d.type!=C.PRIVATE&&d.type!=C.SELF||a in d.members&&(b=d.id)}return b},null)},F=function(a){return{id:parseInt(a.attr("data-user-id"),10),fullname:null,profileimageurl:null,profileimageurlsmall:null,isonline:null,showonlinestatus:null,isblocked:null,iscontact:null,isdeleted:null,canmessage:null,requirescontact:null,contactrequests:[]}},G=function(){return s},H=function(a){s=a,p[q.id].messagesOffset=a},I=function(){return r},J=function(a){r=a,p[q.id].loadedAllMessages=a},K=function(a){return a.find(B.MESSAGES_CONTAINER)},L=function(b){return{id:b.id,name:b.name,subname:b.subname,imageUrl:b.imageUrl,isFavourite:b.isFavourite,isMuted:b.isMuted,type:b.type,totalMemberCount:b.totalMemberCount,loggedInUserId:b.loggedInUserId,messages:b.messages.map(function(b){return a.extend({},b)}),members:Object.keys(b.members).reduce(function(c,d){return c[d]=a.extend({},b.members[d]),c[d].contactrequests=b.members[d].contactrequests.map(function(b){return a.extend({},b)}),c},{})}},M=function(a,b){var c=a.id,d=m.setLoadingMembers(q,!0);return d=m.setLoadingMessages(d,!0),w(d).then(function(){return h.getMemberInfo(c,[b],!0,!0)}).then(function(a){if(a.length)return a[0];throw new Error("Unable to load other user profile")}).then(function(b){var c=m.addMembers(q,[b,a]);return c=m.setLoadingMembers(c,!1),c=m.setLoadingMessages(c,!1),c=m.setName(c,b.fullname),c=m.setType(c,C.PRIVATE),c=m.setImageUrl(c,b.profileimageurl),c=m.setTotalMemberCount(c,2),w(c).then(function(){return b})})["catch"](function(a){var b=m.setLoadingMembers(q,!1);w(b),e.exception(a)})},N=function(a){var b=a.id,c=m.setLoadingMembers(q,!0);return c=m.setLoadingMessages(c,!0),w(c).then(function(){return h.getMemberInfo(b,[b],!0,!0)}).then(function(a){if(a.length)return a[0];throw new Error("Unable to load other user profile")}).then(function(b){var c=m.addMembers(q,[b,a]);return c=m.setLoadingMembers(c,!1),c=m.setLoadingMessages(c,!1),c=m.setName(c,b.fullname),c=m.setType(c,C.SELF),c=m.setImageUrl(c,b.profileimageurl),c=m.setTotalMemberCount(c,1),w(c).then(function(){return b})})["catch"](function(a){var b=m.setLoadingMembers(q,!1);w(b),e.exception(a)})},O=function(a,b){var c=null;if(a.type==C.PRIVATE){var d=a.members.filter(function(a){return a.id!=b});c=d.length?d[0]:null}else a.type==C.SELF&&(c=a.members[0]);var e=a.name,f=a.imageurl;a.type!=C.PRIVATE&&a.type!=C.SELF||(e=e||c?c.fullname:"",f=f||c?c.profileimageurl:"");var g=m.addMembers(q,a.members);return g=m.setName(g,e),g=m.setSubname(g,a.subname),g=m.setType(g,a.type),g=m.setImageUrl(g,f),g=m.setTotalMemberCount(g,a.membercount),g=m.setIsFavourite(g,a.isfavourite),g=m.setIsMuted(g,a.ismuted),g=m.addMessages(g,a.messages)},P=function(a,b,c,d,f){var g=b.id,i=m.setLoadingMembers(q,!0);return i=m.setLoadingMessages(i,!0),w(i).then(function(){return h.getConversation(g,a,!0,!0,0,0,c+1,d,f)}).then(function(a){return a.messages.length>c?a.messages=a.messages.slice(1):J(!0),H(d+c),a}).then(function(a){var c=a.members.filter(function(a){return a.id==b.id});c.length<1&&(a.members=a.members.concat([b]));var d=O(a,b.id);return d=m.setLoadingMembers(d,!1),d=m.setLoadingMessages(d,!1),w(d).then(function(){return a})}).then(function(){return T(a)})["catch"](function(a){var b=m.setLoadingMembers(q,!1);b=m.setLoadingMessages(b,!1),w(b),e.exception(a)})},Q=function(a,b,c,d){var f=a.members.filter(function(a){return a.id==b.id});f.length<1&&(a.members=a.members.concat([b]));var g=O(a,b.id);g=m.setLoadingMembers(g,!1),g=m.setLoadingMessages(g,!0);var h=a.messages.length;return w(g).then(function(){if(hb?a.messages=a.messages.slice(0,-1):J(!0),a):a}).then(function(a){var b=a.members.filter(function(a){return!(a.id in q.members)}),c=m.addMembers(q,b);return c=m.addMessages(c,a.messages),c=m.setLoadingMessages(c,!1),w(c).then(function(){return a})})["catch"](function(a){var b=m.setLoadingMessages(q,!1);throw w(b),a})},S=function(b,c){return function(){var d=q.messages,e=d.length?d[d.length-1]:null;if(e&&!u&&!v){for(var g=[],h=d.length-1;h>=0;h--){var j=d[h];if(j.timeCreated!==e.timeCreated)break;g.push(j.id)}return R(b,0,0,c,g,e.timeCreated).then(function(a){if(a.messages.length){t.restart();var c=L(q);return f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c),T(b)}return a})}return a.Deferred().resolve().promise()}},T=function(a){var b=q.loggedInUserId;return h.markAllConversationMessagesAsRead(b,a).then(function(){var b=m.markMessagesAsRead(q,q.messages);return f.publish(i.CONVERSATION_READ,a),w(b)})},U=function(a){return ia(a).then(function(){var b=m.addPendingBlockUsersById(q,[a]);return w(b)})},V=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.blockUser(q.loggedInUserId,a)}).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingBlockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_BLOCKED,a),w(c)})},W=function(a){return ia(a).then(function(){var b=m.addPendingUnblockUsersById(q,[a]);return w(b)})},X=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.unblockUser(q.loggedInUserId,a)}).then(function(b){var c=m.addMembers(q,[b]);return c=m.removePendingUnblockUsersById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_UNBLOCKED,a),w(c)})},Y=function(a){return ia(a).then(function(){var b=m.addPendingRemoveContactsById(q,[a]);return w(b)})},Z=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.deleteContacts(q.loggedInUserId,[a])}).then(function(b){var c=m.addMembers(q,b);return c=m.removePendingRemoveContactsById(c,[a]),c=m.setLoadingConfirmAction(c,!1),f.publish(i.CONTACT_REMOVED,a),w(c)})},$=function(a){return ia(a).then(function(){var b=m.addPendingAddContactsById(q,[a]);return w(b)})},_=function(a){var b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.createContactRequest(q.loggedInUserId,a)}).then(function(a){if(!a.request)throw new Error(a.warnings[0].message);return a.request}).then(function(b){var c=m.removePendingAddContactsById(q,[a]);return c=m.addContactRequests(c,[b]),c=m.setLoadingConfirmAction(c,!1),w(c)})},aa=function(){var a=q.loggedInUserId,b=q.id;return h.setFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!0);return w(a)}).then(function(){return f.publish(i.CONVERSATION_SET_FAVOURITE,L(q))})},ba=function(){var a=q.loggedInUserId,b=q.id;return h.unsetFavouriteConversations(a,[b]).then(function(){var a=m.setIsFavourite(q,!1);return w(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_FAVOURITE,L(q))})},ca=function(){var a=q.loggedInUserId,b=q.id;return h.setMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!0);return w(a)}).then(function(){return f.publish(i.CONVERSATION_SET_MUTED,L(q))})},da=function(){var a=q.loggedInUserId,b=q.id;return h.unsetMutedConversations(a,[b]).then(function(){var a=m.setIsMuted(q,!1);return w(a)}).then(function(){return f.publish(i.CONVERSATION_UNSET_MUTED,L(q))})},ea=function(a){var b=q.selectedMessageIds;return ia(a).then(function(){var a=m.addPendingDeleteMessagesById(q,b);return w(a)})},fa=function(){var a=q.pendingDeleteMessageIds,b=m.setLoadingConfirmAction(q,!0);return w(b).then(function(){return h.deleteMessages(q.loggedInUserId,a)}).then(function(){var b=m.removeMessagesById(q,a);b=m.removePendingDeleteMessagesById(b,a),b=m.removeSelectedMessagesById(b,a),b=m.setLoadingConfirmAction(b,!1);var c=q.messages[q.messages.length-1],d=b.messages.length?b.messages[b.messages.length-1]:null;if(d&&d.id!=c.id){var e=L(b);f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,e)}else b.messages.length||f.publish(i.CONVERSATION_DELETED,b.id);return w(b)})},ga=function(a){return ia(a).then(function(){var a=m.setPendingDeleteConversation(q,!0);return w(a)})},ha=function(){var a=m.setLoadingConfirmAction(q,!0);return w(a).then(function(){return h.deleteConversation(q.loggedInUserId,q.id)}).then(function(){var a=m.removeMessages(q,q.messages);return a=m.removeSelectedMessagesById(a,q.selectedMessageIds),a=m.setPendingDeleteConversation(a,!1),a=m.setLoadingConfirmAction(a,!1),f.publish(i.CONVERSATION_DELETED,a.id),w(a)})},ia=function(a){var b=q.pendingDeleteMessageIds,c=m.removePendingAddContactsById(q,[a]);return c=m.removePendingRemoveContactsById(c,[a]),c=m.removePendingUnblockUsersById(c,[a]),c=m.removePendingBlockUsersById(c,[a]),c=m.removePendingDeleteMessagesById(c,b),c=m.setPendingDeleteConversation(c,!1),w(c)},ja=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return w(e).then(function(){return h.acceptContactRequest(a,b)}).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),w(b)}).then(function(){f.publish(i.CONTACT_ADDED,q.members[a]),f.publish(i.CONTACT_REQUEST_ACCEPTED,d)})},ka=function(a){var b=q.loggedInUserId,c=q.members[a].contactrequests.filter(function(a){return a.requesteduserid==b}),d=c[0],e=m.setLoadingConfirmAction(q,!0);return w(e).then(function(){return h.declineContactRequest(a,b)}).then(function(a){var b=m.removeContactRequests(q,[d]);return b=m.addMembers(q,[a]),b=m.setLoadingConfirmAction(b,!1),w(b)}).then(function(){f.publish(i.CONTACT_REQUEST_DECLINED,d)})},la=function(a,b){v=!0;var c=m.setSendingMessage(q,!0),d=null;return w(c).then(function(){if(a||q.type!=C.PRIVATE&&q.type!=C.SELF)return h.sendMessageToConversation(a,b);var c=D();return h.sendMessageToUser(c,b).then(function(a){return d=parseInt(a.conversationid,10),a})}).then(function(a){var b=m.addMessages(q,[a]);b=m.setSendingMessage(b,!1);var c=L(b);return b.id||(b=m.setId(b,d),c.id=d,Aa(d),f.publish(i.CONVERSATION_CREATED,c)),w(b).then(function(){v=!1,f.publish(i.CONVERSATION_NEW_LAST_MESSAGE,c)})})["catch"](function(a){v=!1;var b=m.setSendingMessage(q,!1);w(b),e.exception(a)})},ma=function(a){var b=q;return b=q.selectedMessageIds.indexOf(a)>-1?m.removeSelectedMessagesById(q,[a]):m.addSelectedMessagesById(q,[a]),w(b)},na=function(){return ia(D()).then(function(){var a=m.removeSelectedMessagesById(q,q.selectedMessageIds);return w(a)})},oa=function(b,c,d,e){var f=function(a){return l.render(b,c,d,a)};if(!e){var g=m.buildInitialState(q.midnight,q.loggedInUserId,q.id),h=k.buildPatch(g,q);f(h)}return x.push(f),function(b){var c=k.buildPatch(q,b),d=x.map(function(a){return a(c)});return a.when.apply(null,d).then(function(){q=b,b.id&&(p[b.id]={state:b,messagesOffset:G(),loadedAllMessages:I()})})}},pa=function(a){return function(b,c){q.loadingConfirmAction||a(D())["catch"](function(a){var b=m.setLoadingConfirmAction(q,!1);w(b),e.exception(a)}),c.originalEvent.preventDefault()}},qa=function(b,c){var d=a(b.target),e=d.closest(B.FOOTER_CONTAINER),f=e.find(B.MESSAGE_TEXT_AREA),g=f.val().trim();""!==g&&la(q.id,g),c.originalEvent.preventDefault()},ra=function(b,c){var d=window.getSelection(),f=a(b.target);if(""==d.toString()&&!f.is("a")){var g=f.closest(B.MESSAGE),h=parseInt(g.attr("data-message-id"),10);ma(h)["catch"](e.exception),c.originalEvent.preventDefault()}},sa=function(a,b){na()["catch"](e.exception),b.originalEvent.preventDefault()},ta=function(a){return function(b,c){var d=D(),e=q.members[d];n.go(a,o.VIEW_CONTACT,e),c.originalEvent.preventDefault()}},ua=function(a,b){aa()["catch"](e.exception),b.originalEvent.preventDefault()},va=function(a,b){ba()["catch"](e.exception),b.originalEvent.preventDefault()},wa=function(a,b){ca()["catch"](e.exception),b.originalEvent.preventDefault()},xa=function(a,b){da()["catch"](e.exception),b.originalEvent.preventDefault()},ya=function(a){return function(b,c){n.go(a,o.VIEW_GROUP_INFO,{id:q.id,name:q.name,subname:q.subname,imageUrl:q.imageUrl,totalMemberCount:q.totalMemberCount},q.loggedInUserId),c.originalEvent.preventDefault()}},za=function(a,c,g,h){var j=!1,k=K(g),l=[[B.ACTION_REQUEST_BLOCK,pa(U)],[B.ACTION_REQUEST_UNBLOCK,pa(W)],[B.ACTION_REQUEST_ADD_CONTACT,pa($)],[B.ACTION_REQUEST_REMOVE_CONTACT,pa(Y)],[B.ACTION_REQUEST_DELETE_CONVERSATION,pa(ga)],[B.ACTION_CANCEL_EDIT_MODE,sa],[B.ACTION_VIEW_CONTACT,ta(a)],[B.ACTION_VIEW_GROUP_INFO,ya(a)],[B.ACTION_CONFIRM_FAVOURITE,ua],[B.ACTION_CONFIRM_MUTE,wa],[B.ACTION_CONFIRM_UNFAVOURITE,va],[B.ACTION_CONFIRM_UNMUTE,xa]],n=[[B.ACTION_CANCEL_CONFIRM,pa(ia)],[B.ACTION_CONFIRM_BLOCK,pa(V)],[B.ACTION_CONFIRM_UNBLOCK,pa(X)],[B.ACTION_CONFIRM_ADD_CONTACT,pa(_)],[B.ACTION_CONFIRM_REMOVE_CONTACT,pa(Z)],[B.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES,pa(fa)],[B.ACTION_CONFIRM_DELETE_CONVERSATION,pa(ha)],[B.ACTION_REQUEST_ADD_CONTACT,pa($)],[B.ACTION_ACCEPT_CONTACT_REQUEST,pa(ja)],[B.ACTION_DECLINE_CONTACT_REQUEST,pa(ka)],[B.MESSAGE,ra]],p=[[B.SEND_MESSAGE_BUTTON,qa],[B.ACTION_REQUEST_DELETE_SELECTED_MESSAGES,pa(ea)],[B.ACTION_REQUEST_ADD_CONTACT,pa($)],[B.ACTION_REQUEST_UNBLOCK,pa(W)]];b.init(h),d.define(c,[d.events.activate]),d.define(g,[d.events.activate]),d.define(h,[d.events.activate,d.events.enter]),d.define(k,[d.events.scrollTop,d.events.scrollLock]),k.on(d.events.scrollTop,function(a,b){var c=Object.keys(q.members).length>1;if(!u&&!j&&!I()&&c){j=!0;var d=m.setLoadingMessages(q,!0);w(d).then(function(){return R(q.id,z,G(),y,[])}).then(function(){j=!1,H(G()+z)})["catch"](function(a){j=!1,e.exception(a)})}b.originalEvent.preventDefault()}),l.forEach(function(a){var b=a[0],e=a[1];c.on(d.events.activate,b,e)}),n.forEach(function(a){var b=a[0],c=a[1];g.on(d.events.activate,b,c)}),p.forEach(function(a){var b=a[0],c=a[1];h.on(d.events.activate,b,c)}),h.on(d.events.enter,B.MESSAGE_TEXT_AREA,function(a,b){var c=h.attr("data-enter-to-send");c&&"false"!=c&&"0"!=c&&qa(a,b)}),f.subscribe(i.ROUTE_CHANGED,function(a){t&&a.route!=o.VIEW_CONVERSATION&&t.stop()})},Aa=function(a){t&&t.stop(),t=new c(S(a,y),function(a){return a?2*a:A}),t.start()},Ba=function(a,b,c){var d=c.id,e=parseInt(a.attr("data-midnight"),10),f=m.buildInitialState(e,d,b);return q||(q=f),t&&t.stop(),w(f)},Ca=function(a,b,c){return b.id!=c?Ba(a,null,b).then(function(){return h.getConversationBetweenUsers(b.id,c,!0,!0,0,0,z,0,y).then(function(c){return Ea(a,c,b)})["catch"](function(){return M(b,c)})}):Ba(a,null,b).then(function(){return h.getSelfConversation(b.id,z,0,y).then(function(c){return Ea(a,c,b)})["catch"](function(){return N(b)})})},Da=function(a,b,c){var d=null;return b in p&&(d=p[b]),Ba(a,b,c).then(function(){if(d){var a=d.state;return a=m.setLoadingMessages(a,!1),a=m.setLoadingMembers(a,!1),H(d.messagesOffset),J(d.loadedAllMessages),w(a)}return P(b,c,z,0,y)}).then(function(){return Aa(b)})},Ea=function(a,b,c){var d=null;return b.id in p&&(d=p[b.id]),Ba(a,b.id,c).then(function(){if(d){var a=d.state;return a=m.setLoadingMessages(a,!1),a=m.setLoadingMembers(a,!1),H(d.messagesOffset),J(d.loadedAllMessages),w(a)}return Q(b,c,z,y)}).then(function(){return Aa(b.id)})},Fa=function(b,c,d,f,g,h,i){var k=null,l=null;g&&null!==g&&"object"==typeof g?(k=g,l=parseInt(k.id,10)):(k=null,l=parseInt(g,10),l=isNaN(l)?null:l),!l&&h&&i&&(l=E(i));var m=!q||q.id!=l||i&&i!=D();if(d.attr("data-init")||(w=oa(c,d,f,m),za(b,c,d,f),d.attr("data-init",!0)),m){u=!0;var n=null,o=F(d);return n=k?Ea(d,k,o,i):l?Da(d,l,o,i):Ca(d,o,i),n.then(function(){u=!1,c.find(j.SELECTORS.CAN_RECEIVE_FOCUS).first().focus()})["catch"](function(a){u=!1,e.exception(a)})}if(Aa(l),q.type==C.PRIVATE&&h){var p=D();switch(h){case"block":return U(p);case"unblock":return W(p);case"add-contact":return $(p);case"remove-contact":return Y(p)}}return a.Deferred().resolve().promise()},Ga=function(){return g.get_string("messagedrawerviewconversation","core_message",q.name)};return{show:Fa,description:Ga}}); \ No newline at end of file diff --git a/message/amd/build/message_drawer_view_conversation_constants.min.js b/message/amd/build/message_drawer_view_conversation_constants.min.js index a45db355ff4..464ad1e42f6 100644 --- a/message/amd/build/message_drawer_view_conversation_constants.min.js +++ b/message/amd/build/message_drawer_view_conversation_constants.min.js @@ -1 +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_MUTE:'[data-action="confirm-mute"]',ACTION_CONFIRM_UNFAVOURITE:'[data-action="confirm-unfavourite"]',ACTION_CONFIRM_REMOVE_CONTACT:'[data-action="confirm-remove-contact"]',ACTION_CONFIRM_UNBLOCK:'[data-action="confirm-unblock"]',ACTION_CONFIRM_UNMUTE:'[data-action="confirm-unmute"]',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"]',MUTED_ICON_CONTAINER:'[data-region="muted-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}}); \ No newline at end of file +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_MUTE:'[data-action="confirm-mute"]',ACTION_CONFIRM_UNFAVOURITE:'[data-action="confirm-unfavourite"]',ACTION_CONFIRM_REMOVE_CONTACT:'[data-action="confirm-remove-contact"]',ACTION_CONFIRM_UNBLOCK:'[data-action="confirm-unblock"]',ACTION_CONFIRM_UNMUTE:'[data-action="confirm-unmute"]',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"]',MUTED_ICON_CONTAINER:'[data-region="muted-icon-container"]',PLACEHOLDER_CONTAINER:'[data-region="placeholder-container"]',SELF_CONVERSATION_MESSAGE_CONTAINER:'[data-region="self-conversation-message-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",HEADER_SELF:"core_message/message_drawer_view_conversation_header_content_type_self",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,SELF:3},d={PRIVATE:1,PUBLIC:2,FAVOURITE:null};return{SELECTORS:a,TEMPLATES:b,CONVERSATION_TYPES:c,CONVERSATION_CATEGORY_TYPES:d,NEWEST_MESSAGES_FIRST:!0,LOAD_MESSAGE_LIMIT:100,INITIAL_NEW_MESSAGE_POLL_TIMEOUT:1e3}}); \ No newline at end of file diff --git a/message/amd/build/message_drawer_view_conversation_patcher.min.js b/message/amd/build/message_drawer_view_conversation_patcher.min.js index 7ec4cfd0f98..c818b038a64 100644 --- a/message/amd/build/message_drawer_view_conversation_patcher.min.js +++ b/message/amd/build/message_drawer_view_conversation_patcher.min.js @@ -1 +1 @@ -define(["jquery","core/user_date","core_message/message_drawer_view_conversation_constants"],function(a,b,c){var d=function(a,c){var d=a.reduce(function(a,d){var e=b.getUserMidnightForTimestamp(d.timeCreated,c);return a.hasOwnProperty(e)?a[e].push(d):a[e]=[d],a},{});return Object.keys(d).map(function(a){return{timestamp:a,messages:d[a]}})},e=function(a,b,c){b=b.slice();var d=[],e=[],f=[];return a.forEach(function(a){for(var d=!1,g=0;g0,i=g.length>0;return d||e?h&&i?null:h||!i||e.iscontact?!d&&e?e.iscontact?"contact":null:!e&&d?d.iscontact?"non-contact":null:d.iscontact&&!e.iscontact?i?"pending-contact":"non-contact":!d.iscontact&&e.iscontact?"contact":null:"pending-contact":null},C=function(a,b){return!(a.loadingConfirmAction||!b.loadingConfirmAction)||!(a.loadingConfirmAction&&!b.loadingConfirmAction)&&null},D=function(a,b){var c=a.selectedMessageIds.length>0,d=b.selectedMessageIds.length>0,e=a.messages.length!=b.messages.length;return!(c||!d)||!(c&&!d)&&(!(!c||!e)||null)},E=function(a,b){var c=a.selectedMessageIds,d=b.selectedMessageIds;if(g(c,d))return null;var f=e(c,d,function(a,b){return a==b});return{count:d.length,add:f.missingFromA,remove:f.missingFromB}},F=function(a){return Object.keys(a.members).reduce(function(b,c){return c==a.loggedInUserId||b||(b=a.members[c]),b},null)},G=function(a,b){var c=b.contactrequests.filter(function(b){return b.userid==a||b.requesteduserid}),d=c.length>0;return b.requirescontact&&!b.iscontact&&!d},H=function(a,b){var c=F(a),d=F(b),e=a.messages.length>0,f=b.messages.length>0,g=b.loggedInUserId,h=c&&G(g,c),i=d&&G(g,d),j=t(a,b),k=j===!1;if(!a.hasTriedToLoadMessages&&!b.hasTriedToLoadMessages)return null;if(!c&&!d)return null;if(!c&&i)return{show:!0,hasMessages:f,user:d};if(k&&i)return{show:!0,hasMessages:f,user:d};if(a.hasTriedToLoadMessages&&b.hasTriedToLoadMessages){if(!h&&i)return{show:!0,hasMessages:f,user:d};if(h&&!i)return{show:!1,hasMessages:f}}return!a.hasTriedToLoadMessages&&b.hasTriedToLoadMessages&&i?{show:!0,hasMessages:f,user:d}:a.hasTriedToLoadMessages&&!b.hasTriedToLoadMessages&&h?{show:!1,hasMessages:e}:null},I=function(a,b){var c=F(a),d=F(b);return c||d?c&&!d?!c.isblocked&&null:!c&&d?!!d.isblocked||null:!(c.isblocked||!d.isblocked)||!(c.isblocked&&!d.isblocked)&&null:null},J=function(a,b){var c=F(a),d=F(b);return c||d?c&&!d?!c.canmessage||null:!c&&d?!d.canmessage||null:!(!c.canmessage&&d.canmessage)&&(!(!c.canmessage||d.canmessage)||null):null},K=function(a,b){var c=o(a,b),d=D(a,b),e=H(a,b),f=I(a,b),g=J(a,b),h=null!==e?e.show&&e.hasMessages:null,i=F(b),j=function(a,c){if(a)return c;if(null!==a&&!a){if(!i)return{type:"content"};if(i.isblocked)return{type:"unblock"};if(b.messages.length&&G(b.loggedInUserId,i))return{type:"add-contact",user:i};if(!i.canmessage||i.requirescontact&&!i.iscontact)return{type:"unable-to-message"}}return null};if(null===c&&null===d&&null===e&&null===f)return null;for(var k=[[c,{type:"placeholder"}],[d,{type:"edit-mode"}],[g,{type:"unable-to-message"}],[f,{type:"unblock"}],[h,{type:"add-contact",user:i}]],l=0;l0,i=g.length>0,j=a.messages.length>0,k=a.messages.length>0;return h||!i||e.iscontact||k?!(d&&!d.iscontact&&i&&e.iscontact)&&(!(h&&!i)&&(!(!j&&k)&&null)):e.fullname},O=function(b,d){var e={all:{reset:M,conversation:j,scrollToMessage:m,loadingMembers:n,loadingFirstMessages:o,loadingMessages:p,sendingMessage:q,confirmDeleteSelectedMessages:v,inEditMode:D,selectedMessages:E,isFavourite:z,isMuted:A}};e[c.CONVERSATION_TYPES.PRIVATE]={header:k,footer:K,confirmBlockUser:r,confirmUnblockUser:s,confirmAddContact:t,confirmRemoveContact:u,confirmContactRequest:x,confirmDeleteConversation:w,isBlocked:y,isContact:B,loadingConfirmAction:C,requireAddContact:H,contactRequestSent:N},e[c.CONVERSATION_TYPES.PUBLIC]={header:l,footer:L};var f=a.extend({},e.all);return d.type&&d.type in e&&(f=a.extend(f,e[d.type])),Object.keys(f).reduce(function(a,c){var e=f[c],g=e(b,d);return null!==g&&(a[c]=g),a},{})};return{buildPatch:O}}); \ No newline at end of file +define(["jquery","core/user_date","core_message/message_drawer_view_conversation_constants"],function(a,b,c){var d=function(a,c){var d=a.reduce(function(a,d){var e=b.getUserMidnightForTimestamp(d.timeCreated,c);return a.hasOwnProperty(e)?a[e].push(d):a[e]=[d],a},{});return Object.keys(d).map(function(a){return{timestamp:a,messages:d[a]}})},e=function(a,b,c){b=b.slice();var d=[],e=[],f=[];return a.forEach(function(a){for(var d=!1,g=0;g0,i=g.length>0;return d||e?h&&i?null:h||!i||e.iscontact?!d&&e?e.iscontact?"contact":null:!e&&d?d.iscontact?"non-contact":null:d.iscontact&&!e.iscontact?i?"pending-contact":"non-contact":!d.iscontact&&e.iscontact?"contact":null:"pending-contact":null},D=function(a,b){return!(a.loadingConfirmAction||!b.loadingConfirmAction)||!(a.loadingConfirmAction&&!b.loadingConfirmAction)&&null},E=function(a,b){var c=a.selectedMessageIds.length>0,d=b.selectedMessageIds.length>0,e=a.messages.length!=b.messages.length;return!(c||!d)||!(c&&!d)&&(!(!c||!e)||null)},F=function(a,b){var c=a.selectedMessageIds,d=b.selectedMessageIds;if(g(c,d))return null;var f=e(c,d,function(a,b){return a==b});return{count:d.length,add:f.missingFromA,remove:f.missingFromB}},G=function(a){return Object.keys(a.members).reduce(function(b,c){return c==a.loggedInUserId||b||(b=a.members[c]),b},null)},H=function(a,b){var c=b.contactrequests.filter(function(b){return b.userid==a||b.requesteduserid}),d=c.length>0;return b.requirescontact&&!b.iscontact&&!d},I=function(a,b){var c=G(a),d=G(b),e=a.messages.length>0,f=b.messages.length>0,g=b.loggedInUserId,h=c&&H(g,c),i=d&&H(g,d),j=u(a,b),k=j===!1;if(!a.hasTriedToLoadMessages&&!b.hasTriedToLoadMessages)return null;if(!c&&!d)return null;if(!c&&i)return{show:!0,hasMessages:f,user:d};if(k&&i)return{show:!0,hasMessages:f,user:d};if(a.hasTriedToLoadMessages&&b.hasTriedToLoadMessages){if(!h&&i)return{show:!0,hasMessages:f,user:d};if(h&&!i)return{show:!1,hasMessages:f}}return!a.hasTriedToLoadMessages&&b.hasTriedToLoadMessages&&i?{show:!0,hasMessages:f,user:d}:a.hasTriedToLoadMessages&&!b.hasTriedToLoadMessages&&h?{show:!1,hasMessages:e}:null},J=function(a,b){var c=G(a),d=G(b);return c||d?c&&!d?!c.isblocked&&null:!c&&d?!!d.isblocked||null:!(c.isblocked||!d.isblocked)||!(c.isblocked&&!d.isblocked)&&null:null},K=function(a,b){var d=G(a),e=G(b);return b.type==c.CONVERSATION_TYPES.SELF?null:d||e?d&&!e?!d.canmessage||null:!d&&e?!e.canmessage||null:!(!d.canmessage&&e.canmessage)&&(!(!d.canmessage||e.canmessage)||null):null},L=function(a,b){var c=p(a,b),d=E(a,b),e=I(a,b),f=J(a,b),g=K(a,b),h=null!==e?e.show&&e.hasMessages:null,i=G(b),j=function(a,c){if(a)return c;if(null!==a&&!a){if(!i)return{type:"content"};if(i.isblocked)return{type:"unblock"};if(b.messages.length&&H(b.loggedInUserId,i))return{type:"add-contact",user:i};if(!i.canmessage||i.requirescontact&&!i.iscontact)return{type:"unable-to-message"}}return null};if(null===c&&null===d&&null===e&&null===f)return null;for(var k=[[c,{type:"placeholder"}],[d,{type:"edit-mode"}],[g,{type:"unable-to-message"}],[f,{type:"unblock"}],[h,{type:"add-contact",user:i}]],l=0;l0,i=g.length>0,j=a.messages.length>0,k=a.messages.length>0;return h||!i||e.iscontact||k?!(d&&!d.iscontact&&i&&e.iscontact)&&(!(h&&!i)&&(!(!j&&k)&&null)):e.fullname},Q=function(b,d){var e={all:{reset:N,conversation:j,scrollToMessage:n,loadingMembers:o,loadingFirstMessages:p,loadingMessages:q,sendingMessage:r,confirmDeleteSelectedMessages:w,inEditMode:E,selectedMessages:F,isFavourite:A,isMuted:B}};e[c.CONVERSATION_TYPES.PRIVATE]={header:k,footer:L,confirmBlockUser:s,confirmUnblockUser:t,confirmAddContact:u,confirmRemoveContact:v,confirmContactRequest:y,confirmDeleteConversation:x,isBlocked:z,isContact:C,loadingConfirmAction:D,requireAddContact:I,contactRequestSent:P},e[c.CONVERSATION_TYPES.PUBLIC]={header:m,footer:M},e[c.CONVERSATION_TYPES.SELF]={header:l,footer:M,confirmDeleteConversation:x,selfConversationMessage:O};var f=a.extend({},e.all);return d.type&&d.type in e&&(f=a.extend(f,e[d.type])),Object.keys(f).reduce(function(a,c){var e=f[c],g=e(b,d);return null!==g&&(a[c]=g),a},{})};return{buildPatch:Q}}); \ No newline at end of file diff --git a/message/amd/build/message_drawer_view_conversation_renderer.min.js b/message/amd/build/message_drawer_view_conversation_renderer.min.js index b23ddc6ca44..044ff9e0c8d 100644 --- a/message/amd/build/message_drawer_view_conversation_renderer.min.js +++ b/message/amd/build/message_drawer_view_conversation_renderer.min.js @@ -1 +1 @@ -define(["jquery","core/notification","core/str","core/templates","core/user_date","core_message/message_drawer_view_conversation_constants"],function(a,b,c,d,e,f){var g=f.SELECTORS,h=f.TEMPLATES,i=f.CONVERSATION_TYPES,j=function(a){return a.find(g.CONTENT_MESSAGES_CONTAINER)},k=function(a){j(a).removeClass("hidden")},l=function(a){j(a).addClass("hidden")},m=function(a){return a.find(g.CONTACT_REQUEST_SENT_MESSAGE_CONTAINER)},n=function(a){return m(a).addClass("hidden")},o=function(a){return a.find(g.CONTENT_MESSAGES_FOOTER_CONTAINER)},p=function(a){o(a).removeClass("hidden")},q=function(a){o(a).addClass("hidden")},r=function(a){return a.find(g.CONTENT_MESSAGES_FOOTER_EDIT_MODE_CONTAINER)},s=function(a){r(a).removeClass("hidden")},t=function(a){r(a).addClass("hidden")},u=function(a){return a.find(g.PLACEHOLDER_CONTAINER)},v=function(a){u(a).removeClass("hidden")},w=function(a){u(a).addClass("hidden")},x=function(a){return a.find(g.CONTENT_MESSAGES_FOOTER_REQUIRE_CONTACT_CONTAINER)},y=function(a){x(a).removeClass("hidden")},z=function(a){x(a).addClass("hidden")},A=function(a){return a.find(g.CONTENT_MESSAGES_FOOTER_REQUIRE_UNBLOCK_CONTAINER)},B=function(a){A(a).removeClass("hidden")},C=function(a){A(a).addClass("hidden")},D=function(a){return a.find(g.CONTENT_MESSAGES_FOOTER_UNABLE_TO_MESSAGE_CONTAINER)},E=function(a){D(a).removeClass("hidden")},F=function(a){D(a).addClass("hidden")},G=function(a){N(a),Q(a),T(a)},H=function(a){q(a),t(a),w(a),z(a),C(a),F(a)},I=function(a){return a.find(g.CONTENT_PLACEHOLDER_CONTAINER)},J=function(a){I(a).removeClass("hidden")},K=function(a){I(a).addClass("hidden")},L=function(a){return a.find(g.HEADER)},M=function(a){L(a).removeClass("hidden")},N=function(a){L(a).addClass("hidden")},O=function(a){return a.find(g.HEADER_EDIT_MODE)},P=function(a){O(a).removeClass("hidden")},Q=function(a){O(a).addClass("hidden")},R=function(a){return a.find(g.HEADER_PLACEHOLDER_CONTAINER)},S=function(a){R(a).removeClass("hidden")},T=function(a){R(a).addClass("hidden")},U=function(a){return a.find(g.MESSAGE_TEXT_AREA)},V=function(a,b){var c=j(a);return c.find('[data-message-id="'+b+'"]')},W=function(a,b){var c=j(a);return c.find('[data-day-id="'+b+'"]')},X=function(a){return a.find(g.MORE_MESSAGES_LOADING_ICON_CONTAINER)},Y=function(a){X(a).removeClass("hidden")},Z=function(a){X(a).addClass("hidden")},$=function(a){a.find(g.SEND_MESSAGE_BUTTON).prop("disabled",!0),U(a).prop("disabled",!0)},_=function(a){a.find(g.SEND_MESSAGE_BUTTON).prop("disabled",!1),U(a).prop("disabled",!1)},aa=function(a){$(a),a.find(g.SEND_MESSAGE_ICON_CONTAINER).addClass("hidden"),a.find(g.LOADING_ICON_CONTAINER).removeClass("hidden")},ba=function(a){_(a),a.find(g.SEND_MESSAGE_ICON_CONTAINER).removeClass("hidden"),a.find(g.LOADING_ICON_CONTAINER).addClass("hidden")},ca=function(a){var b=U(a);b.val(""),b.focus()},da=function(a){return a.find(g.CONFIRM_DIALOGUE_CONTAINER)},ea=function(a){var b=da(a),c=b.siblings(":not(.hidden)");c.attr("aria-hidden",!0),c.attr("tabindex",-1),c.attr("data-confirm-dialogue-hidden",!0),b.removeClass("hidden")},fa=function(a){var b=da(a),c=b.siblings('[data-confirm-dialogue-hidden="true"]');c.removeAttr("aria-hidden"),c.removeAttr("tabindex"),c.removeAttr("data-confirm-dialogue-hidden"),b.addClass("hidden")},ga=function(a,b){O(a).find(g.MESSAGES_SELECTED_COUNT).text(b)},ha=function(a,b){return a.map(function(a){return{id:a.id,isread:a.isRead,fromloggedinuser:a.fromLoggedInUser,userfrom:a.userFrom,text:a.text,formattedtime:b[a.timeCreated]}})},ia=function(b,c,e,f,g){var i=j(c),k=f.map(function(a){return d.render(h.DAY,{timestamp:a.value.timestamp,messages:ha(a.value.messages,g)})});return a.when.apply(a,k).then(function(){f.forEach(function(b,d){k[d].then(function(d){if(b.before){var e=W(c,b.before.timestamp);return a(d).insertBefore(e)}return i.append(d)})["catch"](function(){})})})},ja=function(b,c,e,f,i){var j=f.map(function(a){return a.value}),k=ha(j,i);return d.render(h.MESSAGES,{messages:k}).then(function(b){var d=a(b);f.forEach(function(a){var b=d.find('[data-message-id="'+a.value.id+'"]');if(a.before){var e=V(c,a.before.id);return b.insertBefore(e)}var f=W(c,a.day.timestamp),h=f.find(g.DAY_MESSAGES_CONTAINER);return h.append(b)})})},ka=function(a,b){b.forEach(function(b){W(a,b.timestamp).remove()})},la=function(a,b){b.forEach(function(b){V(a,b.id).remove()})},ma=function(b,d,f,g){var h=[],i=g.days.add.length>0,j=g.messages.add.length>0,k=[],l=a.Deferred().resolve({}).promise();return i&&(k=k.concat(g.days.add.reduce(function(a,b){return a.concat(b.value.messages.map(function(a){return a.timeCreated}))},[]))),j&&(k=k.concat(g.messages.add.map(function(a){return a.value.timeCreated}))),k.length&&(l=c.get_string("strftimetime24","core_langconfig").then(function(a){var b=k.map(function(b){return{timestamp:b,format:a}});return e.get(b)}).then(function(a){return k.reduce(function(b,c,d){return b[c]=a[d],b},{})})),i&&h.push(l.then(function(a){return ia(b,d,f,g.days.add,a)})),j&&h.push(l.then(function(a){return ja(b,d,f,g.messages.add,a)})),g.days.remove.length>0&&ka(d,g.days.remove),g.messages.remove.length>0&&la(d,g.messages.remove),a.when.apply(a,h)},na=function(a,b,c,e){var f=L(a),g=h.HEADER_PUBLIC;return e.type==i.PRIVATE&&(g=e.showControls?h.HEADER_PRIVATE:h.HEADER_PRIVATE_NO_CONTROLS),d.render(g,e.context).then(function(a,b){d.replaceNodeContents(f,a,b)})},oa=function(a,b,d,e){switch(H(d),e.type){case"placeholder":return v(d);case"add-contact":return c.get_strings([{key:"requirecontacttomessage",component:"core_message",param:e.user.fullname},{key:"isnotinyourcontacts",component:"core_message",param:e.user.fullname}]).then(function(a){var b=a[1],c=a[0],e=x(d);return e.find(g.TITLE).text(b),e.find(g.TEXT).text(c),y(d),a});case"edit-mode":return s(d);case"content":return p(d);case"unblock":return B(d);case"unable-to-message":return E(d)}return!0},pa=function(a,b,c,d){var e=j(b),f=V(b,d),g=f.position();if(g){var h=e.scrollTop()+g.top;e.scrollTop(h)}},qa=function(a,b,c,d){d?(N(a),S(a)):(M(a),T(a))},ra=function(a,b,c,d){d?(l(b),J(b)):(k(b),K(b))},sa=function(a,b,c,d){d?Y(b):Z(b)},ta=function(a,b,c,d){d?aa(c):(ba(c),ca(c))},ua=function(a,b,c,d,e,f,h,i){var j=da(b),k=d.map(function(a){return j.find(a)}),l=j.find(g.CONFIRM_DIALOGUE_CANCEL_BUTTON),m=j.find(g.CONFIRM_DIALOGUE_TEXT),n=j.find(g.CONFIRM_DIALOGUE_HEADER);j.find("button").addClass("hidden"),h?l.removeClass("hidden"):l.addClass("hidden"),f?(n.removeClass("hidden"),n.text(f)):(n.addClass("hidden"),n.text("")),k.forEach(function(a){a.removeClass("hidden")}),m.text(e),ea(c),ea(b),i||ea(a),j.find(g.CAN_RECEIVE_FOCUS).filter(":visible").first().focus()},va=function(a,b,c){var d=da(b),e=d.find(g.CONFIRM_DIALOGUE_CANCEL_BUTTON),f=d.find(g.CONFIRM_DIALOGUE_TEXT),h=d.find(g.CONFIRM_DIALOGUE_HEADER);return fa(b),fa(c),fa(a),d.find("button").addClass("hidden"),e.removeClass("hidden"),f.text(""),h.addClass("hidden"),h.text(""),a.find(g.CAN_RECEIVE_FOCUS).first().focus(),!0},wa=function(a,b,d,e){return e?c.get_string("blockuserconfirm","core_message",e.fullname).then(function(c){return ua(a,b,d,[g.ACTION_CONFIRM_BLOCK],c,"",!0,!1)}):va(a,b,d)},xa=function(a,b,d,e){return e?c.get_string("unblockuserconfirm","core_message",e.fullname).then(function(c){return ua(a,b,d,[g.ACTION_CONFIRM_UNBLOCK],c,"",!0,!1)}):va(a,b,d)},ya=function(a,b,d,e){return e?c.get_string("addcontactconfirm","core_message",e.fullname).then(function(c){return ua(a,b,d,[g.ACTION_CONFIRM_ADD_CONTACT],c,"",!0,!1)}):va(a,b,d)},za=function(a,b,d,e){return e?c.get_string("removecontactconfirm","core_message",e.fullname).then(function(c){return ua(a,b,d,[g.ACTION_CONFIRM_REMOVE_CONTACT],c,"",!0,!1)}):va(a,b,d)},Aa=function(a,b,d,e){return e?c.get_string("deleteselectedmessagesconfirm","core_message").then(function(c){return ua(a,b,d,[g.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES],c,"",!0,!1)}):va(a,b,d)},Ba=function(a,b,d,e){return e?c.get_string("deleteallconfirm","core_message").then(function(c){return ua(a,b,d,[g.ACTION_CONFIRM_DELETE_CONVERSATION],c,"",!0,!1)}):va(a,b,d)},Ca=function(a,b,d,e){return e?c.get_string("userwouldliketocontactyou","core_message",e.fullname).then(function(c){var e=[g.ACTION_ACCEPT_CONTACT_REQUEST,g.ACTION_DECLINE_CONTACT_REQUEST];return ua(a,b,d,e,c,"",!1,!0)}):va(a,b,d)},Da=function(a,b,c,d){d?(a.find(g.ACTION_REQUEST_BLOCK).addClass("hidden"),a.find(g.ACTION_REQUEST_UNBLOCK).removeClass("hidden")):(a.find(g.ACTION_REQUEST_BLOCK).removeClass("hidden"),a.find(g.ACTION_REQUEST_UNBLOCK).addClass("hidden"))},Ea=function(a,b,c,d){var e=a.find(g.FAVOURITE_ICON_CONTAINER),f=a.find(g.ACTION_CONFIRM_FAVOURITE),h=a.find(g.ACTION_CONFIRM_UNFAVOURITE);switch(d){case"hide":e.addClass("hidden"),f.addClass("hidden"),h.addClass("hidden");break;case"show-add":e.addClass("hidden"),f.removeClass("hidden"),h.addClass("hidden");break;case"show-remove":e.removeClass("hidden"),f.addClass("hidden"),h.removeClass("hidden")}},Fa=function(a,b,c,d){var e=a.find(g.MUTED_ICON_CONTAINER),f=a.find(g.ACTION_CONFIRM_MUTE),h=a.find(g.ACTION_CONFIRM_UNMUTE);switch(d){case"hide":e.addClass("hidden"),f.addClass("hidden"),h.addClass("hidden");break;case"show-mute":e.addClass("hidden"),f.removeClass("hidden"),h.addClass("hidden");break;case"show-unmute":e.removeClass("hidden"),f.addClass("hidden"),h.removeClass("hidden")}},Ga=function(a,b,c,d){var e=a.find(g.ACTION_REQUEST_ADD_CONTACT),f=a.find(g.ACTION_REQUEST_REMOVE_CONTACT);switch(d){case"pending-contact":e.addClass("hidden"),f.addClass("hidden");break;case"contact":e.addClass("hidden"),f.removeClass("hidden");break;case"non-contact":e.removeClass("hidden"),f.addClass("hidden")}},Ha=function(a,b,c,d){var e=da(b),f=e.find("button"),h=e.find(g.CONFIRM_DIALOGUE_BUTTON_TEXT),i=e.find(g.LOADING_ICON_CONTAINER);d?(f.prop("disabled",!0),h.addClass("hidden"),i.removeClass("hidden")):(f.prop("disabled",!1),h.removeClass("hidden"),i.addClass("hidden"))},Ia=function(a,b,c,d){var e=null;d?(e=b.find(g.MESSAGE_NOT_SELECTED),e.find(g.MESSAGE_NOT_SELECTED_ICON).removeClass("hidden"),N(a),P(a)):(e=j(b),e.find(g.MESSAGE_NOT_SELECTED_ICON).addClass("hidden"),e.find(g.MESSAGE_SELECTED_ICON).addClass("hidden"),M(a),Q(a))},Ja=function(a,b,c,d){var e=d.count>0;d.add.length&&d.add.forEach(function(a){var c=V(b,a);c.find(g.MESSAGE_NOT_SELECTED_ICON).addClass("hidden"),c.find(g.MESSAGE_SELECTED_ICON).removeClass("hidden"),c.attr("aria-checked",!0)}),d.remove.length&&d.remove.forEach(function(a){var c=V(b,a);e&&c.find(g.MESSAGE_NOT_SELECTED_ICON).removeClass("hidden"),c.find(g.MESSAGE_SELECTED_ICON).addClass("hidden"),c.attr("aria-checked",!1)}),ga(a,d.count)},Ka=function(a,b,d,e){return e.show&&!e.hasMessages?c.get_strings([{key:"requirecontacttomessage",component:"core_message",param:e.user.fullname},{key:"isnotinyourcontacts",component:"core_message",param:e.user.fullname}]).then(function(c){var e=c[1],f=c[0];return ua(a,b,d,[g.ACTION_REQUEST_ADD_CONTACT],f,e,!1,!0)}):va(a,b,d)},La=function(a,b,d,e){var f=m(b);return e?c.get_string("yourcontactrequestpending","core_message",e).then(function(a){return f.find(g.TEXT).text(a),f.removeClass("hidden"),a}):(f.addClass("hidden"),!0)},Ma=function(a,b,c){return va(a,b,c),n(b),G(a),S(a),H(c),v(c),!0},Na=function(c,d,e,f){var g=[{reset:Ma},{conversation:ma,header:na,footer:oa,confirmBlockUser:wa,confirmUnblockUser:xa,confirmAddContact:ya,confirmRemoveContact:za,confirmDeleteSelectedMessages:Aa,confirmDeleteConversation:Ba,confirmContactRequest:Ca,requireAddContact:Ka,contactRequestSent:La},{loadingMembers:qa,loadingFirstMessages:ra,loadingMessages:sa,sendingMessage:ta,isBlocked:Da,isContact:Ga,isFavourite:Ea,isMuted:Fa,loadingConfirmAction:Ha,inEditMode:Ia},{scrollToMessage:pa,selectedMessages:Ja}],h=function(a){var b=[];for(var g in f)if(a.hasOwnProperty(g)){var h=a[g],i=f[g];b.push(h(c,d,e,i))}return b},i=h(g[0]);return i=i.concat(h(g[1])),a.when.apply(a,i).then(function(){for(var a=2;a0,j=g.messages.add.length>0,k=[],l=a.Deferred().resolve({}).promise();return i&&(k=k.concat(g.days.add.reduce(function(a,b){return a.concat(b.value.messages.map(function(a){return a.timeCreated}))},[]))),j&&(k=k.concat(g.messages.add.map(function(a){return a.value.timeCreated}))),k.length&&(l=c.get_string("strftimetime24","core_langconfig").then(function(a){var b=k.map(function(b){return{timestamp:b,format:a}});return e.get(b)}).then(function(a){return k.reduce(function(b,c,d){return b[c]=a[d],b},{})})),i&&h.push(l.then(function(a){return ka(b,d,f,g.days.add,a)})),j&&h.push(l.then(function(a){return la(b,d,f,g.messages.add,a)})),g.days.remove.length>0&&ma(d,g.days.remove),g.messages.remove.length>0&&na(d,g.messages.remove),a.when.apply(a,h)},pa=function(a,b,c,e){var f=N(a),g=h.HEADER_PUBLIC;return e.type==i.PRIVATE?g=e.showControls?h.HEADER_PRIVATE:h.HEADER_PRIVATE_NO_CONTROLS:e.type==i.SELF&&(g=h.HEADER_SELF),d.render(g,e.context).then(function(a,b){d.replaceNodeContents(f,a,b)})},qa=function(a,b,d,e){switch(J(d),e.type){case"placeholder":return x(d);case"add-contact":return c.get_strings([{key:"requirecontacttomessage",component:"core_message",param:e.user.fullname},{key:"isnotinyourcontacts",component:"core_message",param:e.user.fullname}]).then(function(a){var b=a[1],c=a[0],e=z(d);return e.find(g.TITLE).text(b),e.find(g.TEXT).text(c),A(d),a});case"edit-mode":return u(d);case"content":return r(d);case"unblock":return D(d);case"unable-to-message":return G(d)}return!0},ra=function(a,b,c,d){var e=j(b),f=X(b,d),g=f.position();if(g){var h=e.scrollTop()+g.top;e.scrollTop(h)}},sa=function(a,b,c,d){d?(P(a),U(a)):(O(a),V(a))},ta=function(a,b,c,d){d?(l(b),L(b)):(k(b),M(b))},ua=function(a,b,c,d){d?$(b):_(b)},va=function(a,b,c,d){d?ca(c):(da(c),ea(c))},wa=function(a,b,c,d,e,f,h,i){var j=fa(b),k=d.map(function(a){return j.find(a)}),l=j.find(g.CONFIRM_DIALOGUE_CANCEL_BUTTON),m=j.find(g.CONFIRM_DIALOGUE_TEXT),n=j.find(g.CONFIRM_DIALOGUE_HEADER);j.find("button").addClass("hidden"),h?l.removeClass("hidden"):l.addClass("hidden"),f?(n.removeClass("hidden"),n.text(f)):(n.addClass("hidden"),n.text("")),k.forEach(function(a){a.removeClass("hidden")}),m.text(e),ga(c),ga(b),i||ga(a),j.find(g.CAN_RECEIVE_FOCUS).filter(":visible").first().focus()},xa=function(a,b,c){var d=fa(b),e=d.find(g.CONFIRM_DIALOGUE_CANCEL_BUTTON),f=d.find(g.CONFIRM_DIALOGUE_TEXT),h=d.find(g.CONFIRM_DIALOGUE_HEADER);return ha(b),ha(c),ha(a),d.find("button").addClass("hidden"),e.removeClass("hidden"),f.text(""),h.addClass("hidden"),h.text(""),a.find(g.CAN_RECEIVE_FOCUS).first().focus(),!0},ya=function(a,b,d,e){return e?c.get_string("blockuserconfirm","core_message",e.fullname).then(function(c){return wa(a,b,d,[g.ACTION_CONFIRM_BLOCK],c,"",!0,!1)}):xa(a,b,d)},za=function(a,b,d,e){return e?c.get_string("unblockuserconfirm","core_message",e.fullname).then(function(c){return wa(a,b,d,[g.ACTION_CONFIRM_UNBLOCK],c,"",!0,!1)}):xa(a,b,d)},Aa=function(a,b,d,e){return e?c.get_string("addcontactconfirm","core_message",e.fullname).then(function(c){return wa(a,b,d,[g.ACTION_CONFIRM_ADD_CONTACT],c,"",!0,!1)}):xa(a,b,d)},Ba=function(a,b,d,e){return e?c.get_string("removecontactconfirm","core_message",e.fullname).then(function(c){return wa(a,b,d,[g.ACTION_CONFIRM_REMOVE_CONTACT],c,"",!0,!1)}):xa(a,b,d)},Ca=function(a,b,d,e){var f=null;return e==i.SELF?f="deleteselectedmessagesconfirmselfconversation":e&&(f="deleteselectedmessagesconfirm"),f?c.get_string(f,"core_message").then(function(c){return wa(a,b,d,[g.ACTION_CONFIRM_DELETE_SELECTED_MESSAGES],c,"",!0,!1)}):xa(a,b,d)},Da=function(a,b,d,e){var f=null;return e==i.SELF?f="deleteallselfconfirm":e&&(f="deleteallconfirm"),f?c.get_string(f,"core_message").then(function(c){return wa(a,b,d,[g.ACTION_CONFIRM_DELETE_CONVERSATION],c,"",!0,!1)}):xa(a,b,d)},Ea=function(a,b,d,e){return e?c.get_string("userwouldliketocontactyou","core_message",e.fullname).then(function(c){var e=[g.ACTION_ACCEPT_CONTACT_REQUEST,g.ACTION_DECLINE_CONTACT_REQUEST];return wa(a,b,d,e,c,"",!1,!0)}):xa(a,b,d)},Fa=function(a,b,c,d){d?(a.find(g.ACTION_REQUEST_BLOCK).addClass("hidden"),a.find(g.ACTION_REQUEST_UNBLOCK).removeClass("hidden")):(a.find(g.ACTION_REQUEST_BLOCK).removeClass("hidden"),a.find(g.ACTION_REQUEST_UNBLOCK).addClass("hidden"))},Ga=function(a,b,c,d){var e=a.find(g.FAVOURITE_ICON_CONTAINER),f=a.find(g.ACTION_CONFIRM_FAVOURITE),h=a.find(g.ACTION_CONFIRM_UNFAVOURITE);switch(d){case"hide":e.addClass("hidden"),f.addClass("hidden"),h.addClass("hidden");break;case"show-add":e.addClass("hidden"),f.removeClass("hidden"),h.addClass("hidden");break;case"show-remove":e.removeClass("hidden"),f.addClass("hidden"),h.removeClass("hidden")}},Ha=function(a,b,c,d){var e=a.find(g.MUTED_ICON_CONTAINER),f=a.find(g.ACTION_CONFIRM_MUTE),h=a.find(g.ACTION_CONFIRM_UNMUTE);switch(d){case"hide":e.addClass("hidden"),f.addClass("hidden"),h.addClass("hidden");break;case"show-mute":e.addClass("hidden"),f.removeClass("hidden"),h.addClass("hidden");break;case"show-unmute":e.removeClass("hidden"),f.addClass("hidden"),h.removeClass("hidden")}},Ia=function(a,b,c,d){var e=a.find(g.ACTION_REQUEST_ADD_CONTACT),f=a.find(g.ACTION_REQUEST_REMOVE_CONTACT);switch(d){case"pending-contact":e.addClass("hidden"),f.addClass("hidden");break;case"contact":e.addClass("hidden"),f.removeClass("hidden");break;case"non-contact":e.removeClass("hidden"),f.addClass("hidden")}},Ja=function(a,b,c,d){var e=fa(b),f=e.find("button"),h=e.find(g.CONFIRM_DIALOGUE_BUTTON_TEXT),i=e.find(g.LOADING_ICON_CONTAINER);d?(f.prop("disabled",!0),h.addClass("hidden"),i.removeClass("hidden")):(f.prop("disabled",!1),h.removeClass("hidden"),i.addClass("hidden"))},Ka=function(a,b,c,d){var e=null;d?(e=b.find(g.MESSAGE_NOT_SELECTED),e.find(g.MESSAGE_NOT_SELECTED_ICON).removeClass("hidden"),P(a),R(a)):(e=j(b),e.find(g.MESSAGE_NOT_SELECTED_ICON).addClass("hidden"),e.find(g.MESSAGE_SELECTED_ICON).addClass("hidden"),O(a),S(a))},La=function(a,b,c,d){var e=d.count>0;d.add.length&&d.add.forEach(function(a){var c=X(b,a);c.find(g.MESSAGE_NOT_SELECTED_ICON).addClass("hidden"),c.find(g.MESSAGE_SELECTED_ICON).removeClass("hidden"),c.attr("aria-checked",!0)}),d.remove.length&&d.remove.forEach(function(a){var c=X(b,a);e&&c.find(g.MESSAGE_NOT_SELECTED_ICON).removeClass("hidden"),c.find(g.MESSAGE_SELECTED_ICON).addClass("hidden"),c.attr("aria-checked",!1)}),ia(a,d.count)},Ma=function(a,b,d,e){return e.show&&!e.hasMessages?c.get_strings([{key:"requirecontacttomessage",component:"core_message",param:e.user.fullname},{key:"isnotinyourcontacts",component:"core_message",param:e.user.fullname}]).then(function(c){var e=c[1],f=c[0];return wa(a,b,d,[g.ACTION_REQUEST_ADD_CONTACT],f,e,!1,!0)}):xa(a,b,d)},Na=function(a,b,c,d){var e=m(b);return d?e.removeClass("hidden"):e.addClass("hidden"),!0},Oa=function(a,b,d,e){var f=o(b);return e?c.get_string("yourcontactrequestpending","core_message",e).then(function(a){return f.find(g.TEXT).text(a),f.removeClass("hidden"),a}):(f.addClass("hidden"),!0)},Pa=function(a,b,c){return xa(a,b,c),p(b),n(b),I(a),U(a),J(c),x(c),!0},Qa=function(c,d,e,f){var g=[{reset:Pa},{conversation:oa,header:pa,footer:qa,confirmBlockUser:ya,confirmUnblockUser:za,confirmAddContact:Aa,confirmRemoveContact:Ba,confirmDeleteSelectedMessages:Ca,confirmDeleteConversation:Da,confirmContactRequest:Ea,requireAddContact:Ma,selfConversationMessage:Na,contactRequestSent:Oa},{loadingMembers:sa,loadingFirstMessages:ta,loadingMessages:ua,sendingMessage:va,isBlocked:Fa,isContact:Ia,isFavourite:Ga,isMuted:Ha,loadingConfirmAction:Ja,inEditMode:Ka},{scrollToMessage:ra,selectedMessages:La}],h=function(a){var b=[];for(var g in f)if(a.hasOwnProperty(g)){var h=a[g],i=f[g];b.push(h(c,d,e,i))}return b},i=h(g[0]);return i=i.concat(h(g[1])),a.when.apply(a,i).then(function(){for(var a=2;a0&&0==f?-1:0==d&&f>0?1:c>0&&0==e?-1:0==c&&e>0?1:0});var c=a[0][0],d=c.find(j.SECTION_TOGGLE_BUTTON);d.click()}},p=function(a){return a.find(j.SEARCH_INPUT)},q=function(a){return a.attr("data-user-id")},r=function(a){return function(){var b=a.find(j.CONTACT_REQUEST_COUNT),c=parseInt(b.text(),10);c=isNaN(c)?0:c-1,c<=0?b.addClass("hidden"):b.text(c)}},s=function(a,d){var h=p(d),i=[b.tab,b.shift,b.ctrl,b.alt];h.on("click",function(){e.go(a,f.VIEW_SEARCH)}),h.on("keydown",function(b){i.indexOf(b.keyCode)<0&&"Meta"!=b.key&&e.go(a,f.VIEW_SEARCH)}),c.subscribe(g.CONTACT_REQUEST_ACCEPTED,r(d)),c.subscribe(g.CONTACT_REQUEST_DECLINED,r(d))},t=function(a,b,c){b.attr("data-init")||(s(a,b),b.attr("data-init",!0)),p(b).val("");var d=q(c),e=m(d),f=[[c.find(j.FAVOURITES),k.FAVOURITE,!0],[c.find(j.GROUP_MESSAGES),k.PUBLIC,!1],[c.find(j.MESSAGES),k.PRIVATE,!1]];return f.forEach(function(b){var c=b[0],d=b[1],f=b[2],g=e.then(function(a){return n(a.total,d)}),i=e.then(function(a){return n(a.unread,d)});h.show(a,null,c,null,d,f,g,i)}),e.then(function(a){var b=f.map(function(b){var c=b[0],d=b[1],e=n(a.total,d),f=n(a.unread,d);return[c,e,f]});return o(b)})},u=function(){return d.get_string("messagedrawerviewoverview","core_message")};return{show:t,description:u}}); \ No newline at end of file +define(["jquery","core/key_codes","core/pubsub","core/str","core_message/message_drawer_router","core_message/message_drawer_routes","core_message/message_drawer_events","core_message/message_drawer_view_overview_section","core_message/message_repository","core_message/message_drawer_view_conversation_constants"],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"]',SECTION_TOGGLE_BUTTON:"[data-toggle]"},l=null,m=function(a){return null===l&&(l=i.getAllConversationCounts(a)),l},n=function(a,b){var c=0;return c=b===j.CONVERSATION_CATEGORY_TYPES.PRIVATE&&a.types[j.CONVERSATION_TYPES.SELF]?a.types[j.CONVERSATION_TYPES.PRIVATE]+a.types[j.CONVERSATION_TYPES.SELF]:b===j.CONVERSATION_CATEGORY_TYPES.FAVOURITE?a.favourites:a.types[b]},o=function(a){var b=a.some(function(a){var b=a[0];return h.isVisible(b)});if(!b){a.sort(function(a,b){var c=a[1],d=a[2],e=b[1],f=b[2];return d>0&&0==f?-1:0==d&&f>0?1:c>0&&0==e?-1:0==c&&e>0?1:0});var c=a[0][0],d=c.find(k.SECTION_TOGGLE_BUTTON);d.click()}},p=function(a){return a.find(k.SEARCH_INPUT)},q=function(a){return a.attr("data-user-id")},r=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)}},s=function(a,d){var h=p(d),i=[b.tab,b.shift,b.ctrl,b.alt];h.on("click",function(){e.go(a,f.VIEW_SEARCH)}),h.on("keydown",function(b){i.indexOf(b.keyCode)<0&&"Meta"!=b.key&&e.go(a,f.VIEW_SEARCH)}),c.subscribe(g.CONTACT_REQUEST_ACCEPTED,r(d)),c.subscribe(g.CONTACT_REQUEST_DECLINED,r(d))},t=function(a,b,c){b.attr("data-init")||(s(a,b),b.attr("data-init",!0)),p(b).val("");var d=q(c),e=m(d),f=[[c.find(k.FAVOURITES),j.CONVERSATION_CATEGORY_TYPES.FAVOURITE,!0],[c.find(k.GROUP_MESSAGES),j.CONVERSATION_CATEGORY_TYPES.PUBLIC,!1],[c.find(k.MESSAGES),j.CONVERSATION_CATEGORY_TYPES.PRIVATE,!1]];return f.forEach(function(b){var c=b[0],d=b[1],f=b[2],g=e.then(function(a){return n(a.total,d)}),i=e.then(function(a){return n(a.unread,d)});h.show(a,null,c,null,d,f,g,i)}),e.then(function(a){var b=f.map(function(b){var c=b[0],d=b[1],e=n(a.total,d),f=n(a.unread,d);return[c,e,f]});return o(b)})},u=function(){return d.get_string("messagedrawerviewoverview","core_message")};return{show:t,description:u}}); \ No newline at end of file diff --git a/message/amd/build/message_drawer_view_overview_section.min.js b/message/amd/build/message_drawer_view_overview_section.min.js index 42e5adfd2b5..77172647eac 100644 --- a/message/amd/build/message_drawer_view_overview_section.min.js +++ b/message/amd/build/message_drawer_view_overview_section.min.js @@ -1 +1 @@ -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(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={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"]',MUTED_ICON_CONTAINER:'[data-region="muted-icon-container"]',UNREAD_COUNT:'[data-region="unread-count"]',SECTION_TOTAL_COUNT:'[data-region="section-total-count"]',SECTION_TOTAL_COUNT_CONTAINER:'[data-region="section-total-count-container"]',SECTION_UNREAD_COUNT:'[data-region="section-unread-count"]',PLACEHOLDER_CONTAINER:'[data-region="placeholder-container"]'},o={CONVERSATIONS_LIST:"core_message/message_drawer_conversations_list",CONVERSATIONS_LIST_ITEMS_PLACEHOLDER:"core_message/message_drawer_conversations_list_items_placeholder"},p=50,q={},r=!1,s=!1,t=function(a){return l.getRoot(a).hasClass("show")},u=function(a){a.addClass("expanded")},v=function(a){a.removeClass("expanded")},w=function(a,b){var c=a.find(n.SECTION_TOTAL_COUNT_CONTAINER),d=c.find(n.SECTION_TOTAL_COUNT);d.text(b),c.removeClass("hidden"),e.get_string("totalconversations","core_message",b).done(function(a){c.attr("aria-label",a)});var g=b>20?20:b,h=Array.apply(null,Array(g)).map(function(){return!0});f.render(o.CONVERSATIONS_LIST_ITEMS_PLACEHOLDER,{placeholders:h}).then(function(b){var c=a.find(n.PLACEHOLDER_CONTAINER);c.html(b)})["catch"](function(){})},x=function(a,b){var c=a.find(n.SECTION_UNREAD_COUNT);c.text(b),e.get_string("unreadconversations","core_message",b).done(function(a){c.attr("aria-label",a)}),b>0&&c.removeClass("hidden")},y=function(b,d,e){var g=d.map(function(b){var c=b.messages.length?b.messages[b.messages.length-1]:null,d={id:b.id,imageurl:b.imageurl,name:b.name,subname:b.subname,unreadcount:b.unreadcount,ismuted:b.ismuted,lastmessagedate:c?c.timecreated:null,sentfromcurrentuser:c?c.useridfrom==e:null,lastmessage:c?a(c.text).text()||c.text:null};if(b.type==m.CONVERSATION_TYPES.PRIVATE){var f=b.members.reduce(function(a,b){return a||b.id==e||(a=b),a},null);d.userid=f.id,d.showonlinestatus=f.showonlinestatus,d.isonline=f.isonline,d.isblocked=f.isblocked}return b.type==m.CONVERSATION_TYPES.PUBLIC&&(d.lastsendername=b.members.reduce(function(a,b){return a||b.id!=c.useridfrom||(a=b.fullname),a},null)),d});return g.forEach(function(a){(new Date).toDateString()==new Date(1e3*a.lastmessagedate).toDateString()&&(a.istoday=!0)}),f.render(o.CONVERSATIONS_LIST,{conversations:g}).then(function(a){return b.append(a),a})["catch"](c.exception)},z=function(a,b,d){return function(e,f){return h.getConversations(f,a,p+1,d,b).then(function(a){var b=a.conversations;return b.length>p?b=b.slice(0,-1):l.setLoadedAll(e,!0),d+=p,b.forEach(function(a){q[a.id]=a}),b})["catch"](c.exception)}},A=function(a){return a.find(n.SECTION_TOTAL_COUNT)},B=function(a){return a.find(n.SECTION_UNREAD_COUNT)},C=function(a){if(r){var b=A(a),c=parseInt(b.text());c+=1,b.text(c)}},D=function(a){if(r){var b=A(a),c=parseInt(b.text());c-=1,b.text(c)}},E=function(a){if(s){var b=B(a),c=parseInt(b.text());c-=1,b.text(c),c<1&&b.addClass("hidden")}},F=function(a,b){return a.find('[data-conversation-id="'+b+'"]')},G=function(a,b){return a.find('[data-user-id="'+b+'"]')},H=function(a){a.find(n.MUTED_ICON_CONTAINER).removeClass("hidden")},I=function(a){a.find(n.MUTED_ICON_CONTAINER).addClass("hidden")},J=function(a){a.find(n.BLOCKED_ICON_CONTAINER).removeClass("hidden")},K=function(a){a.find(n.BLOCKED_ICON_CONTAINER).addClass("hidden")},L=function(b,c){var d,f=c.messages[c.messages.length-1],h="";d=f.fromLoggedInUser?{key:"you",component:"core_message"}:{key:"sender",component:"core_message",param:f.userFrom.fullname};var i=[d,{key:"strftimetime24",component:"core_langconfig"}];return e.get_strings(i).then(function(a){return h=a[0],g.get([{timestamp:f.timeCreated,format:a[1]}])}).then(function(a){return a[0]}).then(function(d){b.find(n.LAST_MESSAGE_DATE).text(d).removeClass("hidden"),f.fromLoggedInUser||c.type!==m.CONVERSATION_TYPES.PRIVATE||(h="");var e=h+" "+a(f.text).text()+"";return b.find(n.LAST_MESSAGE).html(e)})},M=function(b,d){var e=b.find(n.CONVERSATION),g="";if(!e.length){var h=l.getRoot(b);l.showContent(h),l.hideEmptyMessage(h)}var i=d.messages.length,j=i?d.messages[i-1]:null;j&&(g=a(j.text).text()||j.text);var k={id:d.id,name:d.name,subname:d.subname,lastmessagedate:j?j.timeCreated:null,sentfromcurrentuser:j?j.fromLoggedInUser:null,lastmessage:g,imageurl:d.imageUrl};return q[d.id]=d,(new Date).toDateString()==new Date(1e3*k.lastmessagedate).toDateString()&&(k.istoday=!0),f.render(o.CONVERSATIONS_LIST,{conversations:[k]}).then(function(a){var c=l.getContentContainer(b);return c.prepend(a)}).then(function(){return C(b)})["catch"](c.exception)},N=function(a,b){b.remove(),D(a);var c=a.find(n.CONVERSATION);if(!c.length){var d=l.getRoot(a);l.hideContent(d),l.showEmptyMessage(d)}},O=function(a,b){var c=b.find(n.UNREAD_COUNT);c.text("0"),c.addClass("hidden"),E(a)},P=function(c,e,f,g,h){var m=l.getRoot(e),o=e.find(n.TOGGLE);e.css("min-height",o.outerHeight()),e.on("show.bs.collapse",function(){u(e),l.show(m,f,y)}),e.on("hidden.bs.collapse",function(){v(e)}),d.subscribe(i.CONTACT_BLOCKED,function(a){var b=G(e,a);b.length&&J(b)}),d.subscribe(i.CONTACT_UNBLOCKED,function(a){var b=G(e,a);b.length&&K(b)}),d.subscribe(i.CONVERSATION_SET_MUTED,function(a){var b=a.id,c=F(e,b);c.length&&H(c)}),d.subscribe(i.CONVERSATION_UNSET_MUTED,function(a){var b=a.id,c=F(e,b);c.length&&I(c)}),d.subscribe(i.CONVERSATION_NEW_LAST_MESSAGE,function(a){if(!(g&&a.type!=g||h&&!a.isFavourite||!h&&a.isFavourite)){var b=a.id,c=F(e,b);c.length?L(c,a):M(e,a)}}),d.subscribe(i.CONVERSATION_DELETED,function(a){var b=F(e,a);b.length&&N(e,b)}),d.subscribe(i.CONVERSATION_READ,function(a){var b=F(e,a);b.length&&O(e,b)}),d.subscribe(i.CONVERSATION_SET_FAVOURITE,function(a){var b=null;!h||g&&g!=a.type?g==a.type&&(b=F(e,a.id),b.length&&N(e,b)):(b=F(e,a.id),b.length||M(e,a))}),d.subscribe(i.CONVERSATION_UNSET_FAVOURITE,function(a){var b=null;h?(b=F(e,a.id),b.length&&N(e,b)):g==a.type&&(b=F(e,a.id),b.length||M(e,a))}),b.define(e,[b.events.activate]),e.on(b.events.activate,n.CONVERSATION,function(b,d){var e=a(b.target).closest(n.CONVERSATION),f=e.attr("data-conversation-id"),g=q[f];j.go(c,k.VIEW_CONVERSATION,g),d.originalEvent.preventDefault()})},Q=function(b,c,d,e,f,g,h,i){var j=a(d);if(!j.attr("data-init")){var k=z(f,g,0);if(P(b,j,k,f,g),t(j)){u(j);var m=l.getRoot(j);l.show(m,k,y)}h.then(function(a){w(j,a),r=!0})["catch"](function(){}),i.then(function(a){x(j,a),s=!0})["catch"](function(){}),j.attr("data-init",!0)}};return{show:Q,isVisible:t}}); \ No newline at end of file +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(a,b,c,d,e,f,g,h,i,j,k,l,m){var n={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"]',MUTED_ICON_CONTAINER:'[data-region="muted-icon-container"]',UNREAD_COUNT:'[data-region="unread-count"]',SECTION_TOTAL_COUNT:'[data-region="section-total-count"]',SECTION_TOTAL_COUNT_CONTAINER:'[data-region="section-total-count-container"]',SECTION_UNREAD_COUNT:'[data-region="section-unread-count"]',PLACEHOLDER_CONTAINER:'[data-region="placeholder-container"]'},o={CONVERSATIONS_LIST:"core_message/message_drawer_conversations_list",CONVERSATIONS_LIST_ITEMS_PLACEHOLDER:"core_message/message_drawer_conversations_list_items_placeholder"},p=50,q={},r=!1,s=!1,t=function(a){return l.getRoot(a).hasClass("show")},u=function(a){a.addClass("expanded")},v=function(a){a.removeClass("expanded")},w=function(a,b){var c=a.find(n.SECTION_TOTAL_COUNT_CONTAINER),d=c.find(n.SECTION_TOTAL_COUNT);d.text(b),c.removeClass("hidden"),e.get_string("totalconversations","core_message",b).done(function(a){c.attr("aria-label",a)});var g=b>20?20:b,h=Array.apply(null,Array(g)).map(function(){return!0});f.render(o.CONVERSATIONS_LIST_ITEMS_PLACEHOLDER,{placeholders:h}).then(function(b){var c=a.find(n.PLACEHOLDER_CONTAINER);c.html(b)})["catch"](function(){})},x=function(a,b){var c=a.find(n.SECTION_UNREAD_COUNT);c.text(b),e.get_string("unreadconversations","core_message",b).done(function(a){c.attr("aria-label",a)}),b>0&&c.removeClass("hidden")},y=function(b,d,e){var g=d.map(function(b){var c=b.messages.length?b.messages[b.messages.length-1]:null,d={id:b.id,imageurl:b.imageurl,name:b.name,subname:b.subname,unreadcount:b.unreadcount,ismuted:b.ismuted,lastmessagedate:c?c.timecreated:null,sentfromcurrentuser:c?c.useridfrom==e:null,lastmessage:c?a(c.text).text()||c.text:null},f=null;return b.type==m.CONVERSATION_TYPES.SELF?f=b.members[0]:b.type==m.CONVERSATION_TYPES.PRIVATE&&(f=b.members.reduce(function(a,b){return a||b.id==e||(a=b),a},null)),null!==f&&(d.userid=f.id,d.showonlinestatus=f.showonlinestatus,d.isonline=f.isonline,d.isblocked=f.isblocked),b.type==m.CONVERSATION_TYPES.PUBLIC&&(d.lastsendername=b.members.reduce(function(a,b){return a||b.id!=c.useridfrom||(a=b.fullname),a},null)),d});return g.forEach(function(a){(new Date).toDateString()==new Date(1e3*a.lastmessagedate).toDateString()&&(a.istoday=!0)}),f.render(o.CONVERSATIONS_LIST,{conversations:g}).then(function(a){return b.append(a),a})["catch"](c.exception)},z=function(a,b,d){return function(e,f){return h.getConversations(f,a,p+1,d,b,!0).then(function(a){var b=a.conversations;return b.length>p?b=b.slice(0,-1):l.setLoadedAll(e,!0),d+=p,b.forEach(function(a){q[a.id]=a}),b})["catch"](c.exception)}},A=function(a){return a.find(n.SECTION_TOTAL_COUNT)},B=function(a){return a.find(n.SECTION_UNREAD_COUNT)},C=function(a){if(r){var b=A(a),c=parseInt(b.text());c+=1,b.text(c)}},D=function(a){if(r){var b=A(a),c=parseInt(b.text());c-=1,b.text(c)}},E=function(a){if(s){var b=B(a),c=parseInt(b.text());c-=1,b.text(c),c<1&&b.addClass("hidden")}},F=function(a,b){return a.find('[data-conversation-id="'+b+'"]')},G=function(a,b){return a.find('[data-user-id="'+b+'"]')},H=function(a){a.find(n.MUTED_ICON_CONTAINER).removeClass("hidden")},I=function(a){a.find(n.MUTED_ICON_CONTAINER).addClass("hidden")},J=function(a){a.find(n.BLOCKED_ICON_CONTAINER).removeClass("hidden")},K=function(a){a.find(n.BLOCKED_ICON_CONTAINER).addClass("hidden")},L=function(b,c){var d,f=c.messages[c.messages.length-1],h="";d=f.fromLoggedInUser?{key:"you",component:"core_message"}:{key:"sender",component:"core_message",param:f.userFrom.fullname};var i=[d,{key:"strftimetime24",component:"core_langconfig"}];return e.get_strings(i).then(function(a){return h=a[0],g.get([{timestamp:f.timeCreated,format:a[1]}])}).then(function(a){return a[0]}).then(function(d){b.find(n.LAST_MESSAGE_DATE).text(d).removeClass("hidden"),f.fromLoggedInUser||c.type!==m.CONVERSATION_TYPES.PRIVATE||(h="");var e=h+" "+a(f.text).text()+"";return b.find(n.LAST_MESSAGE).html(e)})},M=function(b,d){var e=b.find(n.CONVERSATION),g="";if(!e.length){var h=l.getRoot(b);l.showContent(h),l.hideEmptyMessage(h)}var i=d.messages.length,j=i?d.messages[i-1]:null;j&&(g=a(j.text).text()||j.text);var k={id:d.id,name:d.name,subname:d.subname,lastmessagedate:j?j.timeCreated:null,sentfromcurrentuser:j?j.fromLoggedInUser:null,lastmessage:g,imageurl:d.imageUrl};return q[d.id]=d,(new Date).toDateString()==new Date(1e3*k.lastmessagedate).toDateString()&&(k.istoday=!0),f.render(o.CONVERSATIONS_LIST,{conversations:[k]}).then(function(a){var c=l.getContentContainer(b);return c.prepend(a)}).then(function(){return C(b)})["catch"](c.exception)},N=function(a,b){b.remove(),D(a);var c=a.find(n.CONVERSATION);if(!c.length){var d=l.getRoot(a);l.hideContent(d),l.showEmptyMessage(d)}},O=function(a,b){var c=b.find(n.UNREAD_COUNT);c.text("0"),c.addClass("hidden"),E(a)},P=function(c,e,f,g,h){var o=l.getRoot(e),p=e.find(n.TOGGLE);e.css("min-height",p.outerHeight()),e.on("show.bs.collapse",function(){u(e),l.show(o,f,y)}),e.on("hidden.bs.collapse",function(){v(e)}),d.subscribe(i.CONTACT_BLOCKED,function(a){var b=G(e,a);b.length&&J(b)}),d.subscribe(i.CONTACT_UNBLOCKED,function(a){var b=G(e,a);b.length&&K(b)}),d.subscribe(i.CONVERSATION_SET_MUTED,function(a){var b=a.id,c=F(e,b);c.length&&H(c)}),d.subscribe(i.CONVERSATION_UNSET_MUTED,function(a){var b=a.id,c=F(e,b);c.length&&I(c)}),d.subscribe(i.CONVERSATION_NEW_LAST_MESSAGE,function(a){if(!(g&&a.type==m.CONVERSATION_TYPES.SELF&&g!=m.CONVERSATION_TYPES.PRIVATE&&!a.isFavourite||g&&a.type!=m.CONVERSATION_TYPES.SELF&&g!=a.type||h&&!a.isFavourite||!h&&a.isFavourite)){var b=a.id,c=F(e,b);c.length?L(c,a):M(e,a)}}),d.subscribe(i.CONVERSATION_DELETED,function(a){var b=F(e,a);b.length&&N(e,b)}),d.subscribe(i.CONVERSATION_READ,function(a){var b=F(e,a);b.length&&O(e,b)}),d.subscribe(i.CONVERSATION_SET_FAVOURITE,function(a){var b=null;!h||g&&g!=a.type?(g==a.type||g==m.CONVERSATION_TYPES.PRIVATE&&a.type==m.CONVERSATION_TYPES.SELF)&&(b=F(e,a.id),b.length&&N(e,b)):(b=F(e,a.id),b.length||M(e,a))}),d.subscribe(i.CONVERSATION_UNSET_FAVOURITE,function(a){var b=null;h?(b=F(e,a.id),b.length&&N(e,b)):(g==a.type||g==m.CONVERSATION_TYPES.PRIVATE&&a.type==m.CONVERSATION_TYPES.SELF)&&(b=F(e,a.id),b.length||M(e,a))}),b.define(e,[b.events.activate]),e.on(b.events.activate,n.CONVERSATION,function(b,d){var e=a(b.target).closest(n.CONVERSATION),f=e.attr("data-conversation-id"),g=q[f];j.go(c,k.VIEW_CONVERSATION,g),d.originalEvent.preventDefault()})},Q=function(b,c,d,e,f,g,h,i){var j=a(d);if(!j.attr("data-init")){var k=z(f,g,0);if(P(b,j,k,f,g),t(j)){u(j);var m=l.getRoot(j);l.show(m,k,y)}h.then(function(a){w(j,a),r=!0})["catch"](function(){}),i.then(function(a){x(j,a),s=!0})["catch"](function(){}),j.attr("data-init",!0)}};return{show:Q,isVisible:t}}); \ No newline at end of file diff --git a/message/amd/build/message_repository.min.js b/message/amd/build/message_repository.min.js index 999ba175551..4b0e9435f29 100644 --- a/message/amd/build/message_repository.min.js +++ b/message/amd/build/message_repository.min.js @@ -1 +1 @@ -define(["jquery","core/ajax","core/notification"],function(a,b,c){var d={PRIVATE:1,PUBLIC:2},e=function(a){"undefined"==typeof a.limit&&(a.limit=0),"undefined"==typeof a.offset&&(a.offset=0),"undefined"==typeof a.type&&(a.type=null),"undefined"==typeof a.favouritesonly&&(a.favouritesonly=!1),a.limitfrom=a.offset,a.limitnum=a.limit,delete a.limit,delete a.offset;var d={methodname:"core_message_data_for_messagearea_conversations",args:a},e=b.call([d])[0];return e.fail(c.exception),e},f=function(a){var d={methodname:"core_message_get_unread_conversations_count",args:a},e=b.call([d])[0];return e.fail(c.exception),e},g=function(a){var d={methodname:"core_message_mark_all_messages_as_read",args:a},e=b.call([d])[0];return e.fail(c.exception),e},h=function(a,c,d){var e={userid:a};"undefined"!=typeof c&&(e.limitnum=c),"undefined"!=typeof d&&(e.limitfrom=d);var f={methodname:"core_message_get_user_contacts",args:e};return b.call([f])[0]},i=function(a,c){var d={methodname:"core_message_data_for_messagearea_get_profile",args:{currentuserid:a,otheruserid:c}};return b.call([d])[0]},j=function(c,d){var e=[{methodname:"core_message_block_user",args:{userid:c,blockeduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:c,userids:[d],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},k=function(c,d){var e=[{methodname:"core_message_unblock_user",args:{userid:c,unblockeduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:c,userids:[d],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},l=function(a,c){var d={methodname:"core_message_create_contact_request",args:{userid:a,requesteduserid:c}};return b.call([d])[0]},m=function(c,d){var e=[{methodname:"core_message_delete_contacts",args:{userid:c,userids:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:c,userids:d,includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b})},n=function(a,c,d,e,f,g){var h={currentuserid:a,convid:c,newest:!!f};"undefined"!=typeof d&&(h.limitnum=d),"undefined"!=typeof e&&(h.limitfrom=e),"undefined"!=typeof g&&(h.timefrom=g);var i={methodname:"core_message_get_conversation_messages",args:h};return b.call([i])[0]},o=function(a,c,d,e){var f={userid:a,search:c};"undefined"!=typeof d&&(f.limitnum=d),"undefined"!=typeof e&&(f.limitfrom=e);var g={methodname:"core_message_message_search_users",args:f};return b.call([g])[0]},p=function(a,c,d,e){var f={userid:a,search:c};"undefined"!=typeof d&&(f.limitnum=d),"undefined"!=typeof e&&(f.limitfrom=e);var g={methodname:"core_message_data_for_messagearea_search_messages",args:f};return b.call([g])[0]},q=function(a,c){var d=c.map(function(b){return{touserid:a,text:b}}),e={methodname:"core_message_send_instant_messages",args:{messages:d}};return b.call([e])[0].then(function(a){var b=a.reduce(function(a,b){return b.errormessage&&a.push(b.errormessage),a},[]);if(b.length)throw new Error(b.join("\n"));return a}).then(function(a){return a.map(function(a){return{id:a.msgid,text:a.text,timecreated:a.timecreated,useridfrom:a.useridfrom,conversationid:a.conversationid}})})},r=function(a,b){return q(a,[b]).then(function(a){return a[0]})},s=function(a,c){var d=c.map(function(a){return{text:a}}),e={methodname:"core_message_send_messages_to_conversation",args:{conversationid:a,messages:d}};return b.call([e])[0]},t=function(a,b){return s(a,[b]).then(function(a){return a[0]})},u=function(a,c){var d={methodname:"core_user_update_user_preferences",args:{userid:a,preferences:c}};return b.call([d])[0]},v=function(a){var c={methodname:"core_user_get_user_preferences",args:{userid:a}};return b.call([c])[0]},w=function(c,d){return a.when.apply(null,b.call(d.map(function(a){return{methodname:"core_message_delete_message",args:{messageid:a,userid:c}}})))},x=function(a,c){var d={methodname:"core_message_delete_conversations_by_id",args:{userid:a,conversationids:[c]}};return b.call([d])[0]},y=function(a){var c={methodname:"core_message_get_contact_requests",args:{userid:a}};return b.call([c])[0]},z=function(c,d){var e=[{methodname:"core_message_confirm_contact_request",args:{userid:c,requesteduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:d,userids:[c],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},A=function(c,d){var e=[{methodname:"core_message_decline_contact_request",args:{userid:c,requesteduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:d,userids:[c],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},B=function(a,c,d,e,f,g,h,i,j){var k={userid:a,conversationid:c};"undefined"!=typeof d&&null!==d&&(k.includecontactrequests=d),"undefined"!=typeof e&&null!==e&&(k.includeprivacyinfo=e),"undefined"!=typeof f&&null!==f&&(k.memberlimit=f),"undefined"!=typeof g&&null!==g&&(k.memberoffset=g),"undefined"!=typeof h&&null!==h&&(k.messagelimit=h),"undefined"!=typeof i&&null!==i&&(k.messageoffset=i),"undefined"!=typeof j&&null!==j&&(k.newestmessagesfirst=j);var l={methodname:"core_message_get_conversation",args:k};return b.call([l])[0]},C=function(a,c,d,e,f,g,h,i,j){var k={userid:a,otheruserid:c};"undefined"!=typeof d&&null!==d&&(k.includecontactrequests=d),"undefined"!=typeof e&&null!==e&&(k.includeprivacyinfo=e),"undefined"!=typeof f&&null!==f&&(k.memberlimit=f),"undefined"!=typeof g&&null!==g&&(k.memberoffset=g),"undefined"!=typeof h&&null!==h&&(k.messagelimit=h),"undefined"!=typeof i&&null!==i&&(k.messageoffset=i),"undefined"!=typeof j&&null!==j&&(k.newestmessagesfirst=j);var l={methodname:"core_message_get_conversation_between_users",args:k};return b.call([l])[0]},D=function(a,c,e,f,g){var h={userid:a,type:c};"undefined"!=typeof e&&null!==e&&(h.limitnum=e),"undefined"!=typeof f&&null!==f&&(h.limitfrom=f),"undefined"!=typeof g&&null!==g&&(h.favourites=g);var i={methodname:"core_message_get_conversations",args:h};return b.call([i])[0].then(function(a){return a.conversations.length&&(a.conversations=a.conversations.map(function(a){if(a.type==d.PRIVATE){var b=a.members.length?a.members[0]:null;b&&(a.name=a.name?a.name:b.fullname,a.imageurl=a.imageurl?a.imageurl:b.profileimageurl)}return a})),a})},E=function(a,c,d,e,f){var g={userid:c,conversationid:a};"undefined"!=typeof d&&null!==d&&(g.limitnum=d),"undefined"!=typeof e&&null!==e&&(g.limitfrom=e),"undefined"!=typeof f&&null!==f&&(g.includecontactrequests=f);var h={methodname:"core_message_get_conversation_members",args:g};return b.call([h])[0]},F=function(a,c){var d={methodname:"core_message_set_favourite_conversations",args:{userid:a,conversations:c}};return b.call([d])[0]},G=function(a,c){var d={methodname:"core_message_unset_favourite_conversations",args:{userid:a,conversations:c}};return b.call([d])[0]},H=function(a,c){var d={methodname:"core_message_mute_conversations",args:{userid:a,conversationids:c}};return b.call([d])[0]},I=function(a,c){var d={methodname:"core_message_unmute_conversations",args:{userid:a,conversationids:c}};return b.call([d])[0]},J=function(a,c,d,e){var f={referenceuserid:a,userids:c};"undefined"!=typeof d&&(f.includecontactrequests=d),"undefined"!=typeof e&&(f.includeprivacyinfo=e);var g={methodname:"core_message_get_member_info",args:f};return b.call([g])[0]},K=function(a,c){var d={methodname:"core_message_mark_all_conversation_messages_as_read",args:{userid:a,conversationid:c}};return b.call([d])[0]},L=function(a){var c={methodname:"core_message_get_user_message_preferences",args:{userid:a}};return b.call([c])[0]},M=function(a){var c={methodname:"core_message_get_conversation_counts",args:{userid:a}};return b.call([c])[0]},N=function(a){var c={methodname:"core_message_get_unread_conversation_counts",args:{userid:a}};return b.call([c])[0]},O=function(c){var d=[{methodname:"core_message_get_conversation_counts",args:{userid:c}},{methodname:"core_message_get_unread_conversation_counts",args:{userid:c}}];return a.when.apply(null,b.call(d)).then(function(a,b){return{total:a,unread:b}})};return{query:e,countUnreadConversations:f,markAllAsRead:g,getContacts:h,getProfile:i,blockUser:j,unblockUser:k,createContactRequest:l,deleteContacts:m,getMessages:n,searchUsers:o,searchMessages:p,sendMessagesToUser:q,sendMessageToUser:r,sendMessagesToConversation:s,sendMessageToConversation:t,savePreferences:u,getPreferences:v,deleteMessages:w,deleteConversation:x,getContactRequests:y,acceptContactRequest:z,declineContactRequest:A,getConversation:B,getConversationBetweenUsers:C,getConversations:D,getConversationMembers:E,setFavouriteConversations:F,setMutedConversations:H,unsetFavouriteConversations:G,unsetMutedConversations:I,getMemberInfo:J,markAllConversationMessagesAsRead:K,getUserMessagePreferences:L,getTotalConversationCounts:M,getUnreadConversationCounts:N,getAllConversationCounts:O}}); \ No newline at end of file +define(["jquery","core/ajax","core/notification","core_message/message_drawer_view_conversation_constants"],function(a,b,c,d){var e=d.CONVERSATION_TYPES,f=function(a){"undefined"==typeof a.limit&&(a.limit=0),"undefined"==typeof a.offset&&(a.offset=0),"undefined"==typeof a.type&&(a.type=null),"undefined"==typeof a.favouritesonly&&(a.favouritesonly=!1),a.limitfrom=a.offset,a.limitnum=a.limit,delete a.limit,delete a.offset;var d={methodname:"core_message_data_for_messagearea_conversations",args:a},e=b.call([d])[0];return e.fail(c.exception),e},g=function(a){var d={methodname:"core_message_get_unread_conversations_count",args:a},e=b.call([d])[0];return e.fail(c.exception),e},h=function(a){var d={methodname:"core_message_mark_all_messages_as_read",args:a},e=b.call([d])[0];return e.fail(c.exception),e},i=function(a,c,d){var e={userid:a};"undefined"!=typeof c&&(e.limitnum=c),"undefined"!=typeof d&&(e.limitfrom=d);var f={methodname:"core_message_get_user_contacts",args:e};return b.call([f])[0]},j=function(a,c){var d={methodname:"core_message_data_for_messagearea_get_profile",args:{currentuserid:a,otheruserid:c}};return b.call([d])[0]},k=function(c,d){var e=[{methodname:"core_message_block_user",args:{userid:c,blockeduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:c,userids:[d],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},l=function(c,d){var e=[{methodname:"core_message_unblock_user",args:{userid:c,unblockeduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:c,userids:[d],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},m=function(a,c){var d={methodname:"core_message_create_contact_request",args:{userid:a,requesteduserid:c}};return b.call([d])[0]},n=function(c,d){var e=[{methodname:"core_message_delete_contacts",args:{userid:c,userids:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:c,userids:d,includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b})},o=function(a,c,d,e,f,g){var h={currentuserid:a,convid:c,newest:!!f};"undefined"!=typeof d&&(h.limitnum=d),"undefined"!=typeof e&&(h.limitfrom=e),"undefined"!=typeof g&&(h.timefrom=g);var i={methodname:"core_message_get_conversation_messages",args:h};return b.call([i])[0]},p=function(a,c,d,e){var f={userid:a,search:c};"undefined"!=typeof d&&(f.limitnum=d),"undefined"!=typeof e&&(f.limitfrom=e);var g={methodname:"core_message_message_search_users",args:f};return b.call([g])[0]},q=function(a,c,d,e){var f={userid:a,search:c};"undefined"!=typeof d&&(f.limitnum=d),"undefined"!=typeof e&&(f.limitfrom=e);var g={methodname:"core_message_data_for_messagearea_search_messages",args:f};return b.call([g])[0]},r=function(a,c){var d=c.map(function(b){return{touserid:a,text:b}}),e={methodname:"core_message_send_instant_messages",args:{messages:d}};return b.call([e])[0].then(function(a){var b=a.reduce(function(a,b){return b.errormessage&&a.push(b.errormessage),a},[]);if(b.length)throw new Error(b.join("\n"));return a}).then(function(a){return a.map(function(a){return{id:a.msgid,text:a.text,timecreated:a.timecreated,useridfrom:a.useridfrom,conversationid:a.conversationid}})})},s=function(a,b){return r(a,[b]).then(function(a){return a[0]})},t=function(a,c){var d=c.map(function(a){return{text:a}}),e={methodname:"core_message_send_messages_to_conversation",args:{conversationid:a,messages:d}};return b.call([e])[0]},u=function(a,b){return t(a,[b]).then(function(a){return a[0]})},v=function(a,c){var d={methodname:"core_user_update_user_preferences",args:{userid:a,preferences:c}};return b.call([d])[0]},w=function(a){var c={methodname:"core_user_get_user_preferences",args:{userid:a}};return b.call([c])[0]},x=function(c,d){return a.when.apply(null,b.call(d.map(function(a){return{methodname:"core_message_delete_message",args:{messageid:a,userid:c}}})))},y=function(a,c){var d={methodname:"core_message_delete_conversations_by_id",args:{userid:a,conversationids:[c]}};return b.call([d])[0]},z=function(a){var c={methodname:"core_message_get_contact_requests",args:{userid:a}};return b.call([c])[0]},A=function(c,d){var e=[{methodname:"core_message_confirm_contact_request",args:{userid:c,requesteduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:d,userids:[c],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},B=function(c,d){var e=[{methodname:"core_message_decline_contact_request",args:{userid:c,requesteduserid:d}},{methodname:"core_message_get_member_info",args:{referenceuserid:d,userids:[c],includecontactrequests:!0,includeprivacyinfo:!0}}];return a.when.apply(null,b.call(e)).then(function(a,b){return b.length?b[0]:{}})},C=function(a,c,d,e,f,g,h,i,j){var k={userid:a,conversationid:c};"undefined"!=typeof d&&null!==d&&(k.includecontactrequests=d),"undefined"!=typeof e&&null!==e&&(k.includeprivacyinfo=e),"undefined"!=typeof f&&null!==f&&(k.memberlimit=f),"undefined"!=typeof g&&null!==g&&(k.memberoffset=g),"undefined"!=typeof h&&null!==h&&(k.messagelimit=h),"undefined"!=typeof i&&null!==i&&(k.messageoffset=i),"undefined"!=typeof j&&null!==j&&(k.newestmessagesfirst=j);var l={methodname:"core_message_get_conversation",args:k};return b.call([l])[0]},D=function(a,c,d,e,f,g,h,i,j){var k={userid:a,otheruserid:c};"undefined"!=typeof d&&null!==d&&(k.includecontactrequests=d),"undefined"!=typeof e&&null!==e&&(k.includeprivacyinfo=e),"undefined"!=typeof f&&null!==f&&(k.memberlimit=f),"undefined"!=typeof g&&null!==g&&(k.memberoffset=g),"undefined"!=typeof h&&null!==h&&(k.messagelimit=h),"undefined"!=typeof i&&null!==i&&(k.messageoffset=i),"undefined"!=typeof j&&null!==j&&(k.newestmessagesfirst=j);var l={methodname:"core_message_get_conversation_between_users",args:k};return b.call([l])[0]},E=function(a,c,d,e){var f={userid:a};"undefined"!=typeof c&&null!==c&&(f.messagelimit=c),"undefined"!=typeof d&&null!==d&&(f.messageoffset=d),"undefined"!=typeof e&&null!==e&&(f.newestmessagesfirst=e);var g={methodname:"core_message_get_self_conversation",args:f};return b.call([g])[0]},F=function(a,c,d,f,g,h){var i={userid:a,type:c};"undefined"!=typeof d&&null!==d&&(i.limitnum=d),"undefined"!=typeof f&&null!==f&&(i.limitfrom=f),"undefined"!=typeof g&&null!==g&&(i.favourites=g),"undefined"!=typeof h&&null!==h&&(i.mergeself=h);var j={methodname:"core_message_get_conversations",args:i};return b.call([j])[0].then(function(a){return a.conversations.length&&(a.conversations=a.conversations.map(function(a){if(a.type==e.PRIVATE||a.type==e.SELF){var b=a.members.length?a.members[0]:null;b&&(a.name=a.name?a.name:b.fullname,a.imageurl=a.imageurl?a.imageurl:b.profileimageurl)}return a})),a})},G=function(a,c,d,e,f){var g={userid:c,conversationid:a};"undefined"!=typeof d&&null!==d&&(g.limitnum=d),"undefined"!=typeof e&&null!==e&&(g.limitfrom=e),"undefined"!=typeof f&&null!==f&&(g.includecontactrequests=f);var h={methodname:"core_message_get_conversation_members",args:g};return b.call([h])[0]},H=function(a,c){var d={methodname:"core_message_set_favourite_conversations",args:{userid:a,conversations:c}};return b.call([d])[0]},I=function(a,c){var d={methodname:"core_message_unset_favourite_conversations",args:{userid:a,conversations:c}};return b.call([d])[0]},J=function(a,c){var d={methodname:"core_message_mute_conversations",args:{userid:a,conversationids:c}};return b.call([d])[0]},K=function(a,c){var d={methodname:"core_message_unmute_conversations",args:{userid:a,conversationids:c}};return b.call([d])[0]},L=function(a,c,d,e){var f={referenceuserid:a,userids:c};"undefined"!=typeof d&&(f.includecontactrequests=d),"undefined"!=typeof e&&(f.includeprivacyinfo=e);var g={methodname:"core_message_get_member_info",args:f};return b.call([g])[0]},M=function(a,c){var d={methodname:"core_message_mark_all_conversation_messages_as_read",args:{userid:a,conversationid:c}};return b.call([d])[0]},N=function(a){var c={methodname:"core_message_get_user_message_preferences",args:{userid:a}};return b.call([c])[0]},O=function(a){var c={methodname:"core_message_get_conversation_counts",args:{userid:a}};return b.call([c])[0]},P=function(a){var c={methodname:"core_message_get_unread_conversation_counts",args:{userid:a}};return b.call([c])[0]},Q=function(c){var d=[{methodname:"core_message_get_conversation_counts",args:{userid:c}},{methodname:"core_message_get_unread_conversation_counts",args:{userid:c}}];return a.when.apply(null,b.call(d)).then(function(a,b){return{total:a,unread:b}})};return{query:f,countUnreadConversations:g,markAllAsRead:h,getContacts:i,getProfile:j,blockUser:k,unblockUser:l,createContactRequest:m,deleteContacts:n,getMessages:o,searchUsers:p,searchMessages:q,sendMessagesToUser:r,sendMessageToUser:s,sendMessagesToConversation:t,sendMessageToConversation:u,savePreferences:v,getPreferences:w,deleteMessages:x,deleteConversation:y,getContactRequests:z,acceptContactRequest:A,declineContactRequest:B,getConversation:C,getConversationBetweenUsers:D,getSelfConversation:E,getConversations:F,getConversationMembers:G,setFavouriteConversations:H,setMutedConversations:J,unsetFavouriteConversations:I,unsetMutedConversations:K,getMemberInfo:L,markAllConversationMessagesAsRead:M,getUserMessagePreferences:N,getTotalConversationCounts:O,getUnreadConversationCounts:P,getAllConversationCounts:Q}}); \ No newline at end of file diff --git a/message/amd/src/message_drawer_view_conversation.js b/message/amd/src/message_drawer_view_conversation.js index 8b8949b566a..60810511940 100644 --- a/message/amd/src/message_drawer_view_conversation.js +++ b/message/amd/src/message_drawer_view_conversation.js @@ -120,11 +120,16 @@ function( * @return {Number} Userid. */ var getOtherUserId = function() { - if (!viewState || viewState.type != CONVERSATION_TYPES.PRIVATE) { + if (!viewState || (viewState.type != CONVERSATION_TYPES.PRIVATE && viewState.type != CONVERSATION_TYPES.SELF)) { return null; } var loggedInUserId = viewState.loggedInUserId; + if (viewState.type == CONVERSATION_TYPES.SELF) { + // It's a self-conversation, so the other user is the one logged in. + return loggedInUserId; + } + var otherUserIds = Object.keys(viewState.members).filter(function(userId) { return loggedInUserId != userId; }); @@ -144,7 +149,7 @@ function( if (!carry) { var state = stateCache[id].state; - if (state.type == CONVERSATION_TYPES.PRIVATE) { + if (state.type == CONVERSATION_TYPES.PRIVATE || state.type == CONVERSATION_TYPES.SELF) { if (userId in state.members) { // We've found a cached conversation for this user! carry = state.id; @@ -287,7 +292,7 @@ function( newState = StateManager.setLoadingMembers(newState, false); newState = StateManager.setLoadingMessages(newState, false); newState = StateManager.setName(newState, profile.fullname); - newState = StateManager.setType(newState, 1); + newState = StateManager.setType(newState, CONVERSATION_TYPES.PRIVATE); newState = StateManager.setImageUrl(newState, profile.profileimageurl); newState = StateManager.setTotalMemberCount(newState, 2); return render(newState) @@ -302,6 +307,50 @@ function( }); }; + /** + * Load up an empty self-conversation for the logged in user. + * Sets all of the conversation details based on the current user. + * + * A conversation isn't created until the user sends the first message. + * + * @param {Object} loggedInUserProfile The logged in user profile. + * @return {Object} Profile returned from repository. + */ + var loadEmptySelfConversation = function(loggedInUserProfile) { + var loggedInUserId = loggedInUserProfile.id; + var newState = StateManager.setLoadingMembers(viewState, true); + newState = StateManager.setLoadingMessages(newState, true); + return render(newState) + .then(function() { + return Repository.getMemberInfo(loggedInUserId, [loggedInUserId], true, true); + }) + .then(function(profiles) { + if (profiles.length) { + return profiles[0]; + } else { + throw new Error('Unable to load other user profile'); + } + }) + .then(function(profile) { + var newState = StateManager.addMembers(viewState, [profile, loggedInUserProfile]); + newState = StateManager.setLoadingMembers(newState, false); + newState = StateManager.setLoadingMessages(newState, false); + newState = StateManager.setName(newState, profile.fullname); + newState = StateManager.setType(newState, CONVERSATION_TYPES.SELF); + newState = StateManager.setImageUrl(newState, profile.profileimageurl); + newState = StateManager.setTotalMemberCount(newState, 1); + return render(newState) + .then(function() { + return profile; + }); + }) + .catch(function(error) { + var newState = StateManager.setLoadingMembers(viewState, false); + render(newState); + Notification.exception(error); + }); + }; + /** * Create a new state from a conversation object. * @@ -310,14 +359,21 @@ function( * @return {Object} new state. */ var updateStateFromConversation = function(conversation, loggedInUserId) { - var otherUsers = conversation.members.filter(function(member) { - return member.id != loggedInUserId; - }); - var otherUser = otherUsers.length ? otherUsers[0] : null; + var otherUser = null; + if (conversation.type == CONVERSATION_TYPES.PRIVATE) { + // For private conversations, remove current logged in user from the members list to get the other user. + var otherUsers = conversation.members.filter(function(member) { + return member.id != loggedInUserId; + }); + otherUser = otherUsers.length ? otherUsers[0] : null; + } else if (conversation.type == CONVERSATION_TYPES.SELF) { + // Self-conversations have only one member. + otherUser = conversation.members[0]; + } + var name = conversation.name; var imageUrl = conversation.imageurl; - - if (conversation.type == CONVERSATION_TYPES.PRIVATE) { + if (conversation.type == CONVERSATION_TYPES.PRIVATE || conversation.type == CONVERSATION_TYPES.SELF) { name = name || otherUser ? otherUser.fullname : ''; imageUrl = imageUrl || otherUser ? otherUser.profileimageurl : ''; } @@ -921,6 +977,7 @@ function( newState = StateManager.setPendingDeleteConversation(newState, false); newState = StateManager.setLoadingConfirmAction(newState, false); PubSub.publish(MessageDrawerEvents.CONVERSATION_DELETED, newState.id); + return render(newState); }); }; @@ -1019,7 +1076,8 @@ function( var newConversationId = null; return render(newState) .then(function() { - if (!conversationId && viewState.type == CONVERSATION_TYPES.PRIVATE) { + if (!conversationId && + (viewState.type == CONVERSATION_TYPES.PRIVATE || viewState.type == CONVERSATION_TYPES.SELF)) { // If it's a new private conversation then we need to use the old // web service function to create the conversation. var otherUserId = getOtherUserId(); @@ -1471,7 +1529,7 @@ function( }; /** - * Load a new empty private conversation between two users. + * Load a new empty private conversation between two users or self-conversation. * * @param {Object} body Conversation body container element. * @param {Object} loggedInUserProfile The logged in user's profile. @@ -1481,28 +1539,50 @@ function( var resetNoConversation = function(body, loggedInUserProfile, otherUserId) { // Always reset the state back to the initial state so that the // state manager and patcher can work correctly. - return resetState(body, null, loggedInUserProfile) - .then(function() { - return Repository.getConversationBetweenUsers( - loggedInUserProfile.id, - otherUserId, - true, - true, - 0, - 0, - LOAD_MESSAGE_LIMIT, - 0, - NEWEST_FIRST - ) - .then(function(conversation) { - // Looks like we have a conversation after all! Let's use that. - return resetByConversation(body, conversation, loggedInUserProfile); - }) - .catch(function() { - // Can't find a conversation. Oh well. Just load up a blank one. - return loadEmptyPrivateConversation(loggedInUserProfile, otherUserId); - }); - }); + if (loggedInUserProfile.id != otherUserId) { + // This is a private conversation between two users. + return resetState(body, null, loggedInUserProfile) + .then(function() { + return Repository.getConversationBetweenUsers( + loggedInUserProfile.id, + otherUserId, + true, + true, + 0, + 0, + LOAD_MESSAGE_LIMIT, + 0, + NEWEST_FIRST + ) + .then(function(conversation) { + // Looks like we have a conversation after all! Let's use that. + return resetByConversation(body, conversation, loggedInUserProfile); + }) + .catch(function() { + // Can't find a conversation. Oh well. Just load up a blank one. + return loadEmptyPrivateConversation(loggedInUserProfile, otherUserId); + }); + }); + } else { + // This is a self-conversation. + return resetState(body, null, loggedInUserProfile) + .then(function() { + return Repository.getSelfConversation( + loggedInUserProfile.id, + LOAD_MESSAGE_LIMIT, + 0, + NEWEST_FIRST + ) + .then(function(conversation) { + // Looks like we have a conversation after all! Let's use that. + return resetByConversation(body, conversation, loggedInUserProfile); + }) + .catch(function() { + // Can't find a conversation. Oh well. Just load up a blank one. + return loadEmptySelfConversation(loggedInUserProfile); + }); + }); + } }; /** diff --git a/message/amd/src/message_drawer_view_conversation_constants.js b/message/amd/src/message_drawer_view_conversation_constants.js index 3bd84c8e218..5c1e4f08a57 100644 --- a/message/amd/src/message_drawer_view_conversation_constants.js +++ b/message/amd/src/message_drawer_view_conversation_constants.js @@ -78,6 +78,7 @@ define([], function() { MORE_MESSAGES_LOADING_ICON_CONTAINER: '[data-region="more-messages-loading-icon-container"]', MUTED_ICON_CONTAINER: '[data-region="muted-icon-container"]', PLACEHOLDER_CONTAINER: '[data-region="placeholder-container"]', + SELF_CONVERSATION_MESSAGE_CONTAINER: '[data-region="self-conversation-message-container"]', SEND_MESSAGE_BUTTON: '[data-action="send-message"]', SEND_MESSAGE_ICON_CONTAINER: '[data-region="send-icon-container"]', TEXT: '[data-region="text"]', @@ -88,20 +89,32 @@ define([], function() { 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', + HEADER_SELF: 'core_message/message_drawer_view_conversation_header_content_type_self', 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' }; + // Conversation types. They must have the same values defined in \core_message\api. var CONVERSATION_TYPES = { PRIVATE: 1, - PUBLIC: 2 + PUBLIC: 2, + SELF: 3 + }; + + // Categories displayed in the message drawer. Some methods (such as filterCountsByType) are expecting their value + // will be the same as the defined in the CONVERSATION_TYPES, except for the favourite. + var CONVERSATION_CATEGORY_TYPES = { + PRIVATE: 1, + PUBLIC: 2, + FAVOURITE: null }; return { SELECTORS: SELECTORS, TEMPLATES: TEMPLATES, CONVERSATION_TYPES: CONVERSATION_TYPES, + CONVERSATION_CATEGORY_TYPES: CONVERSATION_CATEGORY_TYPES, NEWEST_MESSAGES_FIRST: true, LOAD_MESSAGE_LIMIT: 100, INITIAL_NEW_MESSAGE_POLL_TIMEOUT: 1000 diff --git a/message/amd/src/message_drawer_view_conversation_patcher.js b/message/amd/src/message_drawer_view_conversation_patcher.js index 43ea13c4ed8..a0a297ce142 100644 --- a/message/amd/src/message_drawer_view_conversation_patcher.js +++ b/message/amd/src/message_drawer_view_conversation_patcher.js @@ -313,6 +313,37 @@ function( return null; }; + /** + * Build a patch for the header of this conversation. Check if this conversation + * is a group conversation. + * + * @param {Object} state The current state. + * @param {Object} newState The new state. + * @return {Object} patch + */ + var buildHeaderPatchTypeSelf = function(state, newState) { + var shouldRenderHeader = (state.name === null); + + if (shouldRenderHeader) { + return { + type: Constants.CONVERSATION_TYPES.SELF, + // Don't display the controls for the self-conversations. + showControls: false, + context: { + id: newState.id, + name: newState.name, + subname: newState.subname, + imageurl: newState.imageUrl, + isfavourite: newState.isFavourite, + // Don't show favouriting if we don't have a conversation. + showfavourite: newState.id !== null, + showonlinestatus: true, + } + }; + } + + return null; + }; /** * Build a patch for the header of this conversation. Check if this conversation @@ -531,11 +562,11 @@ function( * * @param {Object} state The current state. * @param {Object} newState The new state. - * @return {Bool|Null} + * @return {int|Null} The conversation type of the messages to be deleted. */ var buildConfirmDeleteSelectedMessages = function(state, newState) { if (newState.pendingDeleteMessageIds.length) { - return true; + return newState.type; } else if (state.pendingDeleteMessageIds.length) { return false; } @@ -548,11 +579,11 @@ function( * * @param {Object} state The current state. * @param {Object} newState The new state. - * @return {Bool|Null} + * @return {int|Null} The conversation type to be deleted. */ var buildConfirmDeleteConversation = function(state, newState) { if (!state.pendingDeleteConversation && newState.pendingDeleteConversation) { - return true; + return newState.type; } else if (state.pendingDeleteConversation && !newState.pendingDeleteConversation) { return false; } @@ -948,6 +979,11 @@ function( var oldOtherUser = getOtherUserFromState(state); var newOtherUser = getOtherUserFromState(newState); + if (newState.type == Constants.CONVERSATION_TYPES.SELF) { + // Users always can send message themselves on self-conversations. + return null; + } + if (!oldOtherUser && !newOtherUser) { return null; } else if (oldOtherUser && !newOtherUser) { @@ -1104,6 +1140,19 @@ function( return null; }; + /** + * We should show this message always, for all the self-conversations. + * + * The message should be hidden when it's not a self-conversation. + * + * @param {Object} state The current state. + * @param {Object} newState The new state. + * @return {bool} + */ + var buildSelfConversationMessage = function(state, newState) { + return (newState.type == Constants.CONVERSATION_TYPES.SELF); + }; + /** * We should show the contact request sent message if the user just sent * a contact request to the other user and there are no messages in the @@ -1190,6 +1239,13 @@ function( header: buildHeaderPatchTypePublic, footer: buildFooterPatchTypePublic, }; + // These build functions are only applicable to self-conversations. + config[Constants.CONVERSATION_TYPES.SELF] = { + header: buildHeaderPatchTypeSelf, + footer: buildFooterPatchTypePublic, + confirmDeleteConversation: buildConfirmDeleteConversation, + selfConversationMessage: buildSelfConversationMessage + }; var patchConfig = $.extend({}, config.all); if (newState.type && newState.type in config) { diff --git a/message/amd/src/message_drawer_view_conversation_renderer.js b/message/amd/src/message_drawer_view_conversation_renderer.js index d0b67f23eff..77be40ab8f1 100644 --- a/message/amd/src/message_drawer_view_conversation_renderer.js +++ b/message/amd/src/message_drawer_view_conversation_renderer.js @@ -75,6 +75,26 @@ function( getMessagesContainer(body).addClass('hidden'); }; + /** + * Get the self-conversation message container element. + * + * @param {Object} body Conversation body container element. + * @return {Object} The messages container element. + */ + var getSelfConversationMessageContainer = function(body) { + return body.find(SELECTORS.SELF_CONVERSATION_MESSAGE_CONTAINER); + }; + + /** + * Hide the self-conversation message container element. + * + * @param {Object} body Conversation body container element. + * @return {Object} The messages container element. + */ + var hideSelfConversationMessageContainer = function(body) { + return getSelfConversationMessageContainer(body).addClass('hidden'); + }; + /** * Get the contact request sent container element. * @@ -783,6 +803,8 @@ function( if (data.type == CONVERSATION_TYPES.PRIVATE) { template = data.showControls ? TEMPLATES.HEADER_PRIVATE : TEMPLATES.HEADER_PRIVATE_NO_CONTROLS; + } else if (data.type == CONVERSATION_TYPES.SELF) { + template = TEMPLATES.HEADER_SELF; } return Templates.render(template, data.context) @@ -1121,12 +1143,21 @@ function( * @param {Object} header The header container element. * @param {Object} body The body container element. * @param {Object} footer The footer container element. - * @param {Bool} show If the dialogue should show. + * @param {int|Null} type The messages conversation type to be removed. * @return {Object} jQuery promise */ - var renderConfirmDeleteSelectedMessages = function(header, body, footer, show) { - if (show) { - return Str.get_string('deleteselectedmessagesconfirm', 'core_message') + var renderConfirmDeleteSelectedMessages = function(header, body, footer, type) { + var showmessage = null; + if (type == CONVERSATION_TYPES.SELF) { + // Message displayed to self-conversations is slighly different. + showmessage = 'deleteselectedmessagesconfirmselfconversation'; + } else if (type) { + // This other message should be displayed. + showmessage = 'deleteselectedmessagesconfirm'; + } + + if (showmessage) { + return Str.get_string(showmessage, 'core_message') .then(function(string) { return showConfirmDialogue( header, @@ -1150,12 +1181,21 @@ function( * @param {Object} header The header container element. * @param {Object} body The body container element. * @param {Object} footer The footer container element. - * @param {Bool} show If the dialogue should show + * @param {int|Null} type The conversation type to be removed. * @return {Object} jQuery promise */ - var renderConfirmDeleteConversation = function(header, body, footer, show) { - if (show) { - return Str.get_string('deleteallconfirm', 'core_message') + var renderConfirmDeleteConversation = function(header, body, footer, type) { + var showmessage = null; + if (type == CONVERSATION_TYPES.SELF) { + // Message displayed to self-conversations is slighly different. + showmessage = 'deleteallselfconfirm'; + } else if (type) { + // This other message should be displayed. + showmessage = 'deleteallconfirm'; + } + + if (showmessage) { + return Str.get_string(showmessage, 'core_message') .then(function(string) { return showConfirmDialogue( header, @@ -1437,6 +1477,25 @@ function( } }; + /** + * Show or hide the self-conversation message. + * + * @param {Object} header The header container element. + * @param {Object} body The body container element. + * @param {Object} footer The footer container element. + * @param {Object} displayMessage should the message be displayed?. + * @return {Object|true} jQuery promise + */ + var renderSelfConversationMessage = function(header, body, footer, displayMessage) { + var container = getSelfConversationMessageContainer(body); + if (displayMessage) { + container.removeClass('hidden'); + } else { + container.addClass('hidden'); + } + return true; + }; + /** * Show or hide the require add contact panel. * @@ -1472,6 +1531,7 @@ function( var renderReset = function(header, body, footer) { hideConfirmDialogue(header, body, footer); hideContactRequestSentContainer(body); + hideSelfConversationMessageContainer(body); hideAllHeaderElements(header); showHeaderPlaceholder(header); hideAllFooterElements(footer); @@ -1499,6 +1559,7 @@ function( confirmDeleteConversation: renderConfirmDeleteConversation, confirmContactRequest: renderConfirmContactRequest, requireAddContact: renderRequireAddContact, + selfConversationMessage: renderSelfConversationMessage, contactRequestSent: renderContactRequestSent }, { diff --git a/message/amd/src/message_drawer_view_overview.js b/message/amd/src/message_drawer_view_overview.js index 74f4d71d4d6..d126748cb62 100644 --- a/message/amd/src/message_drawer_view_overview.js +++ b/message/amd/src/message_drawer_view_overview.js @@ -30,7 +30,8 @@ define( 'core_message/message_drawer_routes', 'core_message/message_drawer_events', 'core_message/message_drawer_view_overview_section', - 'core_message/message_repository' + 'core_message/message_repository', + 'core_message/message_drawer_view_conversation_constants' ], function( $, @@ -41,7 +42,8 @@ function( Routes, MessageDrawerEvents, Section, - MessageRepository + MessageRepository, + Constants ) { var SELECTORS = { @@ -53,12 +55,6 @@ function( SECTION_TOGGLE_BUTTON: '[data-toggle]' }; - var CONVERSATION_TYPES = { - PRIVATE: 1, - PUBLIC: 2, - FAVOURITE: null - }; - var loadAllCountsPromise = null; /** @@ -89,7 +85,15 @@ function( * @return {Number} */ var filterCountsByType = function(counts, type) { - return type === CONVERSATION_TYPES.FAVOURITE ? counts.favourites : counts.types[type]; + var total = 0; + if (type === Constants.CONVERSATION_CATEGORY_TYPES.PRIVATE && counts.types[Constants.CONVERSATION_TYPES.SELF]) { + // As private and self conversations are displayed together, we need to add the counts for the self-conversations + // to the private ones, when there is any self-conversation. + total = counts.types[Constants.CONVERSATION_TYPES.PRIVATE] + counts.types[Constants.CONVERSATION_TYPES.SELF]; + } else { + total = type === Constants.CONVERSATION_CATEGORY_TYPES.FAVOURITE ? counts.favourites : counts.types[type]; + } + return total; }; /** @@ -226,11 +230,11 @@ function( var sections = [ // Favourite conversations section. - [body.find(SELECTORS.FAVOURITES), CONVERSATION_TYPES.FAVOURITE, true], + [body.find(SELECTORS.FAVOURITES), Constants.CONVERSATION_CATEGORY_TYPES.FAVOURITE, true], // Group conversations section. - [body.find(SELECTORS.GROUP_MESSAGES), CONVERSATION_TYPES.PUBLIC, false], + [body.find(SELECTORS.GROUP_MESSAGES), Constants.CONVERSATION_CATEGORY_TYPES.PUBLIC, false], // Private conversations section. - [body.find(SELECTORS.MESSAGES), CONVERSATION_TYPES.PRIVATE, false] + [body.find(SELECTORS.MESSAGES), Constants.CONVERSATION_CATEGORY_TYPES.PRIVATE, false] ]; sections.forEach(function(args) { diff --git a/message/amd/src/message_drawer_view_overview_section.js b/message/amd/src/message_drawer_view_overview_section.js index 01dba3e5040..a0ab83c79bb 100644 --- a/message/amd/src/message_drawer_view_overview_section.js +++ b/message/amd/src/message_drawer_view_overview_section.js @@ -183,14 +183,21 @@ function( lastmessage: lastMessage ? $(lastMessage.text).text() || lastMessage.text : null }; - if (conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.PRIVATE) { - var otherUser = conversation.members.reduce(function(carry, member) { + var otherUser = null; + if (conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.SELF) { + // Self-conversations have only one member. + otherUser = conversation.members[0]; + } else if (conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.PRIVATE) { + // For private conversations, remove the current userId from the members to get the other user. + otherUser = conversation.members.reduce(function(carry, member) { if (!carry && member.id != userId) { carry = member; } return carry; }, null); + } + if (otherUser !== null) { formattedConversation.userid = otherUser.id; formattedConversation.showonlinestatus = otherUser.showonlinestatus; formattedConversation.isonline = otherUser.isonline; @@ -238,7 +245,8 @@ function( type, LOAD_LIMIT + 1, offset, - includeFavourites + includeFavourites, + true // Always merge self-conversations with private conversations, to display them together. ) .then(function(response) { var conversations = response.conversations; @@ -575,8 +583,13 @@ function( }); PubSub.subscribe(MessageDrawerEvents.CONVERSATION_NEW_LAST_MESSAGE, function(conversation) { + // Self-conversations could be displayed as private conversations when they are not starred. So we need to exclude + // them from the following check to make sure last messages are updated properly for them. if ( - (type && conversation.type != type) || + (type && conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.SELF && + type != MessageDrawerViewConversationContants.CONVERSATION_TYPES.PRIVATE && !conversation.isFavourite) || + (type && conversation.type != MessageDrawerViewConversationContants.CONVERSATION_TYPES.SELF && + type != conversation.type) || (includeFavourites && !conversation.isFavourite) || (!includeFavourites && conversation.isFavourite) ) { @@ -613,7 +626,11 @@ function( if (!conversationElement.length) { createNewConversation(root, conversation); } - } else if (type == conversation.type) { + } else if (type == conversation.type || + (type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.PRIVATE && + conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.SELF)) { + // Self-conversations are displayed in the private conversations section, so they should be removed from + // there when they are favourited. conversationElement = getConversationElement(root, conversation.id); if (conversationElement.length) { deleteConversation(root, conversationElement); @@ -628,7 +645,11 @@ function( if (conversationElement.length) { deleteConversation(root, conversationElement); } - } else if (type == conversation.type) { + } else if (type == conversation.type || + (type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.PRIVATE && + conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.SELF)) { + // Self-conversations are displayed in the private conversations section, so they should be added + // there when they are unfavourited. conversationElement = getConversationElement(root, conversation.id); if (!conversationElement.length) { createNewConversation(root, conversation); diff --git a/message/amd/src/message_repository.js b/message/amd/src/message_repository.js index 24b234938d6..31c630dba9d 100644 --- a/message/amd/src/message_repository.js +++ b/message/amd/src/message_repository.js @@ -22,12 +22,19 @@ * @copyright 2016 Ryan Wyllie * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notification) { +define( +[ + 'jquery', + 'core/ajax', + 'core/notification', + 'core_message/message_drawer_view_conversation_constants' +], function( + $, + Ajax, + Notification, + Constants) { - var CONVERSATION_TYPES = { - PRIVATE: 1, - PUBLIC: 2 - }; + var CONVERSATION_TYPES = Constants.CONVERSATION_TYPES; /** * Retrieve a list of messages from the server. @@ -771,6 +778,45 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat return Ajax.call([request])[0]; }; + /** + * Get a self-conversation. + * + * @param {int} loggedInUserId The logged in user + * @param {int} messageLimit Limit for messages + * @param {int} messageOffset Offset for messages + * @param {bool} newestMessagesFirst Order the messages by newest first + * @return {object} jQuery promise + */ + var getSelfConversation = function( + loggedInUserId, + messageLimit, + messageOffset, + newestMessagesFirst + ) { + var args = { + userid: loggedInUserId + }; + + if (typeof messageLimit != 'undefined' && messageLimit !== null) { + args.messagelimit = messageLimit; + } + + if (typeof messageOffset != 'undefined' && messageOffset !== null) { + args.messageoffset = messageOffset; + } + + if (typeof newestMessagesFirst != 'undefined' && newestMessagesFirst !== null) { + args.newestmessagesfirst = newestMessagesFirst; + } + + var request = { + methodname: 'core_message_get_self_conversation', + args: args + }; + + return Ajax.call([request])[0]; + }; + /** * Get the conversations for a user. * @@ -786,7 +832,8 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat type, limit, offset, - favourites + favourites, + mergeself ) { var args = { userid: userId, @@ -805,6 +852,10 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat args.favourites = favourites; } + if (typeof mergeself != 'undefined' && mergeself !== null) { + args.mergeself = mergeself; + } + var request = { methodname: 'core_message_get_conversations', args: args @@ -814,7 +865,7 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat .then(function(result) { if (result.conversations.length) { result.conversations = result.conversations.map(function(conversation) { - if (conversation.type == CONVERSATION_TYPES.PRIVATE) { + if (conversation.type == CONVERSATION_TYPES.PRIVATE || conversation.type == CONVERSATION_TYPES.SELF) { var otherUser = conversation.members.length ? conversation.members[0] : null; if (otherUser) { @@ -1093,6 +1144,7 @@ define(['jquery', 'core/ajax', 'core/notification'], function($, Ajax, Notificat declineContactRequest: declineContactRequest, getConversation: getConversation, getConversationBetweenUsers: getConversationBetweenUsers, + getSelfConversation: getSelfConversation, getConversations: getConversations, getConversationMembers: getConversationMembers, setFavouriteConversations: setFavouriteConversations, diff --git a/message/classes/api.php b/message/classes/api.php index 8a56fdc5d2d..b1834047dd5 100644 --- a/message/classes/api.php +++ b/message/classes/api.php @@ -78,6 +78,11 @@ class api { */ const MESSAGE_CONVERSATION_TYPE_GROUP = 2; + /** + * A self conversation. + */ + const MESSAGE_CONVERSATION_TYPE_SELF = 3; + /** * The state for an enabled conversation area. */ @@ -125,14 +130,15 @@ class api { LEFT JOIN {message_user_actions} mua ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?) WHERE (m.useridfrom = ? OR mcm.userid = ?) - AND m.useridfrom != mcm.userid + AND (m.useridfrom != mcm.userid OR mc.type = ?) AND u.deleted = 0 AND u2.deleted = 0 AND mua.id is NULL AND " . $DB->sql_like('smallmessage', '?', false) . " ORDER BY timecreated DESC"; - $params = array($userid, $userid, $userid, self::MESSAGE_ACTION_DELETED, $userid, $userid, '%' . $search . '%'); + $params = array($userid, $userid, $userid, self::MESSAGE_ACTION_DELETED, $userid, $userid, + self::MESSAGE_CONVERSATION_TYPE_SELF, '%' . $search . '%'); // Convert the messages into searchable contacts with their last message being the message that was searched. $conversations = array(); @@ -316,7 +322,11 @@ class api { $fullname = $DB->sql_fullname(); // Users not to include. - $excludeusers = array($userid, $CFG->siteguest); + $excludeusers = array($CFG->siteguest); + if (!$selfconversation = self::get_self_conversation($userid)) { + // Userid should only be excluded when she hasn't a self-conversation. + $excludeusers[] = $userid; + } list($exclude, $excludeparams) = $DB->get_in_or_equal($excludeusers, SQL_PARAMS_NAMED, 'param', false); $params = array('search' => '%' . $DB->sql_like_escape($search) . '%', 'userid1' => $userid, 'userid2' => $userid); @@ -427,7 +437,12 @@ class api { if (!empty($foundusers)) { $noncontacts = helper::get_member_info($userid, array_keys($foundusers)); foreach ($noncontacts as $memberuserid => $memberinfo) { - $noncontacts[$memberuserid]->conversations = self::get_conversations_between_users($userid, $memberuserid, 0, 1000); + if ($memberuserid !== $userid) { + $noncontacts[$memberuserid]->conversations = self::get_conversations_between_users($userid, $memberuserid, 0, + 1000); + } else { + $noncontacts[$memberuserid]->conversations[$selfconversation->id] = $selfconversation; + } } } @@ -514,15 +529,17 @@ class api { * @param int $limitnum * @param int $type the type of the conversation, if you wish to filter to a certain type (see api constants). * @param bool $favourites whether to include NO favourites (false) or ONLY favourites (true), or null to ignore this setting. + * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false) + * when private conversations are requested. * @return array the array of conversations * @throws \moodle_exception */ public static function get_conversations($userid, $limitfrom = 0, $limitnum = 20, int $type = null, - bool $favourites = null) { + bool $favourites = null, bool $mergeself = false) { global $DB; if (!is_null($type) && !in_array($type, [self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, - self::MESSAGE_CONVERSATION_TYPE_GROUP])) { + self::MESSAGE_CONVERSATION_TYPE_GROUP, self::MESSAGE_CONVERSATION_TYPE_SELF])) { throw new \moodle_exception("Invalid value ($type) for type param, please see api constants."); } @@ -553,7 +570,18 @@ class api { } // If we need to restrict type, generate the SQL snippet. - $typesql = !is_null($type) ? " AND mc.type = :convtype " : ""; + $typesql = ""; + $typeparams = []; + if (!is_null($type)) { + if ($mergeself && $type == self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { + // When $megerself is set to true, the self-conversations are returned also with the private conversations. + $typesql = " AND (mc.type = :convtype1 OR mc.type = :convtype2) "; + $typeparams = ['convtype1' => $type, 'convtype2' => self::MESSAGE_CONVERSATION_TYPE_SELF]; + } else { + $typesql = " AND mc.type = :convtype "; + $typeparams = ['convtype' => $type]; + } + } $sql = "SELECT m.id as messageid, mc.id as id, mc.name as conversationname, mc.type as conversationtype, m.useridfrom, m.smallmessage, m.fullmessage, m.fullmessageformat, m.fullmessagetrust, m.fullmessagehtml, m.timecreated, @@ -587,16 +615,16 @@ class api { AND mc.enabled = 1 $typesql $favouritesql ORDER BY (CASE WHEN m.timecreated IS NULL THEN 0 ELSE 1 END) DESC, m.timecreated DESC, id DESC"; - $params = array_merge($favouriteparams, ['userid' => $userid, 'action' => self::MESSAGE_ACTION_DELETED, - 'userid2' => $userid, 'userid3' => $userid, 'userid4' => $userid, 'convaction' => self::CONVERSATION_ACTION_MUTED, - 'convtype' => $type]); + $params = array_merge($favouriteparams, $typeparams, ['userid' => $userid, 'action' => self::MESSAGE_ACTION_DELETED, + 'userid2' => $userid, 'userid3' => $userid, 'userid4' => $userid, 'convaction' => self::CONVERSATION_ACTION_MUTED]); $conversationset = $DB->get_recordset_sql($sql, $params, $limitfrom, $limitnum); $conversations = []; - $selfconversations = []; // Used to track legacy conversations with one's self (both conv members the same user). + $selfconversations = []; // Used to track conversations with one's self. $members = []; $individualmembers = []; $groupmembers = []; + $selfmembers = []; foreach ($conversationset as $conversation) { $conversations[$conversation->id] = $conversation; $members[$conversation->id] = []; @@ -621,13 +649,12 @@ class api { // // For 'individual' type conversations between 2 users, regardless of who sent the last message, // we want the details of the other member in the conversation (i.e. not the current user). - // The only exception to the 'not the current user' rule is for 'self' conversations - a legacy construct in which a user - // can message themselves via user bulk actions. Subsequently, there are 2 records for the same user created in the members - // table. // // For 'group' type conversations, we want the details of the member who sent the last message, if there is one. // This can be the current user or another group member, but for groups without messages, this will be empty. // + // For 'self' type conversations, we want the details of the current user. + // // This also means that if type filtering is specified and only group conversations are returned, we don't need this extra // query to get the 'other' user as we already have that information. @@ -647,6 +674,10 @@ class api { $members[$conversation->id][$conversation->useridfrom] = $conversation->useridfrom; $groupmembers[$conversation->useridfrom] = $conversation->useridfrom; } + } else if ($conversation->conversationtype == self::MESSAGE_CONVERSATION_TYPE_SELF) { + $selfconversations[$conversation->id] = $conversation->id; + $members[$conversation->id][$userid] = $userid; + $selfmembers[$userid] = $userid; } } // If we need to fetch any member information for any of the individual conversations. @@ -665,23 +696,6 @@ class api { $members[$member->conversationid][$member->userid] = $member->userid; $individualmembers[$member->userid] = $member->userid; } - - // Self conversations: If any of the individual conversations which were missing members are still missing members, - // we know these must be 'self' conversations. This is a legacy scenario, created via user bulk actions. - // In such cases, the member returned should be the current user. - // - // NOTE: Currently, these conversations are not returned by this method, however, - // identifying them is important for future reference. - foreach ($individualconversations as $indconvid) { - if (empty($members[$indconvid])) { - // Keep track of the self conversation (for future use). - $selfconversations[$indconvid] = $indconvid; - - // Set the member to the current user. - $members[$indconvid][$userid] = $userid; - $individualmembers[$userid] = $userid; - } - } } // We could fail early here if we're sure that: @@ -692,7 +706,7 @@ class api { // needs to be done in a separate query to avoid doing a join on the messages tables and the user // tables because on large sites these tables are massive which results in extremely slow // performance (typically due to join buffer exhaustion). - if (!empty($individualmembers) || !empty($groupmembers)) { + if (!empty($individualmembers) || !empty($groupmembers) || !empty($selfmembers)) { // Now, we want to remove any duplicates from the group members array. For individual members we will // be doing a more extensive call as we want their contact requests as well as privacy information, // which is not necessary for group conversations. @@ -700,9 +714,10 @@ class api { $individualmemberinfo = helper::get_member_info($userid, $individualmembers, true, true); $groupmemberinfo = helper::get_member_info($userid, $diffgroupmembers); + $selfmemberinfo = helper::get_member_info($userid, $selfmembers); // Don't use array_merge, as we lose array keys. - $memberinfo = $individualmemberinfo + $groupmemberinfo; + $memberinfo = $individualmemberinfo + $groupmemberinfo + $selfmemberinfo; if (empty($memberinfo)) { return []; @@ -766,6 +781,17 @@ class api { $unreadcounts = $DB->get_records_sql($unreadcountssql, [$userid, self::MESSAGE_ACTION_READ, self::MESSAGE_ACTION_DELETED, $userid, $userid]); + // For the self-conversations, get the total number of messages (to know if the conversation is new or it has been emptied). + $selfmessagessql = "SELECT COUNT(m.id) + FROM {messages} m + INNER JOIN {message_conversations} mc + ON mc.id = m.conversationid + WHERE mc.type = ? AND convhash = ?"; + $selfmessagestotal = $DB->count_records_sql( + $selfmessagessql, + [self::MESSAGE_CONVERSATION_TYPE_SELF, helper::get_conversation_hash([$userid])] + ); + // Because we'll be calling format_string on each conversation name and passing contexts, we preload them here. // This warms the cache and saves potentially hitting the DB once for each context fetch below. \context_helper::preload_contexts_by_id(array_column($conversations, 'contextid')); @@ -773,16 +799,14 @@ class api { // Now, create the final return structure. $arrconversations = []; foreach ($conversations as $conversation) { - // Do not include any individual conversations which do not contain a recent message for the user. + // Do not include any individual which do not contain a recent message for the user. // This happens if the user has deleted all messages. + // Exclude the self-conversations with messages but without a recent message because the user has deleted all them. + // Self-conversations without any message should be included, to display them first time they are created. // Group conversations with deleted users or no messages are always returned. - if ($conversation->conversationtype == self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL - && (empty($conversation->messageid))) { - continue; - } - - // Exclude 'self' conversations for now. - if (isset($selfconversations[$conversation->id])) { + if ($conversation->conversationtype == self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL && empty($conversation->messageid) || + ($conversation->conversationtype == self::MESSAGE_CONVERSATION_TYPE_SELF && empty($conversation->messageid) + && $selfmessagestotal > 0)) { continue; } @@ -923,10 +947,12 @@ class api { $memberoffset, $memberlimit ); - // Strip out the requesting user to match what get_conversations does. - $members = array_filter($members, function($member) use ($userid) { - return $member->id != $userid; - }); + if ($conversation->type != self::MESSAGE_CONVERSATION_TYPE_SELF) { + // Strip out the requesting user to match what get_conversations does, except for self-conversations. + $members = array_filter($members, function($member) use ($userid) { + return $member->id != $userid; + }); + } $messages = self::get_conversation_messages( $userid, @@ -1570,7 +1596,8 @@ class api { // Some restrictions we need to be aware of: // - Individual conversations containing soft-deleted user must be counted. // - Individual conversations containing only deleted messages must NOT be counted. - // - Individual conversations which are legacy 'self' conversations (2 members, both the same user) must NOT be counted. + // - Self-conversations with 0 messages must be counted. + // - Self-conversations containing only deleted messages must NOT be counted. // - Group conversations with 0 messages must be counted. // - Linked conversations which are disabled (enabled = 0) must NOT be counted. // - Any type of conversation can be included in the favourites count, however, the type counts and the favourites count @@ -1582,21 +1609,10 @@ class api { $favservice = \core_favourites\service_factory::get_service_for_user_context($usercontext); list($favsql, $favparams) = $favservice->get_join_sql_by_type('core_message', 'message_conversations', 'fav', 'mc.id'); - $sql = "SELECT mc.type, fav.itemtype, COUNT(DISTINCT mc.id) as count + $sql = "SELECT mc.type, fav.itemtype, COUNT(DISTINCT mc.id) as count, MAX(maxvisibleconvmessage.convid) as maxconvidmessage FROM {message_conversations} mc INNER JOIN {message_conversation_members} mcm ON mcm.conversationid = mc.id - INNER JOIN ( - SELECT mcm.conversationid, count(distinct mcm.userid) as membercount - FROM {message_conversation_members} mcm - WHERE mcm.conversationid IN ( - SELECT DISTINCT conversationid - FROM {message_conversation_members} mcm2 - WHERE userid = :userid5 - ) - GROUP BY mcm.conversationid - ) uniquemembercount - ON uniquemembercount.conversationid = mc.id LEFT JOIN ( SELECT m.conversationid as convid, MAX(m.timecreated) as maxtime FROM {messages} m @@ -1613,8 +1629,9 @@ class api { WHERE mcm.userid = :userid3 AND mc.enabled = :enabled AND ( - (mc.type = :individualtype AND maxvisibleconvmessage.convid IS NOT NULL AND membercount > 1) OR - (mc.type = :grouptype) + (mc.type = :individualtype AND maxvisibleconvmessage.convid IS NOT NULL) OR + (mc.type = :grouptype) OR + (mc.type = :selftype) ) GROUP BY mc.type, fav.itemtype ORDER BY mc.type ASC"; @@ -1629,6 +1646,7 @@ class api { 'enabled' => self::MESSAGE_CONVERSATION_ENABLED, 'individualtype' => self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, 'grouptype' => self::MESSAGE_CONVERSATION_TYPE_GROUP, + 'selftype' => self::MESSAGE_CONVERSATION_TYPE_SELF, ] + $favparams; // Assemble the return array. @@ -1636,12 +1654,28 @@ class api { 'favourites' => 0, 'types' => [ self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, - self::MESSAGE_CONVERSATION_TYPE_GROUP => 0 + self::MESSAGE_CONVERSATION_TYPE_GROUP => 0, + self::MESSAGE_CONVERSATION_TYPE_SELF => 0 ] ]; + // For the self-conversations, get the total number of messages (to know if the conversation is new or it has been emptied). + $selfmessagessql = "SELECT COUNT(m.id) + FROM {messages} m + INNER JOIN {message_conversations} mc + ON mc.id = m.conversationid + WHERE mc.type = ? AND convhash = ?"; + $selfmessagestotal = $DB->count_records_sql( + $selfmessagessql, + [self::MESSAGE_CONVERSATION_TYPE_SELF, helper::get_conversation_hash([$userid])] + ); + $countsrs = $DB->get_recordset_sql($sql, $params); foreach ($countsrs as $key => $val) { + // Empty self-conversations with deleted messages should be excluded. + if ($val->type == self::MESSAGE_CONVERSATION_TYPE_SELF && empty($val->maxconvidmessage) && $selfmessagestotal > 0) { + continue; + } if (!empty($val->itemtype)) { $counts['favourites'] += $val->count; continue; @@ -1862,7 +1896,8 @@ class api { // User can post messages and is in the conversation, but we need to check the conversation type to // know whether or not to check the user privacy settings via can_contact_user(). $conversation = $DB->get_record('message_conversations', ['id' => $conversationid], '*', MUST_EXIST); - if ($conversation->type == self::MESSAGE_CONVERSATION_TYPE_GROUP) { + if ($conversation->type == self::MESSAGE_CONVERSATION_TYPE_GROUP || + $conversation->type == self::MESSAGE_CONVERSATION_TYPE_SELF) { return true; } else if ($conversation->type == self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { // Get the other user in the conversation. @@ -2382,6 +2417,23 @@ class api { return $conversations; } + /** + * Returns the self conversation for a user. + * + * @param int $userid The user id to get the self-conversations + * @return \stdClass|false The self-conversation object or false if it doesn't exist + * @since Moodle 3.7 + */ + public static function get_self_conversation(int $userid) { + global $DB; + + $conditions = [ + 'type' => self::MESSAGE_CONVERSATION_TYPE_SELF, + 'convhash' => helper::get_conversation_hash([$userid]) + ]; + return $DB->get_record('message_conversations', $conditions); + } + /** * Creates a conversation between two users. * @@ -2420,7 +2472,8 @@ class api { $validtypes = [ self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, - self::MESSAGE_CONVERSATION_TYPE_GROUP + self::MESSAGE_CONVERSATION_TYPE_GROUP, + self::MESSAGE_CONVERSATION_TYPE_SELF ]; if (!in_array($type, $validtypes)) { @@ -2432,13 +2485,20 @@ class api { if (count($userids) > 2) { throw new \moodle_exception('An individual conversation can not have more than two users.'); } + if ($userids[0] == $userids[1]) { + throw new \moodle_exception('Trying to create an individual conversation instead of a self conversation.'); + } + } else if ($type == self::MESSAGE_CONVERSATION_TYPE_SELF) { + if (count($userids) != 1) { + throw new \moodle_exception('A self conversation can not have more than one user.'); + } } $conversation = new \stdClass(); $conversation->type = $type; $conversation->name = $name; $conversation->convhash = null; - if ($type == self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { + if ($type == self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL || $type == self::MESSAGE_CONVERSATION_TYPE_SELF) { $conversation->convhash = helper::get_conversation_hash($userids); } $conversation->component = $component; @@ -2840,8 +2900,9 @@ class api { * @return bool true if recipient hasn't blocked sender and sender can contact to recipient, false otherwise. */ protected static function can_contact_user(int $recipientid, int $senderid) : bool { - if (has_capability('moodle/site:messageanyuser', \context_system::instance(), $senderid)) { - // The sender has the ability to contact any user across the entire site. + if (has_capability('moodle/site:messageanyuser', \context_system::instance(), $senderid) || + $recipientid == $senderid) { + // The sender has the ability to contact any user across the entire site or themselves. return true; } @@ -3146,7 +3207,8 @@ class api { // Assemble the return array. $counts = ['favourites' => 0, 'types' => [ self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, - self::MESSAGE_CONVERSATION_TYPE_GROUP => 0 + self::MESSAGE_CONVERSATION_TYPE_GROUP => 0, + self::MESSAGE_CONVERSATION_TYPE_SELF => 0 ]]; foreach ($unreadcounts as $convid => $info) { if (isset($favouriteconvids[$convid])) { diff --git a/message/classes/privacy/provider.php b/message/classes/privacy/provider.php index ee90f5c1fce..2bba6daa549 100644 --- a/message/classes/privacy/provider.php +++ b/message/classes/privacy/provider.php @@ -949,14 +949,19 @@ class provider implements // Get subcontext. if (empty($conversation->contextid)) { // Conversations without context are stored in 'Messages | '. - $members = $DB->get_records('message_conversation_members', ['conversationid' => $conversation->id]); - $members = array_filter($members, function ($member) use ($userid) { - return $member->userid != $userid; - }); - if ($otheruser = reset($members)) { - $otherusertext = $otheruser->userid; + if ($conversation->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF) { + // This is a self-conversation. The other user is the same userid. + $otherusertext = $userid; } else { - $otherusertext = get_string('unknownuser', 'core_message') . '_' . $conversation->id; + $members = $DB->get_records('message_conversation_members', ['conversationid' => $conversation->id]); + $members = array_filter($members, function ($member) use ($userid) { + return $member->userid != $userid; + }); + if ($otheruser = reset($members)) { + $otherusertext = $otheruser->userid; + } else { + $otherusertext = get_string('unknownuser', 'core_message') . '_' . $conversation->id; + } } $subcontext = array_merge( diff --git a/message/classes/task/migrate_message_data.php b/message/classes/task/migrate_message_data.php index 2cf5dbdcd11..cafc1085afa 100644 --- a/message/classes/task/migrate_message_data.php +++ b/message/classes/task/migrate_message_data.php @@ -122,7 +122,18 @@ class migrate_message_data extends \core\task\adhoc_task { private function migrate_data($userid, $otheruserid) { global $DB; - if (!$conversationid = \core_message\api::get_conversation_between_users([$userid, $otheruserid])) { + if ($userid == $otheruserid) { + // Since 3.7, pending self-conversations should be migrated during the upgrading process so shouldn't be any + // self-conversations on the legacy tables. However, this extra-check has been added just in case. + $conversation = \core_message\api::get_self_conversation($userid); + if (empty($conversation)) { + $conversation = \core_message\api::create_conversation( + \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF, + [$userid] + ); + } + $conversationid = $conversation->id; + } else if (!$conversationid = \core_message\api::get_conversation_between_users([$userid, $otheruserid])) { $conversation = \core_message\api::create_conversation( \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, [ diff --git a/message/externallib.php b/message/externallib.php index 7535be912ab..f7edd53bd97 100644 --- a/message/externallib.php +++ b/message/externallib.php @@ -1247,7 +1247,7 @@ class core_message_external extends external_api { 'name' => new external_value(PARAM_TEXT, 'The conversation name, if set', VALUE_DEFAULT, null), 'subname' => new external_value(PARAM_TEXT, 'A subtitle for the conversation name, if set', VALUE_DEFAULT, null), 'imageurl' => new external_value(PARAM_URL, 'A link to the conversation picture, if set', VALUE_DEFAULT, null), - 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group)'), + 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group,3=self)'), 'membercount' => new external_value(PARAM_INT, 'Total number of conversation members'), 'ismuted' => new external_value(PARAM_BOOL, 'If the user muted this conversation'), 'isfavourite' => new external_value(PARAM_BOOL, 'If the user marked this conversation as a favourite'), @@ -1752,7 +1752,9 @@ class core_message_external extends external_api { 'favourites' => new external_value(PARAM_BOOL, 'Whether to restrict the results to contain NO favourite conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)', VALUE_DEFAULT, null), - + 'mergeself' => new external_value(PARAM_BOOL, 'Whether to include self-conversations (true) or ONLY private + conversations (false) when private conversations are requested.', + VALUE_DEFAULT, false), ) ); } @@ -1765,11 +1767,14 @@ class core_message_external extends external_api { * @param int $limitnum * @param int|null $type * @param bool|null $favourites + * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false) + * when private conversations are requested. * @return stdClass * @throws \moodle_exception if the messaging feature is disabled on the site. * @since 3.2 */ - public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null) { + public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null, + bool $mergeself = false) { global $CFG, $USER; // All the standard BL checks. @@ -1782,7 +1787,8 @@ class core_message_external extends external_api { 'limitfrom' => $limitfrom, 'limitnum' => $limitnum, 'type' => $type, - 'favourites' => $favourites + 'favourites' => $favourites, + 'mergeself' => $mergeself ); $params = self::validate_parameters(self::get_conversations_parameters(), $params); @@ -1798,7 +1804,8 @@ class core_message_external extends external_api { $params['limitfrom'], $params['limitnum'], $params['type'], - $params['favourites'] + $params['favourites'], + $params['mergeself'] ); return (object) ['conversations' => $conversations]; @@ -2025,6 +2032,91 @@ class core_message_external extends external_api { return self::get_conversation_structure(true); } + /** + * Get self-conversation parameters. + * + * @return external_function_parameters + */ + public static function get_self_conversation_parameters() { + return new external_function_parameters( + array( + 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing self-conversations for'), + 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100), + 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0), + 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true) + ) + ); + } + + /** + * Get a single self-conversation. + * + * @param int $userid The user id to get the self-conversation for + * @param int $messagelimit Limit number of messages to load + * @param int $messageoffset Offset the messages + * @param bool $newestmessagesfirst Order messages by newest first + * @return stdClass + * @throws \moodle_exception if the messaging feature is disabled on the site. + * @since Moodle 3.7 + */ + public static function get_self_conversation( + int $userid, + int $messagelimit = 0, + int $messageoffset = 0, + bool $newestmessagesfirst = true + ) { + global $CFG; + + // All the standard BL checks. + if (empty($CFG->messaging)) { + throw new moodle_exception('disabled', 'message'); + } + + $params = [ + 'userid' => $userid, + 'messagelimit' => $messagelimit, + 'messageoffset' => $messageoffset, + 'newestmessagesfirst' => $newestmessagesfirst + ]; + self::validate_parameters(self::get_self_conversation_parameters(), $params); + + $systemcontext = context_system::instance(); + self::validate_context($systemcontext); + + $conversation = \core_message\api::get_self_conversation($params['userid']); + + if ($conversation) { + $conversation = \core_message\api::get_conversation( + $params['userid'], + $conversation->id, + false, + false, + 0, + 0, + $params['messagelimit'], + $params['messageoffset'], + $params['newestmessagesfirst'] + ); + } + + if ($conversation) { + return $conversation; + } else { + // We have to throw an exception here because the external functions annoyingly + // don't accept null to be returned for a single structure. + throw new \moodle_exception('errorconversationdoesnotexist', 'message'); + } + } + + /** + * Get conversation returns. + * + * @return external_single_structure + */ + public static function get_self_conversation_returns() { + return self::get_conversation_structure(); + } + /** * The messagearea conversations parameters. * @@ -4625,6 +4717,8 @@ class core_message_external extends external_api { 'Total number of individual conversations'), \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT, 'Total number of group conversations'), + \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT, + 'Total number of self conversations'), ] ), ] @@ -4700,6 +4794,8 @@ class core_message_external extends external_api { 'Total number of unread individual conversations'), \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT, 'Total number of unread group conversations'), + \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT, + 'Total number of unread self conversations'), ] ), ] diff --git a/message/templates/message_drawer_view_conversation_body.mustache b/message/templates/message_drawer_view_conversation_body.mustache index a87e91527b0..c584e01b92a 100644 --- a/message/templates/message_drawer_view_conversation_body.mustache +++ b/message/templates/message_drawer_view_conversation_body.mustache @@ -43,6 +43,10 @@ style="overflow-y: auto; overflow-x: hidden" >
+