MDL-56603 messaging: Add a new message link to popup.
authorAdrian Greeve <adrian@moodle.com>
Wed, 16 Nov 2016 06:45:26 +0000 (14:45 +0800)
committerAdrian Greeve <adrian@moodle.com>
Wed, 16 Nov 2016 06:51:17 +0000 (14:51 +0800)
Added a link to create a new message from the message
popup menu.

17 files changed:
lang/en/message.php
message/amd/build/message_area.min.js
message/amd/build/message_area_contacts.min.js
message/amd/build/message_area_search.min.js
message/amd/src/message_area.js
message/amd/src/message_area_contacts.js
message/amd/src/message_area_search.js
message/classes/output/messagearea/message_area.php
message/index.php
message/output/popup/lib.php
message/output/popup/templates/message_popover.mustache
message/templates/message_area.mustache
message/templates/message_area_contacts_area.mustache
message/templates/message_area_messages_area.mustache
theme/boost/scss/moodle/popover-region.scss
theme/bootstrapbase/less/moodle/popover_region.less
theme/bootstrapbase/style/moodle.css

index 404b70a..066c403 100644 (file)
@@ -68,6 +68,9 @@ $string['messagepreferences'] = 'Message preferences';
 $string['messages'] = 'Messages';
 $string['messagingdisabled'] = 'Messaging is disabled on this site, emails will be sent instead';
 $string['newonlymsg'] = 'Show only new';
+$string['newmessage'] = 'New message';
+$string['newmessagesearch'] = 'Select or search for a contact to send a new message.';
+$string['newsearch'] = 'New search';
 $string['noframesjs'] = 'Use more accessible interface';
 $string['nocontacts'] = 'No contacts';
 $string['nomessages'] = 'No messages';
index b117ee3..288f2df 100644 (file)
Binary files a/message/amd/build/message_area.min.js and b/message/amd/build/message_area.min.js differ
index 7ff3d01..aafb31b 100644 (file)
Binary files a/message/amd/build/message_area_contacts.min.js and b/message/amd/build/message_area_contacts.min.js differ
index 0a7f3e4..68f4af0 100644 (file)
Binary files a/message/amd/build/message_area_search.min.js and b/message/amd/build/message_area_search.min.js differ
index 73bad76..b9482aa 100644 (file)
@@ -117,6 +117,15 @@ define(['jquery', 'core_message/message_area_contacts', 'core_message/message_ar
             return this.node.data('userid');
         };
 
+        /**
+         * Function to determine if we should be showing contacts initially or messages.
+         *
+         * @return {boolean} True to show contacts first, otherwise show messages.
+         */
+        Messagearea.prototype.showContactsFirst = function() {
+            return !!this.node.data('displaycontacts');
+        };
+
         return Messagearea;
     }
 );
index 237cb65..9af6333 100644 (file)
@@ -149,9 +149,10 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/cust
             this.messageArea.onDelegateEvent(CustomEvents.events.scrollBottom, SELECTORS.CONTACTS,
                 this._loadContacts.bind(this));
 
-            // Set the number of conversations. We set this to the number of conversations we asked to retrieve not by
-            // the number that was actually retrieved, see MDL-55870.
-            this._numConversationsDisplayed = 20;
+            if (!this.messageArea.showContactsFirst()) {
+                // Set the initial number of conversations to retrieve. Otherwise it will display no conversations.
+                this._numConversationsDisplayed = 20;
+            }
         };
 
         /**
index 0ff1f96..eee0989 100644 (file)
@@ -145,7 +145,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
         );
 
         // Set the initial search area.
-        this._searchArea = this._searchAreas.MESSAGES;
+        this._searchArea = (this.messageArea.showContactsFirst()) ? this._searchAreas.USERS : this._searchAreas.MESSAGES;
     };
 
     /**
index 3c76591..b5cb3bf 100644 (file)
@@ -78,6 +78,11 @@ class message_area implements templatable, renderable {
      */
     public $polltimeout;
 
+    /**
+     * @var bool Are we creating a new message and show the contacts section first?
+     */
+    public $contactsfirst;
+
     /**
      * Constructor.
      *
@@ -86,20 +91,23 @@ class message_area implements templatable, renderable {
      * @param array $contacts
      * @param array|null $messages
      * @param bool $requestedconversation
+     * @param bool $contactsfirst Whether we are viewing the contacts first.
      * @param int $pollmin
      * @param int $pollmax
      * @param int $polltimeout
      */
-    public function __construct($userid, $otheruserid, $contacts, $messages, $requestedconversation, $pollmin, $pollmax,
-            $polltimeout) {
+    public function __construct($userid, $otheruserid, $contacts, $messages, $requestedconversation, $contactsfirst, $pollmin,
+            $pollmax, $polltimeout) {
         $this->userid = $userid;
-        $this->otheruserid = $otheruserid;
+        // Setting the other user to null when showing contacts will remove any contact from being selected.
+        $this->otheruserid = (!$contactsfirst) ? $otheruserid : null;
         $this->contacts = $contacts;
         $this->messages = $messages;
         $this->requestedconversation = $requestedconversation;
         $this->pollmin = $pollmin;
         $this->pollmax = $pollmax;
         $this->polltimeout = $polltimeout;
+        $this->contactsfirst = $contactsfirst;
     }
 
     public function export_for_template(\renderer_base $output) {
@@ -107,13 +115,19 @@ class message_area implements templatable, renderable {
         $data->userid = $this->userid;
         $contacts = new contacts($this->otheruserid, $this->contacts);
         $data->contacts = $contacts->export_for_template($output);
-        $messages = new messages($this->userid, $this->otheruserid, $this->messages);
+        if ($this->contactsfirst) {
+            // Don't show any messages if we are creating a new message.
+            $messages = new messages($this->userid, null, array());
+        } else {
+            $messages = new messages($this->userid, $this->otheruserid, $this->messages);
+        }
         $data->messages = $messages->export_for_template($output);
-        $data->isconversation = true;
+        $data->isconversation = ($this->contactsfirst) ? false : true;
         $data->requestedconversation = $this->requestedconversation;
         $data->pollmin = $this->pollmin;
         $data->pollmax = $this->pollmax;
         $data->polltimeout = $this->polltimeout;
+        $data->contactsfirst = $this->contactsfirst;
 
         return $data;
     }
index 5789216..65349b3 100644 (file)
@@ -41,6 +41,7 @@ $id = optional_param('id', 0, PARAM_INT);
 // we are going to accept other URL parameters to figure this out.
 $user1id = optional_param('user1', $USER->id, PARAM_INT);
 $user2id = optional_param('user2', $id, PARAM_INT);
+$contactsfirst = optional_param('contactsfirst', 0, PARAM_INT);
 
 $url = new moodle_url('/message/index.php');
 if ($id) {
@@ -52,6 +53,9 @@ if ($id) {
     if ($user2id) {
         $url->param('user2', $user2id);
     }
+    if ($contactsfirst) {
+        $url->param('contactsfirst', $contactsfirst);
+    }
 }
 $PAGE->set_url($url);
 
@@ -98,7 +102,11 @@ $settings->make_active();
 // Get the renderer and the information we are going to be use.
 $renderer = $PAGE->get_renderer('core_message');
 $requestedconversation = false;
-$conversations = \core_message\api::get_conversations($user1->id, 0, 20);
+if ($contactsfirst) {
+    $conversations = \core_message\api::get_contacts($user1->id, 0, 20);
+} else {
+    $conversations = \core_message\api::get_conversations($user1->id, 0, 20);
+}
 $messages = [];
 if (!$user2realuser) {
     // If there are conversations, but the user has not chosen a particular one, then render the most recent one.
@@ -131,7 +139,7 @@ $pollmin = !empty($CFG->messagingminpoll) ? $CFG->messagingminpoll : MESSAGE_DEF
 $pollmax = !empty($CFG->messagingmaxpoll) ? $CFG->messagingmaxpoll : MESSAGE_DEFAULT_MAX_POLL_IN_SECONDS;
 $polltimeout = !empty($CFG->messagingtimeoutpoll) ? $CFG->messagingtimeoutpoll : MESSAGE_DEFAULT_TIMEOUT_POLL_IN_SECONDS;
 $messagearea = new \core_message\output\messagearea\message_area($user1->id, $user2->id, $conversations, $messages,
-    $requestedconversation, $pollmin, $pollmax, $polltimeout);
+        $requestedconversation, $contactsfirst, $pollmin, $pollmax, $polltimeout);
 
 // Now the page contents.
 echo $OUTPUT->header();
index 8875855..655fe35 100644 (file)
@@ -46,6 +46,7 @@ function message_popup_render_navbar_output(\renderer_base $renderer) {
         $context = [
             'userid' => $USER->id,
             'urls' => [
+                'writeamessage' => (new moodle_url('/message/index.php', ['contactsfirst' => 1]))->out(),
                 'preferences' => (new moodle_url('/message/edit.php', ['id' => $USER->id]))->out(),
             ],
         ];
index 8d170f1..666242a 100644 (file)
 
     {{$headertext}}{{#str}} messages, message {{/str}}{{/headertext}}
     {{$headeractions}}
+        <div class="newmessage-link">
+            {{$anchor}}
+                <a href="{{{urls.writeamessage}}}">{{#str}} newmessage, message {{/str}}
+                </a>
+            {{/anchor}}
+        </div>
         {{< core/hover_tooltip }}
             {{$anchor}}
                 <a class="mark-all-read-button"
index 8667f41..1a6cbe7 100644 (file)
@@ -14,7 +14,7 @@
     You should have received a copy of the GNU General Public License
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
-<div class="messaging-area-container" data-userid="{{userid}}">
+<div class="messaging-area-container" data-userid="{{userid}}" data-displaycontacts="{{contactsfirst}}">
     <div class="messaging-area {{#requestedconversation}}show-messages{{/requestedconversation}}
             {{^requestedconversation}}hide-messages{{/requestedconversation}}" data-region="messaging-area">
         <div class="contacts-area" data-region="contacts-area" role="tablist">
index 204a219..c60b934 100644 (file)
 }}
 <div class="searchtextarea" data-region="search-text-area">
     <label class="accesshide" for="searchtext">{{#str}}search{{/str}}</label>
-    <input data-region="search-box" type="text" id="searchtext" placeholder="{{#str}}searchmessages, message{{/str}}">
+    <input data-region="search-box" type="text" id="searchtext" placeholder="{{#contactsfirst}} {{#str}}searchforuserorcourse, message{{/str}} {{/contactsfirst}} {{^contactsfirst}} {{#str}}searchmessages, message{{/str}} {{/contactsfirst}}">
     <div data-region="search-filter-area" class="searchfilterarea" style="display:none">
         <div data-region="search-filter" class="searchfilter"></div>
         <div data-action="search-filter-delete" class="searchfilterdelete">{{#pix}}t/delete{{/pix}}</div>
     </div>
 </div>
+{{#contactsfirst}}
+<div class="contacts" data-region="contacts" data-region-content="conversations" style="display:none;" role="tabpanel" id="conversations-tab-panel"></div>
+<div class="contacts" data-region="contacts" data-region-content="contacts" role="tabpanel" id="contacts-tab-panel">
+    {{> core_message/message_area_contacts }}
+</div>
+{{/contactsfirst}}
+{{^contactsfirst}}
 <div class="contacts" data-region="contacts" data-region-content="conversations" role="tabpanel" id="conversations-tab-panel">
     {{> core_message/message_area_contacts }}
 </div>
-{{! Hidden divs to load the other tab and search panels via JS when appropriate. }}
 <div class="contacts" data-region="contacts" data-region-content="contacts" style="display:none;" role="tabpanel" id="contacts-tab-panel"></div>
+{{/contactsfirst}}
+{{! Hidden divs to load the other tab and search panels via JS when appropriate. }}
 <div class="contacts searcharea" data-region="search-results-area" style="display:none;"></div>
 <div class="tabs">
-    <div class="tab tabconversations selected" data-action="conversations-view" role="tab" aria-controls="conversations-tab-panel" aria-selected="true" tabindex="0">
+    <div class="tab tabconversations {{^contactsfirst}}selected{{/contactsfirst}} " data-action="conversations-view" role="tab" aria-controls="conversations-tab-panel" aria-selected="{{^contactsfirst}}true{{/contactsfirst}}{{#contactsfirst}}false{{/contactsfirst}}" tabindex="0">
         <div class="tabimage">{{#pix}}t/message, moodle{{/pix}}</div>
         <div>{{#str}}messages, message{{/str}}</div>
     </div>
-    <div class="tab tabcontacts" data-action="contacts-view" role="tab" aria-controls="contacts-tab-panel" aria-selected="false" tabindex="-1">
+    <div class="tab tabcontacts {{#contactsfirst}}selected{{/contactsfirst}}" data-action="contacts-view" role="tab" aria-controls="contacts-tab-panel" aria-selected="{{#contactsfirst}}true{{/contactsfirst}}{{^contactsfirst}}false{{/contactsfirst}}" tabindex="-1">
         <div class="tabimage">{{#pix}}i/cohort, moodle{{/pix}}</div>
         <div>{{#str}}contacts, message{{/str}}</div>
     </div>
index acfa449..d27a1b8 100644 (file)
     </div>
 </div>
 {{/otheruserid}}
+{{#contactsfirst}}
+<div class="messages-header">
+    <div class="name-container">
+        <div class="name">
+            {{#str}}newmessagesearch, message{{/str}}
+        </div>
+    </div>
+</div>
+{{/contactsfirst}}
 <div class="messages" data-region="messages" data-userid="{{otheruserid}}">
     {{> core_message/message_area_messages }}
 </div>
index 13eeea1..a6716aa 100644 (file)
@@ -123,6 +123,11 @@ $content-item-unread-colour: #f4f4f4;
         height: 12px;
         width: 12px;
     }
+
+    .newmessage-link {
+        margin-right: 10px;
+    }
+
     label {
         display: inline-block;
         text-align: center;
index 9b8d4e6..9edc3d5 100644 (file)
         height: 12px;
         width: 12px;
     }
+    .newmessage-link {
+        margin-right: 10px;
+    }
     label {
         display: inline-block;
         text-align: center;
 
         .popover-region-header-actions {
             float: left;
+
+            .newmessage-link {
+                margin-left: 10px;
+            }
         }
     }
 
index aea5397..92c36a6 100644 (file)
@@ -7815,6 +7815,9 @@ body.path-question-type .mform fieldset.hidden {
   height: 12px;
   width: 12px;
 }
+.popover-region-header-actions .newmessage-link {
+  margin-right: 10px;
+}
 .popover-region-header-actions label {
   display: inline-block;
   text-align: center;
@@ -8060,6 +8063,9 @@ body.path-question-type .mform fieldset.hidden {
 .dir-rtl .popover-region .popover-region-header-actions {
   float: left;
 }
+.dir-rtl .popover-region .popover-region-header-actions .newmessage-link {
+  margin-left: 10px;
+}
 .dir-rtl .navbar .popover-region {
   float: left;
 }