Browse Source

Add a MAMEarliest table to keep track of the earliest message when requesting MAM

Get MAM when MAMEarliest is not there
pull/1456/head
Timothée Jaussoin 2 months ago
parent
commit
7b5bf6d34b
  1. 1
      CHANGELOG.md
  2. 17
      app/MAMEarliest.php
  3. 5
      app/User.php
  4. 78
      app/Widgets/Chat/Chat.php
  5. 5
      app/Widgets/Chats/Chats.php
  6. 31
      database/migrations/20250801115140_create_m_a_m_earliest_table.php
  7. 35
      src/Moxl/Xec/Action/MAM/Get.php

1
CHANGELOG.md

@ -5,6 +5,7 @@ v0.31.1 (master)
---------------------------
* Add a copy external link button on the Posts
* Improve the Communities discovery flow when visiting a server
* Add a MAMEarliest table to keep track of the earliest message when requesting MAM
v0.31
---------------------------

17
app/MAMEarliest.php

@ -0,0 +1,17 @@
<?php
namespace App;
use Awobaz\Compoships\Database\Eloquent\Model;
class MAMEarliest extends Model
{
protected $table = 'mam_earliest';
use \Awobaz\Compoships\Compoships;
public function user()
{
return $this->belongsTo('App\User');
}
}

5
app/User.php

@ -60,6 +60,11 @@ class User extends Model
return $this->hasMany('App\Message');
}
public function MAMEarliests()
{
return $this->hasMany('App\MAMEarliest');
}
public function openChats()
{
return $this->hasMany('App\OpenChat');

78
app/Widgets/Chat/Chat.php

@ -9,6 +9,7 @@ use Moxl\Xec\Action\Muc\GetConfig;
use Moxl\Xec\Action\Muc\SetConfig;
use App\Contact;
use App\MAMEarliest;
use App\Message;
use App\MessageFile;
use App\MessageOmemoHeader;
@ -21,6 +22,7 @@ use App\Widgets\Dictaphone\Dictaphone;
use App\Widgets\Notif\Notif;
use App\Widgets\Post\Post;
use App\Widgets\Toast\Toast;
use Carbon\Carbon;
use Moxl\Xec\Action\BOB\Request;
use Moxl\Xec\Action\Disco\Request as DiscoRequest;
@ -39,12 +41,23 @@ class Chat extends \Movim\Widget\Base
private $_pagination = 50;
private $_wrapper = [];
private $_messageTypes = [
'chat', 'headline', 'invitation',
'jingle_incoming', 'jingle_outgoing', 'jingle_end', 'jingle_retract', 'jingle_reject'
'chat',
'headline',
'invitation',
'jingle_incoming',
'jingle_outgoing',
'jingle_end',
'jingle_retract',
'jingle_reject'
];
private $_messageTypesMuc = [
'groupchat', 'muji_propose', 'muji_retract',
'muc_owner', 'muc_admin', 'muc_outcast', 'muc_member'
'groupchat',
'muji_propose',
'muji_retract',
'muc_owner',
'muc_admin',
'muc_outcast',
'muc_member'
];
private $_mucPresences = [];
@ -177,9 +190,17 @@ class Chat extends \Movim\Widget\Base
if (
$message->isEmpty() && !in_array($message->type, [
'jingle_incoming', 'jingle_outgoing', 'jingle_end', 'muc_owner', 'jingle_retract', 'jingle_reject',
'muji_propose', 'muji_retract',
'muc_admin', 'muc_outcast', 'muc_member'
'jingle_incoming',
'jingle_outgoing',
'jingle_end',
'muc_owner',
'jingle_retract',
'jingle_reject',
'muji_propose',
'muji_retract',
'muc_admin',
'muc_outcast',
'muc_member'
])
) {
return;
@ -453,7 +474,7 @@ class Chat extends \Movim\Widget\Base
->where('jid', $jid)
->select(['bundleid', 'jid'])
->get()
->mapToGroups(fn ($tuple) => [$tuple['jid'] => $tuple['bundleid']])
->mapToGroups(fn($tuple) => [$tuple['jid'] => $tuple['bundleid']])
->toArray()
);
}
@ -513,7 +534,7 @@ class Chat extends \Movim\Widget\Base
})
->select(['bundleid', 'jid'])
->get()
->mapToGroups(fn ($tuple) => [$tuple['jid'] => $tuple['bundleid']])
->mapToGroups(fn($tuple) => [$tuple['jid'] => $tuple['bundleid']])
->toArray()
);
}
@ -872,7 +893,7 @@ class Chat extends \Movim\Widget\Base
->delete();
}
$newEmojis = $emojis->filter(fn ($value, $key) => $value->emoji != $emoji);
$newEmojis = $emojis->filter(fn($value, $key) => $value->emoji != $emoji);
}
$r->setTo($parentMessage->jidfrom != $parentMessage->user_id
@ -1159,7 +1180,7 @@ class Chat extends \Movim\Widget\Base
*
* @param string $jid
*/
public function ajaxClearHistoryConfirm($jid)
public function ajaxClearHistoryConfirm(string $jid)
{
if (!validateJid($jid)) {
return;
@ -1181,6 +1202,8 @@ class Chat extends \Movim\Widget\Base
)->where('user_id', $this->user->id);
})->delete();
$this->user->MAMEarliests()->where('jid', $jid)->delete();
$this->ajaxGet($jid);
}
@ -1275,6 +1298,29 @@ class Chat extends \Movim\Widget\Base
if ($unreadsCount > 0) {
$this->rpc('Chat.insertSeparator', $unreadsCount);
}
// Do we need to query MAM?
if ($messages->isEmpty()) {
$earliest = MAMEarliest::query();
$earliest = $muc ? $earliest->where('to', $jid)
: $earliest->where('jid', $jid);
if (!$earliest->first()) {
$this->rpc('Chat.getHistory', true);
}
} elseif ($messages->count() < $this->_pagination) {
$earliest = MAMEarliest::query();
$earliest = $muc ? $earliest->where('to', $jid)
: $earliest->where('jid', $jid);
$me = $earliest->first();
if (
!$me ||
(new Carbon($me->earliest))->isAfter(new Carbon($messages->first()->published))
) {
$this->rpc('Chat.getHistory', true);
}
}
}
public function prepareMessage(&$message, $jid = null)
@ -1581,8 +1627,14 @@ class Chat extends \Movim\Widget\Base
// Internal messages
if (in_array($message->type, [
'muc_owner', 'muc_admin', 'muc_outcast', 'muc_member',
'jingle_reject', 'jingle_incoming', 'jingle_outgoing', 'jingle_retract',
'muc_owner',
'muc_admin',
'muc_outcast',
'muc_member',
'jingle_reject',
'jingle_incoming',
'jingle_outgoing',
'jingle_retract',
'muji_propose'
])) {
$view = $this->tpl();

5
app/Widgets/Chats/Chats.php

@ -182,8 +182,9 @@ class Chats extends Base
if ($message && $message->published) {
$g->setStart(strtotime($message->published) + 1);
} else {
// We only sync up the last month the first time
$g->setStart(\Carbon\Carbon::now()->subMonth()->timestamp);
// We sync up the last 500 messages at first
$g->setLimit(500);
$g->setBefore('');
}
$g->request();

31
database/migrations/20250801115140_create_m_a_m_earliest_table.php

@ -0,0 +1,31 @@
<?php
use Movim\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateMAMEarliestTable extends Migration
{
public function up()
{
$this->schema->create('mam_earliest', function (Blueprint $table) {
$table->increments('id');
$table->string('user_id');
$table->string('to')->nullable();
$table->string('jid')->nullable();
$table->dateTime('earliest');
$table->foreign('user_id')->references('id')
->on('users')->onDelete('cascade');
$table->timestamps();
$table->unique(['user_id', 'to', 'jid']);
});
}
public function down()
{
$this->schema->drop('mam_earliest');
}
}

35
src/Moxl/Xec/Action/MAM/Get.php

@ -2,6 +2,7 @@
namespace Moxl\Xec\Action\MAM;
use App\MAMEarliest;
use Moxl\Xec\Action;
use Moxl\Stanza\MAM;
use Movim\Session;
@ -9,14 +10,14 @@ use Movim\Session;
class Get extends Action
{
protected $_queryid;
protected $_to;
protected $_jid;
protected $_start;
protected $_end;
protected $_limit;
protected $_after;
protected $_before;
protected ?string $_to = null;
protected ?string $_queryid = null;
protected ?string $_jid = null;
protected ?int $_start = null;
protected ?int $_end = null;
protected ?int $_limit = null;
protected ?string $_after = null;
protected ?string $_before = null;
protected string $_version = '2';
protected int $_messageCounter = 0;
@ -61,6 +62,24 @@ class Get extends Action
$totalCounter = $this->_messageCounter + $messagesCounter;
if (
isset($stanza->fin->set)
&& $stanza->fin->set->attributes()->xmlns == 'http://jabber.org/protocol/rsm'
&& $stanza->fin->set->count == 0
&& (
($this->_end != null && $this->_start == null)
||
($this->_end == null && $this->_start == null && $this->_before == '')
)
) {
$earliest = new MAMEarliest;
$earliest->user_id = \App\User::me()->id;
$earliest->to = $this->_to;
$earliest->jid = $this->_jid;
$earliest->earliest = date(MOVIM_SQL_DATE, $this->_end ?? time());
$earliest->save();
}
if (
isset($stanza->fin)
&& (!isset($stanza->fin->attributes()->complete) || $stanza->fin->attributes()->complete != 'true')

Loading…
Cancel
Save