mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
attempt at not reloading full channel data at every change
This commit is contained in:
parent
9442d87644
commit
c06da99757
@ -118,85 +118,21 @@ void RsGxsChannelPostsModel::handleEvent_main_thread(std::shared_ptr<const RsEve
|
||||
switch(e->mChannelEventCode)
|
||||
{
|
||||
case RsChannelEventCode::UPDATED_MESSAGE:
|
||||
case RsChannelEventCode::READ_STATUS_CHANGED:
|
||||
{
|
||||
// Normally we should just emit dataChanged() on the index of the data that has changed:
|
||||
// We need to update the data!
|
||||
case RsChannelEventCode::READ_STATUS_CHANGED:
|
||||
case RsChannelEventCode::NEW_COMMENT:
|
||||
{
|
||||
// Normally we should just emit dataChanged() on the index of the data that has changed:
|
||||
// We need to update the data!
|
||||
|
||||
// make a copy of e, so as to avoid destruction of the shared pointer during async thread execution, since [e] doesn't actually tell
|
||||
// the original shared_ptr that it is copied! So no counter is updated in event, which will be destroyed (as e will be) during or even before
|
||||
// the execution of the lambda.
|
||||
// In particular, mChannelMsgId may refer to a comment, but this will be handled correctly
|
||||
// by update_single_post which will automatically retrive the correct parent msg.
|
||||
|
||||
RsGxsChannelEvent E(*e);
|
||||
if(e->mChannelGroupId == mChannelGroup.mMeta.mGroupId)
|
||||
update_single_post(e->mChannelGroupId,e->mChannelMsgId,e->mChannelThreadId);
|
||||
};
|
||||
break;
|
||||
|
||||
if(E.mChannelGroupId == mChannelGroup.mMeta.mGroupId)
|
||||
RsThread::async([this, E]()
|
||||
{
|
||||
// 1 - get message data from p3GxsChannels. No need for pointers here, because we send only a single post to postToObject()
|
||||
// At this point we dont know what kind of msg id we have. It can be a vote, a comment or an actual message.
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
std::set<RsGxsMessageId> msg_ids{ E.mChannelMsgId };
|
||||
|
||||
if(!rsGxsChannels->getChannelContent(E.mChannelGroupId,msg_ids, posts,comments,votes))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel message data for channel/msg " << E.mChannelGroupId << "/" << E.mChannelMsgId << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if what we have actually is a comment or a vote. If so we need to update the actual message they refer to
|
||||
|
||||
if(posts.empty()) // means we have a comment or a vote
|
||||
{
|
||||
msg_ids.clear();
|
||||
|
||||
for(auto c:comments) msg_ids.insert(c.mMeta.mThreadId);
|
||||
for(auto v:votes ) msg_ids.insert(v.mMeta.mThreadId);
|
||||
|
||||
comments.clear();
|
||||
votes.clear();
|
||||
|
||||
if(!rsGxsChannels->getChannelContent(E.mChannelGroupId,msg_ids,posts,comments,votes))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel message data for channel/msg " << E.mChannelGroupId << "/" << E.mChannelMsgId << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Need to call this in order to get the actuall comment count. The previous call only retrieves the message, since we supplied the message ID.
|
||||
// another way to go would be to save the comment ids of the existing message and re-insert them before calling getChannelContent.
|
||||
|
||||
if(!rsGxsChannels->getChannelComments(E.mChannelGroupId,msg_ids,comments))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve message comment data for channel/msg " << E.mChannelGroupId << "/" << E.mChannelMsgId << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
updateCommentCounts(posts,comments);
|
||||
|
||||
// 2 - update the model in the UI thread.
|
||||
|
||||
RsQThreadUtils::postToObject( [posts,this]()
|
||||
{
|
||||
for(uint32_t i=0;i<posts.size();++i)
|
||||
{
|
||||
// linear search. Not good at all, but normally this is for a single post.
|
||||
|
||||
for(uint32_t j=0;j<mPosts.size();++j)
|
||||
if(mPosts[j].mMeta.mMsgId == posts[i].mMeta.mMsgId)
|
||||
{
|
||||
mPosts[j] = posts[i];
|
||||
|
||||
triggerViewUpdate();
|
||||
}
|
||||
}
|
||||
},this);
|
||||
});
|
||||
}
|
||||
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -564,6 +500,47 @@ bool operator<(const RsGxsChannelPost& p1,const RsGxsChannelPost& p2)
|
||||
return p1.mMeta.mPublishTs > p2.mMeta.mPublishTs;
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::setSinglePost(const RsGxsChannelGroup& group, const RsGxsChannelPost& post)
|
||||
{
|
||||
if(mChannelGroup.mMeta.mGroupId != group.mMeta.mGroupId)
|
||||
return;
|
||||
|
||||
preMods();
|
||||
|
||||
// This is potentially quadratic, so it should not be called many times!
|
||||
|
||||
bool found=false;
|
||||
|
||||
for(auto& p:mPosts)
|
||||
if(post.mMeta.mMsgId == p.mMeta.mMsgId || post.mMeta.mOrigMsgId == p.mMeta.mMsgId)
|
||||
{
|
||||
p = post;
|
||||
found = true;
|
||||
}
|
||||
if(!found)
|
||||
mPosts.push_back(post);
|
||||
|
||||
std::sort(mPosts.begin(),mPosts.end());
|
||||
|
||||
mFilteredPosts.clear();
|
||||
|
||||
for(uint32_t i=0;i<mPosts.size();++i)
|
||||
mFilteredPosts.push_back(i);
|
||||
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
// debug_dump();
|
||||
#endif
|
||||
|
||||
if (rowCount()>0)
|
||||
{
|
||||
beginInsertRows(QModelIndex(),0,rowCount()-1);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
postMods();
|
||||
|
||||
emit channelPostsLoaded();
|
||||
}
|
||||
void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vector<RsGxsChannelPost>& posts)
|
||||
{
|
||||
preMods();
|
||||
@ -593,6 +570,57 @@ void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vecto
|
||||
emit channelPostsLoaded();
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::update_single_post(const RsGxsGroupId& group_id,const RsGxsMessageId& msg_id,const RsGxsMessageId& thread_id)
|
||||
{
|
||||
RsThread::async([this, group_id, msg_id,thread_id]()
|
||||
{
|
||||
// 1 - get message data from p3GxsChannels. No need for pointers here, because we send only a single post to postToObject()
|
||||
// At this point we dont know what kind of msg id we have. It can be a vote, a comment or an actual message.
|
||||
|
||||
std::vector<RsGxsChannelPost> posts;
|
||||
std::vector<RsGxsComment> comments;
|
||||
std::vector<RsGxsVote> votes;
|
||||
std::set<RsGxsMessageId> msg_ids({ (thread_id.isNull())?msg_id:thread_id } ); // we have a post message
|
||||
|
||||
if(!rsGxsChannels->getChannelContent(group_id,msg_ids, posts,comments,votes))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve channel message data for channel/msg " << group_id << "/" << msg_id << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Need to call this in order to get the actual comment count. The previous call only retrieves the message, since we supplied the message ID.
|
||||
// another way to go would be to save the comment ids of the existing message and re-insert them before calling getChannelContent.
|
||||
|
||||
if(!rsGxsChannels->getChannelComments(group_id,msg_ids,comments))
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve message comment data for channel/msg " << group_id << "/" << msg_id << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Normally, there's a single post in the "post" array. The function below takes a full array of posts however.
|
||||
|
||||
updateCommentCounts(posts,comments);
|
||||
|
||||
// 2 - update the model in the UI thread.
|
||||
|
||||
RsQThreadUtils::postToObject( [posts,this]()
|
||||
{
|
||||
for(uint32_t i=0;i<posts.size();++i)
|
||||
{
|
||||
// linear search. Not good at all, but normally this is for a single post.
|
||||
|
||||
for(uint32_t j=0;j<mPosts.size();++j)
|
||||
if(mPosts[j].mMeta.mMsgId == posts[i].mMeta.mMsgId)
|
||||
{
|
||||
mPosts[j] = posts[i];
|
||||
|
||||
triggerViewUpdate();
|
||||
}
|
||||
}
|
||||
},this);
|
||||
});
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::update_posts(const RsGxsGroupId& group_id)
|
||||
{
|
||||
if(group_id.isNull())
|
||||
|
@ -214,6 +214,7 @@ private:
|
||||
static void computeReputationLevel(uint32_t forum_sign_flags, RsGxsChannelPost& entry);
|
||||
|
||||
void update_posts(const RsGxsGroupId& group_id);
|
||||
void update_single_post(const RsGxsGroupId& group_id, const RsGxsMessageId& msgId, const RsGxsMessageId &thread_id);
|
||||
|
||||
#ifdef TODO
|
||||
void setForumMessageSummary(const std::vector<RsGxsForumMsg>& messages);
|
||||
@ -231,7 +232,8 @@ private:
|
||||
//void computeMessagesHierarchy(const RsGxsChannelGroup& forum_group, const std::vector<RsMsgMetaData> &msgs_array, std::vector<ChannelPostsModelPostEntry> &posts, std::map<RsGxsMessageId, std::vector<std::pair<time_t, RsGxsMessageId> > > &mPostVersions);
|
||||
void createPostsArray(std::vector<RsGxsChannelPost> &posts);
|
||||
void setPosts(const RsGxsChannelGroup& group, std::vector<RsGxsChannelPost> &posts);
|
||||
void initEmptyHierarchy();
|
||||
void setSinglePost(const RsGxsChannelGroup& group, const RsGxsChannelPost& post);
|
||||
void initEmptyHierarchy();
|
||||
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
|
||||
|
||||
std::vector<int> mFilteredPosts; // stores the list of displayes indices due to filtering.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -104,11 +104,11 @@ public:
|
||||
|
||||
/* GxsMessageFrameWidget */
|
||||
virtual QIcon groupIcon() override;
|
||||
virtual void groupIdChanged() override { updateDisplay(true); }
|
||||
virtual void groupIdChanged() override { updateDisplay(true,true); }
|
||||
virtual QString groupName(bool) override;
|
||||
virtual bool navigate(const RsGxsMessageId&) override;
|
||||
|
||||
void updateDisplay(bool complete);
|
||||
void updateDisplay(bool update_group_data, bool update_posts);
|
||||
|
||||
#ifdef TODO
|
||||
/* FeedHolder */
|
||||
@ -141,7 +141,7 @@ protected:
|
||||
|
||||
private slots:
|
||||
void showPostDetails();
|
||||
void updateGroupData();
|
||||
void updateData(bool update_group_data,bool update_posts);
|
||||
void download();
|
||||
void updateDAll_PB();
|
||||
void createMsg();
|
||||
|
@ -194,7 +194,7 @@
|
||||
<item>
|
||||
<widget class="QTabWidget" name="channel_TW">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
@ -402,7 +402,7 @@
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
|
Loading…
Reference in New Issue
Block a user