Address review: pointer hand-off to the workers, event-driven board update

- GxsForumModel / PostedPostsModel: hand the id list to the background
  worker through a pointer deleted after the call, so the lambda capture
  does not deep copy it.
- PostedPostsModel: setAllMsgReadStatus() no longer updates the model
  directly. The batched READ_STATUS_CHANGED event now carries the
  affected ids and their new state (libretroshare side), and the event
  handler applies them locally — so a batch initiated by another
  frontend (e.g. webUI) updates the board view exactly the same way,
  and no post is re-read from the database.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jolavillette 2026-08-01 23:03:27 +02:00
parent ebac1481f0
commit 1b99beebc5
2 changed files with 46 additions and 14 deletions

View File

@ -79,6 +79,31 @@ void RsPostedPostsModel::handleEvent_main_thread(std::shared_ptr<const RsEvent>
case RsPostedEventCode::MESSAGE_VOTES_UPDATED:
case RsPostedEventCode::NEW_MESSAGE:
{
// Batched read-status change ("mark all as read", possibly issued by
// another frontend such as the webUI): the event carries the affected
// message ids and their new state, so update the flags locally
// instead of re-reading the posts from the database.
if( e->mPostedEventCode == RsPostedEventCode::READ_STATUS_CHANGED
&& !e->mPostedMsgIds.empty() )
{
if(e->mPostedGroupId != mPostedGroup.mMeta.mGroupId)
return;
const std::set<RsGxsMessageId> ids(e->mPostedMsgIds.begin(),e->mPostedMsgIds.end());
for(uint32_t i=0;i<mPosts.size();++i)
if(ids.count(mPosts[i].mMeta.mMsgId))
{
if(e->mPostedMsgsRead)
mPosts[i].mMeta.mMsgStatus &= ~(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD | GXS_SERV::GXS_MSG_STATUS_GUI_NEW);
else
mPosts[i].mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
}
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mDisplayedNbPosts-1,0,(void*)NULL));
return;
}
// Normally we should just emit dataChanged() on the index of the data that has changed:
//
// We need to update the data!
@ -754,21 +779,21 @@ void RsPostedPostsModel::setAllMsgReadStatus(bool read)
}
if(!msgIds.empty())
RsThread::async([boardId=mPostedGroup.mMeta.mGroupId, msgIds, read]()
{
// Hand the id list over through a pointer: the lambda capture would
// otherwise deep copy it.
auto* ids = new std::vector<RsGxsMessageId>(std::move(msgIds));
RsThread::async([boardId=mPostedGroup.mMeta.mGroupId, ids, read]()
{
rsPosted->setPostReadStatus(boardId, msgIds, read);
rsPosted->setPostReadStatus(boardId, *ids, read);
delete ids;
} );
}
// Update the local model immediately, since we don't catch the resulting
// event later (that would reload the posts).
for(uint32_t i=0;i<mPosts.size();++i)
if(read)
mPosts[i].mMeta.mMsgStatus &= ~(GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD | GXS_SERV::GXS_MSG_STATUS_GUI_NEW);
else
mPosts[i].mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mDisplayedNbPosts-1,0,(void*)NULL));
// The model is updated when the resulting READ_STATUS_CHANGED event comes
// back (see handleEvent_main_thread()), through the same path as a batch
// initiated by any other frontend (e.g. the webUI).
}
void RsPostedPostsModel::setMsgReadStatus(const QModelIndex& i,bool read_status)
{

View File

@ -894,10 +894,17 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo
rsGxsForums->markRead(std::make_pair(grpId, msgId), read_status);
});
else if(!changed_msgs.empty())
RsThread::async( [grpId=mForumGroup.mMeta.mGroupId,changed_msgs,read_status]()
{
// Hand the (possibly long) id list over through a pointer: the lambda
// capture would otherwise deep copy it.
auto* msgs = new std::vector<RsGxsMessageId>(std::move(changed_msgs));
RsThread::async( [grpId=mForumGroup.mMeta.mGroupId,msgs,read_status]()
{
rsGxsForums->markRead(grpId, changed_msgs, read_status);
rsGxsForums->markRead(grpId, *msgs, read_status);
delete msgs;
});
}
// How the view is refreshed depends on how many *rows* changed, not on how
// many messages were written. A post keeps every edited version of itself in