diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp index 9155d6761..091dbaeb2 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.cpp @@ -263,6 +263,10 @@ void BoardPostDisplayWidgetBase::baseSetup() //frame_comment->show(); commentButton()->show(); + feedFrame()->setProperty("pinned", mDisplayFlags & SHOW_PINNED); + feedFrame()->style()->unpolish(feedFrame()); + feedFrame()->style()->polish(feedFrame()); + setCommentsSize(mPost.mComments); setReadStatus(IS_MSG_NEW(mPost.mMeta.mMsgStatus), IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) || IS_MSG_NEW(mPost.mMeta.mMsgStatus)); diff --git a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h index 5c10af55d..bf487074b 100644 --- a/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h +++ b/retroshare-gui/src/gui/Posted/BoardPostDisplayWidget.h @@ -50,6 +50,7 @@ public: SHOW_NONE = 0x00, SHOW_COMMENTS = 0x01, SHOW_NOTES = 0x02, + SHOW_PINNED = 0x04, }; enum DisplayMode: uint8_t { diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 2c0227cf1..9d065e218 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -186,16 +186,24 @@ void PostedCreatePostDialog::createPost() return; } - RsThread::async([this,post]() + RsThread::async([this,post]() { RsGxsMessageId post_id; + std::string error_message; - bool res = rsPosted->createPost(post,post_id); + bool res = rsPosted->createPostV2(mGrpId, + std::string(ui->titleEdit->text().toUtf8()), + RsUrl(std::string(ui->linkEdit->text().toUtf8())), + std::string(ui->RichTextEditWidget->toHtml().toUtf8()), + post.mMeta.mAuthorId, + post.mImage, + post_id, + error_message); - RsQThreadUtils::postToObject( [res,this]() + RsQThreadUtils::postToObject( [res,error_message,this]() { if(!res) - QMessageBox::information(nullptr,tr("Error while creating post"),tr("An error occurred while creating the post.")); + QMessageBox::information(nullptr,tr("Error while creating post"),tr("An error occurred while creating the post.") + " " + QString::fromStdString(error_message)); accept(); }, this ); diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp index c5ed31892..5cecb25aa 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.cpp @@ -198,6 +198,9 @@ uint8_t PostedPostDelegate::displayFlags(const RsGxsMessageId &id) const if(mShowCommentItems.find(id) != mShowCommentItems.end()) flags |= BoardPostDisplayWidget_compact::SHOW_COMMENTS; + if(mPostListWidget && mPostListWidget->groupData().mPinnedPosts.ids.find(id) != mPostListWidget->groupData().mPinnedPosts.ids.end()) + flags |= BoardPostDisplayWidget_compact::SHOW_PINNED; + return flags; } @@ -366,12 +369,15 @@ void PostedListWidgetWithModel::postContextMenu(const QPoint& point) menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople()))->setData(index); -#ifdef TODO - // This feature is not implemented yet in libretroshare. - if(IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags)) - menu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/edit_16.png"), tr("Edit"), this, SLOT(editPost())); -#endif + { + bool is_pinned = mGroup.mPinnedPosts.ids.find(post.mMeta.mMsgId) != mGroup.mPinnedPosts.ids.end(); + + if(is_pinned) + menu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/pin32.png"), tr("Unpin post"), this, SLOT(unpinPost()))->setData(index); + else + menu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/pin32.png"), tr("Pin post"), this, SLOT(pinPost()))->setData(index); + } menu.exec(QCursor::pos()); } @@ -1011,6 +1017,48 @@ void PostedListWidgetWithModel::voteMsg(RsGxsGrpMsgIdPair msg,bool up_or_down) updateDisplay(true); } +void PostedListWidgetWithModel::pinPost() +{ + QModelIndex index = qobject_cast(QObject::sender())->data().toModelIndex(); + + if(!index.isValid()) + return; + + RsPostedPost post = index.data(Qt::UserRole).value(); + + if(post.mMeta.mMsgId.isNull()) + return; + + RsGxsGroupId grpId = groupId(); + RsGxsMessageId msgId = post.mMeta.mMsgId; + + RsThread::async([grpId, msgId]() + { + rsPosted->pinPost(grpId, msgId); + }); +} + +void PostedListWidgetWithModel::unpinPost() +{ + QModelIndex index = qobject_cast(QObject::sender())->data().toModelIndex(); + + if(!index.isValid()) + return; + + RsPostedPost post = index.data(Qt::UserRole).value(); + + if(post.mMeta.mMsgId.isNull()) + return; + + RsGxsGroupId grpId = groupId(); + RsGxsMessageId msgId = post.mMeta.mMsgId; + + RsThread::async([grpId, msgId]() + { + rsPosted->unpinPost(grpId, msgId); + }); +} + void PostedListWidgetWithModel::handleViewGallery(const RsGxsMessageId& startMsgId) { std::cerr << "Gallery slot triggered for msg:"; diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h index 0432820a3..ba3c699bf 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.h @@ -101,6 +101,7 @@ public: void updateDisplay(bool complete) ; void forceRedraw(); // does not re-load the data, but makes sure the underlying model triggers a full redraw, recomputes indexes, etc. void redraw(); // does not re-load the data, but makes sure the underlying model triggers a full redraw, recomputes only sizes. + const RsPostedGroup& groupData() const { return mGroup; } #ifdef TODO /* FeedHolder */ @@ -153,6 +154,8 @@ private slots: void filterItems(QString s); void updateShowLabel(); void handleViewGallery(const RsGxsMessageId& startMsgId); + void pinPost(); + void unpinPost(); public slots: void handlePostsTreeSizeChange(QSize size); diff --git a/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp b/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp index e827a2fbb..d6c14aaae 100644 --- a/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp +++ b/retroshare-gui/src/gui/Posted/PostedPostsModel.cpp @@ -74,6 +74,36 @@ void RsPostedPostsModel::handleEvent_main_thread(std::shared_ptr switch(e->mPostedEventCode) { + case RsPostedEventCode::UPDATED_POSTED_GROUP: + { + if(E.mPostedGroupId == mPostedGroup.mMeta.mGroupId) + RsThread::async([this, E]() + { + std::vector groups; + if(!rsPosted->getBoardsInfo({E.mPostedGroupId}, groups) || groups.empty()) + return; + + RsPostedGroup group = groups[0]; + + auto *posts = new std::vector(); + auto *comments = new std::vector(); + auto *votes = new std::vector(); + + if(!rsPosted->getBoardAllContent(E.mPostedGroupId, *posts, *comments, *votes)) + { + delete posts; delete comments; delete votes; + return; + } + + RsQThreadUtils::postToObject([group, posts, comments, votes, this]() + { + setPosts(group, *posts); + delete posts; delete comments; delete votes; + }, this); + }); + } + break; + case RsPostedEventCode::UPDATED_MESSAGE: case RsPostedEventCode::READ_STATUS_CHANGED: case RsPostedEventCode::MESSAGE_VOTES_UPDATED: @@ -480,10 +510,16 @@ class PostSorter { public: - PostSorter(RsPostedPostsModel::SortingStrategy s) : mSortingStrategy(s) {} + PostSorter(RsPostedPostsModel::SortingStrategy s, const RsTlvGxsMsgIdSet& pinnedPosts) : mSortingStrategy(s), mPinnedPosts(pinnedPosts) {} bool operator()(const RsPostedPost& p1,const RsPostedPost& p2) const { + bool p1_pinned = mPinnedPosts.ids.find(p1.mMeta.mMsgId) != mPinnedPosts.ids.end(); + bool p2_pinned = mPinnedPosts.ids.find(p2.mMeta.mMsgId) != mPinnedPosts.ids.end(); + + if(p1_pinned != p2_pinned) + return p1_pinned; + switch(mSortingStrategy) { default: @@ -495,6 +531,7 @@ public: private: RsPostedPostsModel::SortingStrategy mSortingStrategy; + const RsTlvGxsMsgIdSet& mPinnedPosts; }; Qt::ItemFlags RsPostedPostsModel::flags(const QModelIndex& index) const @@ -510,7 +547,7 @@ void RsPostedPostsModel::setSortingStrategy(RsPostedPostsModel::SortingStrategy preMods(); mSortingStrategy = s; - std::sort(mPosts.begin(),mPosts.end(), PostSorter(s)); + std::sort(mPosts.begin(),mPosts.end(), PostSorter(s, mPostedGroup.mPinnedPosts)); postMods(); } @@ -564,7 +601,7 @@ void RsPostedPostsModel::setPosts(const RsPostedGroup& group, std::vector