Browse Source

Refactor the message loading flow

feature/templater
Timothée Jaussoin 1 month ago
parent
commit
1db07b5f58
  1. 8
      app/Message.php
  2. 91
      app/Widgets/Chat/Chat.php
  3. 2
      app/Widgets/Chat/_chat.tpl
  4. 91
      app/Widgets/Chat/chat.js
  5. 5
      app/Widgets/Chats/Chats.php

8
app/Message.php

@ -51,12 +51,12 @@ class Message extends Model
];
public const MESSAGE_TYPE_MUC = [
'groupchat',
'muji_propose',
'muji_retract',
'muc_owner',
'muc_admin',
'muc_member',
'muc_outcast',
'muc_member'
'muc_owner',
'muji_propose',
'muji_retract',
];
public static function boot()

91
app/Widgets/Chat/Chat.php

@ -155,7 +155,7 @@ class Chat extends \Movim\Widget\Base
->where('mucjid', $this->user->id)
->first();
$this->prepareMessages($jid, ($presence), true);
$this->getMessages($jid, muc: ($presence), seenOnly: true);
}
}
@ -176,20 +176,10 @@ class Chat extends \Movim\Widget\Base
$rawbody = $message->getInlinedBodyAttribute(true) ?? $message->body;
if (
$message->isEmpty() && !in_array($message->type, [
'jingle_end',
'jingle_finish',
'jingle_incoming',
'jingle_outgoing',
'jingle_reject',
'jingle_retract',
'muc_admin',
'muc_member',
'muc_outcast',
'muc_owner',
'muji_propose',
'muji_retract',
])
$message->isEmpty() && !in_array(
$message->type,
array_merge(Message::MESSAGE_TYPE, Message::MESSAGE_TYPE_MUC)
)
) {
return;
}
@ -379,24 +369,19 @@ class Chat extends \Movim\Widget\Base
public function ajaxInit()
{
$view = $this->tpl();
$date = $view->draw('_chat_date');
$separator = $view->draw('_chat_separator');
$this->rpc('Chat.resetCurrentDateTime');
$this->rpc('Chat.setGeneralElements', $date, $separator);
$this->rpc(
'Chat.setConfig',
$this->_pagination,
$this->__('message.error'),
$this->__('chat.action_impossible_encrypted')
'Chat.init',
$view->draw('_chat_date'),
$view->draw('_chat_separator'),
[
'pagination' => $this->_pagination,
'delivery_error' => $this->__('message.error'),
'action_impossible_encrypted_error' => $this->__('chat.action_impossible_encrypted')
]
);
}
public function ajaxClearCounter(string $jid)
{
$this->prepareMessages($jid, false, true, false);
}
/**
* Get the header
*/
@ -449,8 +434,8 @@ class Chat extends \Movim\Widget\Base
}
$this->rpc('Chat.setObservers');
$this->rpc('Chat.resetCurrentDateTime');
$this->prepareMessages($jid);
$this->rpc('Chat.resetOldestMessageDateTime');
$this->getMessages($jid);
$this->rpc('Notif.current', 'chat|' . $jid);
$this->rpc('Chat.scrollToSeparator');
@ -495,8 +480,8 @@ class Chat extends \Movim\Widget\Base
}
$this->rpc('Chat.setObservers');
$this->rpc('Chat.resetCurrentDateTime'); // TODO, not call there all the time ?!
$this->prepareMessages($room, true);
$this->rpc('Chat.resetOldestMessageDateTime'); // TODO, not call there all the time ?!
$this->getMessages($room, muc: true);
$this->rpc('Notif.current', 'chat|' . $room);
$this->rpc('Chat.scrollToSeparator');
@ -1008,7 +993,7 @@ class Chat extends \Movim\Widget\Base
}
/**
* @brief Get a specific message contect
* @brief Get a specific message context
*/
public function ajaxGetMessageContext(string $jid, int $mid)
{
@ -1026,31 +1011,10 @@ class Chat extends \Movim\Widget\Base
->first();
if ($contextMessage) {
$messages = \App\Message::jid($jid)
->where('published', '>=', $contextMessage->published);
$messages = $contextMessage->isMuc()
? $messages->whereIn('type', Message::MESSAGE_TYPE_MUC)->whereNull('subject')
: $messages->whereIn('type', Message::MESSAGE_TYPE);
$messages = $messages->orderBy('published', 'asc')
->withCount('reactions')
->take($this->_pagination)
->get();
if ($messages->count() > 0) {
$messages = $messages->reverse();
foreach ($messages as $message) {
$this->prepareMessage($message);
}
$this->rpc('MovimTpl.fill', '#' . cleanupId($jid) . '-conversation', '');
$this->rpc('MovimUtils.addClass', '#scroll_now.button.action', 'show');
$this->rpc('Chat.appendMessagesWrapper', $this->_wrapper, true);
$this->rpc('Chat.scrollAndBlinkMessageMid', $mid);
$this->_wrapper = [];
}
$this->rpc('MovimTpl.fill', '#' . cleanupId($jid) . '-conversation', '');
$this->ajaxGetHistory($jid, $contextMessage->published, muc: $contextMessage->isMuc(), prepend: false, tryMam: false);
$this->rpc('Chat.scrollAndBlinkMessageMid', $mid);
$this->rpc('MovimUtils.addClass', '#scroll_now.button.action', 'show');
}
}
@ -1238,7 +1202,14 @@ class Chat extends \Movim\Widget\Base
return $view->draw('_chat');
}
public function prepareMessages($jid, $muc = false, $seenOnly = false, $event = true)
public function ajaxClearAndGetMessages(string $jid, $muc = false)
{
$this->rpc('MovimTpl.fill', '#' . cleanupId($jid) . '-conversation', '');
$this->getMessages($jid, $muc);
$this->rpc('MovimUtils.removeClass', '#scroll_now.button.action', 'show');
}
public function getMessages(string $jid, $muc = false, $seenOnly = false, $event = true)
{
if (!validateJid($jid)) {
return;
@ -1336,7 +1307,7 @@ class Chat extends \Movim\Widget\Base
}
}
public function prepareMessage(&$message, $jid = null)
public function prepareMessage(&$message, $jid = null): array
{
if ($jid != $message->jidto && $jid != $message->jidfrom && $jid != null) {
return $this->_wrapper;

2
app/Widgets/Chat/_chat.tpl

@ -32,7 +32,7 @@
</section>
</div>
<div class="chat_box {if="isset($conference) && $conference->presence && $conference->presence->mucrole == 'visitor'"}disabled{/if}">
<a id="scroll_now" class="button action color small" onclick="Chat.getChat('{$jid}')">
<a id="scroll_now" class="button action color small" onclick="Chat_ajaxClearAndGetMessages('{$jid}', {if="$muc"}true{/if})">
<i class="material-symbols">clock_arrow_down</i>
</a>
<a id="scroll_down" class="button action color transparent small" onclick="Chat.scrollTotally()">

91
app/Widgets/Chat/chat.js

@ -4,8 +4,7 @@ var Chat = {
date: null,
separator: null,
// Date time of the oldest message displayed
currentDateTime: null,
oldestMessageDateTime: null,
edit: false,
// Scroll
@ -46,6 +45,18 @@ var Chat = {
// Keep track of replaced messages hash when loading history or refreshing
replacedHash: [],
init: function (date, separator, config) {
var div = document.createElement('div');
div.innerHTML = date;
Chat.date = div.firstChild.cloneNode(true);
div.innerHTML = separator;
Chat.separator = div.firstChild.cloneNode(true);
Chat.pagination = config['pagination'];
Chat.delivery_error = config['delivery_error'];
Chat.action_impossible_encrypted_error = config['action_impossible_encrypted_error'];
},
autocomplete: function (event, jid) {
RoomsUtils_ajaxMucUsersAutocomplete(jid);
},
@ -158,7 +169,7 @@ var Chat = {
if (textarea) {
Chat_ajaxGetHistory(
textarea.dataset.jid,
Chat.currentDateTime,
Chat.oldestMessageDateTime,
Boolean(textarea.dataset.muc),
true,
tryMam);
@ -637,16 +648,8 @@ var Chat = {
Chat.delivery_error = delivery_error;
Chat.action_impossible_encrypted_error = action_impossible_encrypted_error;
},
resetCurrentDateTime: function () {
Chat.currentDateTime = null;
},
setGeneralElements(date, separator) {
var div = document.createElement('div');
div.innerHTML = date;
Chat.date = div.firstChild.cloneNode(true);
div.innerHTML = separator;
Chat.separator = div.firstChild.cloneNode(true);
resetOldestMessageDateTime: function () {
Chat.oldestMessageDateTime = null;
},
setSpecificElements: function (left, right) {
var div = document.createElement('div');
@ -662,7 +665,7 @@ var Chat = {
discussion.onscroll = function () {
if (this.scrollTop < 1
&& Chat.currentDateTime) {
&& Chat.oldestMessageDateTime) {
Chat.getHistory(true);
}
@ -935,8 +938,8 @@ var Chat = {
/**
* We might have old messages reacted pushed by the server
*/
if (Chat.currentDateTime
&& Chat.currentDateTime > messageDateTime
if (Chat.oldestMessageDateTime
&& Chat.oldestMessageDateTime > messageDateTime
&& !prepend) {
return;
}
@ -946,8 +949,8 @@ var Chat = {
}
for (speakertime in page[date]) {
if (Chat.currentDateTime == null) {
Chat.currentDateTime = page[date][speakertime].published;
if (Chat.oldestMessageDateTime == null) {
Chat.oldestMessageDateTime = page[date][speakertime].published;
}
Chat.appendMessage(speakertime, page[date][speakertime], prepend);
@ -1037,11 +1040,9 @@ var Chat = {
} else {
if (data.user_id == data.jidfrom || data.mine) {
bubble = Chat.right.cloneNode(true);
if (data.mine) {
id = data.jidfrom;
} else {
id = data.jidto;
}
id = (data.mine)
? data.jidfrom
: data.jidto;
} else {
bubble = Chat.left.cloneNode(true);
id = data.jidfrom;
@ -1275,17 +1276,14 @@ var Chat = {
}
}
if (prepend) {
if (new Date(Chat.currentDateTime) > new Date(data.published)) {
Chat.currentDateTime = data.published;
}
if (new Date(Chat.oldestMessageDateTime) > new Date(data.published)) {
Chat.oldestMessageDateTime = data.published;
}
// We prepend
if (!mergeMsg) {
if (!mergeMsg) {
if (prepend) {
MovimTpl.prepend('#' + id, bubble.outerHTML);
}
} else {
if (!mergeMsg) {
} else {
MovimTpl.append('#' + id, bubble.outerHTML);
}
}
@ -1657,28 +1655,29 @@ var Chat = {
}
return url.protocol === "http:" || url.protocol === "https:";
},
getChat: function (jid) {
var room = (MovimUtils.urlParts().params[1] === 'room');
if (room) {
Chat.getRoom(jid);
} else {
Chat.get(jid);
}
}
};
MovimWebsocket.attach(function () {
Chat_ajaxInit();
if (!Chat.pagination) {
Chat_ajaxInit();
}
var jid = MovimUtils.urlParts().params[0];
var room = (MovimUtils.urlParts().params[1] === 'room');
if (jid) {
if (Boolean(document.getElementById(MovimUtils.cleanupId(jid) + '-conversation')) && Chat.currentDateTime) {
Chat_ajaxGetHistory(jid, Chat.currentDateTime, room, false, true);
if (Boolean(document.getElementById(MovimUtils.cleanupId(jid) + '-conversation')) && Chat.oldestMessageDateTime) {
Chat_ajaxGetHistory(
jid,
Chat.oldestMessageDateTime,
(MovimUtils.urlParts().params[1] === 'room'),
false,
false
);
} else {
Chat.getChat(jid);
(MovimUtils.urlParts().params[1] === 'room')
? Chat.getRoom(jid)
: Chat.get(jid);
}
} else {
if (!MovimUtils.isMobile()) {

5
app/Widgets/Chats/Chats.php

@ -10,6 +10,7 @@ use App\Message;
use App\OpenChat;
use App\Roster;
use App\User;
use App\Widgets\Chat\Chat;
use Carbon\Carbon;
use Movim\CurrentCall;
@ -255,9 +256,11 @@ class Chats extends Base
$tpl->cacheClear('_chats_item', $jid);
$this->rpc('MovimTpl.remove', $this->getItemId($jid));
$this->rpc('Chat_ajaxClearCounter', $jid);
$this->rpc('Chats.refresh');
// Clear the counter
(new Chat)->getMessages($jid, seenOnly: true, event: false);
if ($closeDiscussion) {
$this->rpc('Chat_ajaxGet');
}

Loading…
Cancel
Save