diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index e05ea4fc0..96a812b51 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -3445,6 +3445,10 @@ void RsGenExchange::removeDeleteExistingMessages( std::list& msgs, Gx } } +DistantSearchGroupStatus RsGenExchange::getDistantSearchStatus(const RsGxsGroupId& group_id) +{ + return mNetService->getDistantSearchStatus(group_id) ; +} void RsGenExchange::turtleGroupRequest(const RsGxsGroupId& group_id) { mNetService->turtleGroupRequest(group_id) ; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 5b18e5663..a72562391 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -222,7 +222,7 @@ public: * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) * @return false if could not redeem token */ - bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult& msgIds); + bool getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult& msgIds)override; /*! @@ -231,14 +231,14 @@ public: * @param groupInfo * @return false if could not redeem token */ - bool getGroupMeta(const uint32_t &token, std::list& groupInfo); + bool getGroupMeta(const uint32_t &token, std::list& groupInfo)override; /*! * retrieves message meta data associated to a request token * @param token token to be redeemed * @param msgInfo the meta data to be retrieved for token store here */ - bool getMsgMeta(const uint32_t &token, GxsMsgMetaMap &msgInfo); + bool getMsgMeta(const uint32_t &token, GxsMsgMetaMap &msgInfo)override; /*! * Retrieve msg meta for a given token for message related info @@ -246,7 +246,7 @@ public: * @param msgIds a map of RsGxsGrpMsgIdPair -> msgList (vector) * @return false if could not redeem token */ - bool getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap& msgMeta); + bool getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap& msgMeta)override; /*! * Retrieves the meta data of a newly created group. The meta is kept in cache for the current session. @@ -294,7 +294,7 @@ public: */ virtual bool acceptNewMessage(const RsGxsMsgMetaData *msgMeta, uint32_t size) ; - bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe); + bool subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe) override; /*! * Gets service statistic for a given services @@ -302,7 +302,7 @@ public: * @param stats the status * @return true if token exists false otherwise */ - bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats); + bool getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats) override; /*! * Get group statistic @@ -310,7 +310,7 @@ public: * @param stats the stats associated to token requ * @return true if token is false otherwise */ - bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats); + bool getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats) override; /*! * \brief turtleGroupRequest @@ -321,7 +321,14 @@ public: void turtleGroupRequest(const RsGxsGroupId& group_id); void turtleSearchRequest(const std::string& match_string); - /** + /*! + * \brief getDistantSearchStatus + * Returns the status of ongoing search: unknown (probably not even searched), known as a search result, + * data request ongoing and data available + */ + DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) ; + + /** * @brief Search local groups. Blocking API. * @param matchString string to look for in the search * @param results storage for results @@ -720,21 +727,21 @@ public: * \brief getDefaultStoragePeriod. All times in seconds. * \return */ - virtual uint32_t getDefaultStoragePeriod() { return mNetService->getDefaultKeepAge() ; } + virtual uint32_t getDefaultStoragePeriod() override{ return mNetService->getDefaultKeepAge() ; } - virtual uint32_t getStoragePeriod(const RsGxsGroupId& grpId) ; - virtual void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) ; + virtual uint32_t getStoragePeriod(const RsGxsGroupId& grpId) override; + virtual void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) override; - virtual uint32_t getDefaultSyncPeriod(); - virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) ; - virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) ; - virtual bool getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats); + virtual uint32_t getDefaultSyncPeriod()override; + virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) override; + virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) override; + virtual bool getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats); uint16_t serviceType() const override { return mServType ; } uint32_t serviceFullType() const { return RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(mServType); } virtual RsReputationLevel minReputationForForwardingMessages( - uint32_t group_sign_flags, uint32_t identity_flags ); + uint32_t group_sign_flags, uint32_t identity_flags )override; protected: /** Notifications **/ diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index e46b7efee..740c1d2ab 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -5158,6 +5158,20 @@ bool RsGxsNetService::locked_stampMsgServerUpdateTS(const RsGxsGroupId& gid) return true; } +DistantSearchGroupStatus RsGxsNetService::getDistantSearchStatus(const RsGxsGroupId& group_id) +{ + auto it = mSearchedGroups.find(group_id); + + if(it != mSearchedGroups.end()) + return it->second.status; + + for(auto it2:mDistantSearchResults) + if(it2.second.find(group_id) != it2.second.end()) + return DistantSearchGroupStatus::CAN_BE_REQUESTED; + + return DistantSearchGroupStatus::UNKNOWN; +} + TurtleRequestId RsGxsNetService::turtleGroupRequest(const RsGxsGroupId& group_id) { RS_STACK_MUTEX(mNxsMutex) ; @@ -5180,6 +5194,7 @@ TurtleRequestId RsGxsNetService::turtleGroupRequest(const RsGxsGroupId& group_id rec.request_id = req; rec.ts = now; + rec.status = DistantSearchGroupStatus::ONGOING_REQUEST; mSearchRequests[req] = group_id; @@ -5364,6 +5379,9 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsig } std::vector new_grps(1,nxs_grp); + GroupRequestRecord& rec(mSearchedGroups[nxs_grp->grpId]) ; + rec.status = DistantSearchGroupStatus::HAVE_GROUP_DATA; + #ifdef NXS_NET_DEBUG_8 GXSNETDEBUG___ << " passing the grp data to observer." << std::endl; #endif diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 78f384e42..9322811fc 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -57,10 +57,11 @@ class RsGroupNetworkStatsRecord struct GroupRequestRecord { - GroupRequestRecord(): ts(0), request_id(0) {} + GroupRequestRecord(): ts(0),request_id(0),status(DistantSearchGroupStatus::UNKNOWN) {} rstime_t ts ; TurtleRequestId request_id; + DistantSearchGroupStatus status; }; /*! @@ -102,47 +103,48 @@ public: virtual ~RsGxsNetService(); - virtual RsServiceInfo getServiceInfo() { return mServiceInfo; } + virtual RsServiceInfo getServiceInfo() override { return mServiceInfo; } - virtual void getItemNames(std::map& names) const ; + virtual void getItemNames(std::map& names) const override ; public: - virtual uint16_t serviceType() const { return mServType ; } + virtual uint16_t serviceType() const override { return mServType ; } /*! * Use this to set how far back synchronisation and storage of messages should take place * @param age the max age a sync/storage item can to be allowed in a synchronisation */ - virtual void setSyncAge(const RsGxsGroupId& grpId,uint32_t age_in_secs); - virtual void setKeepAge(const RsGxsGroupId& grpId,uint32_t age_in_secs); + virtual void setSyncAge(const RsGxsGroupId& grpId,uint32_t age_in_secs)override ; + virtual void setKeepAge(const RsGxsGroupId& grpId,uint32_t age_in_secs)override ; - virtual uint32_t getSyncAge(const RsGxsGroupId& id); - virtual uint32_t getKeepAge(const RsGxsGroupId& id); + virtual uint32_t getSyncAge(const RsGxsGroupId& id)override ; + virtual uint32_t getKeepAge(const RsGxsGroupId& id)override ; - virtual uint32_t getDefaultSyncAge() { return mDefaultMsgSyncPeriod ; } - virtual uint32_t getDefaultKeepAge() { return mDefaultMsgStorePeriod ; } + virtual uint32_t getDefaultSyncAge() override { return mDefaultMsgSyncPeriod ; } + virtual uint32_t getDefaultKeepAge() override { return mDefaultMsgStorePeriod ; } - virtual void setDefaultKeepAge(uint32_t t) { mDefaultMsgStorePeriod = t ; } - virtual void setDefaultSyncAge(uint32_t t) { mDefaultMsgSyncPeriod = t ; } + virtual void setDefaultKeepAge(uint32_t t) override { mDefaultMsgStorePeriod = t ; } + virtual void setDefaultSyncAge(uint32_t t) override { mDefaultMsgSyncPeriod = t ; } /*! * \brief Search methods. * These four methods are used to request distant search and receive the results. * \param group_id */ - virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id); - virtual TurtleRequestId turtleSearchRequest(const std::string& match_string); + virtual TurtleRequestId turtleGroupRequest(const RsGxsGroupId& group_id)override ; + virtual TurtleRequestId turtleSearchRequest(const std::string& match_string)override ; - virtual bool search(const std::string& substring,std::list& group_infos) ; - virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len); - virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list& group_infos); - virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len); + virtual bool search(const std::string& substring,std::list& group_infos) override ; + virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)override ; + virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list& group_infos)override ; + virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)override ; - virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &group_infos); - virtual bool clearDistantSearchResults(const TurtleRequestId& id); - virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&, RsGxsGroupSearchResults &); + virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &group_infos)override ; + virtual bool clearDistantSearchResults(const TurtleRequestId& id)override ; + virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&, RsGxsGroupSearchResults &)override ; + virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId&) override ; /*! * pauses synchronisation of subscribed groups and request for group id @@ -150,7 +152,7 @@ public: * @param enabled set to false to disable pause, and true otherwise */ // NOT IMPLEMENTED - virtual void pauseSynchronisation(bool enabled); + virtual void pauseSynchronisation(bool enabled)override ; /*! @@ -159,7 +161,7 @@ public: * @param msgId the messages to retrieve * @return request token to be redeemed */ - virtual int requestMsg(const RsGxsGrpMsgIdPair& /* msgId */){ return 0;} + virtual int requestMsg(const RsGxsGrpMsgIdPair& /* msgId */)override { return 0;} /*! * Request for this group is sent through to peers on your network @@ -167,46 +169,46 @@ public: * @param enabled set to false to disable pause, and true otherwise * @return request token to be redeemed */ - virtual int requestGrp(const std::list& grpId, const RsPeerId& peerId); + virtual int requestGrp(const std::list& grpId, const RsPeerId& peerId)override ; /*! * share publish keys for the specified group with the peers in the specified list. */ - virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::set& peers) ; + virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::set& peers) override ; /*! * Returns statistics for the group networking activity: popularity (number of friends subscribers) and max_visible_msg_count, * that is the max nnumber of messages reported by a friend. */ - virtual bool getGroupNetworkStats(const RsGxsGroupId& id,RsGroupNetworkStats& stats) ; + virtual bool getGroupNetworkStats(const RsGxsGroupId& id,RsGroupNetworkStats& stats) override ; /*! * Used to inform the net service that we changed subscription status. That helps * optimising data transfer when e.g. unsubsribed groups are updated less often, etc */ - virtual void subscribeStatusChanged(const RsGxsGroupId& id,bool subscribed) ; + virtual void subscribeStatusChanged(const RsGxsGroupId& id,bool subscribed) override ; - virtual void rejectMessage(const RsGxsMessageId& msg_id) ; + virtual void rejectMessage(const RsGxsMessageId& msg_id) override ; - virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& grp_server_update_TS,rstime_t& msg_server_update_TS) ; - virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) ; - virtual bool removeGroups(const std::list& groups); - virtual bool isDistantPeer(const RsPeerId& pid); + virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,rstime_t& grp_server_update_TS,rstime_t& msg_server_update_TS) override ; + virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) override ; + virtual bool removeGroups(const std::list& groups)override ; + virtual bool isDistantPeer(const RsPeerId& pid)override ; /* p3Config methods */ public: - bool loadList(std::list& load); - bool saveList(bool &cleanup, std::list&); - RsSerialiser *setupSerialiser(); + bool loadList(std::list& load)override ; + bool saveList(bool &cleanup, std::list&)override ; + RsSerialiser *setupSerialiser()override ; public: /*! * initiates synchronisation */ - int tick(); + int tick()override ; void threadTick() override; /// @see RsTickingThread diff --git a/libretroshare/src/gxs/rsnxs.h b/libretroshare/src/gxs/rsnxs.h index 7276f3421..ea12e146a 100644 --- a/libretroshare/src/gxs/rsnxs.h +++ b/libretroshare/src/gxs/rsnxs.h @@ -141,6 +141,14 @@ public: virtual bool search(const std::string& substring,std::list& group_infos) =0; virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)=0; + /*! + * \brief getDistantSearchStatus + * Request status of a possibly ongoing/finished search. If UNKNOWN is returned, it means that no + * such group is under request + * \return + */ + virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId&) =0; + /*! * Initiates a search through the network * This returns messages which contains the search terms set in RsGxsSearch diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index b7ec8ee7f..7c91f41cd 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -519,10 +519,16 @@ public: * @param[out] distantGroup storage for group data * @return false on error, true otherwise */ - virtual bool getDistantSearchResultGroupData( - const RsGxsGroupId& groupId, RsGxsChannelGroup& distantGroup ) = 0; + virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& groupId, RsGxsChannelGroup& distantGroup ) = 0; - /** + /** + * @brief getDistantSearchStatus + * Returns the status of ongoing search: unknown (probably not even searched), known as a search result, + * data request ongoing and data available + */ + virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) =0; + + /** * @brief Clear accumulated search results * @jsonapi{development} * @param[in] reqId search id diff --git a/libretroshare/src/retroshare/rsgxsiface.h b/libretroshare/src/retroshare/rsgxsiface.h index 74e67008f..ce64bf4ed 100644 --- a/libretroshare/src/retroshare/rsgxsiface.h +++ b/libretroshare/src/retroshare/rsgxsiface.h @@ -145,6 +145,14 @@ struct RsGxsChanges : RsEvent RsTokenService* mService; /// Weak pointer, not serialized }; +enum class DistantSearchGroupStatus:uint8_t +{ + UNKNOWN = 0x00, // no search ongoing for this group + CAN_BE_REQUESTED = 0x01, // a search result mentions this group, so the group data can be requested + ONGOING_REQUEST = 0x02, // the group data has been requested and the request is pending + HAVE_GROUP_DATA = 0x03, // group data has been received. Group can be subscribed. +}; + /*! * All implementations must offer thread safety */ diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index a3117c8a4..839dd4b5a 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -2423,6 +2423,10 @@ bool p3GxsChannels::retrieveDistantSearchResults(TurtleRequestId req,std::mapretrieveDistantSearchResults(req,results); } +DistantSearchGroupStatus p3GxsChannels::getDistantSearchStatus(const RsGxsGroupId& group_id) +{ + return netService()->getDistantSearchStatus(group_id); +} bool p3GxsChannels::getDistantSearchResultGroupData(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group) { RsGxsGroupSearchResults gs; diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h index da274690b..5ab1d414c 100644 --- a/libretroshare/src/services/p3gxschannels.h +++ b/libretroshare/src/services/p3gxschannels.h @@ -71,6 +71,7 @@ protected: virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map &results) ; virtual bool clearDistantSearchResults(TurtleRequestId req); virtual bool getDistantSearchResultGroupData(const RsGxsGroupId& group_id,RsGxsChannelGroup& distant_group); + virtual DistantSearchGroupStatus getDistantSearchStatus(const RsGxsGroupId& group_id) ; // Overloaded to cache new groups. virtual RsGenExchange::ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp index 7fbbf2eed..3ae3c380c 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.cpp @@ -1158,7 +1158,28 @@ void GxsChannelPostsWidgetWithModel::insertChannelDetails(const RsGxsChannelGrou //ui->feedToolButton->setEnabled(false); //ui->fileToolButton->setEnabled(false); #endif - ui->subscribeToolButton->setText(tr("Subscribe ") + " " + QString::number(group.mMeta.mPop) ); + + if(IS_GROUP_SUBSCRIBED(group.mMeta.mSubscribeFlags)) + ui->subscribeToolButton->setText(tr("Unsubscribe")); + else + { + switch(rsGxsChannels->getDistantSearchStatus(group.mMeta.mGroupId)) + { + case DistantSearchGroupStatus::UNKNOWN: // means no search ongoing. This is not a distant search + case DistantSearchGroupStatus::HAVE_GROUP_DATA: // fallthrough + ui->subscribeToolButton->setText(tr("Subscribe")); + ui->subscribeToolButton->setToolTip(""); + break; + case DistantSearchGroupStatus::CAN_BE_REQUESTED: // means no search ongoing. This is not a distant search + ui->subscribeToolButton->setText(tr("Request data")); + ui->subscribeToolButton->setToolTip(tr("Hit this button to retrieve the data you need to subscribe to this channel") ); + break; + case DistantSearchGroupStatus::ONGOING_REQUEST: + ui->subscribeToolButton->setText(tr("Ongoing request...")); + ui->subscribeToolButton->setToolTip(""); + break; + } + } showPostDetails(); } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h index ed7bd66f3..579f83a92 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.h @@ -103,8 +103,8 @@ public: ~GxsChannelPostsWidgetWithModel(); /* GxsMessageFrameWidget */ - virtual QIcon groupIcon(); - virtual void groupIdChanged() { updateDisplay(true); } + virtual QIcon groupIcon() override; + virtual void groupIdChanged() override { updateDisplay(true); } virtual QString groupName(bool) override; virtual bool navigate(const RsGxsMessageId&) override; @@ -126,7 +126,7 @@ protected: virtual bool insertGroupData(const RsGxsGenericGroupData *data) override; #endif virtual bool useThread() { return mUseThread; } - virtual void blank() ; + virtual void blank() override ; #ifdef TODO virtual bool getGroupData(RsGxsGenericGroupData *& data) override; @@ -137,7 +137,7 @@ protected: #endif /* GxsMessageFrameWidget */ - virtual void setAllMessagesReadDo(bool read, uint32_t &token); + virtual void setAllMessagesReadDo(bool read, uint32_t &token) override; private slots: void showPostDetails();