Merge branch 'MDL-66226-master-2' of https://github.com/snake/moodle
@ -103,6 +103,10 @@ $string['messagepreferences'] = 'Message preferences';
|
||||
$string['message'] = 'Message';
|
||||
$string['messagecontactrequestsnotification'] = '{$a} is requesting to be added as a contact.';
|
||||
$string['messagecontactrequestsnotificationsubject'] = 'Contact request from {$a}';
|
||||
$string['messagecontentaudio'] = 'Audio';
|
||||
$string['messagecontentimage'] = 'Image';
|
||||
$string['messagecontentmultimediageneral'] = 'Other media';
|
||||
$string['messagecontentvideo'] = 'Video';
|
||||
$string['messagedrawerviewcontact'] = 'User details for {$a}';
|
||||
$string['messagedrawerviewcontacts'] = 'Message contacts';
|
||||
$string['messagedrawerviewconversation'] = 'Conversation with {$a}';
|
||||
|
@ -257,6 +257,10 @@ class icon_system_fontawesome extends icon_system_font {
|
||||
'core:i/mean' => 'fa-calculator',
|
||||
'core:i/menu' => 'fa-ellipsis-v',
|
||||
'core:i/menubars' => 'fa-bars',
|
||||
'core:i/messagecontentaudio' => 'fa-headphones',
|
||||
'core:i/messagecontentimage' => 'fa-image',
|
||||
'core:i/messagecontentvideo' => 'fa-film',
|
||||
'core:i/messagecontentmultimediageneral' => 'fa-file-video-o',
|
||||
'core:i/mnethost' => 'fa-external-link',
|
||||
'core:i/moodle_host' => 'fa-graduation-cap',
|
||||
'core:i/moremenu' => 'fa-ellipsis-h',
|
||||
|
@ -27,6 +27,7 @@ define(
|
||||
'core/notification',
|
||||
'core/pubsub',
|
||||
'core/str',
|
||||
'core/pending',
|
||||
'core/templates',
|
||||
'core/user_date',
|
||||
'core_message/message_repository',
|
||||
@ -42,6 +43,7 @@ function(
|
||||
Notification,
|
||||
PubSub,
|
||||
Str,
|
||||
Pending,
|
||||
Templates,
|
||||
UserDate,
|
||||
MessageRepository,
|
||||
@ -200,62 +202,120 @@ function(
|
||||
* @return {Object} jQuery promise.
|
||||
*/
|
||||
var render = function(conversations, userId) {
|
||||
var formattedConversations = conversations.map(function(conversation) {
|
||||
|
||||
// Helper to format the last message for rendering.
|
||||
// Returns a promise which resolves to either a string, or null
|
||||
// (such as in the event of an empty personal space).
|
||||
var pending = new Pending();
|
||||
|
||||
var formatMessagePreview = async function(lastMessage) {
|
||||
if (!lastMessage) {
|
||||
return null;
|
||||
}
|
||||
var isMedia = lastMessage.text.includes('src');
|
||||
|
||||
if (!isMedia) {
|
||||
// Try to get the text value of the content.
|
||||
// If that's not possible, we'll report it under the catch-all 'other media'.
|
||||
var messagePreview = $(lastMessage.text).text();
|
||||
if (messagePreview) {
|
||||
return messagePreview;
|
||||
}
|
||||
}
|
||||
|
||||
// As a fallback, report unknowns as 'other media' type content.
|
||||
var pix = 'i/messagecontentmultimediageneral';
|
||||
var label = 'messagecontentmultimediageneral';
|
||||
|
||||
if (lastMessage.text.includes('<img')) {
|
||||
pix = 'i/messagecontentimage';
|
||||
label = 'messagecontentimage';
|
||||
} else if (lastMessage.text.includes('<video')) {
|
||||
pix = 'i/messagecontentvideo';
|
||||
label = 'messagecontentvideo';
|
||||
} else if (lastMessage.text.includes('<audio')) {
|
||||
pix = 'i/messagecontentaudio';
|
||||
label = 'messagecontentaudio';
|
||||
}
|
||||
|
||||
try {
|
||||
var labelString = await Str.get_string(label, 'core_message');
|
||||
var icon = await Templates.renderPix(pix, 'core', labelString);
|
||||
return icon + ' ' + labelString;
|
||||
} catch (error) {
|
||||
Notification.exception(error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
var mapPromises = conversations.map(function(conversation) {
|
||||
|
||||
var lastMessage = conversation.messages.length ? conversation.messages[conversation.messages.length - 1] : null;
|
||||
|
||||
var formattedConversation = {
|
||||
id: conversation.id,
|
||||
imageurl: conversation.imageurl,
|
||||
name: conversation.name,
|
||||
subname: conversation.subname,
|
||||
unreadcount: conversation.unreadcount,
|
||||
ismuted: conversation.ismuted,
|
||||
lastmessagedate: lastMessage ? lastMessage.timecreated : null,
|
||||
sentfromcurrentuser: lastMessage ? lastMessage.useridfrom == userId : null,
|
||||
lastmessage: lastMessage ? $(lastMessage.text).text() || lastMessage.text : null
|
||||
};
|
||||
return formatMessagePreview(lastMessage)
|
||||
.then(function(messagePreview) {
|
||||
var formattedConversation = {
|
||||
id: conversation.id,
|
||||
imageurl: conversation.imageurl,
|
||||
name: conversation.name,
|
||||
subname: conversation.subname,
|
||||
unreadcount: conversation.unreadcount,
|
||||
ismuted: conversation.ismuted,
|
||||
lastmessagedate: lastMessage ? lastMessage.timecreated : null,
|
||||
sentfromcurrentuser: lastMessage ? lastMessage.useridfrom == userId : null,
|
||||
lastmessage: messagePreview
|
||||
};
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
return carry;
|
||||
}, null);
|
||||
}
|
||||
|
||||
if (otherUser !== null) {
|
||||
formattedConversation.userid = otherUser.id;
|
||||
formattedConversation.showonlinestatus = otherUser.showonlinestatus;
|
||||
formattedConversation.isonline = otherUser.isonline;
|
||||
formattedConversation.isblocked = otherUser.isblocked;
|
||||
}
|
||||
|
||||
if (conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.PUBLIC) {
|
||||
formattedConversation.lastsendername = conversation.members.reduce(function(carry, member) {
|
||||
if (!carry && lastMessage && member.id == lastMessage.useridfrom) {
|
||||
carry = member.fullname;
|
||||
if (otherUser !== null) {
|
||||
formattedConversation.userid = otherUser.id;
|
||||
formattedConversation.showonlinestatus = otherUser.showonlinestatus;
|
||||
formattedConversation.isonline = otherUser.isonline;
|
||||
formattedConversation.isblocked = otherUser.isblocked;
|
||||
}
|
||||
return carry;
|
||||
}, null);
|
||||
}
|
||||
|
||||
return formattedConversation;
|
||||
if (conversation.type == MessageDrawerViewConversationContants.CONVERSATION_TYPES.PUBLIC) {
|
||||
formattedConversation.lastsendername = conversation.members.reduce(function(carry, member) {
|
||||
if (!carry && lastMessage && member.id == lastMessage.useridfrom) {
|
||||
carry = member.fullname;
|
||||
}
|
||||
return carry;
|
||||
}, null);
|
||||
}
|
||||
|
||||
return formattedConversation;
|
||||
}).catch(Notification.exception);
|
||||
});
|
||||
|
||||
formattedConversations.forEach(function(conversation) {
|
||||
if (new Date().toDateString() == new Date(conversation.lastmessagedate * 1000).toDateString()) {
|
||||
conversation.istoday = true;
|
||||
}
|
||||
});
|
||||
return Promise.all(mapPromises)
|
||||
.then(function(formattedConversations) {
|
||||
formattedConversations.forEach(function(conversation) {
|
||||
if (new Date().toDateString() == new Date(conversation.lastmessagedate * 1000).toDateString()) {
|
||||
conversation.istoday = true;
|
||||
}
|
||||
});
|
||||
|
||||
return Templates.render(TEMPLATES.CONVERSATIONS_LIST, {conversations: formattedConversations});
|
||||
return Templates.render(TEMPLATES.CONVERSATIONS_LIST, {conversations: formattedConversations});
|
||||
}).then(function(html, js) {
|
||||
pending.resolve();
|
||||
return $.Deferred().resolve(html, js);
|
||||
}).catch(function(error) {
|
||||
pending.resolve();
|
||||
Notification.exception(error);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -78,7 +78,7 @@
|
||||
{{#str}} sender, core_message, {{.}} {{/str}}
|
||||
{{/lastsendername}}
|
||||
{{/sentfromcurrentuser}}
|
||||
<span class="text-muted">{{lastmessage}}</span>
|
||||
<span class="text-muted">{{{lastmessage}}}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="d-flex align-self-stretch">
|
||||
|
BIN
pix/i/messagecontentaudio.png
Normal file
After Width: | Height: | Size: 435 B |
2
pix/i/messagecontentaudio.svg
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1728 886q0 166-60 314l-20 49-185 33q-22 83-90.5 136.5t-156.5 53.5v32q0 14-9 23t-23 9h-64q-14 0-23-9t-9-23v-576q0-14 9-23t23-9h64q14 0 23 9t9 23v32q71 0 130 35.5t93 95.5l68-12q29-95 29-193 0-148-88-279t-236.5-209-315.5-78-315.5 78-236.5 209-88 279q0 98 29 193l68 12q34-60 93-95.5t130-35.5v-32q0-14 9-23t23-9h64q14 0 23 9t9 23v576q0 14-9 23t-23 9h-64q-14 0-23-9t-9-23v-32q-88 0-156.5-53.5t-90.5-136.5l-185-33-20-49q-60-148-60-314 0-151 67-291t179-242.5 266-163.5 320-61 320 61 266 163.5 179 242.5 67 291z" fill="#999"/></svg>
|
After Width: | Height: | Size: 663 B |
BIN
pix/i/messagecontentimage.png
Normal file
After Width: | Height: | Size: 340 B |
2
pix/i/messagecontentimage.svg
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="2048" height="1792" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg"><path d="M704 576q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136zm1024 384v448h-1408v-192l320-320 160 160 512-512zm96-704h-1600q-13 0-22.5 9.5t-9.5 22.5v1216q0 13 9.5 22.5t22.5 9.5h1600q13 0 22.5-9.5t9.5-22.5v-1216q0-13-9.5-22.5t-22.5-9.5zm160 32v1216q0 66-47 113t-113 47h-1600q-66 0-113-47t-47-113v-1216q0-66 47-113t113-47h1600q66 0 113 47t47 113z" fill="#999"/></svg>
|
After Width: | Height: | Size: 514 B |
BIN
pix/i/messagecontentmultimediageneral.png
Normal file
After Width: | Height: | Size: 302 B |
2
pix/i/messagecontentmultimediageneral.svg
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1596 380q28 28 48 76t20 88v1152q0 40-28 68t-68 28h-1344q-40 0-68-28t-28-68v-1600q0-40 28-68t68-28h896q40 0 88 20t76 48zm-444-244v376h376q-10-29-22-41l-313-313q-12-12-41-22zm384 1528v-1024h-416q-40 0-68-28t-28-68v-416h-768v1536h1280zm-640-896q52 0 90 38t38 90v384q0 52-38 90t-90 38h-384q-52 0-90-38t-38-90v-384q0-52 38-90t90-38h384zm492 2q20 8 20 30v576q0 22-20 30-8 2-12 2-14 0-23-9l-265-266v-90l265-266q9-9 23-9 4 0 12 2z" fill="#999"/></svg>
|
After Width: | Height: | Size: 583 B |
BIN
pix/i/messagecontentvideo.png
Normal file
After Width: | Height: | Size: 249 B |
2
pix/i/messagecontentvideo.svg
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg width="2048" height="1792" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg"><path d="M448 1600v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm0-384v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm0-384v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm1024 768v-512q0-26-19-45t-45-19h-768q-26 0-45 19t-19 45v512q0 26 19 45t45 19h768q26 0 45-19t19-45zm-1024-1152v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm1408 1152v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm-384-768v-512q0-26-19-45t-45-19h-768q-26 0-45 19t-19 45v512q0 26 19 45t45 19h768q26 0 45-19t19-45zm384 384v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm0-384v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm0-384v-128q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v128q0 26 19 45t45 19h128q26 0 45-19t19-45zm128-160v1344q0 66-47 113t-113 47h-1600q-66 0-113-47t-47-113v-1344q0-66 47-113t113-47h1600q66 0 113 47t47 113z" fill="#999"/></svg>
|
After Width: | Height: | Size: 1.2 KiB |