diff --git a/libretroshare/src/chat/p3chatservice.cc b/libretroshare/src/chat/p3chatservice.cc index 67ca8f210..2f5df22fe 100644 --- a/libretroshare/src/chat/p3chatservice.cc +++ b/libretroshare/src/chat/p3chatservice.cc @@ -855,12 +855,8 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *& ci) { #ifdef RS_DIRECT_CHAT /* notify public chat message */ - RsServer::notify()->AddPopupMessage( - RS_POPUP_GROUPCHAT, - ci->PeerId().toStdString(), "", message ); - RsServer::notify()->AddFeedItem( - RS_FEED_ITEM_CHAT_NEW, - ci->PeerId().toStdString(), message, "" ); + RsServer::notify()->AddPopupMessage( RS_POPUP_GROUPCHAT, ci->PeerId().toStdString(), "", message ); + //RsServer::notify()->AddFeedItem( RS_FEED_ITEM_CHAT_NEW, ci->PeerId().toStdString(), message, "" ); #else // def RS_DIRECT_CHAT /* Ignore deprecated direct node broadcast chat messages */ return false; diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 017c3bbb2..7337fc627 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1262,8 +1262,10 @@ int pqissl::accept_locked( SSL *ssl, int fd, if (rsPeers->servicePermissionFlags(PeerId()) & RS_NODE_PERM_REQUIRE_WL) checking_flags |= RSBANLIST_CHECKING_FLAGS_WHITELIST; - if(rsBanList && !rsBanList->isAddressAccepted( - foreign_addr, checking_flags, check_result )) + if( RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) != PeerId()) + std::cerr << "(EE) pqissl::accept_locked(): PeerId() is " << PeerId() << " but certificate ID is " << RsX509Cert::getCertSslId(*SSL_get_peer_certificate(ssl)) << std::endl; + + if(rsBanList && !rsBanList->isAddressAccepted( foreign_addr, checking_flags, check_result )) { RsErr() << __PRETTY_FUNCTION__ << " Refusing incoming SSL connection from blacklisted " @@ -1273,11 +1275,19 @@ int pqissl::accept_locked( SSL *ssl, int fd, << std::endl; print_stacktrace(); - RsServer::notify()->AddFeedItem( - RS_FEED_ITEM_SEC_IP_BLACKLISTED, - PeerId().toStdString(), - sockaddr_storage_iptostring(foreign_addr), "", "", - check_result); + if(rsEvents) + { + auto ev = std::make_shared(); + + X509 *x509 = SSL_get_peer_certificate(ssl) ; + + ev->mSslId = RsX509Cert::getCertSslId(*x509); + ev->mLocator = RsUrl(foreign_addr); + ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::IP_IS_BLACKLISTED; + + rsEvents->postEvent(ev); + } + reset_locked(); return failure; } diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index 123cfaf3e..d03d3ab32 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -70,6 +70,9 @@ enum class RsEventType : uint32_t /// @see RsMailStatusEvent MAIL_STATUS_CHANGE = 7, + /// @see RsGxsCircleEvent + GXS_CIRCLES = 8, + MAX /// Used to detect invalid event type passed }; diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 407871d80..f9262b3a8 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -123,7 +123,7 @@ struct RsGxsCircleDetails : RsSerializable { RsGxsCircleDetails() : mCircleType(static_cast(RsGxsCircleType::EXTERNAL)), - mAmIAllowed(false) {} + mAmIAllowed(false),mAmIAdmin(false) {} ~RsGxsCircleDetails() override; RsGxsCircleId mCircleId; @@ -136,6 +136,9 @@ struct RsGxsCircleDetails : RsSerializable * list & subscribed list). */ bool mAmIAllowed; + /// true when we're an administrator of the circle group, meaning that we can add/remove members from the invitee list. + bool mAmIAdmin; + /// This crosses admin list and subscribed list std::set mAllowedGxsIds; std::set mAllowedNodes; @@ -152,12 +155,41 @@ struct RsGxsCircleDetails : RsSerializable RS_SERIAL_PROCESS(mCircleType); RS_SERIAL_PROCESS(mRestrictedCircleId); RS_SERIAL_PROCESS(mAmIAllowed); + RS_SERIAL_PROCESS(mAmIAdmin); RS_SERIAL_PROCESS(mAllowedGxsIds); RS_SERIAL_PROCESS(mAllowedNodes); RS_SERIAL_PROCESS(mSubscriptionFlags); } }; +struct RsGxsCircleEvent: RsEvent +{ + RsGxsCircleEvent() + : RsEvent(RsEventType::GXS_CIRCLES), mCircleEventType(UNKNOWN) {} + + enum CircleEventType: uint8_t { + UNKNOWN = 0x00, + CIRCLE_MEMBERSHIP_REQUEST = 0x01, // mCircleId contains the circle id and mGxsId is the id requesting membership + CIRCLE_MEMBERSHIP_INVITE = 0x02, // mCircleId is the circle that invites me, and mGxsId is my own Id that is invited + CIRCLE_MEMBERSHIP_LEAVE = 0x03, // mCircleId contains the circle id and mGxsId is the id dropping membership + CIRCLE_MEMBERSHIP_JOIN = 0x04, // mCircleId contains the circle id and mGxsId is the id of the new member + CIRCLE_MEMBERSHIP_REVOQUED= 0x05, // mCircleId contains the circle id and mGxsId is the id that was revoqued by admin + }; + + CircleEventType mCircleEventType; + RsGxsCircleId mCircleId; + RsGxsId mGxsId; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mCircleEventType); + RS_SERIAL_PROCESS(mCircleId); + RS_SERIAL_PROCESS(mGxsId); + } +}; + class RsGxsCircles: public RsGxsIfaceHelper { public: @@ -243,6 +275,17 @@ public: */ virtual bool getCircleRequests( const RsGxsGroupId& circleId, std::vector& requests ) = 0; + /** + * @brief Get specific circle request + * @jsonapi{development} + * @param[in] circleId id of the circle of which the requests are requested + * @param[in] msgId id of the request + * @param[out] msg storage for the circle request + * @return false if something failed, true otherwhise + */ + virtual bool getCircleRequest(const RsGxsGroupId& circleId, + const RsGxsMessageId& msgId, + RsGxsCircleMsg& msg) =0; /** * @brief Invite identities to circle diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index 6cb55dd66..d69357cdb 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -115,8 +115,11 @@ const uint32_t RS_FEED_ITEM_CHAT_NEW = RS_FEED_TYPE_CHAT | 0x0001; const uint32_t RS_FEED_ITEM_MESSAGE = RS_FEED_TYPE_MSG | 0x0001; const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001; -const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001; -const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002; +const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001; +const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002; +const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003; +const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004; +const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED = RS_FEED_TYPE_CIRCLE | 0x0005; const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001; diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index eed23313d..658af5892 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -305,6 +305,32 @@ bool p3GxsCircles::getCircleRequests( const RsGxsGroupId& circleId, return getMsgData(token, requests); } +bool p3GxsCircles::getCircleRequest(const RsGxsGroupId& circleId,const RsGxsMessageId& msgId,RsGxsCircleMsg& msg) +{ + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + + std::set contentsIds; + contentsIds.insert(msgId); + + GxsMsgReq msgIds; + msgIds[circleId] = contentsIds; + + uint32_t token; + if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE ) + return false; + + std::vector msgs; + + if(getMsgData(token, msgs) && msgs.size() == 1) + { + msg = msgs.front(); + return true; + } + else + return false; +} + bool p3GxsCircles::inviteIdsToCircle( const std::set& identities, const RsGxsCircleId& circleId ) { @@ -372,6 +398,7 @@ void p3GxsCircles::service_tick() return; } + void p3GxsCircles::notifyChanges(std::vector &changes) { #ifdef DEBUG_CIRCLES @@ -397,13 +424,35 @@ void p3GxsCircles::notifyChanges(std::vector &changes) #ifdef DEBUG_CIRCLES std::cerr << " Msgs for Group: " << mit->first << std::endl; #endif - force_cache_reload(RsGxsCircleId(mit->first)); + RsGxsCircleId circle_id(mit->first); - if (notify && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) ) + force_cache_reload(circle_id); + + RsGxsCircleDetails details; + getCircleDetails(circle_id,details); + + if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) ) for (auto msgIdIt(mit->second.begin()), end(mit->second.end()); msgIdIt != end; ++msgIdIt) { - const RsGxsMessageId& msgId = *msgIdIt; - notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_MEMB_REQ,RsGxsCircleId(mit->first).toStdString(),msgId.toStdString()); + // @Gio: should this be async? + RsGxsCircleMsg msg; + getCircleRequest(RsGxsGroupId(circle_id),*msgIdIt,msg); + + // notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_MEMB_REQ,RsGxsCircleId(mit->first).toStdString(),msgId.toStdString()); + + auto ev = std::make_shared(); + + ev->mCircleId = circle_id; + ev->mGxsId = msg.mMeta.mAuthorId; + + if (msg.stuff == "SUBSCRIPTION_REQUEST_UNSUBSCRIBE") + ev->mCircleEventType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_LEAVE; + else if(details.mAllowedGxsIds.find(msg.mMeta.mAuthorId) != details.mAllowedGxsIds.end()) + ev->mCircleEventType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_JOIN; + else + ev->mCircleEventType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_REQUEST; + + rsEvents->sendEvent(ev); } } @@ -436,15 +485,60 @@ void p3GxsCircles::notifyChanges(std::vector &changes) } if(groupChange) + { + std::list own_ids; + rsIdentity->getOwnIds(own_ids); + for(std::list::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git) { #ifdef DEBUG_CIRCLES std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl; #endif - force_cache_reload(RsGxsCircleId(*git)) ; - if (notify && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) ) - notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_INVIT_REC,RsGxsCircleId(*git).toStdString(),""); - } + +#ifdef TODO + // This code will not work: we would like to detect changes in the circle data that reflects the fact that one of the + // owned GXS ids is invited. But there's no way to compare the old circle data to the new if cache has to be updated. + // For this we need to add the old metadata and group data in the RsGxsGroupChange structure and account for it. + + if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) ) + { + RsGxsCircleId circle_id(*git); + force_cache_reload(circle_id); + + RsGxsCircleDetails details; + getCircleDetails(circle_id,details); + + // We check that the change corresponds to one of our own ids. Since we do not know what the change is, we notify + // for whatever is different from what is currently known. Other ids, that get invited only trigger a notification when the + // ID also accepts the invitation, so it becomes a member of the circle. + + for(auto own_id: own_ids) + { + auto it = details.mSubscriptionFlags.find(own_id); + + if(it == details.mSubscriptionFlags.end()) + continue; + + bool invited ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ); + bool subscrb ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED ); + + if(std::find(details.mAllowedGxsIds.begin(),details.mAllowedGxsIds.end(),id) != details.mAllowedGxsIds.end() && !me_in_circle) + { + auto ev = std::make_shared(); + + ev->mType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_INVITE; + ev->mCircleId = circle_id; + ev->mGxsId = ; + + rsEvents->sendEvent(ev); + } + } + + //notify->AddFeedItem(RS_FEED_ITEM_CIRCLE_INVIT_REC,RsGxsCircleId(*git).toStdString(),""); + } +#endif + } + } } RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements @@ -479,6 +573,7 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails details.mSubscriptionFlags.clear(); details.mAllowedGxsIds.clear(); details.mAmIAllowed = false ; + details.mAmIAdmin = bool(data.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN); for(std::map::const_iterator it(data.mMembershipStatus.begin());it!=data.mMembershipStatus.end();++it) { @@ -789,7 +884,7 @@ RsGxsCircleCache::RsGxsCircleCache() mUpdateTime = 0; mGroupStatus = 0; mGroupSubscribeFlags = 0; - mLastUpdatedMembershipTS = 0 ; + mLastUpdatedMembershipTS = 0 ; return; } diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index 9eb6c15bb..1b25fcf27 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -207,6 +207,11 @@ virtual RsServiceInfo getServiceInfo(); bool inviteIdsToCircle( const std::set& identities, const RsGxsCircleId& circleId ) override; + /// @see RsGxsCircles + bool getCircleRequest(const RsGxsGroupId& circleId, + const RsGxsMessageId& msgId, + RsGxsCircleMsg& msg) override; + virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details); virtual bool getCircleExternalIdList(std::list &circleIds); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index b4f582db5..942262b8d 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -82,7 +82,6 @@ NewsFeed::NewsFeed(QWidget *parent) : ui->setupUi(this); mTokenQueueChannel = NULL; - mTokenQueueCircle = NULL; mTokenQueueForum = NULL; mTokenQueuePosted = NULL; @@ -139,9 +138,6 @@ NewsFeed::~NewsFeed() if (mTokenQueueChannel) { delete(mTokenQueueChannel); } - if (mTokenQueueCircle) { - delete(mTokenQueueCircle); - } if (mTokenQueueForum) { delete(mTokenQueueForum); } @@ -198,10 +194,61 @@ void NewsFeed::handleEvent_main_thread(std::shared_ptr event) if(event->mType == RsEventType::AUTHSSL_CONNECTION_AUTENTICATION && (flags & RS_FEED_TYPE_SECURITY)) handleSecurityEvent(event); - if(event->mType == RsEventType::PEER_CONNECTION && (flags & RS_FEED_TYPE_PEER)) + if(event->mType == RsEventType::PEER_CONNECTION && (flags & RS_FEED_TYPE_PEER)) handleConnectionEvent(event); + + if(event->mType == RsEventType::GXS_CIRCLES && (flags & RS_FEED_TYPE_CIRCLE)) + handleCircleEvent(event); } +void NewsFeed::handleCircleEvent(std::shared_ptr event) +{ + const RsGxsCircleEvent *pe = dynamic_cast(event.get()); + if(!pe) + return; + + RsGxsCircleDetails details; + + if(!rsGxsCircles->getCircleDetails(pe->mCircleId,details)) + { + std::cerr << "(EE) Cannot get information about circle " << pe->mCircleId << ". Not in cache?" << std::endl; + return; + } + + // Check if the circle is one of which we belong to. If so, then notify in the GUI about other members leaving/subscribing + + if(details.mAmIAllowed || details.mAmIAdmin) + { + switch(pe->mCircleEventType) + { + case RsGxsCircleEvent::CIRCLE_MEMBERSHIP_REQUEST: // only show membership requests if we're an admin of that circle + if(details.mAmIAdmin) + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ),true); + break; + + case RsGxsCircleEvent::CIRCLE_MEMBERSHIP_JOIN: + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true); + break; + + case RsGxsCircleEvent::CIRCLE_MEMBERSHIP_LEAVE: + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true); + break; + + case RsGxsCircleEvent::CIRCLE_MEMBERSHIP_INVITE: + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVIT_REC),true); + break; + + case RsGxsCircleEvent::CIRCLE_MEMBERSHIP_REVOQUED: + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED),true); + break; + + default: + break; + } + } +} + + void NewsFeed::handleConnectionEvent(std::shared_ptr event) { const RsConnectionEvent *pe = dynamic_cast(event.get()); @@ -422,51 +469,6 @@ void NewsFeed::updateDisplay() addFeedItemFilesNew(fi); break; - case RS_FEED_ITEM_CIRCLE_MEMB_REQ: - if (flags & RS_FEED_TYPE_CIRCLE) - { - if (!mTokenQueueCircle) { - mTokenQueueCircle = new TokenQueue(rsGxsCircles->getTokenService(), instance); - } - - RsGxsGroupId grpId(fi.mId1); - RsGxsMessageId msgId(fi.mId2); - if (!grpId.isNull() && !msgId.isNull()) { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - - GxsMsgReq msgIds; - std::set &vect_msgIds = msgIds[grpId]; - vect_msgIds.insert(msgId); - - uint32_t token; - mTokenQueueCircle->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, TOKEN_TYPE_MESSAGE); - } - } - // addFeedItemCircleMembReq(fi); - break; - case RS_FEED_ITEM_CIRCLE_INVIT_REC: - if (flags & RS_FEED_TYPE_CIRCLE) - { - if (!mTokenQueueCircle) { - mTokenQueueCircle = new TokenQueue(rsGxsCircles->getTokenService(), instance); - } - - RsGxsGroupId grpId(fi.mId1); - if (!grpId.isNull()) { - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - - std::list grpIds; - grpIds.push_back(grpId); - - uint32_t token; - mTokenQueueCircle->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_GROUP); - } - } - // addFeedItemCircleInvitRec(fi); - break; - default: std::cerr << "(EE) Unknown type " << std::hex << fi.mType << std::dec << " in news feed." << std::endl; break; @@ -658,6 +660,7 @@ void NewsFeed::testFeeds(uint notifyFlags) #endif } +#ifdef TO_REMOVE void NewsFeed::loadCircleGroup(const uint32_t &token) { std::vector groups; @@ -694,41 +697,7 @@ void NewsFeed::loadCircleGroup(const uint32_t &token) } } } - -void NewsFeed::loadCircleMessage(const uint32_t &token) -{ - std::vector msgs; - if (!rsGxsCircles->getMsgData(token, msgs)) { - std::cerr << "NewsFeed::loadCircleMessage() ERROR getting data"; - std::cerr << std::endl; - return; - } - - std::list own_identities; - rsIdentity->getOwnIds(own_identities); - - std::vector::iterator msgIt; - for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) { - RsGxsCircleMsg msg = *(msgIt); - RsGxsCircleDetails details; - if(rsGxsCircles->getCircleDetails(RsGxsCircleId(msg.mMeta.mGroupId),details)) { - //for(std::list::const_iterator it(own_identities.begin());it!=own_identities.end();++it) { - // std::map::const_iterator vit = details.mSubscriptionFlags.find(*it); - // if (vit != details.mSubscriptionFlags.end()) { - RsFeedItem fi; - fi.mId1 = msgIt->mMeta.mGroupId.toStdString(); - fi.mId2 = msgIt->mMeta.mAuthorId.toStdString(); - - if (msgIt->stuff == "SUBSCRIPTION_REQUEST_UNSUBSCRIBE") - instance->remFeedItemCircleMembReq(fi); - else - instance->addFeedItemCircleMembReq(fi); - - //} - //} - } - } -} +#endif void NewsFeed::loadChannelGroup(const uint32_t &token) { @@ -1025,6 +994,7 @@ void NewsFeed::loadRequest(const TokenQueue *queue, const TokenRequest &req) } } +#ifdef TO_REMOVE if (queue == mTokenQueueCircle) { switch (req.mUserType) { case TOKEN_TYPE_GROUP: @@ -1041,6 +1011,7 @@ void NewsFeed::loadRequest(const TokenQueue *queue, const TokenRequest &req) break; } } +#endif if (queue == mTokenQueueForum) { switch (req.mUserType) { @@ -1562,6 +1533,7 @@ void NewsFeed::addFeedItemFilesNew(const RsFeedItem &/*fi*/) #endif } +#ifdef TO_REMOVE void NewsFeed::addFeedItemCircleMembReq(const RsFeedItem &fi) { RsGxsCircleId circleId(fi.mId1); @@ -1621,6 +1593,7 @@ void NewsFeed::addFeedItemCircleInvitRec(const RsFeedItem &fi) std::cerr << "NewsFeed::addFeedItemCircleInvitRec()" << std::endl; #endif } +#endif /* FeedHolder Functions (for FeedItem functionality) */ QScrollArea *NewsFeed::getScrollArea() diff --git a/retroshare-gui/src/gui/NewsFeed.h b/retroshare-gui/src/gui/NewsFeed.h index 52164330b..08cde3660 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -102,9 +102,11 @@ private slots: void sendNewsFeedChanged(); private: + void handleEvent_main_thread(std::shared_ptr event); + void handleSecurityEvent(std::shared_ptr event); void handleConnectionEvent(std::shared_ptr event); - void handleEvent_main_thread(std::shared_ptr event); + void handleCircleEvent(std::shared_ptr event); void addFeedItem(FeedItem *item); void addFeedItemIfUnique(FeedItem *item, bool replace); @@ -160,9 +162,6 @@ private: virtual void loadPostedGroup(const uint32_t &token); virtual void loadPostedMessage(const uint32_t &token); - virtual void loadCircleGroup(const uint32_t &token); - virtual void loadCircleMessage(const uint32_t &token); - private: TokenQueue *mTokenQueueChannel; TokenQueue *mTokenQueueCircle; diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp b/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp index 8cd67d28f..582d1be47 100644 --- a/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp @@ -91,12 +91,18 @@ void GxsCircleItem::setup() ui->iconLabel->setPixmap(pixmap); ui->gxsIdLabel->setId(mGxsId); - - - ui->acceptButton->setToolTip(tr("Grant membership request")); - ui->revokeButton->setToolTip(tr("Revoke membership request")); - connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(grantCircleMembership())); - connect(ui->revokeButton, SIGNAL(clicked()), this, SLOT(revokeCircleMembership())); + if(circleDetails.mAmIAdmin) + { + ui->acceptButton->setToolTip(tr("Grant membership request")); + ui->revokeButton->setToolTip(tr("Revoke membership request")); + connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(grantCircleMembership())); + connect(ui->revokeButton, SIGNAL(clicked()), this, SLOT(revokeCircleMembership())); + } + else + { + ui->acceptButton->setEnabled(false); + ui->revokeButton->setEnabled(false); + } } else if (mType == RS_FEED_ITEM_CIRCLE_INVIT_REC) { @@ -110,7 +116,43 @@ void GxsCircleItem::setup() connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(acceptCircleSubscription())); ui->revokeButton->setHidden(true); } + else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_LEAVE) + { + ui->titleLabel->setText(idName + tr(" has left this circle you belong to.")); + ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str())); + ui->gxsIdLabel->setText(idName); + ui->iconLabel->setPixmap(pixmap); + ui->gxsIdLabel->setId(mGxsId); + ui->acceptButton->setHidden(true); + ui->revokeButton->setHidden(true); + } + else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_JOIN) + { + ui->titleLabel->setText(idName + tr(" has join this circle you also belong to.")); + ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str())); + ui->gxsIdLabel->setText(idName); + ui->iconLabel->setPixmap(pixmap); + ui->gxsIdLabel->setId(mGxsId); + + ui->acceptButton->setHidden(true); + ui->revokeButton->setHidden(true); + } + else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED) + { + if(rsIdentity->isOwnId(mGxsId)) + ui->titleLabel->setText(tr("Your identity %1 has been revoqued from this circle.").arg(idName)); + else + ui->titleLabel->setText(tr("Identity %1 has been revoqued from this circle you belong to.").arg(idName)); + + ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str())); + ui->gxsIdLabel->setText(idName); + ui->iconLabel->setPixmap(pixmap); + ui->gxsIdLabel->setId(mGxsId); + + ui->acceptButton->setHidden(true); + ui->revokeButton->setHidden(true); + } } else {