diff --git a/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp b/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp index cd014168a..e827a2fbb 100644 --- a/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp +++ b/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp @@ -79,6 +79,31 @@ void RsPostedPostsModel::handleEvent_main_thread(std::shared_ptr 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 ids(e->mPostedMsgIds.begin(),e->mPostedMsgIds.end()); + + for(uint32_t i=0;imPostedMsgsRead) + 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(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;imarkRead(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(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