improved efficiency of channel posts loading

This commit is contained in:
csoler 2020-04-17 23:23:59 +02:00
parent fa8968797c
commit 678bcf5830
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
5 changed files with 108 additions and 81 deletions

View File

@ -44,21 +44,55 @@
* #define DEBUG_ITEM 1
****/
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate)
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup& group, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, group.mMeta.mGroupId, messageId, isHome, rsGxsChannels, autoUpdate), mGroup(group) // this one should be in GxsFeedItem
{
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
init(messageId,older_versions) ;
mPost.mMeta.mGroupId = group.mMeta.mGroupId;
QVector<RsGxsMessageId> v;
//bool self = false;
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
v.push_back(*it) ;
if(older_versions.find(messageId) == older_versions.end())
v.push_back(messageId);
setMessageVersions(v) ;
setup();
//init(messageId,older_versions) ;
}
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsChannels, autoUpdate) // this one should be in GxsFeedItem
{
mPost.mMeta.mMsgId.clear(); // security
init(post.mMeta.mMsgId,older_versions) ;
mPost = post ;
mPost.mMeta.mMsgId = messageId; // useful for uniqueIdentifer() before the post is loaded
QVector<RsGxsMessageId> v;
//bool self = false;
for(std::set<RsGxsMessageId>::const_iterator it(older_versions.begin());it!=older_versions.end();++it)
v.push_back(*it) ;
if(older_versions.find(messageId) == older_versions.end())
v.push_back(messageId);
setMessageVersions(v) ;
setup();
loadGroup();
}
// GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate,const std::set<RsGxsMessageId>& older_versions) :
// GxsFeedItem(feedHolder, feedId, post.mMeta.mGroupId, post.mMeta.mMsgId, isHome, rsGxsChannels, autoUpdate)
// {
// mPost.mMeta.mMsgId.clear(); // security
// init(post.mMeta.mMsgId,older_versions) ;
// mPost = post ;
// }
void GxsChannelPostItem::init(const RsGxsMessageId& messageId,const std::set<RsGxsMessageId>& older_versions)
{
QVector<RsGxsMessageId> v;
@ -86,7 +120,11 @@ void GxsChannelPostItem::paintEvent(QPaintEvent *e)
{
mLoaded = true ;
requestGroup();
std::set<RsGxsMessageId> older_versions; // not so nice. We need to use std::set everywhere
for(auto& m:messageVersions())
older_versions.insert(m);
fill();
requestMessage();
requestComment();
}
@ -107,6 +145,7 @@ bool GxsChannelPostItem::isUnread() const
void GxsChannelPostItem::setup()
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui::GxsChannelPostItem;
ui->setupUi(this);
@ -165,29 +204,6 @@ void GxsChannelPostItem::setup()
ui->expandFrame->hide();
}
bool GxsChannelPostItem::setGroup(const RsGxsChannelGroup &group, bool doFill)
{
if (groupId() != group.mMeta.mGroupId) {
std::cerr << "GxsChannelPostItem::setGroup() - Wrong id, cannot set post";
std::cerr << std::endl;
return false;
}
mGroup = group;
// If not publisher, hide the edit button. Without the publish key, there's no way to edit a message.
#ifdef DEBUG_ITEM
std::cerr << "Group subscribe flags = " << std::hex << mGroup.mMeta.mSubscribeFlags << std::dec << std::endl ;
#endif
if( !IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags) )
ui->editButton->hide() ;
if (doFill) {
fill();
}
return true;
}
bool GxsChannelPostItem::setPost(const RsGxsChannelPost &post, bool doFill)
{
@ -231,46 +247,6 @@ void GxsChannelPostItem::loadComments()
comments(title);
}
void GxsChannelPostItem::loadGroup()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelGroupItem::loadGroup()";
std::cerr << std::endl;
#endif
RsThread::async([this]()
{
// 1 - get group data
std::vector<RsGxsChannelGroup> groups;
const std::list<RsGxsGroupId> groupIds = { groupId() };
if(!rsGxsChannels->getChannelsInfo(groupIds,groups))
{
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
return;
}
if (groups.size() != 1)
{
std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
return;
}
RsGxsChannelGroup group(groups[0]);
RsQThreadUtils::postToObject( [group,this]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */
setGroup(group);
}, this );
});
}
void GxsChannelPostItem::loadMessage()
{
#ifdef DEBUG_ITEM
@ -408,6 +384,9 @@ void GxsChannelPostItem::fill()
ui->logoLabel->setPixmap(thumbnail);
}
if( !IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags) )
ui->editButton->hide() ;
if (!mIsHome)
{
if (mCloseOnRead && !IS_MSG_NEW(mPost.mMeta.mMsgStatus)) {
@ -829,3 +808,43 @@ void GxsChannelPostItem::makeUpVote()
emit vote(msgId, true);
}
void GxsChannelPostItem::loadGroup()
{
#ifdef DEBUG_ITEM
std::cerr << "GxsChannelGroupItem::loadGroup()";
std::cerr << std::endl;
#endif
RsThread::async([this]()
{
// 1 - get group data
std::vector<RsGxsChannelGroup> groups;
const std::list<RsGxsGroupId> groupIds = { groupId() };
if(!rsGxsChannels->getChannelsInfo(groupIds,groups))
{
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
return;
}
if (groups.size() != 1)
{
std::cerr << "GxsGxsChannelGroupItem::loadGroup() Wrong number of Items";
std::cerr << std::endl;
return;
}
RsGxsChannelGroup group(groups[0]);
RsQThreadUtils::postToObject( [group,this]()
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread, for example to update the data model with new information
* after a blocking call to RetroShare API complete */
mGroup = group;
}, this );
});
}

View File

@ -42,15 +42,18 @@ public:
// It can be used for all apparences of channel posts. But in rder to merge comments from the previous versions of the post, the list of
// previous posts should be supplied. It's optional. If not supplied only the comments of the new version will be displayed.
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId& groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
// This method can be called when additional information is known about the post. In this case, the widget will be initialized with some
// minimap information from the post and completed when the use displays it, which shouldn't cost anything more.
// This one is used in channel thread widget. We don't want the group data to reload at every post, so we load it in the hosting
// GxsChannelsPostsWidget and pass it to created items.
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup& group, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
// // This method can be called when additional information is known about the post. In this case, the widget will be initialized with some
// // minimap information from the post and completed when the use displays it, which shouldn't cost anything more.
//
// GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost& post, bool isHome, bool autoUpdate, const std::set<RsGxsMessageId>& older_versions = std::set<RsGxsMessageId>());
//GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelGroup &group, const RsGxsChannelPost &post, bool isHome, bool autoUpdate);
//GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate);
virtual ~GxsChannelPostItem();
uint64_t uniqueIdentifier() const override { return hash_64bits("GxsChannelPostItem " + messageId().toStdString()) ; }

View File

@ -67,7 +67,6 @@ protected:
virtual void fillThreadCreatePost(const QVariant &/*post*/, bool /*related*/, int /*current*/, int /*count*/) {}
/* GXS functions */
void requestGroupData();
void loadGroupData();
void loadAllPosts();
void loadPosts(const std::set<RsGxsMessageId>& msgIds);

View File

@ -520,7 +520,7 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool re
older_versions.insert(meta.mMsgId);
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, meta.mGroupId,meta.mMsgId, true, false,older_versions);
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, mGroup,meta.mMsgId, true, false,older_versions);
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(meta.mPublishTs));
return ;
@ -539,7 +539,7 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool re
}
else
{
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, meta.mGroupId,meta.mMsgId, true, true);
GxsChannelPostItem *item = new GxsChannelPostItem(this, 0, mGroup,meta.mMsgId, true, true);
ui->feedWidget->addFeedItem(item, ROLE_PUBLISH, QDateTime::fromTime_t(meta.mPublishTs));
}
@ -548,6 +548,8 @@ void GxsChannelPostsWidget::createPostItem(const RsGxsChannelPost& post, bool re
#endif
}
void GxsChannelPostsWidget::fillThreadCreatePost(const QVariant &post, bool related, int current, int count)
{
/* show fill progress */
@ -842,6 +844,8 @@ bool GxsChannelPostsWidget::getGroupData(RsGxsGenericGroupData *& data)
if(rsGxsChannels->getChannelsInfo(std::list<RsGxsGroupId>({groupId()}),groups) && groups.size()==1)
{
data = new RsGxsChannelGroup(groups[0]);
mGroup = groups[0]; // make a local copy to pass on to items
return true;
}
else
@ -852,6 +856,7 @@ bool GxsChannelPostsWidget::getGroupData(RsGxsGenericGroupData *& data)
{
insertChannelDetails(distant_group);
data = new RsGxsChannelGroup(distant_group);
mGroup = distant_group; // make a local copy to pass on to items
return true ;
}
}

View File

@ -106,6 +106,7 @@ private:
private:
QAction *mAutoDownloadAction;
RsGxsChannelGroup mGroup;
bool mUseThread;
RsEventsHandlerId_t mEventHandlerId ;