From 83049259f2dd59e4390807ae5b9ac4b1bd1db43d Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 6 May 2016 21:37:17 -0400 Subject: [PATCH] added bullets to show subscription status of circles. Enabled message sync in circles. Changed flags in GxsCirclesDetails to include new subscription flags --- libretroshare/src/retroshare/rsgxscircles.h | 35 +++++------------- libretroshare/src/rsserver/rsinit.cc | 6 +-- libretroshare/src/services/p3gxscircles.cc | 4 +- libretroshare/src/services/p3gxscircles.h | 6 +-- retroshare-gui/src/gui/Identity/IdDialog.cpp | 33 +++++++++++------ .../src/gui/People/CircleWidget.cpp | 2 +- .../src/gui/People/PeopleDialog.cpp | 2 +- .../gui/gxschannels/GxsChannelPostsWidget.cpp | 2 +- retroshare-gui/src/gui/icons.qrc | 1 + .../src/gui/icons/bullet_blue_128.png | Bin 0 -> 9453 bytes 10 files changed, 43 insertions(+), 48 deletions(-) create mode 100644 retroshare-gui/src/gui/icons/bullet_blue_128.png diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 942e0935d..f650db4e6 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -59,6 +59,12 @@ static const uint32_t GXS_CIRCLE_TYPE_LOCAL = 0x0004 ; // not distri static const uint32_t GXS_CIRCLE_TYPE_EXT_SELF = 0x0005 ; // self-restricted. Not used, except at creation time when the circle ID isn't known yet. Set to EXTERNAL afterwards. static const uint32_t GXS_CIRCLE_TYPE_YOUR_EYES_ONLY = 0x0006 ; // distributed to nodes signed by your own PGP key only. +static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST = 0x0001 ;// user is validated by circle admin +static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED = 0x0002 ;// user has subscribed the group +static const uint32_t GXS_EXTERNAL_CIRCLE_FLAGS_ALLOWED = 0x0003 ;// user is allowed. Combines both flags above. + +static const uint32_t GXS_CIRCLE_FLAGS_IS_EXTERNAL = 0x0008 ;// user is allowed + /* Permissions is part of GroupMetaData */ class GxsPermissions @@ -100,36 +106,15 @@ class RsGxsCircleMsg class RsGxsCircleDetails { public: - RsGxsCircleDetails() : mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mIsExternal(true), mAmIAllowed(false) {} + RsGxsCircleDetails() : mCircleType(GXS_CIRCLE_TYPE_EXTERNAL), mAmIAllowed(false) {} RsGxsCircleId mCircleId; std::string mCircleName; uint32_t mCircleType; - bool mIsExternal; - bool mAmIAllowed ; - -#ifdef TO_REMOVE - bool operator ==(const RsGxsCircleDetails& rGxsDetails) { - return ( mCircleId == rGxsDetails.mCircleId - && mCircleName == rGxsDetails.mCircleName - && mCircleType == rGxsDetails.mCircleType - && mIsExternal == rGxsDetails.mIsExternal - && mAllowedGxsIds == rGxsDetails.mAllowedGxsIds - && mAllowedNodes == rGxsDetails.mAllowedNodes - ); - } - - bool operator !=(const RsGxsCircleDetails& rGxsDetails) { - return ( mCircleId != rGxsDetails.mCircleId - || mCircleName != rGxsDetails.mCircleName - || mCircleType != rGxsDetails.mCircleType - || mIsExternal != rGxsDetails.mIsExternal - || mAllowedGxsIds != rGxsDetails.mAllowedGxsIds - || mAllowedNodes != rGxsDetails.mAllowedNodes - ); - } -#endif + uint32_t mSubscribeFlags ; + + bool mAmIAllowed ; std::set mAllowedGxsIds; std::set mAllowedNodes; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index dce5a3c97..352d4578f 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1345,15 +1345,13 @@ int RsServer::StartupRetroShare() mGxsCircles, mGxsCircles->getServiceInfo(), mGxsIdService, mGxsCircles,mGxsIdService, pgpAuxUtils, - true,false); // synchronise group automatic - // don't sync messages at all. + true, // synchronise group automatic + true); // sync messages automatic, since they contain subscription requests. mGxsCircles->setNetworkExchangeService(gxscircles_ns) ; /**** Posted GXS service ****/ - - RsGeneralDataService* posted_ds = new RsDataService(currGxsDir + "/", "posted_db", RS_SERVICE_GXS_TYPE_POSTED, NULL, rsInitConfig->gxs_passwd); diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index 7f441132e..e4f650ff0 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -266,12 +266,14 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails details.mCircleName = data.mCircleName; details.mCircleType = data.mCircleType; - details.mIsExternal = data.mIsExternal; details.mAllowedGxsIds = data.mAllowedGxsIds; details.mAllowedNodes = data.mAllowedNodes; details.mAmIAllowed = data.mAmIAllowed ; + +#warning p3GxsCircles::getCircleDetails(): make this right later when the backend is there + details.mSubscribeFlags = GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST ; return true; } } diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index f421f9598..1edb5a3c6 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -164,12 +164,10 @@ class RsGxsCircleCache class PgpAuxUtils; -class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, - public GxsTokenQueue, public RsTickEvent +class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, public GxsTokenQueue, public RsTickEvent { public: - p3GxsCircles(RsGeneralDataService* gds, RsNetworkExchangeService* nes, - p3IdService *identities, PgpAuxUtils *pgpUtils); + p3GxsCircles(RsGeneralDataService* gds, RsNetworkExchangeService* nes, p3IdService *identities, PgpAuxUtils *pgpUtils); virtual RsServiceInfo getServiceInfo(); diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 7053d5abd..54d7374dd 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -407,7 +407,6 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token) rsGxsCircles->getCircleDetails(RsGxsCircleId(vit->mGroupId), details) ; bool should_re_add = true ; - bool subscribed = vit->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ; bool am_I_in_circle = details.mAmIAllowed ; QTreeWidgetItem *item = NULL ; @@ -495,16 +494,28 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token) item->setFont(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS,font) ; } - if (subscribed) - { - item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_green_128.png")) ; - item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("This circle is \"subscribed\" i.e. advertised to neighbor nodes")) ; - } - else - { - item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_yellow_128.png")) ; - item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,"") ; - } + switch(details.mSubscribeFlags) + { + case GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED: + item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_yellow_128.png")) ; + item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("Your request to be in this group is still pending. You need to wait the administrator to validate it.")) ; + break ; + + case GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST: + item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_blue_128.png")) ; + item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("You are invited to this group by the administrator. Right click to join the group.")) ; + break ; + + case GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST | GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED: + item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(":icons/bullet_green_128.png")) ; + item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,tr("You are a member of this group.")) ; + break ; + + default: + item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon()) ; + item->setToolTip(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,"") ; + break ; + } } } diff --git a/retroshare-gui/src/gui/People/CircleWidget.cpp b/retroshare-gui/src/gui/People/CircleWidget.cpp index 5ca84269d..2681a0ab1 100644 --- a/retroshare-gui/src/gui/People/CircleWidget.cpp +++ b/retroshare-gui/src/gui/People/CircleWidget.cpp @@ -43,7 +43,7 @@ static bool same_RsGxsCircleDetails(const RsGxsCircleDetails& d1,const RsGxsCirc return ( d1.mCircleId == d2.mCircleId && d1.mCircleName == d2.mCircleName && d1.mCircleType == d2.mCircleType - && d1.mIsExternal == d2.mIsExternal + && d1.mSubscribeFlags == d2.mSubscribeFlags && d1.mAllowedGxsIds== d2.mAllowedGxsIds && d1.mAllowedNodes == d2.mAllowedNodes ); diff --git a/retroshare-gui/src/gui/People/PeopleDialog.cpp b/retroshare-gui/src/gui/People/PeopleDialog.cpp index 3990087fb..842627338 100644 --- a/retroshare-gui/src/gui/People/PeopleDialog.cpp +++ b/retroshare-gui/src/gui/People/PeopleDialog.cpp @@ -286,7 +286,7 @@ void PeopleDialog::insertCircles(uint32_t token) continue ; }//if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(git->mGroupId), details)) - if (!details.mIsExternal){ + if (details.mCircleType != GXS_CIRCLE_TYPE_EXTERNAL){ std::map::iterator itFound; if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end()) { std::cerr << "PeopleDialog::insertExtCircles() add new Internal GroupId: " << gsItem.mGroupId; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp index 648de299e..dd5c39b50 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp @@ -288,7 +288,7 @@ void GxsChannelPostsWidget::insertChannelDetails(const RsGxsChannelGroup &group) distrib_string = tr("Restricted to members of circle ")+QString::fromStdString(group.mMeta.mCircleId.toStdString()) ; } break ; - case GXS_CIRCLE_TYPE_YOUREYESONLY: distrib_string = tr("Your eyes only"); + case GXS_CIRCLE_TYPE_YOUR_EYES_ONLY: distrib_string = tr("Your eyes only"); break ; case GXS_CIRCLE_TYPE_LOCAL: distrib_string = tr("You and your friend nodes"); break ; diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index 1c5d42952..fe073ca1b 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -10,6 +10,7 @@ icons/blank_green_128.png icons/browsable_blue_128.png icons/browsable_green_128.png + icons/bullet_blue_128.png icons/bullet_green_128.png icons/bullet_grey_128.png icons/bullet_red_128.png diff --git a/retroshare-gui/src/gui/icons/bullet_blue_128.png b/retroshare-gui/src/gui/icons/bullet_blue_128.png new file mode 100644 index 0000000000000000000000000000000000000000..aa03d3041dcdf161548f3dfabff674792c990449 GIT binary patch literal 9453 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 literal 0 HcmV?d00001