Merge branch 'wip-MDL-56603-master-v2' of git://github.com/abgreeve/moodle

This commit is contained in:
Andrew Nicols 2016-11-16 15:36:37 +08:00
commit 7da7c1e24a
18 changed files with 140 additions and 22 deletions

View File

@ -68,6 +68,9 @@ $string['messagepreferences'] = 'Message preferences';
$string['messages'] = 'Messages'; $string['messages'] = 'Messages';
$string['messagingdisabled'] = 'Messaging is disabled on this site, emails will be sent instead'; $string['messagingdisabled'] = 'Messaging is disabled on this site, emails will be sent instead';
$string['newonlymsg'] = 'Show only new'; $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['noframesjs'] = 'Use more accessible interface';
$string['nocontacts'] = 'No contacts'; $string['nocontacts'] = 'No contacts';
$string['nomessages'] = 'No messages'; $string['nomessages'] = 'No messages';
@ -96,6 +99,8 @@ $string['requiresconfiguration'] = 'Requires configuration';
$string['searchforuser'] = 'Search for a user'; $string['searchforuser'] = 'Search for a user';
$string['searchforuserorcourse'] = 'Search for a user or course'; $string['searchforuserorcourse'] = 'Search for a user or course';
$string['searchmessages'] = 'Search messages'; $string['searchmessages'] = 'Search messages';
$string['searchcombined'] = 'Search people and messages';
$string['seeall'] = 'See all';
$string['selectmessagestodelete'] = 'Select messages to delete'; $string['selectmessagestodelete'] = 'Select messages to delete';
$string['selectnotificationtoview'] = 'Select from the list of notifications on the side to view more details'; $string['selectnotificationtoview'] = 'Select from the list of notifications on the side to view more details';
$string['send'] = 'Send'; $string['send'] = 'Send';

View File

@ -63,5 +63,13 @@
</div> </div>
{{> core/loading }} {{> core/loading }}
</div> </div>
{{$anchor}}
<a class="see-all-link"
href="{{{urls.seeall}}}">
<div class="popover-region-footer-container">
<div class="popover-region-seeall-text">{{#str}} seeall, message {{/str}}</div>
</div>
</a>
{{/anchor}}
</div> </div>
</div> </div>

View File

@ -1 +1 @@
define(["jquery","core_message/message_area_contacts","core_message/message_area_messages","core_message/message_area_profile","core_message/message_area_tabs","core_message/message_area_search"],function(a,b,c,d,e,f){function g(b,c,d,e){this.node=a(b),this.pollmin=c,this.pollmax=d,this.polltimeout=e,this._init()}return g.prototype.node=null,g.prototype.pollmin=null,g.prototype.pollmax=null,g.prototype.polltimeout=null,g.prototype._init=function(){new b(this),new c(this),new d(this),new e(this),new f(this)},g.prototype.onDelegateEvent=function(a,b,c){this.node.on(a,b,c)},g.prototype.onCustomEvent=function(a,b){this.node.on(a,b)},g.prototype.trigger=function(a,b){"undefined"==typeof b&&(b=""),this.node.trigger(a,b)},g.prototype.find=function(a){return this.node.find(a)},g.prototype.getCurrentUserId=function(){return this.node.data("userid")},g}); define(["jquery","core_message/message_area_contacts","core_message/message_area_messages","core_message/message_area_profile","core_message/message_area_tabs","core_message/message_area_search"],function(a,b,c,d,e,f){function g(b,c,d,e){this.node=a(b),this.pollmin=c,this.pollmax=d,this.polltimeout=e,this._init()}return g.prototype.node=null,g.prototype.pollmin=null,g.prototype.pollmax=null,g.prototype.polltimeout=null,g.prototype._init=function(){new b(this),new c(this),new d(this),new e(this),new f(this)},g.prototype.onDelegateEvent=function(a,b,c){this.node.on(a,b,c)},g.prototype.onCustomEvent=function(a,b){this.node.on(a,b)},g.prototype.trigger=function(a,b){"undefined"==typeof b&&(b=""),this.node.trigger(a,b)},g.prototype.find=function(a){return this.node.find(a)},g.prototype.getCurrentUserId=function(){return this.node.data("userid")},g.prototype.showContactsFirst=function(){return!!this.node.data("displaycontacts")},g});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -117,6 +117,15 @@ define(['jquery', 'core_message/message_area_contacts', 'core_message/message_ar
return this.node.data('userid'); 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; return Messagearea;
} }
); );

View File

@ -149,9 +149,10 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/cust
this.messageArea.onDelegateEvent(CustomEvents.events.scrollBottom, SELECTORS.CONTACTS, this.messageArea.onDelegateEvent(CustomEvents.events.scrollBottom, SELECTORS.CONTACTS,
this._loadContacts.bind(this)); this._loadContacts.bind(this));
// Set the number of conversations. We set this to the number of conversations we asked to retrieve not by if (!this.messageArea.showContactsFirst()) {
// the number that was actually retrieved, see MDL-55870. // Set the initial number of conversations to retrieve. Otherwise it will display no conversations.
this._numConversationsDisplayed = 20; this._numConversationsDisplayed = 20;
}
}; };
/** /**

View File

@ -145,7 +145,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
); );
// Set the initial search area. // Set the initial search area.
this._searchArea = this._searchAreas.MESSAGES; this._searchArea = (this.messageArea.showContactsFirst()) ? this._searchAreas.USERS : this._searchAreas.MESSAGES;
}; };
/** /**

View File

@ -78,6 +78,11 @@ class message_area implements templatable, renderable {
*/ */
public $polltimeout; public $polltimeout;
/**
* @var bool Are we creating a new message and show the contacts section first?
*/
public $contactsfirst;
/** /**
* Constructor. * Constructor.
* *
@ -86,20 +91,23 @@ class message_area implements templatable, renderable {
* @param array $contacts * @param array $contacts
* @param array|null $messages * @param array|null $messages
* @param bool $requestedconversation * @param bool $requestedconversation
* @param bool $contactsfirst Whether we are viewing the contacts first.
* @param int $pollmin * @param int $pollmin
* @param int $pollmax * @param int $pollmax
* @param int $polltimeout * @param int $polltimeout
*/ */
public function __construct($userid, $otheruserid, $contacts, $messages, $requestedconversation, $pollmin, $pollmax, public function __construct($userid, $otheruserid, $contacts, $messages, $requestedconversation, $contactsfirst, $pollmin,
$polltimeout) { $pollmax, $polltimeout) {
$this->userid = $userid; $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->contacts = $contacts;
$this->messages = $messages; $this->messages = $messages;
$this->requestedconversation = $requestedconversation; $this->requestedconversation = $requestedconversation;
$this->pollmin = $pollmin; $this->pollmin = $pollmin;
$this->pollmax = $pollmax; $this->pollmax = $pollmax;
$this->polltimeout = $polltimeout; $this->polltimeout = $polltimeout;
$this->contactsfirst = $contactsfirst;
} }
public function export_for_template(\renderer_base $output) { public function export_for_template(\renderer_base $output) {
@ -107,13 +115,19 @@ class message_area implements templatable, renderable {
$data->userid = $this->userid; $data->userid = $this->userid;
$contacts = new contacts($this->otheruserid, $this->contacts); $contacts = new contacts($this->otheruserid, $this->contacts);
$data->contacts = $contacts->export_for_template($output); $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->messages = $messages->export_for_template($output);
$data->isconversation = true; $data->isconversation = ($this->contactsfirst) ? false : true;
$data->requestedconversation = $this->requestedconversation; $data->requestedconversation = $this->requestedconversation;
$data->pollmin = $this->pollmin; $data->pollmin = $this->pollmin;
$data->pollmax = $this->pollmax; $data->pollmax = $this->pollmax;
$data->polltimeout = $this->polltimeout; $data->polltimeout = $this->polltimeout;
$data->contactsfirst = $this->contactsfirst;
return $data; return $data;
} }

View File

@ -41,6 +41,7 @@ $id = optional_param('id', 0, PARAM_INT);
// we are going to accept other URL parameters to figure this out. // we are going to accept other URL parameters to figure this out.
$user1id = optional_param('user1', $USER->id, PARAM_INT); $user1id = optional_param('user1', $USER->id, PARAM_INT);
$user2id = optional_param('user2', $id, PARAM_INT); $user2id = optional_param('user2', $id, PARAM_INT);
$contactsfirst = optional_param('contactsfirst', 0, PARAM_INT);
$url = new moodle_url('/message/index.php'); $url = new moodle_url('/message/index.php');
if ($id) { if ($id) {
@ -52,6 +53,9 @@ if ($id) {
if ($user2id) { if ($user2id) {
$url->param('user2', $user2id); $url->param('user2', $user2id);
} }
if ($contactsfirst) {
$url->param('contactsfirst', $contactsfirst);
}
} }
$PAGE->set_url($url); $PAGE->set_url($url);
@ -98,7 +102,11 @@ $settings->make_active();
// Get the renderer and the information we are going to be use. // Get the renderer and the information we are going to be use.
$renderer = $PAGE->get_renderer('core_message'); $renderer = $PAGE->get_renderer('core_message');
$requestedconversation = false; $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 = []; $messages = [];
if (!$user2realuser) { if (!$user2realuser) {
// If there are conversations, but the user has not chosen a particular one, then render the most recent one. // 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; $pollmax = !empty($CFG->messagingmaxpoll) ? $CFG->messagingmaxpoll : MESSAGE_DEFAULT_MAX_POLL_IN_SECONDS;
$polltimeout = !empty($CFG->messagingtimeoutpoll) ? $CFG->messagingtimeoutpoll : MESSAGE_DEFAULT_TIMEOUT_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, $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. // Now the page contents.
echo $OUTPUT->header(); echo $OUTPUT->header();

View File

@ -46,6 +46,8 @@ function message_popup_render_navbar_output(\renderer_base $renderer) {
$context = [ $context = [
'userid' => $USER->id, 'userid' => $USER->id,
'urls' => [ 'urls' => [
'seeall' => (new moodle_url('/message/index.php'))->out(),
'writeamessage' => (new moodle_url('/message/index.php', ['contactsfirst' => 1]))->out(),
'preferences' => (new moodle_url('/message/edit.php', ['id' => $USER->id]))->out(), 'preferences' => (new moodle_url('/message/edit.php', ['id' => $USER->id]))->out(),
], ],
]; ];

View File

@ -52,6 +52,12 @@
{{$headertext}}{{#str}} messages, message {{/str}}{{/headertext}} {{$headertext}}{{#str}} messages, message {{/str}}{{/headertext}}
{{$headeractions}} {{$headeractions}}
<div class="newmessage-link">
{{$anchor}}
<a href="{{{urls.writeamessage}}}">{{#str}} newmessage, message {{/str}}
</a>
{{/anchor}}
</div>
{{< core/hover_tooltip }} {{< core/hover_tooltip }}
{{$anchor}} {{$anchor}}
<a class="mark-all-read-button" <a class="mark-all-read-button"

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>. 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}} <div class="messaging-area {{#requestedconversation}}show-messages{{/requestedconversation}}
{{^requestedconversation}}hide-messages{{/requestedconversation}}" data-region="messaging-area"> {{^requestedconversation}}hide-messages{{/requestedconversation}}" data-region="messaging-area">
<div class="contacts-area" data-region="contacts-area" role="tablist"> <div class="contacts-area" data-region="contacts-area" role="tablist">

View File

@ -16,24 +16,32 @@
}} }}
<div class="searchtextarea" data-region="search-text-area"> <div class="searchtextarea" data-region="search-text-area">
<label class="accesshide" for="searchtext">{{#str}}search{{/str}}</label> <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-area" class="searchfilterarea" style="display:none">
<div data-region="search-filter" class="searchfilter"></div> <div data-region="search-filter" class="searchfilter"></div>
<div data-action="search-filter-delete" class="searchfilterdelete">{{#pix}}t/delete{{/pix}}</div> <div data-action="search-filter-delete" class="searchfilterdelete">{{#pix}}t/delete{{/pix}}</div>
</div> </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"> <div class="contacts" data-region="contacts" data-region-content="conversations" role="tabpanel" id="conversations-tab-panel">
{{> core_message/message_area_contacts }} {{> core_message/message_area_contacts }}
</div> </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> <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="contacts searcharea" data-region="search-results-area" style="display:none;"></div>
<div class="tabs"> <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 class="tabimage">{{#pix}}t/message, moodle{{/pix}}</div>
<div>{{#str}}messages, message{{/str}}</div> <div>{{#str}}messages, message{{/str}}</div>
</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 class="tabimage">{{#pix}}i/cohort, moodle{{/pix}}</div>
<div>{{#str}}contacts, message{{/str}}</div> <div>{{#str}}contacts, message{{/str}}</div>
</div> </div>

View File

@ -40,6 +40,15 @@
</div> </div>
</div> </div>
{{/otheruserid}} {{/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}}"> <div class="messages" data-region="messages" data-userid="{{otheruserid}}">
{{> core_message/message_area_messages }} {{> core_message/message_area_messages }}
</div> </div>

View File

@ -4,10 +4,12 @@ $region-container-height: 500px;
$region-container-width: 380px; $region-container-width: 380px;
$region-container-z-index: 1; $region-container-z-index: 1;
$region-header-height: 25px; $region-header-height: 25px;
$region-footer-height: 30px;
$content-item-hover-colour-bg: #79b5e6; $content-item-hover-colour-bg: #79b5e6;
$content-item-hover-colour-text: #fff; $content-item-hover-colour-text: #fff;
$content-item-selected-colour-bg: #4f94cd; $content-item-selected-colour-bg: #4f94cd;
$content-item-unread-colour: #f4f4f4; $content-item-unread-colour: #f4f4f4;
$content-header-footer-height: $region-header-height + $region-footer-height;
@mixin invisible() { @mixin invisible() {
opacity: 0; opacity: 0;
@ -103,6 +105,14 @@ $content-item-unread-colour: #f4f4f4;
box-sizing: border-box; box-sizing: border-box;
} }
.popover-region-footer-container {
height: $region-footer-height;
text-align: center;
border-top: $standard-border;
background-color: $popover-bg;
padding-top: 3px;
}
.popover-region-header-text { .popover-region-header-text {
float: left; float: left;
margin: 0; margin: 0;
@ -123,6 +133,11 @@ $content-item-unread-colour: #f4f4f4;
height: 12px; height: 12px;
width: 12px; width: 12px;
} }
.newmessage-link {
margin-right: 10px;
}
label { label {
display: inline-block; display: inline-block;
text-align: center; text-align: center;
@ -131,7 +146,7 @@ $content-item-unread-colour: #f4f4f4;
} }
.popover-region-content-container { .popover-region-content-container {
height: calc(100% - 25px); height: calc(100% - #{$content-header-footer-height});
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;

View File

@ -81,6 +81,17 @@
box-sizing: border-box; box-sizing: border-box;
} }
.popover-region-footer-container {
height: 30px;
text-align: center;
border-top: 1px solid #ddd;
background-color: @popoverBackground;
.popover-region-seeall-text {
padding-top: 4px;
}
}
.popover-region-header-text { .popover-region-header-text {
float: left; float: left;
margin: 0; margin: 0;
@ -101,6 +112,9 @@
height: 12px; height: 12px;
width: 12px; width: 12px;
} }
.newmessage-link {
margin-right: 10px;
}
label { label {
display: inline-block; display: inline-block;
text-align: center; text-align: center;
@ -109,7 +123,7 @@
} }
.popover-region-content-container { .popover-region-content-container {
height: ~"calc(100% - 25px)"; height: ~"calc(100% - 56px)";
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
@ -447,6 +461,10 @@
.popover-region-header-actions { .popover-region-header-actions {
float: left; float: left;
.newmessage-link {
margin-left: 10px;
}
} }
} }

View File

@ -7796,6 +7796,15 @@ body.path-question-type .mform fieldset.hidden {
border-bottom: 1px solid #ddd; border-bottom: 1px solid #ddd;
box-sizing: border-box; box-sizing: border-box;
} }
.popover-region-footer-container {
height: 30px;
text-align: center;
border-top: 1px solid #ddd;
background-color: #fff;
}
.popover-region-footer-container .popover-region-seeall-text {
padding-top: 4px;
}
.popover-region-header-text { .popover-region-header-text {
float: left; float: left;
margin: 0; margin: 0;
@ -7815,13 +7824,16 @@ body.path-question-type .mform fieldset.hidden {
height: 12px; height: 12px;
width: 12px; width: 12px;
} }
.popover-region-header-actions .newmessage-link {
margin-right: 10px;
}
.popover-region-header-actions label { .popover-region-header-actions label {
display: inline-block; display: inline-block;
text-align: center; text-align: center;
margin-bottom: 0; margin-bottom: 0;
} }
.popover-region-content-container { .popover-region-content-container {
height: calc(100% - 25px); height: calc(100% - 56px);
width: 100%; width: 100%;
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
@ -8060,6 +8072,9 @@ body.path-question-type .mform fieldset.hidden {
.dir-rtl .popover-region .popover-region-header-actions { .dir-rtl .popover-region .popover-region-header-actions {
float: left; float: left;
} }
.dir-rtl .popover-region .popover-region-header-actions .newmessage-link {
margin-left: 10px;
}
.dir-rtl .navbar .popover-region { .dir-rtl .navbar .popover-region {
float: left; float: left;
} }