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/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 1a091891f..a973bc1ef 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -163,10 +163,25 @@ void RsGenExchange::tick() processRoutingClues() ; - if(!mNotifications.empty()) { - notifyChanges(mNotifications); - mNotifications.clear(); + std::vector mNotifications_copy; + + // make a non-deep copy of mNotifications so that it can be passed off-mutex to notifyChanged() + // that will delete it. The potential high cost of notifyChanges() makes it preferable to call off-mutex. + { + RS_STACK_MUTEX(mGenMtx); + if(!mNotifications.empty()) + { + mNotifications_copy = mNotifications; + mNotifications.clear(); + } + } + + // Calling notifyChanges() calls back RsGxsIfaceHelper::receiveChanges() that deletes the pointers in the array + // and the array itself. This is pretty bad and we should normally delete the changes here. + + if(!mNotifications_copy.empty()) + notifyChanges(mNotifications_copy); } // implemented service tick function @@ -1118,38 +1133,25 @@ void RsGenExchange::receiveChanges(std::vector& changes) if((mc = dynamic_cast(n)) != nullptr) { if (mc->metaChange()) - { addMessageChanged(out.mMsgsMeta, mc->msgChangeMap); - } else - { addMessageChanged(out.mMsgs, mc->msgChangeMap); - } } else if((gc = dynamic_cast(n)) != nullptr) { if(gc->metaChange()) - { out.mGrpsMeta.splice(out.mGrpsMeta.end(), gc->mGrpIdList); - } else - { out.mGrps.splice(out.mGrps.end(), gc->mGrpIdList); - } } - else if(( gt = - dynamic_cast(n) ) != nullptr) - { + else if(( gt = dynamic_cast(n) ) != nullptr) out.mDistantSearchReqs.push_back(gt->mRequestId); - } else - RsErr() << __PRETTY_FUNCTION__ << " Unknown changes type!" - << std::endl; + RsErr() << __PRETTY_FUNCTION__ << " Unknown changes type!" << std::endl; delete n; } changes.clear() ; - RsServer::notify()->notifyGxsChange(out); if(rsEvents) rsEvents->postEvent(std::move(evt)); } diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index 0a1a45024..08ca943a6 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -1296,7 +1296,9 @@ bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) } if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK) { +#ifdef DEBUG_GXS_TUNNEL std::cerr << "(EE) Cannot talk to tunnel id " << tunnel_id << ". Tunnel status is: " << it->second.status << std::endl; +#endif return false; } diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 0b2fa91ec..1e5d3e58e 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -1186,11 +1186,13 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) RsErr() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl; - if(rsEvents) - { - ev->mErrorMsg = errMsg; - rsEvents->postEvent(std::move(ev)); - } +// if(rsEvents) +// { +// ev->mErrorMsg = errMsg; +// ev->mErrorCode = RsAuthSslConnectionAutenticationEvent::NO_CERTIFICATE_SUPPLIED; +// +// rsEvents->postEvent(std::move(ev)); +// } return verificationFailed; } @@ -1217,8 +1219,11 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) if(rsEvents) { ev->mSslCn = sslCn; + ev->mSslId = sslId; ev->mPgpId = pgpId; ev->mErrorMsg = errMsg; + ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; + rsEvents->postEvent(std::move(ev)); } @@ -1237,6 +1242,8 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslId = sslId; ev->mSslCn = sslCn; ev->mErrorMsg = errMsg; + ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; + rsEvents->postEvent(std::move(ev)); } @@ -1266,6 +1273,7 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslCn = sslCn; ev->mPgpId = pgpId; ev->mErrorMsg = errorMsg; + ev->mErrorCode = RsAuthSslError::MISMATCHED_PGP_ID; rsEvents->postEvent(std::move(ev)); } @@ -1290,12 +1298,29 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslId = sslId; ev->mSslCn = sslCn; ev->mPgpId = pgpId; + + switch(auth_diagnostic) + { + case RS_SSL_HANDSHAKE_DIAGNOSTIC_ISSUER_UNKNOWN: + ev->mErrorCode = RsAuthSslError::NOT_A_FRIEND; + break; + case RS_SSL_HANDSHAKE_DIAGNOSTIC_WRONG_SIGNATURE: + ev->mErrorCode = RsAuthSslError::PGP_SIGNATURE_VALIDATION_FAILED; + break; + default: + ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; + break; + } + ev->mErrorMsg = errMsg; rsEvents->postEvent(std::move(ev)); } return verificationFailed; } +#ifdef AUTHSSL_DEBUG + std::cerr << "******* VerifyX509Callback cert: " << std::hex << ctx->cert <getGPGOwnId() && !AuthGPG::getAuthGPG()->isGPGAccepted(pgpId) ) { @@ -1311,28 +1336,20 @@ int AuthSSLimpl::VerifyX509Callback(int /*preverify_ok*/, X509_STORE_CTX* ctx) ev->mSslCn = sslCn; ev->mPgpId = pgpId; ev->mErrorMsg = errMsg; + ev->mErrorCode = RsAuthSslError::NOT_A_FRIEND; rsEvents->postEvent(std::move(ev)); } return verificationFailed; } - setCurrentConnectionAttemptInfo(pgpId, sslId, sslCn); + //setCurrentConnectionAttemptInfo(pgpId, sslId, sslCn); LocalStoreCert(x509Cert); RsInfo() << __PRETTY_FUNCTION__ << " authentication successfull for " << "sslId: " << sslId << " isSslOnlyFriend: " << isSslOnlyFriend << std::endl; - if(rsEvents) - { - ev->mSuccess = true; - ev->mSslId = sslId; - ev->mSslCn = sslCn; - ev->mPgpId = pgpId; - rsEvents->postEvent(std::move(ev)); - } - return verificationSuccess; } @@ -1583,32 +1600,6 @@ bool AuthSSLimpl::decrypt(void *&out, int &outlen, const void *in, int inlen) return true; } - -/********************************************************************************/ -/********************************************************************************/ -/********************* Cert Search / Add / Remove **************************/ -/********************************************************************************/ -/********************************************************************************/ - -void AuthSSLimpl::setCurrentConnectionAttemptInfo(const RsPgpId& gpg_id,const RsPeerId& ssl_id,const std::string& ssl_cn) -{ -#ifdef AUTHSSL_DEBUG - std::cerr << "AuthSSL: registering connection attempt from:" << std::endl; - std::cerr << " GPG id: " << gpg_id << std::endl; - std::cerr << " SSL id: " << ssl_id << std::endl; - std::cerr << " SSL cn: " << ssl_cn << std::endl; -#endif - _last_gpgid_to_connect = gpg_id ; - _last_sslid_to_connect = ssl_id ; - _last_sslcn_to_connect = ssl_cn ; -} -void AuthSSLimpl::getCurrentConnectionAttemptInfo(RsPgpId& gpg_id,RsPeerId& ssl_id,std::string& ssl_cn) -{ - gpg_id = _last_gpgid_to_connect ; - ssl_id = _last_sslid_to_connect ; - ssl_cn = _last_sslcn_to_connect ; -} - /* Locked search -> internal help function */ bool AuthSSLimpl::locked_FindCert(const RsPeerId& id, X509** cert) { @@ -1785,9 +1776,6 @@ bool AuthSSLimpl::loadList(std::list& load) return true; } -RsAuthSslConnectionAutenticationEvent::RsAuthSslConnectionAutenticationEvent() : - RsEvent(RsEventType::AUTHSSL_CONNECTION_AUTENTICATION), mSuccess(false) {} - const EVP_PKEY*RsX509Cert::getPubKey(const X509& x509) { #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) diff --git a/libretroshare/src/pqi/authssl.h b/libretroshare/src/pqi/authssl.h index d7973e869..b63bd0e7a 100644 --- a/libretroshare/src/pqi/authssl.h +++ b/libretroshare/src/pqi/authssl.h @@ -52,34 +52,6 @@ RsPeerId getCertSslId(const X509& x509); const EVP_PKEY* getPubKey(const X509& x509); }; -/** - * Event triggered by AuthSSL when authentication of a connection attempt either - * fail or success - */ -struct RsAuthSslConnectionAutenticationEvent : RsEvent -{ - RsAuthSslConnectionAutenticationEvent(); - - bool mSuccess; - RsPeerId mSslId; - std::string mSslCn; - RsPgpId mPgpId; - std::string mErrorMsg; - - ///* @see RsEvent @see RsSerializable - void serial_process( RsGenericSerializer::SerializeJob j, - RsGenericSerializer::SerializeContext& ctx) override - { - RsEvent::serial_process(j, ctx); - RS_SERIAL_PROCESS(mSuccess); - RS_SERIAL_PROCESS(mSslId); - RS_SERIAL_PROCESS(mSslCn); - RS_SERIAL_PROCESS(mPgpId); - RS_SERIAL_PROCESS(mErrorMsg); - } -}; - - /** * This is an implementation of SSL certificate authentication with PGP * signatures, instead of centralized certification authority. @@ -165,13 +137,6 @@ public: /// SSL specific functions used in pqissl/pqissllistener virtual SSL_CTX* getCTX() = 0; - virtual void setCurrentConnectionAttemptInfo( - const RsPgpId& gpg_id, const RsPeerId& ssl_id, - const std::string& ssl_cn ) = 0; - virtual void getCurrentConnectionAttemptInfo( - RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) = 0; - - /** * This function parse X509 certificate from the file and return some * verified informations, like ID and signer @@ -258,14 +223,6 @@ public: /* SSL specific functions used in pqissl/pqissllistener */ SSL_CTX* getCTX() override; - /* Restored these functions: */ - void setCurrentConnectionAttemptInfo( - const RsPgpId& gpg_id, const RsPeerId& ssl_id, - const std::string& ssl_cn ) override; - void getCurrentConnectionAttemptInfo( - RsPgpId& gpg_id, RsPeerId& ssl_id, std::string& ssl_cn ) override; - - private: bool LocalStoreCert(X509* x509); diff --git a/libretroshare/src/pqi/p3linkmgr.cc b/libretroshare/src/pqi/p3linkmgr.cc index 100a16cad..a63054093 100644 --- a/libretroshare/src/pqi/p3linkmgr.cc +++ b/libretroshare/src/pqi/p3linkmgr.cc @@ -473,27 +473,20 @@ void p3LinkMgrIMPL::tickMonitors() #endif /* notify GUI */ - if (peer.actions & RS_PEER_CONNECTED) + if (rsEvents && (peer.actions & RS_PEER_CONNECTED)) { - p3Notify *notify = RsServer::notify(); - - if (notify) - { - // normally these two below should disappear: there's no notion of popup in libretroshare. - // all GUI-type display features should be chosen in NotifyQt. - notify->AddPopupMessage(RS_POPUP_CONNECT, peer.id.toStdString(),"", "Online: "); - notify->AddFeedItem(RS_FEED_ITEM_PEER_CONNECT, peer.id.toStdString()); - - notify->notifyPeerConnected(peer.id.toStdString()); - } + auto e = std::make_shared(); + e->mConnectionInfoCode = RsConnectionEventCode::PEER_CONNECTED; + e->mSslId = peer.id; + rsEvents->postEvent(e); } - if (peer.actions & RS_PEER_DISCONNECTED) + if (rsEvents && (peer.actions & RS_PEER_DISCONNECTED)) { - p3Notify *notify = RsServer::notify(); - - if (notify) - notify->notifyPeerDisconnected(peer.id.toStdString()); - } + auto e = std::make_shared(); + e->mConnectionInfoCode = RsConnectionEventCode::PEER_DISCONNECTED; + e->mSslId = peer.id; + rsEvents->postEvent(e); + } } } diff --git a/libretroshare/src/pqi/p3notify.cc b/libretroshare/src/pqi/p3notify.cc index 621c34119..7a5dc8c45 100644 --- a/libretroshare/src/pqi/p3notify.cc +++ b/libretroshare/src/pqi/p3notify.cc @@ -217,8 +217,6 @@ void p3Notify::notifyChatLobbyEvent(uint64_t lobby_id, uint32_t event_type,const void p3Notify::notifyListPreChange(int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListPreChange(list,type) ; } void p3Notify::notifyListChange (int list, int type) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyListChange (list,type) ; } -void p3Notify::notifyPeerConnected (const std::string& peer_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerConnected(peer_id); } -void p3Notify::notifyPeerDisconnected (const std::string& peer_id) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerDisconnected(peer_id); } void p3Notify::notifyErrorMsg (int list, int sev, std::string msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyErrorMsg(list,sev,msg) ; } void p3Notify::notifyChatMessage (const ChatMessage &msg) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatMessage(msg) ; } void p3Notify::notifyChatStatus (const ChatId& chat_id, const std::string& status_string) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyChatStatus(chat_id,status_string) ; } @@ -235,8 +233,6 @@ void p3Notify::notifyOwnAvatarChanged () void p3Notify::notifyOwnStatusMessageChanged() { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyOwnStatusMessageChanged() ; } void p3Notify::notifyDiskFull (uint32_t location , uint32_t size_limit_in_MB ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiskFull (location,size_limit_in_MB) ; } void p3Notify::notifyPeerStatusChanged (const std::string& peer_id , uint32_t status ) { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChanged (peer_id,status) ; } -void p3Notify::notifyGxsChange (const RsGxsChanges& changes) {FOR_ALL_NOTIFY_CLIENTS (*it)->notifyGxsChange(changes) ;} -void p3Notify::notifyConnectionWithoutCert () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyConnectionWithoutCert(); } void p3Notify::notifyPeerStatusChangedSummary () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyPeerStatusChangedSummary() ; } void p3Notify::notifyDiscInfoChanged () { FOR_ALL_NOTIFY_CLIENTS (*it)->notifyDiscInfoChanged () ; } diff --git a/libretroshare/src/pqi/p3notify.h b/libretroshare/src/pqi/p3notify.h index 7cbbbef55..46fb69c8e 100644 --- a/libretroshare/src/pqi/p3notify.h +++ b/libretroshare/src/pqi/p3notify.h @@ -91,8 +91,6 @@ class p3Notify: public RsNotify // Notifications of clients. Can be called from anywhere inside libretroshare. // - void notifyPeerConnected (const std::string& /* peer_id */); - void notifyPeerDisconnected (const std::string& /* peer_id */); void notifyListPreChange (int /* list */, int /* type */) ; void notifyListChange (int /* list */, int /* type */) ; void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) ; @@ -111,7 +109,6 @@ class p3Notify: public RsNotify void notifyOwnStatusMessageChanged () ; void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) ; void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) ; - void notifyGxsChange (const RsGxsChanges& /* changes */); void notifyConnectionWithoutCert (); void notifyPeerStatusChangedSummary () ; diff --git a/libretroshare/src/pqi/p3peermgr.cc b/libretroshare/src/pqi/p3peermgr.cc index 564eb44b8..07eb180d4 100644 --- a/libretroshare/src/pqi/p3peermgr.cc +++ b/libretroshare/src/pqi/p3peermgr.cc @@ -1804,12 +1804,24 @@ bool p3PeerMgrIMPL::addCandidateForOwnExternalAddress(const RsPeerId &from, cons // Notify for every friend that has reported a wrong external address, except if that address is in the IP whitelist. - if((rsBanList!=NULL && !rsBanList->isAddressAccepted(addr_filtered,RSBANLIST_CHECKING_FLAGS_WHITELIST)) && (!sockaddr_storage_sameip(own_addr,addr_filtered))) - { - std::cerr << " Peer " << from << " reports a connection address (" << sockaddr_storage_iptostring(addr_filtered) <<") that is not your current external address (" << sockaddr_storage_iptostring(own_addr) << "). This is weird." << std::endl; + if((rsBanList && !rsBanList->isAddressAccepted(addr_filtered, RSBANLIST_CHECKING_FLAGS_WHITELIST)) + && !sockaddr_storage_sameip(own_addr, addr_filtered) ) + { + RsInfo() << __PRETTY_FUNCTION__ << " Peer " << from + << " reports a connection address (" << addr_filtered + <<") that is not your current external address (" + << own_addr << "). This is weird." << std::endl; - RsServer::notify()->AddFeedItem(RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, from.toStdString(), sockaddr_storage_iptostring(own_addr), sockaddr_storage_iptostring(addr)); - } + if(rsEvents) + { + auto ev = std::make_shared(); + ev->mSslId = from; + ev->mOwnLocator = RsUrl(own_addr); + ev->mReportedLocator = RsUrl(addr); + ev->mConnectionInfoCode = RsConnectionEventCode::PEER_REPORTS_WRONG_IP; + rsEvents->postEvent(ev); + } + } // we could also sweep over all connected friends and see if some report a different address. diff --git a/libretroshare/src/pqi/pqissl.cc b/libretroshare/src/pqi/pqissl.cc index 773c74e50..0ef930fc2 100644 --- a/libretroshare/src/pqi/pqissl.cc +++ b/libretroshare/src/pqi/pqissl.cc @@ -1096,8 +1096,7 @@ int pqissl::SSL_Connection_Complete() if (err != 1) { int serr = SSL_get_error(ssl_connection, err); - if ((serr == SSL_ERROR_WANT_READ) - || (serr == SSL_ERROR_WANT_WRITE)) + if ((serr == SSL_ERROR_WANT_READ) || (serr == SSL_ERROR_WANT_WRITE)) { #ifdef PQISSL_LOG_DEBUG rslog(RSL_DEBUG_BASIC, pqisslzone, @@ -1108,6 +1107,14 @@ int pqissl::SSL_Connection_Complete() return 0; } + if(rsEvents) + { + X509 *x509 = SSL_get_peer_certificate(ssl_connection); + auto ev = std::make_shared(); + ev->mSslId = RsX509Cert::getCertSslId(*x509); + ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION; + rsEvents->postEvent(ev); + } std::string out; rs_sprintf(out, "pqissl::SSL_Connection_Complete()\nIssues with SSL Connect(%d)!\n", err); @@ -1253,10 +1260,12 @@ 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__ + RsInfo() << __PRETTY_FUNCTION__ << " Refusing incoming SSL connection from blacklisted " << "foreign address " << foreign_addr << ". Reason: " << check_result << ". This should never happen " @@ -1264,11 +1273,16 @@ 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) + { + X509 *x509 = SSL_get_peer_certificate(ssl); + auto ev = std::make_shared(); + ev->mSslId = RsX509Cert::getCertSslId(*x509); + ev->mLocator = RsUrl(foreign_addr); + ev->mErrorCode = RsAuthSslError::IP_IS_BLACKLISTED; + rsEvents->postEvent(ev); + } + reset_locked(); return failure; } @@ -1324,7 +1338,7 @@ int pqissl::accept_locked( SSL *ssl, int fd, /* shutdown existing - in all cases use the new one */ if ((ssl_connection) && (ssl_connection != ssl)) { - std::cerr << __PRETTY_FUNCTION__ + RsInfo() << __PRETTY_FUNCTION__ << " closing Previous/Existing ssl_connection" << std::endl; SSL_shutdown(ssl_connection); SSL_free (ssl_connection); @@ -1332,7 +1346,7 @@ int pqissl::accept_locked( SSL *ssl, int fd, if ((sockfd > -1) && (sockfd != fd)) { - std::cerr << __PRETTY_FUNCTION__ << " closing Previous/Existing sockfd" + RsInfo() << __PRETTY_FUNCTION__ << " closing Previous/Existing sockfd" << std::endl; net_internal_close(sockfd); } @@ -1348,7 +1362,7 @@ int pqissl::accept_locked( SSL *ssl, int fd, */ sockaddr_storage_copy(foreign_addr, remote_addr); - std::cerr << __PRETTY_FUNCTION__ << " SUCCESSFUL connection to: " + RsInfo() << __PRETTY_FUNCTION__ << " SUCCESSFUL connection to: " << PeerId().toStdString() << " remoteaddr: " << sockaddr_storage_iptostring(remote_addr) << std::endl; diff --git a/libretroshare/src/pqi/pqissllistener.cc b/libretroshare/src/pqi/pqissllistener.cc index 3d62db9ea..fa25bfe0b 100644 --- a/libretroshare/src/pqi/pqissllistener.cc +++ b/libretroshare/src/pqi/pqissllistener.cc @@ -424,23 +424,8 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool { // attempt the accept again. int fd = SSL_get_fd(incoming_connexion_info.ssl); - - AuthSSL::getAuthSSL()->setCurrentConnectionAttemptInfo(RsPgpId(),RsPeerId(),std::string()) ; int err = SSL_accept(incoming_connexion_info.ssl); - // Now grab the connection info that was filled in by the callback. - // In the case the callback did not succeed the SSL certificate will not be accessible - // from SSL_get_peer_certificate, so we need to get it from the callback system. - // - AuthSSL::getAuthSSL()->getCurrentConnectionAttemptInfo(incoming_connexion_info.gpgid,incoming_connexion_info.sslid,incoming_connexion_info.sslcn) ; - -#ifdef DEBUG_LISTENNER - std::cerr << "Info from callback: " << std::endl; - std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl; - std::cerr << " Got SSL Id = " << incoming_connexion_info.sslid << std::endl; - std::cerr << " Got SSL CN = " << incoming_connexion_info.sslcn << std::endl; -#endif - if (err <= 0) { int ssl_err = SSL_get_error(incoming_connexion_info.ssl, err); @@ -486,10 +471,22 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool break; } - closeConnection(fd, incoming_connexion_info.ssl) ; - pqioutput(PQL_WARNING, pqissllistenzone, "Read Error on the SSL Socket\nShutting it down!"); + // We use SSL_get_verify_result() in order to differentiate two cases: + // case 1: the incoming connection is closed because the peer is not a friend. This is already handled in authssl. + // case 2: the incoming connection is closed because no authentication info is available, in which case it returns X509_V_OK + auto vres = SSL_get_verify_result(incoming_connexion_info.ssl); + + if(vres == X509_V_OK && nullptr != rsEvents) + { + auto ev = std::make_shared(); + ev->mLocator = RsUrl(incoming_connexion_info.addr); + ev->mErrorCode = RsAuthSslError::MISSING_AUTHENTICATION_INFO; + rsEvents->postEvent(ev); + } + closeConnection(fd, incoming_connexion_info.ssl); + // failure -1, pending 0, sucess 1. return -1; } @@ -505,23 +502,22 @@ int pqissllistenbase::continueSSL(IncomingSSLInfo& incoming_connexion_info, bool incoming_connexion_info.sslcn = RsX509Cert::getCertName(*x509); incoming_connexion_info.sslid = RsX509Cert::getCertSslId(*x509); -#ifdef DEBUG_LISTENNER +#ifndef DEBUG_LISTENNER + std::cerr << "ContinueSSL:" << std::endl; std::cerr << " Got PGP Id = " << incoming_connexion_info.gpgid << std::endl; std::cerr << " Got SSL Id = " << incoming_connexion_info.sslid << std::endl; std::cerr << " Got SSL CN = " << incoming_connexion_info.sslcn << std::endl; #endif } + #ifdef DEBUG_LISTENNER else std::cerr << " no info." << std::endl; #endif - // if it succeeds if (0 < completeConnection(fd, incoming_connexion_info)) - { return 1; - } /* else we shut it down! */ pqioutput(PQL_WARNING, pqissllistenzone, diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index cd774b979..bc5d00cf5 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -27,6 +27,7 @@ #include #include "util/rsmemory.h" +#include "util/rsurl.h" #include "serialiser/rsserializable.h" #include "serialiser/rstypeserializer.h" #include "util/rstime.h" @@ -61,7 +62,7 @@ enum class RsEventType : uint32_t AUTHSSL_CONNECTION_AUTENTICATION = 3, /// @see pqissl - REMOTE_PEER_REFUSED_CONNECTION = 4, + PEER_CONNECTION = 4, /// @see RsGxsChanges GXS_CHANGES = 5, @@ -72,6 +73,18 @@ enum class RsEventType : uint32_t /// @see RsMailStatusEvent MAIL_STATUS_CHANGE = 7, + /// @see RsGxsCircleEvent + GXS_CIRCLES = 8, + + /// @see RsGxsChannelEvent + GXS_CHANNELS = 9, + + /// @see RsGxsForumEvent + GXS_FORUMS = 10, + + /// @see RsGxsPostedEvent + GXS_POSTED = 11, + MAX /// Used to detect invalid event type passed }; @@ -173,3 +186,4 @@ public: virtual ~RsEvents(); }; + diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index 3e0d95219..8e6939672 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -103,6 +103,48 @@ struct RsGxsChannelPost : RsSerializable }; +enum class RsChannelEventCode: uint8_t +{ + UNKNOWN = 0x00, + NEW_CHANNEL = 0x01, /// emitted when new channel is received + + /// emitted when existing channel is updated + UPDATED_CHANNEL = 0x02, + + /// new message reeived in a particular channel (group and msg id) + NEW_MESSAGE = 0x03, + + /// existing message has been updated in a particular channel + UPDATED_MESSAGE = 0x04, + + /// publish key for this channel has been received + RECEIVED_PUBLISH_KEY = 0x05, + + /// subscription for channel mChannelGroupId changed. + SUBSCRIBE_STATUS_CHANGED = 0x06, +}; + +struct RsGxsChannelEvent: RsEvent +{ + RsGxsChannelEvent(): + RsEvent(RsEventType::GXS_CHANNELS), + mChannelEventCode(RsChannelEventCode::UNKNOWN) {} + + RsChannelEventCode mChannelEventCode; + RsGxsGroupId mChannelGroupId; + RsGxsMessageId mChannelMsgId; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override + { + RsEvent::serial_process(j, ctx); + + RS_SERIAL_PROCESS(mChannelEventCode); + RS_SERIAL_PROCESS(mChannelGroupId); + RS_SERIAL_PROCESS(mChannelMsgId); + } +}; + class RsGxsChannels: public RsGxsIfaceHelper, public RsGxsCommentService { public: diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 80e5862cf..5ef69fda8 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,63 @@ 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); } }; + +enum class RsGxsCircleEventCode: uint8_t +{ + UNKNOWN = 0x00, + + /** mCircleId contains the circle id and mGxsId is the id requesting + * membership */ + CIRCLE_MEMBERSHIP_REQUEST = 0x01, + + /** mCircleId is the circle that invites me, and mGxsId is my own Id that is + * invited */ + CIRCLE_MEMBERSHIP_INVITE = 0x02, + + /** mCircleId contains the circle id and mGxsId is the id dropping + * membership */ + CIRCLE_MEMBERSHIP_LEAVE = 0x03, + + /// mCircleId contains the circle id and mGxsId is the id of the new member + CIRCLE_MEMBERSHIP_JOIN = 0x04, + + /** mCircleId contains the circle id and mGxsId is the id that was revoqued + * by admin */ + CIRCLE_MEMBERSHIP_REVOQUED= 0x05, +}; + +struct RsGxsCircleEvent: RsEvent +{ + RsGxsCircleEvent() + : RsEvent(RsEventType::GXS_CIRCLES), + mCircleEventType(RsGxsCircleEventCode::UNKNOWN) {} + + + RsGxsCircleEventCode 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); + } + + ~RsGxsCircleEvent() override; +}; + class RsGxsCircles: public RsGxsIfaceHelper { public: @@ -243,6 +297,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/rsgxsforums.h b/libretroshare/src/retroshare/rsgxsforums.h index 92f2d11d5..1ce658ab3 100644 --- a/libretroshare/src/retroshare/rsgxsforums.h +++ b/libretroshare/src/retroshare/rsgxsforums.h @@ -105,6 +105,46 @@ struct RsGxsForumMsg : RsSerializable }; +enum class RsForumEventCode: uint8_t +{ + UNKNOWN = 0x00, + NEW_FORUM = 0x01, /// emitted when new forum is received + UPDATED_FORUM = 0x02, /// emitted when existing forum is updated + + /// new message reeived in a particular forum + NEW_MESSAGE = 0x03, + + /// existing message has been updated in a particular forum + UPDATED_MESSAGE = 0x04, + + /// forum was subscribed or unsubscribed + SUBSCRIBE_STATUS_CHANGED = 0x05, +}; + +struct RsGxsForumEvent: RsEvent +{ + RsGxsForumEvent() + : RsEvent(RsEventType::GXS_FORUMS), + mForumEventCode(RsForumEventCode::UNKNOWN) {} + + RsForumEventCode mForumEventCode; + RsGxsGroupId mForumGroupId; + RsGxsMessageId mForumMsgId; + + ///* @see RsEvent @see RsSerializable + void serial_process( + RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mForumEventCode); + RS_SERIAL_PROCESS(mForumGroupId); + RS_SERIAL_PROCESS(mForumMsgId); + } + + ~RsGxsForumEvent() override; +}; + class RsGxsForums: public RsGxsIfaceHelper { public: diff --git a/libretroshare/src/retroshare/rsmsgs.h b/libretroshare/src/retroshare/rsmsgs.h index 109084dd7..915444360 100644 --- a/libretroshare/src/retroshare/rsmsgs.h +++ b/libretroshare/src/retroshare/rsmsgs.h @@ -296,10 +296,25 @@ struct MsgTagType : RsSerializable } //namespace Rs } //namespace Msgs + +enum class RsMailStatusEventCode: uint8_t +{ + NEW_MESSAGE = 0x00, + MESSAGE_REMOVED = 0x01, + MESSAGE_SENT = 0x02, + + /// means the peer received the message + MESSAGE_RECEIVED_ACK = 0x03, + + /// An error occurred attempting to sign the message + SIGNATURE_FAILED = 0x04, +}; + struct RsMailStatusEvent : RsEvent { RsMailStatusEvent() : RsEvent(RsEventType::MAIL_STATUS_CHANGE) {} + RsMailStatusEventCode mMailStatusEventCode; std::set mChangedMsgIds; /// @see RsEvent @@ -308,6 +323,7 @@ struct RsMailStatusEvent : RsEvent { RsEvent::serial_process(j, ctx); RS_SERIAL_PROCESS(mChangedMsgIds); + RS_SERIAL_PROCESS(mMailStatusEventCode); } ~RsMailStatusEvent() override; diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index 894d1f30d..d69357cdb 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -79,9 +79,10 @@ const uint32_t RS_FEED_ITEM_PEER_DISCONNECT = RS_FEED_TYPE_PEER | 0x000 const uint32_t RS_FEED_ITEM_PEER_HELLO = RS_FEED_TYPE_PEER | 0x0003; const uint32_t RS_FEED_ITEM_PEER_NEW = RS_FEED_TYPE_PEER | 0x0004; const uint32_t RS_FEED_ITEM_PEER_OFFSET = RS_FEED_TYPE_PEER | 0x0005; +const uint32_t RS_FEED_ITEM_PEER_DENIES_CONNEXION = RS_FEED_TYPE_PEER | 0x0006; const uint32_t RS_FEED_ITEM_SEC_CONNECT_ATTEMPT = RS_FEED_TYPE_SECURITY | 0x0001; -const uint32_t RS_FEED_ITEM_SEC_AUTH_DENIED = RS_FEED_TYPE_SECURITY | 0x0002; +const uint32_t RS_FEED_ITEM_SEC_AUTH_DENIED = RS_FEED_TYPE_SECURITY | 0x0002; // locally denied connection const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_IN = RS_FEED_TYPE_SECURITY | 0x0003; const uint32_t RS_FEED_ITEM_SEC_UNKNOWN_OUT = RS_FEED_TYPE_SECURITY | 0x0004; const uint32_t RS_FEED_ITEM_SEC_WRONG_SIGNATURE = RS_FEED_TYPE_SECURITY | 0x0005; @@ -114,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; @@ -212,8 +216,6 @@ public: NotifyClient() {} virtual ~NotifyClient() {} - virtual void notifyPeerConnected (const std::string& /* peer_id */) {} - virtual void notifyPeerDisconnected (const std::string& /* peer_id */) {} virtual void notifyListPreChange (int /* list */, int /* type */) {} virtual void notifyListChange (int /* list */, int /* type */) {} virtual void notifyErrorMsg (int /* list */, int /* sev */, std::string /* msg */) {} @@ -230,8 +232,6 @@ public: virtual void notifyOwnStatusMessageChanged () {} virtual void notifyDiskFull (uint32_t /* location */, uint32_t /* size limit in MB */) {} virtual void notifyPeerStatusChanged (const std::string& /* peer_id */, uint32_t /* status */) {} - virtual void notifyGxsChange (const RsGxsChanges& /* changes */) {} - virtual void notifyConnectionWithoutCert () {} /* one or more peers has changed the states */ virtual void notifyPeerStatusChangedSummary () {} diff --git a/libretroshare/src/retroshare/rspeers.h b/libretroshare/src/retroshare/rspeers.h index bc1254658..65b028326 100644 --- a/libretroshare/src/retroshare/rspeers.h +++ b/libretroshare/src/retroshare/rspeers.h @@ -206,6 +206,100 @@ std::string RsPeerTrustString(uint32_t trustLvl); std::string RsPeerNetModeString(uint32_t netModel); std::string RsPeerLastConnectString(uint32_t lastConnect); +//===================================================================================================// +// Connexion and security events // +//===================================================================================================// + +enum class RsAuthSslError: uint8_t +{ + NO_ERROR = 0x00, + MISSING_AUTHENTICATION_INFO = 0x01, + PGP_SIGNATURE_VALIDATION_FAILED = 0x02, + MISMATCHED_PGP_ID = 0x03, + NO_CERTIFICATE_SUPPLIED = 0x04, + NOT_A_FRIEND = 0x05, + MISSING_CERTIFICATE = 0x06, + IP_IS_BLACKLISTED = 0x07, + PEER_REFUSED_CONNECTION = 0x08, + UNKNOWN_ERROR = 0x09, +}; + +/** + * Event triggered by AuthSSL when authentication of a connection attempt either + * fail or success + */ +struct RsAuthSslConnectionAutenticationEvent : RsEvent +{ + RsAuthSslConnectionAutenticationEvent() : + RsEvent(RsEventType::AUTHSSL_CONNECTION_AUTENTICATION) {} + + RsPeerId mSslId; + std::string mSslCn; + RsPgpId mPgpId; + RsUrl mLocator; + std::string mErrorMsg; + RsAuthSslError mErrorCode; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mSslId); + RS_SERIAL_PROCESS(mSslCn); + RS_SERIAL_PROCESS(mPgpId); + RS_SERIAL_PROCESS(mLocator); + RS_SERIAL_PROCESS(mErrorMsg); + RS_SERIAL_PROCESS(mErrorCode); + } + + ~RsAuthSslConnectionAutenticationEvent() override; +}; + +enum class RsConnectionEventCode: uint8_t +{ + UNKNOWN = 0x00, + PEER_CONNECTED = 0x01, + PEER_DISCONNECTED = 0x02, + PEER_TIME_SHIFT = 0x03, // mTimeShift = time shift in seconds + PEER_REPORTS_WRONG_IP = 0x04, // mPeerLocator = address reported, mOwnLocator = own address +}; + +struct RsConnectionEvent : RsEvent +{ + RsConnectionEvent() + : RsEvent(RsEventType::PEER_CONNECTION), + mConnectionInfoCode(RsConnectionEventCode::UNKNOWN), mTimeShift(0) {} + + RsConnectionEventCode mConnectionInfoCode; + RsPeerId mSslId; + RsUrl mOwnLocator; + RsUrl mReportedLocator; + + /** If there is a time shift with the peer aka + * mConnectionInfoCode == PEER_TIME_SHIFT contains the time shift value in + * seconds */ + rstime_t mTimeShift; + + ///* @see RsEvent @see RsSerializable + void serial_process( + RsGenericSerializer::SerializeJob j, + RsGenericSerializer::SerializeContext& ctx ) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mConnectionInfoCode); + RS_SERIAL_PROCESS(mSslId); + RS_SERIAL_PROCESS(mOwnLocator); + RS_SERIAL_PROCESS(mReportedLocator); + RS_SERIAL_PROCESS(mTimeShift); + } + + ~RsConnectionEvent() override; +}; + +//===================================================================================================// +// Peer Details // +//===================================================================================================// /* We should definitely split this into 2 sub-structures: * PGP info (or profile info) with all info related to PGP keys diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index a42f06c40..211f67bb1 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -68,6 +68,33 @@ class RsPostedGroup std::ostream &operator<<(std::ostream &out, const RsPostedGroup &group); std::ostream &operator<<(std::ostream &out, const RsPostedPost &post); +enum class RsPostedEventCode: uint8_t +{ + UNKNOWN = 0x00, + NEW_POSTED_GROUP = 0x01, + NEW_MESSAGE = 0x02 +}; + + +struct RsGxsPostedEvent: RsEvent +{ + RsGxsPostedEvent(): + RsEvent(RsEventType::GXS_POSTED), + mPostedEventCode(RsPostedEventCode::UNKNOWN) {} + + RsPostedEventCode mPostedEventCode; + RsGxsGroupId mPostedGroupId; + RsGxsMessageId mPostedMsgId; + + ///* @see RsEvent @see RsSerializable + void serial_process( RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) override + { + RsEvent::serial_process(j, ctx); + RS_SERIAL_PROCESS(mPostedEventCode); + RS_SERIAL_PROCESS(mPostedGroupId); + RS_SERIAL_PROCESS(mPostedMsgId); + } +}; class RsPosted : public RsGxsIfaceHelper, public RsGxsCommentService { diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 0ea163f35..d4c99d259 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -1859,3 +1859,5 @@ RsPeerStateChangedEvent::RsPeerStateChangedEvent(RsPeerId sslId) : RsEvent(RsEventType::PEER_STATE_CHANGED), mSslId(sslId) {} RsPeers::~RsPeers() = default; +RsAuthSslConnectionAutenticationEvent::~RsAuthSslConnectionAutenticationEvent() = default; +RsConnectionEvent::~RsConnectionEvent() = default; diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index fd40a5783..8ee484d08 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -136,14 +136,14 @@ uint32_t p3GxsChannels::channelsAuthenPolicy() static const uint32_t GXS_CHANNELS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months static const uint8_t GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ; -struct RsGxsForumNotifyRecordsItem: public RsItem +struct RsGxsGroupNotifyRecordsItem: public RsItem { - RsGxsForumNotifyRecordsItem() + RsGxsGroupNotifyRecordsItem() : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG,GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD) {} - virtual ~RsGxsForumNotifyRecordsItem() {} + virtual ~RsGxsGroupNotifyRecordsItem() {} void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) @@ -167,7 +167,7 @@ public: switch(item_sub_id) { - case GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsForumNotifyRecordsItem(); + case GXS_CHANNELS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsGroupNotifyRecordsItem(); default: return NULL; } @@ -178,7 +178,7 @@ bool p3GxsChannels::saveList(bool &cleanup, std::list&saveList) { cleanup = true ; - RsGxsForumNotifyRecordsItem *item = new RsGxsForumNotifyRecordsItem ; + RsGxsGroupNotifyRecordsItem *item = new RsGxsGroupNotifyRecordsItem ; { RS_STACK_MUTEX(mKnownChannelsMutex); @@ -198,7 +198,7 @@ bool p3GxsChannels::loadList(std::list& loadList) rstime_t now = time(NULL); - RsGxsForumNotifyRecordsItem *fnr = dynamic_cast(item) ; + RsGxsGroupNotifyRecordsItem *fnr = dynamic_cast(item) ; if(fnr) { @@ -238,12 +238,6 @@ void p3GxsChannels::notifyChanges(std::vector &changes) std::cerr << "p3GxsChannels::notifyChanges() : " << changes.size() << "changes to notify" << std::endl; #endif - p3Notify* notify = nullptr; - if (!changes.empty()) - { - notify = RsServer::notify(); - } - /* iterate through and grab any new messages */ std::list unprocessedGroups; @@ -256,13 +250,17 @@ void p3GxsChannels::notifyChanges(std::vector &changes) if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) { /* message received */ - if (notify) + if (rsEvents) { std::map > &msgChangeMap = msgChange->msgChangeMap; for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1) { - notify->AddFeedItem(RS_FEED_ITEM_CHANNEL_MSG, mit->first.toStdString(), mit1->toStdString()); + auto ev = std::make_shared(); + ev->mChannelMsgId = *mit1; + ev->mChannelGroupId = mit->first; + ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE; + rsEvents->postEvent(ev); } } } @@ -298,48 +296,68 @@ void p3GxsChannels::notifyChanges(std::vector &changes) } else { - if (notify) + if (rsEvents) { RsGxsGroupChange *grpChange = dynamic_cast(*it); if (grpChange) { switch (grpChange->getType()) { - default: - case RsGxsNotify::TYPE_PROCESSED: - case RsGxsNotify::TYPE_PUBLISHED: - break; - - case RsGxsNotify::TYPE_RECEIVED_NEW: + default: + case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed + { + std::list &grpList = grpChange->mGrpIdList; + std::list::iterator git; + for (git = grpList.begin(); git != grpList.end(); ++git) { - /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - RS_STACK_MUTEX(mKnownChannelsMutex); - for (git = grpList.begin(); git != grpList.end(); ++git) - { - if(mKnownChannels.find(*git) == mKnownChannels.end()) - { - notify->AddFeedItem(RS_FEED_ITEM_CHANNEL_NEW, git->toStdString()); - mKnownChannels.insert(std::make_pair(*git,time(NULL))) ; - } - else - std::cerr << "(II) Not notifying already known channel " << *git << std::endl; - } - break; + auto ev = std::make_shared(); + ev->mChannelGroupId = *git; + ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED; + rsEvents->postEvent(ev); } - case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: + } + break; + + case RsGxsNotify::TYPE_PUBLISHED: + case RsGxsNotify::TYPE_RECEIVED_NEW: + { + /* group received */ + std::list &grpList = grpChange->mGrpIdList; + std::list::iterator git; + RS_STACK_MUTEX(mKnownChannelsMutex); + for (git = grpList.begin(); git != grpList.end(); ++git) { - /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) + if(mKnownChannels.find(*git) == mKnownChannels.end()) { - notify->AddFeedItem(RS_FEED_ITEM_CHANNEL_PUBLISHKEY, git->toStdString()); + mKnownChannels.insert(std::make_pair(*git,time(NULL))) ; + IndicateConfigChanged(); + + auto ev = std::make_shared(); + ev->mChannelGroupId = *git; + ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL; + rsEvents->postEvent(ev); } - break; + else + std::cerr << "(II) Not notifying already known channel " << *git << std::endl; } + break; + } + + case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: + { + /* group received */ + std::list &grpList = grpChange->mGrpIdList; + std::list::iterator git; + for (git = grpList.begin(); git != grpList.end(); ++git) + { + auto ev = std::make_shared(); + ev->mChannelGroupId = *git; + ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY; + rsEvents->postEvent(ev); + } + break; + } } } } @@ -351,6 +369,7 @@ void p3GxsChannels::notifyChanges(std::vector &changes) if(!unprocessedGroups.empty()) request_SpecificSubscribedGroups(unprocessedGroups); + // the call below deletes changes and its content. RsGxsIfaceHelper::receiveChanges(changes); } diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index a7d201292..a2fac2db8 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 ) { @@ -442,6 +468,7 @@ void p3GxsCircles::service_tick() return; } + void p3GxsCircles::notifyChanges(std::vector &changes) { #ifdef DEBUG_CIRCLES @@ -467,13 +494,31 @@ 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()); + RsGxsCircleMsg msg; + getCircleRequest(RsGxsGroupId(circle_id),*msgIdIt,msg); + + auto ev = std::make_shared(); + ev->mCircleId = circle_id; + ev->mGxsId = msg.mMeta.mAuthorId; + + if (msg.stuff == "SUBSCRIPTION_REQUEST_UNSUBSCRIBE") + ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE; + else if(details.mAllowedGxsIds.find(msg.mMeta.mAuthorId) != details.mAllowedGxsIds.end()) + ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN; + else + ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST; + + rsEvents->postEvent(ev); } } @@ -506,15 +551,59 @@ 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); + } + } + + } +#endif + } + } } RsGxsIfaceHelper::receiveChanges(changes); // this clear up the vector and delete its elements @@ -550,6 +639,7 @@ bool p3GxsCircles::getCircleDetails( 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) { @@ -860,7 +950,7 @@ RsGxsCircleCache::RsGxsCircleCache() mUpdateTime = 0; mGroupStatus = 0; mGroupSubscribeFlags = 0; - mLastUpdatedMembershipTS = 0 ; + mLastUpdatedMembershipTS = 0 ; return; } @@ -2324,3 +2414,4 @@ RsGxsCircles::~RsGxsCircles() = default; RsGxsCircleMsg::~RsGxsCircleMsg() = default; RsGxsCircleDetails::~RsGxsCircleDetails() = default; RsGxsCircleGroup::~RsGxsCircleGroup() = default; +RsGxsCircleEvent::~RsGxsCircleEvent() = default; diff --git a/libretroshare/src/services/p3gxscircles.h b/libretroshare/src/services/p3gxscircles.h index 07dab3db7..da93142cc 100644 --- a/libretroshare/src/services/p3gxscircles.h +++ b/libretroshare/src/services/p3gxscircles.h @@ -208,6 +208,11 @@ public: bool inviteIdsToCircle( const std::set& identities, const RsGxsCircleId& circleId ) override; + /// @see RsGxsCircles + bool getCircleRequest(const RsGxsGroupId& circleId, + const RsGxsMessageId& msgId, + RsGxsCircleMsg& msg) override; + /// @see RsGxsCircles bool exportCircleLink( std::string& link, const RsGxsCircleId& circleId, diff --git a/libretroshare/src/services/p3gxsforums.cc b/libretroshare/src/services/p3gxsforums.cc index 775f0ddd3..128b5db39 100644 --- a/libretroshare/src/services/p3gxsforums.cc +++ b/libretroshare/src/services/p3gxsforums.cc @@ -53,7 +53,7 @@ p3GxsForums::p3GxsForums( RsGeneralDataService *gds, RsGenExchange( gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXS_TYPE_FORUMS, gixs, forumsAuthenPolicy()), RsGxsForums(static_cast(*this)), mGenToken(0), - mGenActive(false), mGenCount(0) + mGenActive(false), mGenCount(0), mKnownForumsMutex("GXS forums known forums timestamp cache") { // Test Data disabled in Repo. //RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD); @@ -96,14 +96,14 @@ uint32_t p3GxsForums::forumsAuthenPolicy() static const uint32_t GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months static const uint8_t GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ; -struct RsGxsForumNotifyRecordsItem: public RsItem +struct RsGxsGroupNotifyRecordsItem: public RsItem { - RsGxsForumNotifyRecordsItem() + RsGxsGroupNotifyRecordsItem() : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_FORUMS_CONFIG,GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD) {} - virtual ~RsGxsForumNotifyRecordsItem() {} + virtual ~RsGxsGroupNotifyRecordsItem() {} void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx ) @@ -127,7 +127,7 @@ public: switch(item_sub_id) { - case GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsForumNotifyRecordsItem(); + case GXS_FORUMS_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsGroupNotifyRecordsItem(); default: return NULL; } @@ -138,7 +138,7 @@ bool p3GxsForums::saveList(bool &cleanup, std::list&saveList) { cleanup = true ; - RsGxsForumNotifyRecordsItem *item = new RsGxsForumNotifyRecordsItem ; + RsGxsGroupNotifyRecordsItem *item = new RsGxsGroupNotifyRecordsItem ; item->records = mKnownForums ; @@ -155,7 +155,7 @@ bool p3GxsForums::loadList(std::list& loadList) rstime_t now = time(NULL); - RsGxsForumNotifyRecordsItem *fnr = dynamic_cast(item) ; + RsGxsGroupNotifyRecordsItem *fnr = dynamic_cast(item) ; if(fnr != NULL) { @@ -181,82 +181,140 @@ RsSerialiser* p3GxsForums::setupSerialiser() void p3GxsForums::notifyChanges(std::vector &changes) { - if (!changes.empty()) +#ifdef GXSFORUMS_DEBUG + std::cerr << "p3GxsForums::notifyChanges() : " << changes.size() << "changes to notify" << std::endl; +#endif + + std::vector::iterator it; + for(it = changes.begin(); it != changes.end(); ++it) { - p3Notify *notify = RsServer::notify(); - - if (notify) + RsGxsMsgChange *msgChange = dynamic_cast(*it); + if (msgChange) { - std::vector::iterator it; - for(it = changes.begin(); it != changes.end(); ++it) - { - RsGxsNotify *c = *it; - - switch (c->getType()) + if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) /* message received */ + if (rsEvents) { - default: - case RsGxsNotify::TYPE_PROCESSED: - case RsGxsNotify::TYPE_PUBLISHED: - break; + std::map >& msgChangeMap = msgChange->msgChangeMap; + for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) + for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1) + { + auto ev = std::make_shared(); + ev->mForumMsgId = *mit1; + ev->mForumGroupId = mit->first; + ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE; + rsEvents->postEvent(ev); + } + } - case RsGxsNotify::TYPE_RECEIVED_NEW: +#ifdef NOT_USED_YET + if (!msgChange->metaChange()) + { +#ifdef GXSCHANNELS_DEBUG + std::cerr << "p3GxsForums::notifyChanges() Found Message Change Notification"; + std::cerr << std::endl; +#endif + + std::map > &msgChangeMap = msgChange->msgChangeMap; + for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) + { +#ifdef GXSCHANNELS_DEBUG + std::cerr << "p3GxsForums::notifyChanges() Msgs for Group: " << mit->first; + std::cerr << std::endl; +#endif + bool enabled = false; + if (autoDownloadEnabled(mit->first, enabled) && enabled) { - RsGxsMsgChange *msgChange = dynamic_cast(c); - if (msgChange) - { - std::map > &msgChangeMap = msgChange->msgChangeMap; +#ifdef GXSCHANNELS_DEBUG + std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first; + std::cerr << std::endl; +#endif - for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) - { - for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1) - notify->AddFeedItem(RS_FEED_ITEM_FORUM_MSG, mit->first.toStdString(), mit1->toStdString()); - } - break; - } - - RsGxsGroupChange *grpChange = dynamic_cast(*it); - if (grpChange) - { - /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - - for (git = grpList.begin(); git != grpList.end(); ++git) - { - if(mKnownForums.find(*git) == mKnownForums.end()) - { - notify->AddFeedItem(RS_FEED_ITEM_FORUM_NEW, git->toStdString()); - mKnownForums.insert(std::make_pair(*git,time(NULL))) ; - - IndicateConfigChanged(); - } - else - std::cerr << "(II) Not notifying already known forum " << *git << std::endl; - } - break; - } - break; - } - - case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: - { - RsGxsGroupChange *grpChange = dynamic_cast(*it); - if (grpChange) - { - /* group received */ - std::list &grpList = grpChange->mGrpIdList; - std::list::iterator git; - for (git = grpList.begin(); git != grpList.end(); ++git) - { - notify->AddFeedItem(RS_FEED_ITEM_FORUM_PUBLISHKEY, git->toStdString()); - } - break; - } - break; + /* problem is most of these will be comments and votes, + * should make it occasional - every 5mins / 10minutes TODO */ + unprocessedGroups.push_back(mit->first); } } } +#endif } + else + { + if (rsEvents) + { + RsGxsGroupChange *grpChange = dynamic_cast(*it); + if (grpChange) + { + switch (grpChange->getType()) + { + default: + case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed + { + std::list &grpList = grpChange->mGrpIdList; + std::list::iterator git; + for (git = grpList.begin(); git != grpList.end(); ++git) + { + auto ev = std::make_shared(); + ev->mForumGroupId = *git; + ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED; + rsEvents->postEvent(ev); + } + + } + break; + + case RsGxsNotify::TYPE_PUBLISHED: + case RsGxsNotify::TYPE_RECEIVED_NEW: + { + /* group received */ + std::list &grpList = grpChange->mGrpIdList; + std::list::iterator git; + + RS_STACK_MUTEX(mKnownForumsMutex); + for (git = grpList.begin(); git != grpList.end(); ++git) + { + if(mKnownForums.find(*git) == mKnownForums.end()) + { + mKnownForums.insert( + std::make_pair(*git, time(nullptr))); + IndicateConfigChanged(); + + auto ev = std::make_shared(); + ev->mForumGroupId = *git; + ev->mForumEventCode = RsForumEventCode::NEW_FORUM; + rsEvents->postEvent(ev); + } + else + RsInfo() << __PRETTY_FUNCTION__ + << " Not notifying already known forum " + << *git << std::endl; + } + break; + } + +#ifdef NOT_USED_YET + case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: + { + /* group received */ + std::list &grpList = grpChange->mGrpIdList; + std::list::iterator git; + for (git = grpList.begin(); git != grpList.end(); ++git) + { + auto ev = std::make_shared(); + + ev->mChannelGroupId = *git; + ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY; + + rsEvents->sendEvent(ev); + } + } + break; +#endif + } + } + } + } + + /* shouldn't need to worry about groups - as they need to be subscribed to */ } RsGxsIfaceHelper::receiveChanges(changes); @@ -1087,3 +1145,4 @@ bool RsGxsForumGroup::canEditPosts(const RsGxsId& id) const RsGxsForumGroup::~RsGxsForumGroup() = default; RsGxsForumMsg::~RsGxsForumMsg() = default; RsGxsForums::~RsGxsForums() = default; +RsGxsForumEvent::~RsGxsForumEvent() = default; diff --git a/libretroshare/src/services/p3gxsforums.h b/libretroshare/src/services/p3gxsforums.h index 8d2ea3294..ae2bf74bf 100644 --- a/libretroshare/src/services/p3gxsforums.h +++ b/libretroshare/src/services/p3gxsforums.h @@ -166,4 +166,5 @@ bool generateGroup(uint32_t &token, std::string groupName); RsGxsMessageId mGenThreadId; std::map mKnownForums ; + RsMutex mKnownForumsMutex; }; diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index ebf2ce496..8acd44501 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -175,14 +175,12 @@ void p3MsgService::processIncomingMsg(RsMsgItem *mi) mi->msgFlags &= (RS_MSG_FLAGS_DISTANT | RS_MSG_FLAGS_SYSTEM); // remove flags except those mi->msgFlags |= RS_MSG_FLAGS_NEW; - p3Notify *notify = RsServer::notify(); - if (notify) + if (rsEvents) { - notify->AddPopupMessage(RS_POPUP_MSG, mi->PeerId().toStdString(), mi->subject, mi->message); - - std::string out; - rs_sprintf(out, "%lu", mi->msgId); - notify->AddFeedItem(RS_FEED_ITEM_MESSAGE, out, "", ""); + auto ev = std::make_shared(); + ev->mMailStatusEventCode = RsMailStatusEventCode::NEW_MESSAGE; + ev->mChangedMsgIds.insert(std::to_string(mi->msgId)); + rsEvents->postEvent(ev); } imsg[mi->msgId] = mi; @@ -207,13 +205,6 @@ void p3MsgService::processIncomingMsg(RsMsgItem *mi) } RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD); - - if(rsEvents) - { - std::shared_ptr pEvent(new RsMailStatusEvent()); - pEvent->mChangedMsgIds.insert(std::to_string(mi->msgId)); - rsEvents->postEvent(pEvent); - } } bool p3MsgService::checkAndRebuildPartialMessage(RsMsgItem *ci) @@ -345,8 +336,8 @@ int p3MsgService::checkOutgoingMessages() bool changed = false; std::list output_queue; - using Evt_t = RsMailStatusEvent; - std::shared_ptr pEvent(new Evt_t()); + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; { RS_STACK_MUTEX(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -404,11 +395,10 @@ int p3MsgService::checkOutgoingMessages() mit->second->msgFlags |= RS_MSG_FLAGS_ROUTED; } } +#ifdef DEBUG_DISTANT_MSG else - { - Dbg3() << __PRETTY_FUNCTION__ << " Delaying until available..." - << std::endl; - } + Dbg3() << __PRETTY_FUNCTION__ << " Delaying until available..." << std::endl; +#endif } /* clean up */ @@ -906,8 +896,9 @@ bool p3MsgService::removeMsgId(const std::string &mid) } bool changed = false; - using Evt_t = RsMailStatusEvent; - std::shared_ptr pEvent(new Evt_t()); + + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_REMOVED; { RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ @@ -1274,8 +1265,9 @@ uint32_t p3MsgService::sendMail( std::back_inserter(msgInfo.files) ); uint32_t ret = 0; - using Evt_t = RsMailStatusEvent; - std::shared_ptr pEvent(new Evt_t()); + + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::MESSAGE_SENT; auto pSend = [&](const std::set& sDest) { @@ -2089,10 +2081,13 @@ void p3MsgService::notifyDataStatus( const GRouterMsgPropagationId& id, NOTIFY_TYPE_ADD ); IndicateConfigChanged(); - using Evt_t = RsMailStatusEvent; - std::shared_ptr pEvent(new Evt_t()); - pEvent->mChangedMsgIds.insert(std::to_string(msg_id)); - if(rsEvents) rsEvents->postEvent(pEvent); + if(rsEvents) + { + auto pEvent = std::make_shared(); + pEvent->mMailStatusEventCode = RsMailStatusEventCode::NEW_MESSAGE; + pEvent->mChangedMsgIds.insert(std::to_string(msg_id)); + rsEvents->postEvent(pEvent); + } return; } @@ -2189,11 +2184,11 @@ bool p3MsgService::notifyGxsTransSendStatus( RsGxsTransId mailId, Dbg2() << __PRETTY_FUNCTION__ << " " << mailId << ", " << static_cast(status) << std::endl; - using Evt_t = RsMailStatusEvent; - std::shared_ptr pEvent(new Evt_t()); + auto pEvent = std::make_shared(); if( status == GxsTransSendStatus::RECEIPT_RECEIVED ) { + pEvent->mMailStatusEventCode = RsMailStatusEventCode::NEW_MESSAGE; uint32_t msg_id; { @@ -2248,19 +2243,20 @@ bool p3MsgService::notifyGxsTransSendStatus( RsGxsTransId mailId, else if( status >= GxsTransSendStatus::FAILED_RECEIPT_SIGNATURE ) { uint32_t msg_id; + pEvent->mMailStatusEventCode = RsMailStatusEventCode::SIGNATURE_FAILED; { RS_STACK_MUTEX(gxsOngoingMutex); - - std::cerr << __PRETTY_FUNCTION__ << " mail delivery " - << "mailId: " << mailId - << " failed with " << static_cast(status); + RsErr() << __PRETTY_FUNCTION__ << " mail delivery " + << "mailId: " << mailId + << " failed with " << static_cast(status); auto it = gxsOngoingMessages.find(mailId); if(it == gxsOngoingMessages.end()) { - std::cerr << " cannot find pending message to notify" - << std::endl; + RsErr() << __PRETTY_FUNCTION__ + << " cannot find pending message to notify" + << std::endl; return false; } diff --git a/libretroshare/src/services/p3postbase.cc b/libretroshare/src/services/p3postbase.cc index 9fb939baa..51308194c 100644 --- a/libretroshare/src/services/p3postbase.cc +++ b/libretroshare/src/services/p3postbase.cc @@ -29,7 +29,7 @@ #include "rsitems/rsgxscommentitems.h" #include "rsserver/p3face.h" -#include "retroshare/rsnotify.h" +#include "retroshare/rsposted.h" // For Dummy Msgs. #include "util/rsrandom.h" @@ -87,12 +87,6 @@ void p3PostBase::notifyChanges(std::vector &changes) std::cerr << std::endl; #endif - p3Notify *notify = NULL; - if (!changes.empty()) - { - notify = RsServer::notify(); - } - std::vector::iterator it; for(it = changes.begin(); it != changes.end(); ++it) @@ -118,13 +112,15 @@ void p3PostBase::notifyChanges(std::vector &changes) // It could be taken a step further and directly request these msgs for an update. addGroupForProcessing(mit->first); - if (notify && msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) - { + if (rsEvents && msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1) { - notify->AddFeedItem(RS_FEED_ITEM_POSTED_MSG, mit->first.toStdString(), mit1->toStdString()); + auto ev = std::make_shared(); + ev->mPostedMsgId = *mit1; + ev->mPostedGroupId = mit->first; + ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE; + rsEvents->postEvent(ev); } - } } } @@ -137,17 +133,20 @@ void p3PostBase::notifyChanges(std::vector &changes) #endif std::list &groupList = groupChange->mGrpIdList; - std::list::iterator git; - for(git = groupList.begin(); git != groupList.end(); ++git) + + for(auto git = groupList.begin(); git != groupList.end(); ++git) { #ifdef POSTBASE_DEBUG std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git; std::cerr << std::endl; #endif - if (notify && groupChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) + if (rsEvents && groupChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) { - notify->AddFeedItem(RS_FEED_ITEM_POSTED_NEW, git->toStdString()); + auto ev = std::make_shared(); + ev->mPostedGroupId = *git; + ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP; + rsEvents->postEvent(ev); } } } diff --git a/libretroshare/src/services/p3rtt.cc b/libretroshare/src/services/p3rtt.cc index 4c7effe36..0dc2f41e2 100644 --- a/libretroshare/src/services/p3rtt.cc +++ b/libretroshare/src/services/p3rtt.cc @@ -20,19 +20,20 @@ * * *******************************************************************************/ #include +#include +#include #include "util/rsdir.h" #include "retroshare/rsiface.h" +#include "retroshare/rspeers.h" #include "pqi/pqibin.h" #include "pqi/pqistore.h" #include "pqi/p3linkmgr.h" #include "rsserver/p3face.h" - +#include "util/cxx17retrocompat.h" #include "services/p3rtt.h" #include "rsitems/rsrttitems.h" -#include -#include /**** * #define DEBUG_RTT 1 @@ -352,28 +353,29 @@ int p3rtt::storePongResult(const RsPeerId& id, uint32_t counter, double recv_ts, while(peerInfo->mPongResults.size() > MAX_PONG_RESULTS) - { peerInfo->mPongResults.pop_front(); - } //Wait at least 20 pongs before compute mean time offset if(peerInfo->mPongResults.size() > 20) { double mean = 0; - for(std::list::const_iterator prIt = peerInfo->mPongResults.begin(), end = peerInfo->mPongResults.end(); prIt != end; ++ prIt) - { - mean += prIt->mOffset; - } + for(auto prIt : std::as_const(peerInfo->mPongResults)) + mean += prIt.mOffset; peerInfo->mCurrentMeanOffset = mean / peerInfo->mPongResults.size(); + if(fabs(peerInfo->mCurrentMeanOffset) > 120) { - p3Notify *notify = RsServer::notify(); - if (notify) + if(rsEvents) { - //notify->AddPopupMessage(RS_POPUP_OFFSET, eerInfo->mId.toStdString(),"", "Time Offset: "); - notify->AddFeedItem(RS_FEED_ITEM_PEER_OFFSET, peerInfo->mId.toStdString()); + auto ev = std::make_shared(); + ev->mSslId = peerInfo->mId; + ev->mTimeShift = static_cast(peerInfo->mCurrentMeanOffset); + ev->mConnectionInfoCode = RsConnectionEventCode::PEER_TIME_SHIFT; + rsEvents->postEvent(ev); } - std::cerr << "(WW) Peer:" << peerInfo->mId << " get time offset more than two minutes with you!!!" << std::endl; + RsWarn() << __PRETTY_FUNCTION__ << " Peer: " << peerInfo->mId + << " have a time offset of more than two minutes with you" + << std::endl; } } return 1; @@ -438,6 +440,7 @@ bool RttPeerInfo::initialisePeerInfo(const RsPeerId& id) mCurrentPingTS = 0; mCurrentPingCounter = 0; mCurrentPongRecvd = true; + mCurrentMeanOffset = 0; mSentPings = 0; mLostPongs = 0; diff --git a/libretroshare/src/services/p3rtt.h b/libretroshare/src/services/p3rtt.h index 80a369d17..c8df64034 100644 --- a/libretroshare/src/services/p3rtt.h +++ b/libretroshare/src/services/p3rtt.h @@ -34,6 +34,8 @@ class p3ServiceControl; class RttPeerInfo { public: + RttPeerInfo() + : mCurrentPingTS(0.0),mCurrentPingCounter(0.0),mCurrentPongRecvd(false),mCurrentMeanOffset(0.0),mLostPongs(0),mSentPings(0){} bool initialisePeerInfo(const RsPeerId& id); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 9a017270c..995ac13fc 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -18,7 +18,6 @@ * * *******************************************************************************/ -#include #include #include "NewsFeed.h" @@ -33,6 +32,7 @@ #include #include +#include "util/qtthreadsutils.h" #include "feeds/ChatMsgItem.h" #include "feeds/GxsCircleItem.h" #include "feeds/GxsChannelGroupItem.h" @@ -70,20 +70,14 @@ static NewsFeed *instance = NULL; /** Constructor */ -NewsFeed::NewsFeed(QWidget *parent) : - RsAutoUpdatePage(1000,parent), - ui(new Ui::NewsFeed) +NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed) { + mEventHandlerId =0; // needed to force intialization by registerEventsHandler() + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerId ); + /* Invoke the Qt Designer generated object setup routine */ ui->setupUi(this); - mTokenQueueChannel = NULL; - mTokenQueueCircle = NULL; - mTokenQueueForum = NULL; - mTokenQueuePosted = NULL; - - setUpdateWhenInvisible(true); - if (!instance) { instance = this; } @@ -96,7 +90,7 @@ NewsFeed::NewsFeed(QWidget *parent) : connect(ui->sortComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(sortChanged(int))); connect(ui->removeAllButton, SIGNAL(clicked()), ui->feedWidget, SLOT(clear())); - connect(ui->feedWidget, SIGNAL(feedCountChanged()), this, SLOT(sendNewsFeedChanged())); + connect(ui->feedWidget, SIGNAL(feedCountChanged()), this, SLOT(sendNewsFeedChanged()),Qt::QueuedConnection); connect(ui->feedOptionsButton, SIGNAL(clicked()), this, SLOT(feedoptions())); ui->feedOptionsButton->hide(); // (csoler) Hidden until we repare the system to display a specific settings page. @@ -123,25 +117,14 @@ QString hlp_str = tr( NewsFeed::~NewsFeed() { + rsEvents->unregisterEventsHandler(mEventHandlerId); + // save settings processSettings(false); if (instance == this) { instance = NULL; } - - if (mTokenQueueChannel) { - delete(mTokenQueueChannel); - } - if (mTokenQueueCircle) { - delete(mTokenQueueCircle); - } - if (mTokenQueueForum) { - delete(mTokenQueueForum); - } - if (mTokenQueuePosted) { - delete(mTokenQueuePosted); - } } UserNotify *NewsFeed::getUserNotify(QObject *parent) @@ -176,251 +159,242 @@ void NewsFeed::sortChanged(int index) ui->feedWidget->setSortRole(ROLE_RECEIVED, sortOrder); } -void NewsFeed::updateDisplay() -{ - if (!rsNotify) - return; +// handler for the new notification system in libretroshare. +void NewsFeed::handleEvent(std::shared_ptr event) +{ + // /!\ Absolutely no access to Qt structures (such as Settings) should happen here!!! + + RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); +} + +void NewsFeed::handleEvent_main_thread(std::shared_ptr event) +{ uint flags = Settings->getNewsFeedFlags(); - /* check for new messages */ - RsFeedItem fi; - if (rsNotify->GetFeedItem(fi)) + 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)) + handleConnectionEvent(event); + + if(event->mType == RsEventType::GXS_CIRCLES && (flags & RS_FEED_TYPE_CIRCLE)) + handleCircleEvent(event); + + if(event->mType == RsEventType::GXS_CHANNELS && (flags & RS_FEED_TYPE_CHANNEL)) + handleChannelEvent(event); + + if(event->mType == RsEventType::GXS_FORUMS && (flags & RS_FEED_TYPE_FORUM)) + handleForumEvent(event); + + if(event->mType == RsEventType::GXS_POSTED && (flags & RS_FEED_TYPE_POSTED)) + handleMailEvent(event); + + if(event->mType == RsEventType::MAIL_STATUS_CHANGE && (flags & RS_FEED_TYPE_MSG)) + handlePostedEvent(event); +} + +void NewsFeed::handleMailEvent(std::shared_ptr event) +{ + const RsMailStatusEvent *pe = + dynamic_cast(event.get()); + if(!pe) return; + + switch(pe->mMailStatusEventCode) { - switch(fi.mType) + case RsMailStatusEventCode::NEW_MESSAGE: + for(auto msgid: pe->mChangedMsgIds) + addFeedItem( new MsgItem(this, NEWSFEED_MESSAGELIST, msgid, false)); + break; + default: break; + } +} + +void NewsFeed::handlePostedEvent(std::shared_ptr event) +{ + const RsGxsPostedEvent *pe = + dynamic_cast(event.get()); + if(!pe) return; + + switch(pe->mPostedEventCode) + { + case RsPostedEventCode::NEW_POSTED_GROUP: + addFeedItem( new PostedGroupItem(this, NEWSFEED_POSTEDNEWLIST, pe->mPostedGroupId, false, true)); + break; + case RsPostedEventCode::NEW_MESSAGE: + addFeedItem( new PostedItem(this, NEWSFEED_POSTEDMSGLIST, pe->mPostedGroupId, pe->mPostedMsgId, false, true)); + break; + default: break; + } +} + +void NewsFeed::handleForumEvent(std::shared_ptr event) +{ + const RsGxsForumEvent *pe = dynamic_cast(event.get()); + if(!pe) return; + + switch(pe->mForumEventCode) + { + case RsForumEventCode::UPDATED_FORUM: + case RsForumEventCode::NEW_FORUM: + addFeedItem(new GxsForumGroupItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, false, true)); + break; + case RsForumEventCode::UPDATED_MESSAGE: + case RsForumEventCode::NEW_MESSAGE: + addFeedItem(new GxsForumMsgItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, pe->mForumMsgId, false, true)); + break; + default: break; + } +} + +void NewsFeed::handleChannelEvent(std::shared_ptr event) +{ + const RsGxsChannelEvent* pe = + dynamic_cast(event.get()); + if(!pe) return; + + switch(pe->mChannelEventCode) + { + case RsChannelEventCode::UPDATED_CHANNEL: // [[fallthrough]]; + case RsChannelEventCode::NEW_CHANNEL: + addFeedItem(new GxsChannelGroupItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, false, true)); + break; + case RsChannelEventCode::UPDATED_MESSAGE: // [[fallthrough]]; + case RsChannelEventCode::NEW_MESSAGE: + addFeedItem(new GxsChannelPostItem(this, NEWSFEED_CHANNELNEWLIST, pe->mChannelGroupId, pe->mChannelMsgId, false, true)); + break; + case RsChannelEventCode::RECEIVED_PUBLISH_KEY: + addFeedItem(new GxsChannelGroupItem(this, NEWSFEED_CHANNELPUBKEYLIST, pe->mChannelGroupId, false, true)); + break; + default: break; + } +} + +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 RS_FEED_ITEM_PEER_CONNECT: - if (flags & RS_FEED_TYPE_PEER) - addFeedItemPeerConnect(fi); - break; - case RS_FEED_ITEM_PEER_DISCONNECT: - if (flags & RS_FEED_TYPE_PEER) - addFeedItemPeerDisconnect(fi); - break; - case RS_FEED_ITEM_PEER_HELLO: - if (flags & RS_FEED_TYPE_PEER) - addFeedItemPeerHello(fi); - break; - case RS_FEED_ITEM_PEER_NEW: - if (flags & RS_FEED_TYPE_PEER) - addFeedItemPeerNew(fi); - break; - case RS_FEED_ITEM_PEER_OFFSET: - //if (flags & RS_FEED_TYPE_PEER) //Always allow this feed even if Friend notify is disabled. - addFeedItemPeerOffset(fi); - break; - - case RS_FEED_ITEM_SEC_CONNECT_ATTEMPT: - case RS_FEED_ITEM_SEC_WRONG_SIGNATURE: - case RS_FEED_ITEM_SEC_BAD_CERTIFICATE: - case RS_FEED_ITEM_SEC_MISSING_CERTIFICATE: - case RS_FEED_ITEM_SEC_INTERNAL_ERROR: - if (Settings->getMessageFlags() & RS_MESSAGE_CONNECT_ATTEMPT) { - MessageComposer::sendConnectAttemptMsg(RsPgpId(fi.mId1), RsPeerId(fi.mId2), QString::fromUtf8(fi.mId3.c_str())); - } - if (flags & RS_FEED_TYPE_SECURITY) - addFeedItemSecurityConnectAttempt(fi); - break; - case RS_FEED_ITEM_SEC_AUTH_DENIED: - if (flags & RS_FEED_TYPE_SECURITY) - addFeedItemSecurityAuthDenied(fi); - break; - case RS_FEED_ITEM_SEC_UNKNOWN_IN: - if (flags & RS_FEED_TYPE_SECURITY) - addFeedItemSecurityUnknownIn(fi); - break; - case RS_FEED_ITEM_SEC_UNKNOWN_OUT: - if (flags & RS_FEED_TYPE_SECURITY) - addFeedItemSecurityUnknownOut(fi); - break; - - case RS_FEED_ITEM_SEC_IP_BLACKLISTED: - if (flags & RS_FEED_TYPE_SECURITY_IP) - addFeedItemSecurityIpBlacklisted(fi, false); - break; - - case RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED: - if (flags & RS_FEED_TYPE_SECURITY_IP) - addFeedItemSecurityWrongExternalIpReported(fi, false); - break; - - case RS_FEED_ITEM_CHANNEL_NEW: - if (flags & RS_FEED_TYPE_CHANNEL) - addFeedItemChannelNew(fi); - break; -// case RS_FEED_ITEM_CHANNEL_UPDATE: -// if (flags & RS_FEED_TYPE_CHANNEL) -// addFeedItemChannelUpdate(fi); -// break; - case RS_FEED_ITEM_CHANNEL_MSG: - if (flags & RS_FEED_TYPE_CHANNEL) - addFeedItemChannelMsg(fi); - break; - case RS_FEED_ITEM_CHANNEL_PUBLISHKEY: - { - if (!mTokenQueueChannel) { - mTokenQueueChannel = new TokenQueue(rsGxsChannels->getTokenService(), instance); - } - - addFeedItemChannelPublishKey(fi); - -// 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; -// mTokenQueueChannel->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_PUBLISHKEY); -// } - } - break; - - case RS_FEED_ITEM_FORUM_NEW: - if (flags & RS_FEED_TYPE_FORUM) - addFeedItemForumNew(fi); - break; -// case RS_FEED_ITEM_FORUM_UPDATE: -// if (flags & RS_FEED_TYPE_FORUM) -// addFeedItemForumUpdate(fi); -// break; - case RS_FEED_ITEM_FORUM_MSG: - if (flags & RS_FEED_TYPE_FORUM) - addFeedItemForumMsg(fi); - break; - case RS_FEED_ITEM_FORUM_PUBLISHKEY: - { - if (!mTokenQueueForum) { - mTokenQueueForum = new TokenQueue(rsGxsForums->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; - mTokenQueueForum->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_PUBLISHKEY); - } - } -// if (flags & RS_FEED_TYPE_FORUM) -// addFeedItemForumPublishKey(fi); - break; - - case RS_FEED_ITEM_POSTED_NEW: - if (flags & RS_FEED_TYPE_POSTED) - addFeedItemPostedNew(fi); - break; -// case RS_FEED_ITEM_POSTED_UPDATE: -// if (flags & RS_FEED_TYPE_POSTED) -// addFeedItemPostedUpdate(fi); -// break; - case RS_FEED_ITEM_POSTED_MSG: - if (flags & RS_FEED_TYPE_POSTED) - addFeedItemPostedMsg(fi); - break; - -#if 0 - case RS_FEED_ITEM_BLOG_NEW: - if (flags & RS_FEED_TYPE_BLOG) - addFeedItemBlogNew(fi); - break; - case RS_FEED_ITEM_BLOG_MSG: - if (flags & RS_FEED_TYPE_BLOG) - addFeedItemBlogMsg(fi); - break; -#endif - - case RS_FEED_ITEM_CHAT_NEW: - if (flags & RS_FEED_TYPE_CHAT) - addFeedItemChatNew(fi, false); - break; - - case RS_FEED_ITEM_MESSAGE: - if (flags & RS_FEED_TYPE_MSG) - addFeedItemMessage(fi); - break; - - case RS_FEED_ITEM_FILES_NEW: - if (flags & RS_FEED_TYPE_FILES) - 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; - } - } else { - /* process plugin feeds */ - int pluginCount = rsPlugins->nbPlugins(); - for (int i = 0; i < pluginCount; ++i) { - RsPlugin *rsPlugin = rsPlugins->plugin(i); - if (rsPlugin) { - FeedNotify *feedNotify = rsPlugin->qt_feedNotify(); - if (feedNotify && feedNotify->notifyEnabled()) { - FeedItem *item = feedNotify->feedItem(this); - if (item) { - addFeedItem(item); - break; - } - } - } + case RsGxsCircleEventCode::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 RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN: + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true); + break; + case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE: + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true); + break; + case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE: + addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVIT_REC),true); + break; + case RsGxsCircleEventCode::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()); + if(!pe) return; + + auto& e(*pe); + +#ifdef NEWS_DEBUG + std::cerr << "NotifyQt: handling connection event from peer " << e.mSslId << std::endl; +#endif + + switch(e.mConnectionInfoCode) + { + case RsConnectionEventCode::PEER_CONNECTED: + addFeedItemIfUnique(new PeerItem(this, NEWSFEED_PEERLIST, e.mSslId, PEER_TYPE_CONNECT, false), true); + break; + case RsConnectionEventCode::PEER_DISCONNECTED: // not handled yet + break; + case RsConnectionEventCode::PEER_TIME_SHIFT: + addFeedItemIfUnique(new PeerItem(this, NEWSFEED_PEERLIST, e.mSslId, PEER_TYPE_OFFSET, false),false); + break; + case RsConnectionEventCode::PEER_REPORTS_WRONG_IP: + addFeedItemIfUnique(new SecurityIpItem( + this, e.mSslId, e.mOwnLocator.toString(), + e.mReportedLocator.toString(), + RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, + false ), false); + break; + default: break; + } +} + +void NewsFeed::handleSecurityEvent(std::shared_ptr event) +{ + const RsAuthSslConnectionAutenticationEvent *pe = dynamic_cast(event.get()); + + if(!pe) + return; + + auto& e(*pe); +#ifdef NEWS_DEBUG + std::cerr << "NotifyQt: handling security event from (" << e.mSslId << "," << e.mPgpId << ") error code: " << (int)e.mErrorCode << std::endl; +#endif + uint flags = Settings->getNewsFeedFlags(); + + if(e.mErrorCode == RsAuthSslError::PEER_REFUSED_CONNECTION) + { + addFeedItemIfUnique(new PeerItem(this, NEWSFEED_PEERLIST, e.mSslId, PEER_TYPE_HELLO, false), true ); + return; + } + + uint32_t FeedItemType=0; + + switch(e.mErrorCode) + { + case RsAuthSslError::NO_CERTIFICATE_SUPPLIED: // fallthrough + case RsAuthSslError::MISMATCHED_PGP_ID: // fallthrough + case RsAuthSslError::MISSING_AUTHENTICATION_INFO: + FeedItemType = RS_FEED_ITEM_SEC_BAD_CERTIFICATE; break; + case RsAuthSslError::PGP_SIGNATURE_VALIDATION_FAILED: + FeedItemType = RS_FEED_ITEM_SEC_WRONG_SIGNATURE; break; + case RsAuthSslError::NOT_A_FRIEND: + FeedItemType = RS_FEED_ITEM_SEC_CONNECT_ATTEMPT; break; + case RsAuthSslError::IP_IS_BLACKLISTED: + FeedItemType = RS_FEED_ITEM_SEC_IP_BLACKLISTED; break; + case RsAuthSslError::MISSING_CERTIFICATE: + FeedItemType = RS_FEED_ITEM_SEC_MISSING_CERTIFICATE; break; + default: + return; // display nothing + } + + RsPeerDetails det; + rsPeers->getPeerDetails(e.mSslId,det) || rsPeers->getGPGDetails(e.mPgpId,det); + + addFeedItemIfUnique(new SecurityItem(this, NEWSFEED_SECLIST, e.mPgpId, e.mSslId, det.location, e.mLocator.toString(), FeedItemType, false), true ); + + if (Settings->getMessageFlags() & RS_MESSAGE_CONNECT_ATTEMPT) + MessageComposer::addConnectAttemptMsg(e.mPgpId, e.mSslId, QString::fromStdString(det.name + "(" + det.location + ")")); +} + void NewsFeed::testFeeds(uint notifyFlags) { +#ifdef TO_REMOVE if (!instance) { return; } @@ -435,578 +409,13 @@ void NewsFeed::testFeeds(uint notifyFlags) ++pos; RsFeedItem fi; - - switch(type) { - case RS_FEED_TYPE_PEER: - fi.mId1 = rsPeers->getOwnId().toStdString(); - - instance->addFeedItemPeerConnect(fi); - instance->addFeedItemPeerDisconnect(fi); - instance->addFeedItemPeerHello(fi); - instance->addFeedItemPeerNew(fi); - instance->addFeedItemPeerOffset(fi); - break; - - case RS_FEED_TYPE_SECURITY: - fi.mId1 = rsPeers->getGPGOwnId().toStdString(); - fi.mId2 = rsPeers->getOwnId().toStdString(); - - instance->addFeedItemSecurityConnectAttempt(fi); - instance->addFeedItemSecurityAuthDenied(fi); - instance->addFeedItemSecurityUnknownIn(fi); - instance->addFeedItemSecurityUnknownOut(fi); - - break; - - case RS_FEED_TYPE_SECURITY_IP: - fi.mId1 = rsPeers->getOwnId().toStdString(); - fi.mId2 = "0.0.0.0"; - fi.mResult1 = RSBANLIST_CHECK_RESULT_BLACKLISTED; - instance->addFeedItemSecurityIpBlacklisted(fi, true); - - //fi.mId1 = rsPeers->getOwnId().toStdString(); - fi.mId2 = "0.0.0.1"; - fi.mId3 = "0.0.0.2"; - fi.mResult1 = 0; - instance->addFeedItemSecurityWrongExternalIpReported(fi, true); - - break; - - case RS_FEED_TYPE_CHANNEL: - { - if (!instance->mTokenQueueChannel) { - instance->mTokenQueueChannel = new TokenQueue(rsGxsChannels->getTokenService(), instance); - } - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token; - instance->mTokenQueueChannel->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_GROUP); - - break; - } - - case RS_FEED_TYPE_FORUM: - { - if (!instance->mTokenQueueForum) { - instance->mTokenQueueForum = new TokenQueue(rsGxsForums->getTokenService(), instance); - } - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token; - instance->mTokenQueueForum->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_GROUP); - - break; - } - - case RS_FEED_TYPE_POSTED: - { - if (!instance->mTokenQueuePosted) { - instance->mTokenQueuePosted = new TokenQueue(rsPosted->getTokenService(), instance); - } - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token; - instance->mTokenQueuePosted->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_GROUP); - - break; - } - -#if 0 - case RS_FEED_TYPE_BLOG: -// not used -// instance->addFeedItemBlogNew(fi); -// instance->addFeedItemBlogMsg(fi); - break; -#endif - - case RS_FEED_TYPE_CHAT: - fi.mId1 = rsPeers->getOwnId().toStdString(); - fi.mId2 = tr("This is a test.").toUtf8().constData(); - - instance->addFeedItemChatNew(fi, true); - break; - - case RS_FEED_TYPE_MSG: - { - std::list msgList; - rsMail->getMessageSummaries(msgList); - - std::list::const_iterator msgIt; - for (msgIt = msgList.begin(); msgIt != msgList.end(); ++msgIt) { - if (fi.mId1.empty()) { - /* store first message */ - fi.mId1 = msgIt->msgId; - } - - if (msgIt->msgflags & RS_MSG_TRASH) { - continue; - } - - if ((msgIt->msgflags & RS_MSG_BOXMASK) == RS_MSG_INBOX) { - /* take message from inbox */ - fi.mId1 = msgIt->msgId; - break; - } - } - - instance->addFeedItemMessage(fi); - break; - } - - case RS_FEED_TYPE_FILES: -// not used -// instance->addFeedItemFilesNew(fi); - break; - - case RS_FEED_TYPE_CIRCLE: - { - if (!instance->mTokenQueueCircle) { - instance->mTokenQueueCircle = new TokenQueue(rsGxsCircles->getTokenService(), instance); - } - - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token; - instance->mTokenQueueCircle->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, TOKEN_TYPE_GROUP); - - break; - } -// instance->addFeedItemCircleMembReq(fi); -// instance->addFeedItemCircleInvitRec(fi); - break; - - } } instance->ui->feedWidget->enableCountChangedSignal(true); instance->sendNewsFeedChanged(); -} - -void NewsFeed::loadCircleGroup(const uint32_t &token) -{ - std::vector groups; - if (!rsGxsCircles->getGroupData(token, groups)) { - std::cerr << "NewsFeed::loadCircleGroup() ERROR getting data"; - std::cerr << std::endl; - return; - } - - std::list own_identities; - rsIdentity->getOwnIds(own_identities); - - std::vector::const_iterator circleIt; - for (circleIt = groups.begin(); circleIt != groups.end(); ++circleIt) { - RsGxsCircleGroup group = *(circleIt); - RsGxsCircleDetails details; - if(rsGxsCircles->getCircleDetails(group.mMeta.mCircleId,details)) - { - for(std::list::const_iterator it(own_identities.begin());it!=own_identities.end();++it) { - std::map::const_iterator vit = details.mSubscriptionFlags.find(*it); - uint32_t subscribe_flags = (vit == details.mSubscriptionFlags.end())?0:(vit->second); - - if( !(subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED) - && (subscribe_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) ) { - - RsFeedItem fi; - fi.mId1 = group.mMeta.mGroupId.toStdString(); - fi.mId2 = it->toStdString(); - - instance->addFeedItemCircleInvitRec(fi); - - } - } - } - } -} - -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); - - //} - //} - } - } -} - -void NewsFeed::loadChannelGroup(const uint32_t &token) -{ - std::vector groups; - if (!rsGxsChannels->getGroupData(token, groups)) { - std::cerr << "NewsFeed::loadChannelGroup() ERROR getting data"; - std::cerr << std::endl; - return; - } - - RsFeedItem fi; - std::vector::iterator channelIt; - for (channelIt = groups.begin(); channelIt != groups.end(); ++channelIt) { - if (fi.mId1.empty()) { - /* store first channel */ - fi.mId1 = channelIt->mMeta.mGroupId.toStdString(); - } - - if (!channelIt->mDescription.empty()) { - /* take channel with description */ - fi.mId1 = channelIt->mMeta.mGroupId.toStdString(); - break; - } - } - - if (fi.mId1.empty()) { - return; - } - - instance->addFeedItemChannelNew(fi); -// instance->addFeedItemChanUpdate(fi); - - /* Prepare group ids for message request */ - std::list grpIds; - for (channelIt = groups.begin(); channelIt != groups.end(); ++channelIt) { - grpIds.push_back(channelIt->mMeta.mGroupId); - } - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD; - uint32_t msgToken; - instance->mTokenQueueChannel->requestMsgInfo(msgToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_MESSAGE); -} - -void NewsFeed::loadChannelPost(const uint32_t &token) -{ - std::vector posts; - if (!rsGxsChannels->getPostData(token, posts)) { - std::cerr << "NewsFeed::loadChannelPost() ERROR getting data"; - std::cerr << std::endl; - return; - } - - RsFeedItem fi; - std::vector::iterator postIt; - for (postIt = posts.begin(); postIt != posts.end(); ++postIt) { - if (fi.mId2.empty()) { - /* store first channel message */ - fi.mId1 = postIt->mMeta.mGroupId.toStdString(); - fi.mId2 = postIt->mMeta.mMsgId.toStdString(); - } - - if (!postIt->mMsg.empty()) { - /* take channel message with description */ - fi.mId1 = postIt->mMeta.mGroupId.toStdString(); - fi.mId2 = postIt->mMeta.mMsgId.toStdString(); - break; - } - } - - if (!fi.mId1.empty()) { - instance->addFeedItemChannelMsg(fi); - } -} - -void NewsFeed::loadChannelPublishKey(const uint32_t &token) -{ - std::vector groups; - if (!rsGxsChannels->getGroupData(token, groups)) { - std::cerr << "NewsFeed::loadChannelPublishKey() ERROR getting data"; - std::cerr << std::endl; - return; - } - - if (groups.size() != 1) - { - std::cerr << "NewsFeed::loadChannelPublishKey() Wrong number of Items"; - std::cerr << std::endl; - return; - } -#ifdef UNUSED_CODE - MessageComposer::sendChannelPublishKey(groups[0]); #endif - - RsGxsChannelGroup& grp = *groups.begin(); - - RsFeedItem fi; - fi.mId1 = grp.mMeta.mGroupId.toStdString(); - - - addFeedItemChannelPublishKey(fi); -} - -void NewsFeed::loadForumGroup(const uint32_t &token) -{ - std::vector forums; - if (!rsGxsForums->getGroupData(token, forums)) { - std::cerr << "NewsFeed::loadForumGroup() ERROR getting data"; - std::cerr << std::endl; - return; - } - - RsFeedItem fi; - std::vector::iterator forumIt; - for (forumIt = forums.begin(); forumIt != forums.end(); ++forumIt) { - if (fi.mId1.empty()) { - /* store first forum */ - fi.mId1 = forumIt->mMeta.mGroupId.toStdString(); - } - - if (!forumIt->mDescription.empty()) { - /* take forum with description */ - fi.mId1 = forumIt->mMeta.mGroupId.toStdString(); - break; - } - } - - if (fi.mId1.empty()) { - return; - } - - instance->addFeedItemForumNew(fi); -// instance->addFeedItemForumUpdate(fi); - - /* Prepare group ids for message request */ - std::list grpIds; - for (forumIt = forums.begin(); forumIt != forums.end(); ++forumIt) { - grpIds.push_back(forumIt->mMeta.mGroupId); - } - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD; - uint32_t msgToken; - instance->mTokenQueueForum->requestMsgInfo(msgToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_MESSAGE); -} - -void NewsFeed::loadForumMessage(const uint32_t &token) -{ - std::vector msgs; - if (!rsGxsForums->getMsgData(token, msgs)) { - std::cerr << "NewsFeed::loadForumPost() ERROR getting data"; - std::cerr << std::endl; - return; - } - - RsFeedItem fi; - std::vector::iterator msgIt; - for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) { - if (fi.mId2.empty()) { - /* store first forum message */ - fi.mId1 = msgIt->mMeta.mGroupId.toStdString(); - fi.mId2 = msgIt->mMeta.mMsgId.toStdString(); - } - - if (!msgIt->mMsg.empty()) { - /* take forum message with description */ - fi.mId1 = msgIt->mMeta.mGroupId.toStdString(); - fi.mId2 = msgIt->mMeta.mMsgId.toStdString(); - break; - } - } - - if (!fi.mId1.empty()) { - instance->addFeedItemForumMsg(fi); - } -} - -void NewsFeed::loadForumPublishKey(const uint32_t &token) -{ - std::vector groups; - if (!rsGxsForums->getGroupData(token, groups)) { - std::cerr << "NewsFeed::loadForumPublishKey() ERROR getting data"; - std::cerr << std::endl; - return; - } - - if (groups.size() != 1) - { - std::cerr << "NewsFeed::loadForumPublishKey() Wrong number of Items"; - std::cerr << std::endl; - return; - } -#ifdef UNUSED_CODE - MessageComposer::sendForumPublishKey(groups[0]); -#endif - - std::cerr << "(EE) Unimplemented code: received an order to load/display item for received forum publish key, but the implementation is missing." << std::endl; -} - -void NewsFeed::loadPostedGroup(const uint32_t &token) -{ - std::vector posted; - if (!rsPosted->getGroupData(token, posted)) { - std::cerr << "NewsFeed::loadPostedGroup() ERROR getting data"; - std::cerr << std::endl; - return; - } - - RsFeedItem fi; - std::vector::iterator postedIt; - for (postedIt = posted.begin(); postedIt != posted.end(); ++postedIt) { - if (fi.mId1.empty()) { - /* store first posted */ - fi.mId1 = postedIt->mMeta.mGroupId.toStdString(); - } - - if (!postedIt->mDescription.empty()) { - /* take posted with description */ - fi.mId1 = postedIt->mMeta.mGroupId.toStdString(); - break; - } - } - - if (fi.mId1.empty()) { - return; - } - - instance->addFeedItemPostedNew(fi); -// instance->addFeedItemPostedUpdate(fi); - - /* Prepare group ids for message request */ - std::list grpIds; - for (postedIt = posted.begin(); postedIt != posted.end(); ++postedIt) { - grpIds.push_back(postedIt->mMeta.mGroupId); - } - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; - opts.mOptions = RS_TOKREQOPT_MSG_THREAD; - uint32_t msgToken; - instance->mTokenQueuePosted->requestMsgInfo(msgToken, RS_TOKREQ_ANSTYPE_SUMMARY, opts, grpIds, TOKEN_TYPE_MESSAGE); -} - -void NewsFeed::loadPostedMessage(const uint32_t &token) -{ - std::vector msgs; - if (!rsPosted->getPostData(token, msgs)) { - std::cerr << "NewsFeed::loadPostedPost() ERROR getting data"; - std::cerr << std::endl; - return; - } - - RsFeedItem fi; - std::vector::iterator msgIt; - for (msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) { - if (fi.mId2.empty()) { - /* store first posted message */ - fi.mId1 = msgIt->mMeta.mGroupId.toStdString(); - fi.mId2 = msgIt->mMeta.mMsgId.toStdString(); - } - - if (!msgIt->mLink.empty()) { - /* take posted message with description */ - fi.mId1 = msgIt->mMeta.mGroupId.toStdString(); - fi.mId2 = msgIt->mMeta.mMsgId.toStdString(); - break; - } - } - - if (!fi.mId1.empty()) { - instance->addFeedItemPostedMsg(fi); - } -} - -void NewsFeed::loadRequest(const TokenQueue *queue, const TokenRequest &req) -{ - if (queue == mTokenQueueChannel) { - switch (req.mUserType) { - case TOKEN_TYPE_GROUP: - loadChannelGroup(req.mToken); - break; - - case TOKEN_TYPE_MESSAGE: - loadChannelPost(req.mToken); - break; - - case TOKEN_TYPE_PUBLISHKEY: - loadChannelPublishKey(req.mToken); - break; - - default: - std::cerr << "NewsFeed::loadRequest() ERROR: INVALID CHANNEL TYPE"; - std::cerr << std::endl; - break; - } - } - - if (queue == mTokenQueueCircle) { - switch (req.mUserType) { - case TOKEN_TYPE_GROUP: - loadCircleGroup(req.mToken); - break; - - case TOKEN_TYPE_MESSAGE: - loadCircleMessage(req.mToken); - break; - - default: - std::cerr << "NewsFeed::loadRequest() ERROR: INVALID CIRCLE TYPE"; - std::cerr << std::endl; - break; - } - } - - if (queue == mTokenQueueForum) { - switch (req.mUserType) { - case TOKEN_TYPE_GROUP: - loadForumGroup(req.mToken); - break; - - case TOKEN_TYPE_MESSAGE: - loadForumMessage(req.mToken); - break; - - case TOKEN_TYPE_PUBLISHKEY: - loadForumPublishKey(req.mToken); - break; - - default: - std::cerr << "NewsFeed::loadRequest() ERROR: INVALID FORUM TYPE"; - std::cerr << std::endl; - break; - } - } - - if (queue == mTokenQueuePosted) { - switch (req.mUserType) { - case TOKEN_TYPE_GROUP: - loadPostedGroup(req.mToken); - break; - - case TOKEN_TYPE_MESSAGE: - loadPostedMessage(req.mToken); - break; - - default: - std::cerr << "NewsFeed::loadRequest() ERROR: INVALID POSTED TYPE"; - std::cerr << std::endl; - break; - } - } + std::cerr << "(EE) testFeeds() is currently disabled" << std::endl; } void NewsFeed::testFeed(FeedNotify *feedNotify) @@ -1047,82 +456,17 @@ void NewsFeed::addFeedItem(FeedItem *item) } ui->feedWidget->addFeedItem(item, ROLE_RECEIVED, QDateTime::currentDateTime()); + sendNewsFeedChanged(); } -struct AddFeedItemIfUniqueData +void NewsFeed::addFeedItemIfUnique(FeedItem *item, bool replace) { - AddFeedItemIfUniqueData(FeedItem *feedItem, int type - , const std::string& id1, const std::string& id2 - , const std::string& id3, const std::string& id4) - : mType(type), mId1(id1), mId2(id2), mId3(id3), mId4(id4) - { - mGxsCircleItem = dynamic_cast(feedItem); - mPeerItem = dynamic_cast(feedItem); - mSecItem = dynamic_cast(feedItem); - mSecurityIpItem = dynamic_cast(feedItem); - } + FeedItem *feedItem = ui->feedWidget->findFeedItem(item->uniqueIdentifier()); - int mType; - const std::string& mId1; - const std::string& mId2; - const std::string& mId3; - const std::string& mId4; - - GxsCircleItem *mGxsCircleItem; - PeerItem *mPeerItem; - SecurityItem *mSecItem; - SecurityIpItem *mSecurityIpItem; -}; - -static bool addFeedItemIfUniqueCallback(FeedItem *feedItem, void *data) -{ - AddFeedItemIfUniqueData *findData = (AddFeedItemIfUniqueData*) data; - if (!findData || findData->mId1.empty()) { - return false; - } - - if (findData->mGxsCircleItem) { - GxsCircleItem *gxsCircleItem = dynamic_cast(feedItem); - if (gxsCircleItem && gxsCircleItem->isSame(RsGxsCircleId(findData->mId1), RsGxsId(findData->mId2), findData->mType)) { - return true; - } - return false; - } - - if (findData->mPeerItem) { - PeerItem *peerItem = dynamic_cast(feedItem); - if (peerItem && peerItem->isSame(RsPeerId(findData->mId1), findData->mType)) { - return true; - } - return false; - } - - if (findData->mSecItem) { - SecurityItem *secitem = dynamic_cast(feedItem); - if (secitem && secitem->isSame(RsPeerId(findData->mId1), findData->mType)) { - return true; - } - return false; - } - - if (findData->mSecurityIpItem) { - SecurityIpItem *securityIpItem = dynamic_cast(feedItem); - if (securityIpItem && securityIpItem->isSame(RsPeerId(findData->mId1), findData->mId2, findData->mId3, findData->mType)) { - return true; - } - return false; - } - - return false; -} - -void NewsFeed::addFeedItemIfUnique(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, bool replace) -{ - AddFeedItemIfUniqueData data(item, itemType, id1, id2, id3, id4); - FeedItem *feedItem = ui->feedWidget->findFeedItem(addFeedItemIfUniqueCallback, &data); - - if (feedItem) { - if (!replace) { + if (feedItem) + { + if (!replace) + { delete item; return; } @@ -1131,481 +475,21 @@ void NewsFeed::addFeedItemIfUnique(FeedItem *item, int itemType, const std::stri } addFeedItem(item); + sendNewsFeedChanged(); } -void NewsFeed::remUniqueFeedItem(FeedItem *item, int itemType, const std::string &id1, const std::string &id2, const std::string &id3, const std::string &id4) +void NewsFeed::remUniqueFeedItem(FeedItem *item) { - AddFeedItemIfUniqueData data(item, itemType, id1, id2, id3, id4); - FeedItem *feedItem = ui->feedWidget->findFeedItem(addFeedItemIfUniqueCallback, &data); + FeedItem *feedItem = ui->feedWidget->findFeedItem(item->uniqueIdentifier()); - if (feedItem) { + if (feedItem) + { delete item; ui->feedWidget->removeFeedItem(feedItem); } } -void NewsFeed::addFeedItemPeerConnect(const RsFeedItem &fi) -{ - /* make new widget */ - PeerItem *pi = new PeerItem(this, NEWSFEED_PEERLIST, RsPeerId(fi.mId1), PEER_TYPE_CONNECT, false); - - /* add to layout */ - addFeedItem(pi); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemPeerConnect()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemPeerDisconnect(const RsFeedItem &fi) -{ - /* make new widget */ - PeerItem *pi = new PeerItem(this, NEWSFEED_PEERLIST, RsPeerId(fi.mId1), PEER_TYPE_STD, false); - - /* add to layout */ - addFeedItem(pi); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemPeerDisconnect()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemPeerHello(const RsFeedItem &fi) -{ - /* make new widget */ - PeerItem *pi = new PeerItem(this, NEWSFEED_PEERLIST, RsPeerId(fi.mId1), PEER_TYPE_HELLO, false); - - /* add to layout */ - addFeedItem(pi); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemPeerHello()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemPeerNew(const RsFeedItem &fi) -{ - /* make new widget */ - PeerItem *pi = new PeerItem(this, NEWSFEED_PEERLIST, RsPeerId(fi.mId1), PEER_TYPE_NEW_FOF, false); - - /* add to layout */ - addFeedItem(pi); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemPeerNew()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemPeerOffset(const RsFeedItem &fi) -{ - /* make new widget */ - PeerItem *pi = new PeerItem(this, NEWSFEED_PEERLIST, RsPeerId(fi.mId1), PEER_TYPE_OFFSET, false); - - /* add to layout */ - addFeedItemIfUnique(pi, PEER_TYPE_OFFSET, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemPeerOffset()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemSecurityConnectAttempt(const RsFeedItem &fi) -{ - /* make new widget */ - SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, fi.mType, false); - - /* add to layout */ - addFeedItemIfUnique(pi, fi.mType, fi.mId2, "", "", "", false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemSecurityConnectAttempt()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemSecurityAuthDenied(const RsFeedItem &fi) -{ - /* make new widget */ - SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, fi.mType, false); - - /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_AUTH_DENIED, fi.mId2, "", "", "", false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemSecurityAuthDenied()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemSecurityUnknownIn(const RsFeedItem &fi) -{ - /* make new widget */ - SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, RS_FEED_ITEM_SEC_UNKNOWN_IN, false); - - /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_IN, fi.mId2, "", "", "", false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemSecurityUnknownIn()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemSecurityUnknownOut(const RsFeedItem &fi) -{ - /* make new widget */ - SecurityItem *pi = new SecurityItem(this, NEWSFEED_SECLIST, RsPgpId(fi.mId1), RsPeerId(fi.mId2), fi.mId3, fi.mId4, RS_FEED_ITEM_SEC_UNKNOWN_OUT, false); - - /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_UNKNOWN_OUT, fi.mId2, "", "", "", false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemSecurityUnknownOut()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemSecurityIpBlacklisted(const RsFeedItem &fi, bool isTest) -{ - /* make new widget */ - SecurityIpItem *pi = new SecurityIpItem(this, RsPeerId(fi.mId1), fi.mId2, fi.mResult1, RS_FEED_ITEM_SEC_IP_BLACKLISTED, isTest); - - /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_IP_BLACKLISTED, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemSecurityIpBlacklisted()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemSecurityWrongExternalIpReported(const RsFeedItem &fi, bool isTest) -{ - /* make new widget */ - SecurityIpItem *pi = new SecurityIpItem(this, RsPeerId(fi.mId1), fi.mId2, fi.mId3, RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, isTest); - - /* add to layout */ - addFeedItemIfUnique(pi, RS_FEED_ITEM_SEC_IP_WRONG_EXTERNAL_IP_REPORTED, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemSecurityWrongExternalIpReported()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemChannelNew(const RsFeedItem &fi) -{ - RsGxsGroupId grpId(fi.mId1); - - if (grpId.isNull()) { - return; - } - - /* make new widget */ - GxsChannelGroupItem *item = new GxsChannelGroupItem(this, NEWSFEED_CHANNELNEWLIST, grpId, false, true); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemChanNew()"; - std::cerr << std::endl; -#endif -} - -//void NewsFeed::addFeedItemChannelUpdate(const RsFeedItem &fi) -//{ -// /* make new widget */ -// ChanNewItem *cni = new ChanNewItem(this, NEWSFEED_CHANNEWLIST, fi.mId1, false, false); - -// /* add to layout */ -// addFeedItem(cni); - -//#ifdef NEWS_DEBUG -// std::cerr << "NewsFeed::addFeedItemChanUpdate()"; -// std::cerr << std::endl; -//#endif -//} - -void NewsFeed::addFeedItemChannelMsg(const RsFeedItem &fi) -{ - RsGxsGroupId grpId(fi.mId1); - RsGxsMessageId msgId(fi.mId2); - - if (grpId.isNull() || msgId.isNull()) { - return; - } - - /* make new widget */ - GxsChannelPostItem *item = new GxsChannelPostItem(this, NEWSFEED_CHANNELNEWLIST, grpId, msgId, false, true); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemChanMsg()"; - std::cerr << std::endl; -#endif -} -void NewsFeed::addFeedItemChannelPublishKey(const RsFeedItem &fi) -{ - RsGxsGroupId grpId(fi.mId1); - - if (grpId.isNull()) - return; - - /* make new widget */ - GxsChannelGroupItem *item = new GxsChannelGroupItem(this, NEWSFEED_CHANNELPUBKEYLIST, grpId, false, true); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemChanMsg()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemForumNew(const RsFeedItem &fi) -{ - RsGxsGroupId grpId(fi.mId1); - - if (grpId.isNull()) { - return; - } - - /* make new widget */ - GxsForumGroupItem *item = new GxsForumGroupItem(this, NEWSFEED_FORUMNEWLIST, grpId, false, true); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemForumNew()"; - std::cerr << std::endl; -#endif -} - -//void NewsFeed::addFeedItemForumUpdate(const RsFeedItem &fi) -//{ -// /* make new widget */ -// ForumNewItem *fni = new ForumNewItem(this, NEWSFEED_FORUMNEWLIST, fi.mId1, false, false); - -// /* add to layout */ -// addFeedItem(fni); - -//#ifdef NEWS_DEBUG -// std::cerr << "NewsFeed::addFeedItemForumUpdate()"; -// std::cerr << std::endl; -//#endif -//} - -void NewsFeed::addFeedItemForumMsg(const RsFeedItem &fi) -{ - RsGxsGroupId grpId(fi.mId1); - RsGxsMessageId msgId(fi.mId2); - - if (grpId.isNull() || msgId.isNull()) { - return; - } - - /* make new widget */ - GxsForumMsgItem *item = new GxsForumMsgItem(this, NEWSFEED_FORUMMSGLIST, grpId, msgId, false, true); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemForumMsg()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemPostedNew(const RsFeedItem &fi) -{ - RsGxsGroupId grpId(fi.mId1); - - if (grpId.isNull()) { - return; - } - - /* make new widget */ - PostedGroupItem *item = new PostedGroupItem(this, NEWSFEED_POSTEDNEWLIST, grpId, false, true); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemPostedNew()"; - std::cerr << std::endl; -#endif -} - -//void NewsFeed::addFeedItemPostedUpdate(const RsFeedItem &fi) -//{ -// /* make new widget */ -// GxsPostedGroupItem *item = new GxsPostedGroupItem(this, NEWSFEED_POSTEDNEWLIST, grpId, false, true); - -// /* add to layout */ -// addFeedItem(item); - -//#ifdef NEWS_DEBUG -// std::cerr << "NewsFeed::addFeedItemPostedUpdate()"; -// std::cerr << std::endl; -//#endif -//} - -void NewsFeed::addFeedItemPostedMsg(const RsFeedItem &fi) -{ - RsGxsGroupId grpId(fi.mId1); - RsGxsMessageId msgId(fi.mId2); - - if (grpId.isNull() || msgId.isNull()) { - return; - } - - /* make new widget */ - PostedItem *item = new PostedItem(this, NEWSFEED_POSTEDMSGLIST, grpId, msgId, false, true); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemPostedMsg()"; - std::cerr << std::endl; -#endif -} - -#if 0 -void NewsFeed::addFeedItemBlogNew(const RsFeedItem &fi) -{ - Q_UNUSED(fi); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemBlogNew()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemBlogMsg(const RsFeedItem &fi) -{ - Q_UNUSED(fi); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemBlogMsg()"; - std::cerr << std::endl; -#endif -} - -#endif - -void NewsFeed::addFeedItemChatNew(const RsFeedItem &fi, bool addWithoutCheck) -{ -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemChatNew()"; - std::cerr << std::endl; -#endif - - if (!addWithoutCheck && fi.mId1 == rsPeers->getOwnId().toStdString()) { - /* chat message from myself */ - return; - } - - /* make new widget */ - ChatMsgItem *cm = new ChatMsgItem(this, NEWSFEED_CHATMSGLIST, RsPeerId(fi.mId1), fi.mId2); - - /* add to layout */ - addFeedItem(cm); -} - -void NewsFeed::addFeedItemMessage(const RsFeedItem &fi) -{ - /* make new widget */ - MsgItem *mi = new MsgItem(this, NEWSFEED_MESSAGELIST, fi.mId1, false); - - /* add to layout */ - addFeedItem(mi); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemMessage()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemFilesNew(const RsFeedItem &/*fi*/) -{ -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemFilesNew()"; - std::cerr << std::endl; -#endif -} - -void NewsFeed::addFeedItemCircleMembReq(const RsFeedItem &fi) -{ - RsGxsCircleId circleId(fi.mId1); - RsGxsId gxsId(fi.mId2); - - if (circleId.isNull() || gxsId.isNull()) { - return; - } - - /* make new widget */ - GxsCircleItem *item = new GxsCircleItem(this, NEWSFEED_CIRCLELIST, circleId, gxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ); - - /* add to layout */ - addFeedItemIfUnique(item, RS_FEED_ITEM_CIRCLE_MEMB_REQ, fi.mId1, fi.mId2, fi.mId3, fi.mId4, false); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemCircleMembReq()" << std::endl; -#endif -} - -void NewsFeed::remFeedItemCircleMembReq(const RsFeedItem &fi) -{ - RsGxsCircleId circleId(fi.mId1); - RsGxsId gxsId(fi.mId2); - - if (circleId.isNull() || gxsId.isNull()) { - return; - } - - /* make new widget */ - GxsCircleItem *item = new GxsCircleItem(this, NEWSFEED_CIRCLELIST, circleId, gxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ); - - /* add to layout */ - remUniqueFeedItem(item, RS_FEED_ITEM_CIRCLE_MEMB_REQ, fi.mId1, fi.mId2, fi.mId3, fi.mId4); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::remFeedItemCircleMembReq()" << std::endl; -#endif -} - -void NewsFeed::addFeedItemCircleInvitRec(const RsFeedItem &fi) -{ - RsGxsCircleId circleId(fi.mId1); - RsGxsId gxsId(fi.mId2); - - if (circleId.isNull()) { - return; - } - - /* make new widget */ - GxsCircleItem *item = new GxsCircleItem(this, NEWSFEED_CIRCLELIST, circleId, gxsId, RS_FEED_ITEM_CIRCLE_INVIT_REC); - - /* add to layout */ - addFeedItem(item); - -#ifdef NEWS_DEBUG - std::cerr << "NewsFeed::addFeedItemCircleInvitRec()" << std::endl; -#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 3b91774ce..c255d56ac 100644 --- a/retroshare-gui/src/gui/NewsFeed.h +++ b/retroshare-gui/src/gui/NewsFeed.h @@ -56,7 +56,7 @@ class RsFeedItem; class FeedNotify; class FeedItem; -class NewsFeed : public RsAutoUpdatePage, public FeedHolder, public TokenResponse +class NewsFeed : public MainPage,public FeedHolder { Q_OBJECT @@ -81,7 +81,7 @@ public: static void testFeeds(uint notifyFlags); static void testFeed(FeedNotify *feedNotify); - virtual void updateDisplay(); + void handleEvent(std::shared_ptr event); // get events from libretroshare signals: void newsFeedChanged(int count); @@ -89,82 +89,36 @@ signals: protected: void processSettings(bool load); - /* TokenResponse */ - virtual void loadRequest(const TokenQueue *queue, const TokenRequest &req); - private slots: -// void toggleChanMsgItems(bool on); void feedoptions(); void sortChanged(int index); void sendNewsFeedChanged(); private: + void handleEvent_main_thread(std::shared_ptr event); + + void handleSecurityEvent(std::shared_ptr event); + void handleConnectionEvent(std::shared_ptr event); + void handleCircleEvent(std::shared_ptr event); + void handleForumEvent(std::shared_ptr event); + void handleMailEvent(std::shared_ptr event); + void handlePostedEvent(std::shared_ptr event); + void handleChannelEvent(std::shared_ptr event); + void addFeedItem(FeedItem *item); - void addFeedItemIfUnique(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4, bool replace); - void remUniqueFeedItem(FeedItem *item, int itemType, const std::string& id1, const std::string& id2, const std::string& id3, const std::string& id4); - - void addFeedItemPeerConnect(const RsFeedItem &fi); - void addFeedItemPeerDisconnect(const RsFeedItem &fi); - void addFeedItemPeerHello(const RsFeedItem &fi); - void addFeedItemPeerNew(const RsFeedItem &fi); - void addFeedItemPeerOffset(const RsFeedItem &fi); - - void addFeedItemSecurityConnectAttempt(const RsFeedItem &fi); - void addFeedItemSecurityAuthDenied(const RsFeedItem &fi); - void addFeedItemSecurityUnknownIn(const RsFeedItem &fi); - void addFeedItemSecurityUnknownOut(const RsFeedItem &fi); - void addFeedItemSecurityIpBlacklisted(const RsFeedItem &fi, bool isTest); - void addFeedItemSecurityWrongExternalIpReported(const RsFeedItem &fi, bool isTest); - - void addFeedItemChannelNew(const RsFeedItem &fi); -// void addFeedItemChannelUpdate(const RsFeedItem &fi); - void addFeedItemChannelMsg(const RsFeedItem &fi); - void addFeedItemChannelPublishKey(const RsFeedItem &fi); - - void addFeedItemForumNew(const RsFeedItem &fi); -// void addFeedItemForumUpdate(const RsFeedItem &fi); - void addFeedItemForumMsg(const RsFeedItem &fi); - - void addFeedItemPostedNew(const RsFeedItem &fi); -// void addFeedItemPostedUpdate(const RsFeedItem &fi); - void addFeedItemPostedMsg(const RsFeedItem &fi); - + void addFeedItemIfUnique(FeedItem *item, bool replace); + void remUniqueFeedItem(FeedItem *item); #if 0 void addFeedItemBlogNew(const RsFeedItem &fi); void addFeedItemBlogMsg(const RsFeedItem &fi); #endif - void addFeedItemChatNew(const RsFeedItem &fi, bool addWithoutCheck); - void addFeedItemMessage(const RsFeedItem &fi); - void addFeedItemFilesNew(const RsFeedItem &fi); - - void addFeedItemCircleMembReq(const RsFeedItem &fi); - void remFeedItemCircleMembReq(const RsFeedItem &fi); - void addFeedItemCircleInvitRec(const RsFeedItem &fi); - - virtual void loadChannelGroup(const uint32_t &token); - virtual void loadChannelPost(const uint32_t &token); - virtual void loadChannelPublishKey(const uint32_t &token); - - virtual void loadForumGroup(const uint32_t &token); - virtual void loadForumMessage(const uint32_t &token); - virtual void loadForumPublishKey(const uint32_t &token); - - 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; - TokenQueue *mTokenQueueForum; - TokenQueue *mTokenQueuePosted; - /* UI - from Designer */ Ui::NewsFeed *ui; + + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/Posted/PostedItem.h b/retroshare-gui/src/gui/Posted/PostedItem.h index 333018dee..7bb920a6c 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.h +++ b/retroshare-gui/src/gui/Posted/PostedItem.h @@ -49,6 +49,7 @@ public: const RsPostedPost &getPost() const; RsPostedPost &post(); + uint64_t uniqueIdentifier() const override { return hash_64bits("PostedItem " + mMessageId.toStdString()); } protected: /* FeedItem */ virtual void doExpand(bool open); diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index 898328677..164ba1a89 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -7,7 +7,7 @@ 0 0 825 - 337 + 339 @@ -529,10 +529,22 @@ + + + 0 + 0 + + + + + 50 + 44 + + - 24 - 16777215 + 50 + 44 @@ -549,10 +561,22 @@ + + + 0 + 0 + + + + + 50 + 44 + + - 24 - 16777215 + 50 + 44 @@ -692,9 +716,9 @@ - - + + diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index 8a1973457..b3bf1793a 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -37,6 +37,8 @@ #define POSTED_DEFAULT_LISTING_LENGTH 10 #define POSTED_MAX_INDEX 10000 +#define DEBUG_POSTED_LIST_WIDGET + #define TOPIC_DEFAULT_IMAGE ":/icons/png/posted.png" /** Constructor */ @@ -143,15 +145,19 @@ QScrollArea *PostedListWidget::getScrollArea() void PostedListWidget::deleteFeedItem(QWidget */*item*/, uint32_t /*type*/) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::deleteFeedItem() Nah"; std::cerr << std::endl; +#endif return; } void PostedListWidget::openChat(const RsPeerId & /*peerId*/) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::openChat() Nah"; std::cerr << std::endl; +#endif return; } @@ -207,8 +213,10 @@ void PostedListWidget::getRankings(int i) if (groupId().isNull()) return; +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::getRankings()"; std::cerr << std::endl; +#endif int oldSortMethod = mSortMethod; @@ -268,6 +276,7 @@ void PostedListWidget::submitVote(const RsGxsGrpMsgIdPair &msgId, bool up) vote.mVoteType = GXS_VOTE_DOWN; }//if (up) +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::submitVote()"; std::cerr << std::endl; @@ -275,6 +284,7 @@ void PostedListWidget::submitVote(const RsGxsGrpMsgIdPair &msgId, bool up) std::cerr << "ThreadId : " << vote.mMeta.mThreadId << std::endl; std::cerr << "ParentId : " << vote.mMeta.mParentId << std::endl; std::cerr << "AuthorId : " << vote.mMeta.mAuthorId << std::endl; +#endif uint32_t token; rsPosted->createNewVote(token, vote); @@ -464,8 +474,10 @@ static bool CmpPINew(const GxsFeedItem *a, const GxsFeedItem *b) void PostedListWidget::applyRanking() { /* uses current settings to sort posts, then add to layout */ +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::applyRanking()"; std::cerr << std::endl; +#endif shallowClearPosts(); @@ -474,25 +486,33 @@ void PostedListWidget::applyRanking() { default: case RsPosted::HotRankType: +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::applyRanking() HOT"; std::cerr << std::endl; +#endif qSort(mPostItems.begin(), mPostItems.end(), CmpPIHot); break; case RsPosted::NewRankType: +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::applyRanking() NEW"; std::cerr << std::endl; +#endif qSort(mPostItems.begin(), mPostItems.end(), CmpPINew); break; case RsPosted::TopRankType: +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::applyRanking() TOP"; std::cerr << std::endl; +#endif qSort(mPostItems.begin(), mPostItems.end(), CmpPITop); break; } mLastSortMethod = mSortMethod; +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::applyRanking() Sorted mPostList"; std::cerr << std::endl; +#endif /* go through list (skipping out-of-date items) to get */ QLayout *alayout = ui->scrollAreaWidgetContents->layout(); @@ -500,42 +520,54 @@ void PostedListWidget::applyRanking() time_t min_ts = 0; foreach (PostedItem *item, mPostItems) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::applyRanking() Item: " << item; std::cerr << std::endl; +#endif if (item->getPost().mMeta.mPublishTs < min_ts) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "\t Skipping OLD"; std::cerr << std::endl; +#endif item->hide(); continue; } if (counter >= mPostIndex + mPostShow) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "\t END - Counter too high"; std::cerr << std::endl; +#endif item->hide(); } else if (counter >= mPostIndex) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "\t Adding to Layout"; std::cerr << std::endl; +#endif /* add it in! */ alayout->addWidget(item); item->show(); } else { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "\t Skipping to Low"; std::cerr << std::endl; +#endif item->hide(); } ++counter; } +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::applyRanking() Loaded New Order"; std::cerr << std::endl; +#endif // trigger a redraw. ui->scrollAreaWidgetContents->update(); @@ -564,7 +596,9 @@ bool PostedListWidget::navigatePostItem(const RsGxsMessageId & /*msgId*/) void PostedListWidget::shallowClearPosts() { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::shallowClearPosts()" << std::endl; +#endif std::list postedItems; std::list::iterator pit; @@ -576,24 +610,30 @@ void PostedListWidget::shallowClearPosts() QLayoutItem *litem = alayout->itemAt(i); if (!litem) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::shallowClearPosts() missing litem"; std::cerr << std::endl; +#endif continue; } PostedItem *item = dynamic_cast(litem->widget()); if (item) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::shallowClearPosts() item: " << item; std::cerr << std::endl; +#endif postedItems.push_back(item); } +#ifdef DEBUG_POSTED_LIST_WIDGET else { std::cerr << "PostedListWidget::shallowClearPosts() Found Child, which is not a PostedItem???"; std::cerr << std::endl; } +#endif } for(pit = postedItems.begin(); pit != postedItems.end(); ++pit) @@ -646,15 +686,19 @@ void PostedListWidget::insertPosts(const uint32_t &token) // modify post content if(mPosts.find(p.mMeta.mMsgId) != mPosts.end()) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::updateCurrentDisplayComplete() updating MsgId: " << p.mMeta.mMsgId; std::cerr << std::endl; +#endif mPosts[p.mMeta.mMsgId]->setPost(p); } else { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::updateCurrentDisplayComplete() loading New MsgId: " << p.mMeta.mMsgId; std::cerr << std::endl; +#endif /* insert new entry */ loadPost(p); } @@ -689,8 +733,10 @@ void PostedListWidget::setAllMessagesReadDo(bool read, uint32_t &token) void PostedListWidget::loadRequest(const TokenQueue *queue, const TokenRequest &req) { +#ifdef DEBUG_POSTED_LIST_WIDGET std::cerr << "PostedListWidget::loadRequest() UserType: " << req.mUserType; std::cerr << std::endl; +#endif if (queue == mTokenQueue) { diff --git a/retroshare-gui/src/gui/RetroShareLink.cpp b/retroshare-gui/src/gui/RetroShareLink.cpp index 0631ddee4..fe7374c90 100644 --- a/retroshare-gui/src/gui/RetroShareLink.cpp +++ b/retroshare-gui/src/gui/RetroShareLink.cpp @@ -578,7 +578,7 @@ RetroShareLink RetroShareLink::createCertificate(const RsPeerId& ssl_id) return link; } -RetroShareLink RetroShareLink::createUnknwonSslCertificate(const RsPeerId& sslId, const RsPgpId& gpgId) +RetroShareLink RetroShareLink::createUnknownSslCertificate(const RsPeerId& sslId, const RsPgpId& gpgId) { RetroShareLink link; link.clear(); diff --git a/retroshare-gui/src/gui/RetroShareLink.h b/retroshare-gui/src/gui/RetroShareLink.h index 9858571d5..61c794b11 100644 --- a/retroshare-gui/src/gui/RetroShareLink.h +++ b/retroshare-gui/src/gui/RetroShareLink.h @@ -90,7 +90,7 @@ class RetroShareLink static RetroShareLink createMessage(const RsPeerId &peerId, const QString& subject); static RetroShareLink createMessage(const RsGxsId &peerId, const QString& subject); static RetroShareLink createCertificate(const RsPeerId &ssl_id) ; - static RetroShareLink createUnknwonSslCertificate(const RsPeerId &sslId, const RsPgpId &gpgId = RsPgpId()) ; + static RetroShareLink createUnknownSslCertificate(const RsPeerId &sslId, const RsPgpId &gpgId = RsPgpId()) ; static RetroShareLink createExtraFile(const QString& name, uint64_t size, const QString& hash, const QString& ssl_id); static RetroShareLink createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash) ; static RetroShareLink createIdentity(const RsGxsId& gxs_id,const QString& name,const QString& radix_data) ; diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 38e6ba3fd..7b07f9086 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -47,6 +47,7 @@ #include "RSTreeWidgetItem.h" #include "StatusDefs.h" #include "util/misc.h" +#include "util/qtthreadsutils.h" #include "vmessagebox.h" #include "util/QtVersion.h" #include "gui/chat/ChatUserNotify.h" @@ -176,6 +177,9 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent) ui->filterLineEdit->setPlaceholderText(tr("Search")) ; ui->filterLineEdit->showFilterIcon(); + mEventHandlerId=0; // forces initialization + rsEvents->registerEventsHandler( [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId ); + mModel = new RsFriendListModel(); mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this); @@ -236,8 +240,6 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent) connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); - connect(NotifyQt::getInstance(), SIGNAL(peerConnected(const QString&)) , this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); - connect(NotifyQt::getInstance(), SIGNAL(peerDisconnected(const QString&)), this, SLOT(forceUpdateDisplay()),Qt::QueuedConnection); connect(ui->actionShowOfflineFriends, SIGNAL(triggered(bool)), this, SLOT(setShowUnconnected(bool))); connect(ui->actionShowState, SIGNAL(triggered(bool)), this, SLOT(setShowState(bool)) ); @@ -254,6 +256,17 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent) } +void NewFriendList::handleEvent(std::shared_ptr e) +{ + if(e->mType == RsEventType::PEER_CONNECTION) + { + // /!\ The function we're in is called from a different thread. It's very important + // to use this trick in order to avoid data races. + + RsQThreadUtils::postToObject( [=]() { forceUpdateDisplay() ; }, this ) ; + } +} + NewFriendList::~NewFriendList() { delete ui; diff --git a/retroshare-gui/src/gui/common/NewFriendList.h b/retroshare-gui/src/gui/common/NewFriendList.h index 17214093d..6e5f617f9 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.h +++ b/retroshare-gui/src/gui/common/NewFriendList.h @@ -95,6 +95,7 @@ private slots: protected: void changeEvent(QEvent *e); + void handleEvent(std::shared_ptr e); private: Ui::NewFriendList *ui; @@ -117,6 +118,7 @@ private: // Settings for peer list display bool mShowState; + RsEventsHandlerId_t mEventHandlerId; std::set openGroups; std::set openPeers; diff --git a/retroshare-gui/src/gui/common/RSFeedWidget.cpp b/retroshare-gui/src/gui/common/RSFeedWidget.cpp index 264eda7e8..fff41d11b 100644 --- a/retroshare-gui/src/gui/common/RSFeedWidget.cpp +++ b/retroshare-gui/src/gui/common/RSFeedWidget.cpp @@ -28,7 +28,8 @@ #include -#define COLUMN_FEED 0 +#define COLUMN_FEED 0 +#define COLUMN_IDENTIFIER 1 #define SINGLE_STEP 15 @@ -74,6 +75,8 @@ RSFeedWidget::RSFeedWidget(QWidget *parent) ui->treeWidget->installEventFilter(this); ui->treeWidget->setVerticalScrollBar(new RSFeedWidgetScrollBar); + ui->treeWidget->setColumnCount(2); + ui->treeWidget->setColumnHidden(COLUMN_IDENTIFIER,true); } RSFeedWidget::~RSFeedWidget() @@ -130,17 +133,14 @@ bool RSFeedWidget::eventFilter(QObject *object, QEvent *event) void RSFeedWidget::feedAdded(FeedItem *feedItem, QTreeWidgetItem *treeItem) { - mItems.insert(feedItem, treeItem); } void RSFeedWidget::feedRemoved(FeedItem *feedItem) { - mItems.remove(feedItem); } void RSFeedWidget::feedsCleared() { - mItems.clear(); } void RSFeedWidget::connectSignals(FeedItem *feedItem) @@ -179,6 +179,7 @@ void RSFeedWidget::addFeedItem(FeedItem *feedItem, Qt::ItemDataRole sortRole, co QTreeWidgetItem *treeItem = new RSTreeWidgetItem(mFeedCompareRole); treeItem->setData(COLUMN_FEED, sortRole, value); + treeItem->setData(COLUMN_IDENTIFIER, Qt::DisplayRole, QString("%1").arg(feedItem->uniqueIdentifier(),8,16,QChar('0'))); ui->treeWidget->addTopLevelItem(treeItem); ui->treeWidget->setItemWidget(treeItem, 0, feedItem); @@ -206,6 +207,7 @@ void RSFeedWidget::addFeedItem(FeedItem *feedItem, const QMapsetData(COLUMN_FEED, it.key(), it.value()); } + treeItem->setData(COLUMN_IDENTIFIER, Qt::DisplayRole, QString("%1").arg(feedItem->uniqueIdentifier(),8,16,QChar('0'))); ui->treeWidget->addTopLevelItem(treeItem); ui->treeWidget->setItemWidget(treeItem, 0, feedItem); @@ -223,14 +225,13 @@ void RSFeedWidget::addFeedItem(FeedItem *feedItem, const QMapuniqueIdentifier()); + + if (!treeItem) return; - } treeItem->setData(COLUMN_FEED, sortRole, value); } @@ -241,10 +242,9 @@ void RSFeedWidget::setSort(FeedItem *feedItem, const QMapuniqueIdentifier()); + if (!treeItem) return; - } QMap::const_iterator it; for (it = sort.begin(); it != sort.end(); ++it) { @@ -388,13 +388,23 @@ void RSFeedWidget::removeFeedItem(FeedItem *feedItem) return; } - disconnectSignals(feedItem); + QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem->uniqueIdentifier()); - QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem); - feedRemoved(feedItem); - if (treeItem) { - delete(treeItem); - } + if (treeItem) + { + int treeItem_index = ui->treeWidget->indexOfTopLevelItem(treeItem); + + if(treeItem_index < 0) + { + std::cerr << "(EE) Cannot remove designated item \"" << feedItem->uniqueIdentifier() << "\": not found!" << std::endl; + return ; + } + + feedRemoved(feedItem); + disconnectSignals(feedItem); + + delete ui->treeWidget->takeTopLevelItem(treeItem_index); + } if (!mCountChangedDisabled) { emit feedCountChanged(); @@ -418,40 +428,42 @@ void RSFeedWidget::feedItemDestroyed(FeedItem *feedItem) { /* No need to disconnect when object will be destroyed */ - QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem); - feedRemoved(feedItem); - if (treeItem) { - delete(treeItem); - } + QTreeWidgetItem *treeItem = findTreeWidgetItem(feedItem->uniqueIdentifier()); - if (!mCountChangedDisabled) { + feedRemoved(feedItem); + if (treeItem) + delete(treeItem); + + if (!mCountChangedDisabled) emit feedCountChanged(); - } } -QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(FeedItem *feedItem) +QTreeWidgetItem *RSFeedWidget::findTreeWidgetItem(uint64_t identifier) { - QMap::iterator it = mItems.find(feedItem); - if (it == mItems.end()) { - return NULL; - } + QList list = ui->treeWidget->findItems(QString("%1").arg(identifier,8,16,QChar('0')),Qt::MatchExactly,COLUMN_IDENTIFIER); - return it.value(); + if(list.empty()) + return nullptr; + else if(list.size() == 1) + return list.front(); + else + { + std::cerr << "(EE) More than a single item with identifier \"" << identifier << "\" in the feed tree widget. This shouldn't happen!" << std::endl; + return nullptr; + } } bool RSFeedWidget::scrollTo(FeedItem *feedItem, bool focus) { - QTreeWidgetItem *item = findTreeWidgetItem(feedItem); - if (!feedItem) { + QTreeWidgetItem *item = findTreeWidgetItem(feedItem->uniqueIdentifier()); + if (!feedItem) return false; - } ui->treeWidget->scrollToItem(item); ui->treeWidget->setCurrentItem(item); - if (focus) { + if (focus) ui->treeWidget->setFocus(); - } return true; } @@ -476,25 +488,24 @@ void RSFeedWidget::withAll(RSFeedWidgetCallbackFunction callback, void *data) } } -FeedItem *RSFeedWidget::findFeedItem(RSFeedWidgetFindCallbackFunction callback, void *data) +FeedItem *RSFeedWidget::findFeedItem(uint64_t identifier) { - if (!callback) { - return NULL; - } - QTreeWidgetItemIterator it(ui->treeWidget); - QTreeWidgetItem *treeItem; + QTreeWidgetItem *treeItem=NULL; + + // this search could probably be automatised by giving the tree items the identifier as data for some specific role, then calling QTreeWidget::findItems() +#warning TODO while ((treeItem = *it) != NULL) { ++it; FeedItem *feedItem = feedItemFromTreeItem(treeItem); - if (!feedItem) { + if (!feedItem) continue; - } - if (callback(feedItem, data)) { + uint64_t id = feedItem->uniqueIdentifier(); + + if (id == identifier) return feedItem; - } } return NULL; diff --git a/retroshare-gui/src/gui/common/RSFeedWidget.h b/retroshare-gui/src/gui/common/RSFeedWidget.h index b440c0850..bc38adf84 100644 --- a/retroshare-gui/src/gui/common/RSFeedWidget.h +++ b/retroshare-gui/src/gui/common/RSFeedWidget.h @@ -71,7 +71,7 @@ public: bool scrollTo(FeedItem *feedItem, bool focus); void withAll(RSFeedWidgetCallbackFunction callback, void *data); - FeedItem *findFeedItem(RSFeedWidgetFindCallbackFunction callback, void *data); + FeedItem *findFeedItem(uint64_t identifier); void selectedFeedItems(QList &feedItems); @@ -98,7 +98,7 @@ private: void connectSignals(FeedItem *feedItem); void disconnectSignals(FeedItem *feedItem); FeedItem *feedItemFromTreeItem(QTreeWidgetItem *treeItem); - QTreeWidgetItem *findTreeWidgetItem(FeedItem *feedItem); + QTreeWidgetItem *findTreeWidgetItem(uint64_t identifier); void filterItems(); void filterItem(QTreeWidgetItem *treeItem, FeedItem *feedItem); @@ -117,9 +117,6 @@ private: /* Options */ int mCountChangedDisabled; - /* Items */ - QMap mItems; - Ui::RSFeedWidget *ui; }; diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp index 7ea64e7b5..4ad6315b9 100755 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.cpp @@ -337,24 +337,49 @@ void ConnectFriendWizard::setCertificate(const QString &certificate, bool friend void ConnectFriendWizard::setGpgId(const RsPgpId &gpgId, const RsPeerId &sslId, bool friendRequest) { - if (!rsPeers->getGPGDetails(gpgId, peerDetails)) { - setField("errorMessage", tr("Cannot get peer details of PGP key %1").arg(QString::fromStdString(gpgId.toStdString()))); + if(sslId == rsPeers->getOwnId()) + { + setField("errorMessage", tr("This is your own certificate! You would not want to make friend with yourself. Wouldn't you?") ) ; setStartId(Page_ErrorMessage); - return; + error = false; } - /* Set ssl id when available */ - peerDetails.id = sslId; + if (!rsPeers->getGPGDetails(gpgId, peerDetails)) + { + mIsShortInvite = true; - //setStartId(friendRequest ? Page_FriendRequest : Page_Conclusion); - setStartId(Page_Conclusion); - if (friendRequest){ - ui->cp_Label->show(); - ui->requestinfolabel->show(); - setTitleText(ui->ConclusionPage,tr("Friend request")); - ui->ConclusionPage->setSubTitle(tr("Details about the request")); - setButtonText(QWizard::FinishButton , tr("Accept")); - } + peerDetails.id = sslId; + peerDetails.gpg_id = gpgId; + peerDetails.skip_pgp_signature_validation = true; + + mCertificate.clear(); + + setStartId(Page_Conclusion); + + if (friendRequest){ + ui->cp_Label->show(); + ui->requestinfolabel->show(); + setTitleText(ui->ConclusionPage, tr("Friend request")); + ui->ConclusionPage->setSubTitle(tr("Details about the request")); + setButtonText(QWizard::FinishButton , tr("Accept")); + } + } + else + { + /* Set ssl id when available */ + peerDetails.id = sslId; + mIsShortInvite = false; + + //setStartId(friendRequest ? Page_FriendRequest : Page_Conclusion); + setStartId(Page_Conclusion); + if (friendRequest){ + ui->cp_Label->show(); + ui->requestinfolabel->show(); + setTitleText(ui->ConclusionPage,tr("Friend request")); + ui->ConclusionPage->setSubTitle(tr("Details about the request")); + setButtonText(QWizard::FinishButton , tr("Accept")); + } + } } ConnectFriendWizard::~ConnectFriendWizard() @@ -507,7 +532,7 @@ void ConnectFriendWizard::initializePage(int id) ui->cp_Label->setText(tr("You have a friend request from") + " " + QString::fromUtf8(peerDetails.name.c_str())); ui->nameEdit->setText(QString::fromUtf8(peerDetails.name.c_str())); ui->trustEdit->setText(trustString); - ui->emailEdit->setText(QString::fromUtf8(peerDetails.email.c_str())); + ui->profileIdEdit->setText(QString::fromStdString(peerDetails.gpg_id.toStdString())); QString loc = QString::fromUtf8(peerDetails.location.c_str()); if (!loc.isEmpty()) { @@ -540,12 +565,19 @@ void ConnectFriendWizard::initializePage(int id) ui->ipLabel->setPixmap(QPixmap(":/images/anonymous_128_blue.png").scaledToHeight(S*2,Qt::SmoothTransformation)); ui->ipLabel->setToolTip("This is a Hidden node - you need tor/i2p proxy to connect"); } - - if(peerDetails.email.empty()) + if(mIsShortInvite) { - ui->emailLabel->hide(); // is it ever used? - ui->emailEdit->hide(); + ui->nameEdit->setText(tr("[Unknown]")); + ui->addKeyToKeyring_CB->setChecked(false); + ui->addKeyToKeyring_CB->setEnabled(false); + ui->signersEdit->hide(); + ui->signersLabel->hide(); + ui->signGPGCheckBox->setChecked(false); + ui->signGPGCheckBox->setEnabled(false); + ui->acceptNoSignGPGCheckBox->setChecked(true); + ui->acceptNoSignGPGCheckBox->setEnabled(false); } + ui->ipEdit->setTextInteractionFlags(Qt::TextSelectableByMouse); } diff --git a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui index a950d3ceb..9cbd53ca0 100644 --- a/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui +++ b/retroshare-gui/src/gui/connect/ConnectFriendWizard.ui @@ -6,8 +6,8 @@ 0 0 - 600 - 437 + 1139 + 1171 @@ -480,14 +480,14 @@ - + - Email: + Profile ID: - + Email @@ -794,8 +794,8 @@ - + diff --git a/retroshare-gui/src/gui/feeds/ChatMsgItem.h b/retroshare-gui/src/gui/feeds/ChatMsgItem.h index bdfc343fe..fe946a4b9 100644 --- a/retroshare-gui/src/gui/feeds/ChatMsgItem.h +++ b/retroshare-gui/src/gui/feeds/ChatMsgItem.h @@ -37,6 +37,7 @@ public: void updateItemStatic(); + virtual uint64_t uniqueIdentifier() const override { return hash_64bits("ChatMsgItem " + mPeerId.toStdString()); } protected: /* FeedItem */ virtual void doExpand(bool /*open*/) {} diff --git a/retroshare-gui/src/gui/feeds/FeedItem.cpp b/retroshare-gui/src/gui/feeds/FeedItem.cpp index 19cfdbf72..2e5353e40 100644 --- a/retroshare-gui/src/gui/feeds/FeedItem.cpp +++ b/retroshare-gui/src/gui/feeds/FeedItem.cpp @@ -18,10 +18,11 @@ * * *******************************************************************************/ +#include #include "FeedItem.h" /** Constructor */ -FeedItem::FeedItem(QWidget *parent) : QWidget(parent) +FeedItem::FeedItem(QWidget *parent) : QWidget(parent), mHash(0) { mWasExpanded = false; } @@ -43,3 +44,16 @@ void FeedItem::expand(bool open) mWasExpanded = true; } } + +uint64_t FeedItem::hash_64bits(const std::string& s) const +{ + if(mHash == 0) + { + mHash = 0x01110bbfa09; + + for(uint32_t i=0;i> 3)) + s[i]*0x217898fbba7 + 0x0294379); + } + + return mHash; +} diff --git a/retroshare-gui/src/gui/feeds/FeedItem.h b/retroshare-gui/src/gui/feeds/FeedItem.h index 04adc9381..7cd6808a1 100644 --- a/retroshare-gui/src/gui/feeds/FeedItem.h +++ b/retroshare-gui/src/gui/feeds/FeedItem.h @@ -36,16 +36,24 @@ public: bool wasExpanded() { return mWasExpanded; } void expand(bool open); + /*! + * \brief uniqueIdentifier + * \return returns a string that is unique to this specific item. The string will be used to search for an existing item that + * would contain the same information. It should therefore sumarise the data represented by the item. + */ + virtual uint64_t uniqueIdentifier() const =0; protected: virtual void doExpand(bool open) = 0; virtual void expandFill(bool /*first*/) {} + uint64_t hash_64bits(const std::string& s) const; signals: void sizeChanged(FeedItem *feedItem); void feedItemDestroyed(FeedItem *feedItem); private: bool mWasExpanded; + mutable uint64_t mHash; }; #endif diff --git a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h index 5a307d522..1a0c56a70 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelGroupItem.h @@ -41,7 +41,7 @@ public: ~GxsChannelGroupItem(); bool setGroup(const RsGxsChannelGroup &group); - + uint64_t uniqueIdentifier() const override { return hash_64bits("GxsChannelGroupItem " + groupId().toStdString()) ; } protected: /* FeedItem */ virtual void doExpand(bool open); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp index c166d115b..cdb4eeaf2 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.cpp @@ -71,6 +71,7 @@ void GxsChannelPostItem::init(const RsGxsMessageId& messageId,const std::setdownloadButton, SIGNAL(clicked()), this, SLOT(download())); // HACK FOR NOW. + ui->commentButton->hide();// hidden until properly enabled. connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments())); connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void))); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h index 8f045c2d9..8b9d21c57 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.h @@ -53,6 +53,8 @@ public: //GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsChannelPost &post, bool isHome, bool autoUpdate); virtual ~GxsChannelPostItem(); + uint64_t uniqueIdentifier() const override { hash_64bits("GxsChannelPostItem " + mPost.mMeta.mMsgId.toStdString()) ; } + bool setGroup(const RsGxsChannelGroup &group, bool doFill = true); bool setPost(const RsGxsChannelPost &post, bool doFill = true); diff --git a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui index 3747fc5db..01d113665 100644 --- a/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui +++ b/retroshare-gui/src/gui/feeds/GxsChannelPostItem.ui @@ -6,7 +6,7 @@ 0 0 - 1140 + 1359 342 @@ -57,18 +57,6 @@ 0 - - - 82 - 108 - - - - - 156 - 107 - - @@ -138,12 +126,6 @@ 0 - - - 16777215 - 60 - - Short Description @@ -570,8 +552,8 @@ - + diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp b/retroshare-gui/src/gui/feeds/GxsCircleItem.cpp index 8fe52b6b4..aa161cde4 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 { @@ -125,14 +167,9 @@ void GxsCircleItem::setup() } -bool GxsCircleItem::isSame(const RsGxsCircleId &circleId, const RsGxsId &gxsId, uint32_t type) +uint64_t GxsCircleItem::uniqueIdentifier() const { - if ((mCircleId == circleId) && (mGxsId == gxsId) && (mType == type)) - { - return true; - } - return false; - + return hash_64bits("GxsCircle " + mCircleId.toStdString() + " " + mGxsId.toStdString() + " " + QString::number(mType).toStdString()); } void GxsCircleItem::removeItem() diff --git a/retroshare-gui/src/gui/feeds/GxsCircleItem.h b/retroshare-gui/src/gui/feeds/GxsCircleItem.h index a08adb8c1..a45114ed6 100644 --- a/retroshare-gui/src/gui/feeds/GxsCircleItem.h +++ b/retroshare-gui/src/gui/feeds/GxsCircleItem.h @@ -52,8 +52,7 @@ public: GxsCircleItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsCircleId &circleId, const RsGxsId &gxsId, const uint32_t type); virtual ~GxsCircleItem(); - bool isSame(const RsGxsCircleId &circleId, const RsGxsId &gxsId, uint32_t type); - + uint64_t uniqueIdentifier() const override; void loadRequest(const TokenQueue *queue, const TokenRequest &req); diff --git a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h index 19e438b69..87bffa022 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumGroupItem.h @@ -42,6 +42,7 @@ public: bool setGroup(const RsGxsForumGroup &group); + uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumGroupItem " + groupId().toStdString()) ; } protected: /* FeedItem */ virtual void doExpand(bool open); diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp index 8e1dba4ea..0e691258c 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp @@ -43,6 +43,8 @@ GxsForumMsgItem::GxsForumMsgItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate) : GxsFeedItem(feedHolder, feedId, groupId, messageId, isHome, rsGxsForums, autoUpdate) { + mMessage.mMeta.mMsgId = messageId; // useful for uniqueIdentifier() before the post is actually loaded + mMessage.mMeta.mGroupId = groupId; setup(); requestGroup(); diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h index ff152f92b..be275aa07 100644 --- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h +++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.h @@ -43,6 +43,7 @@ public: bool setGroup(const RsGxsForumGroup &group, bool doFill = true); bool setMessage(const RsGxsForumMsg &msg, bool doFill = true); + uint64_t uniqueIdentifier() const override { return hash_64bits("GxsForumMsgItem " + mMessage.mMeta.mMsgId.toStdString()) ; } protected: /* FeedItem */ virtual void doExpand(bool open); diff --git a/retroshare-gui/src/gui/feeds/MsgItem.h b/retroshare-gui/src/gui/feeds/MsgItem.h index 6aa595767..469f8cbb7 100644 --- a/retroshare-gui/src/gui/feeds/MsgItem.h +++ b/retroshare-gui/src/gui/feeds/MsgItem.h @@ -38,6 +38,7 @@ public: void updateItemStatic(); + uint64_t uniqueIdentifier() const override { return hash_64bits("MsgItem " + mMsgId) ; } protected: /* FeedItem */ virtual void doExpand(bool open); diff --git a/retroshare-gui/src/gui/feeds/NewsFeedUserNotify.cpp b/retroshare-gui/src/gui/feeds/NewsFeedUserNotify.cpp index e089aa946..e71c166f2 100644 --- a/retroshare-gui/src/gui/feeds/NewsFeedUserNotify.cpp +++ b/retroshare-gui/src/gui/feeds/NewsFeedUserNotify.cpp @@ -26,7 +26,7 @@ NewsFeedUserNotify::NewsFeedUserNotify(NewsFeed *newsFeed, QObject *parent) : { mNewFeedCount = 0; - connect(newsFeed, SIGNAL(newsFeedChanged(int)), this, SLOT(newsFeedChanged(int))); + connect(newsFeed, SIGNAL(newsFeedChanged(int)), this, SLOT(newsFeedChanged(int)),Qt::QueuedConnection); } void NewsFeedUserNotify::newsFeedChanged(int count) diff --git a/retroshare-gui/src/gui/feeds/PeerItem.cpp b/retroshare-gui/src/gui/feeds/PeerItem.cpp index c1ccd788e..87d510e4b 100644 --- a/retroshare-gui/src/gui/feeds/PeerItem.cpp +++ b/retroshare-gui/src/gui/feeds/PeerItem.cpp @@ -67,17 +67,11 @@ PeerItem::PeerItem(FeedHolder *parent, uint32_t feedId, const RsPeerId &peerId, updateItem(); } - -bool PeerItem::isSame(const RsPeerId &peerId, uint32_t type) +uint64_t PeerItem::uniqueIdentifier() const { - if ((mPeerId == peerId) && (mType == type)) - { - return true; - } - return false; + return hash_64bits("PeerItem " + mPeerId.toStdString() + " " + QString::number(mType).toStdString()) ; } - void PeerItem::updateItemStatic() { if (!rsPeers) @@ -100,7 +94,7 @@ void PeerItem::updateItemStatic() title = tr("Friend Connected"); break; case PEER_TYPE_HELLO: - title = tr("Connect Attempt"); + title = tr("Connection refused by peer"); break; case PEER_TYPE_NEW_FOF: title = tr("Friend of Friend"); @@ -135,15 +129,16 @@ void PeerItem::updateItemStatic() } else { - statusLabel->setText(tr("Unknown Peer")); - titleLabel->setText(tr("Unknown Peer")); - trustLabel->setText(tr("Unknown Peer")); - nameLabel->setText(tr("Unknown Peer")); - idLabel->setText(tr("Unknown Peer")); - locLabel->setText(tr("Unknown Peer")); - ipLabel->setText(tr("Unknown Peer")); - connLabel->setText(tr("Unknown Peer")); - lastLabel->setText(tr("Unknown Peer")); + peerNameLabel->setText(tr("Unknown peer")); + statusLabel->setText(tr("Unknown")); + titleLabel->setText(tr("Unknown peer")); + trustLabel->setText(tr("Unknown")); + nameLabel->setText(tr("Unknown")); + idLabel->setText(tr("Unknown")); + locLabel->setText(tr("Unknown")); + ipLabel->setText(tr("Unknown")); + connLabel->setText(tr("Unknown")); + lastLabel->setText(tr("Unknown")); chatButton->setEnabled(false); } @@ -192,7 +187,19 @@ void PeerItem::updateItem() statusLabel->setText(status); trustLabel->setText(QString::fromStdString(RsPeerTrustString(details.trustLvl))); - ipLabel->setText(QString("%1:%2/%3:%4").arg(QString::fromStdString(details.localAddr)).arg(details.localPort).arg(QString::fromStdString(details.extAddr)).arg(details.extPort)); + QString ip_string; + + if(details.localPort != 0) + ip_string += QString("%1:%2").arg(QString::fromStdString(details.localAddr)).arg(details.localPort); + + if(details.extPort != 0) + { + if(!ip_string.isNull()) + ip_string += "/" ; + + ip_string += ip_string += QString("%1:%2").arg(QString::fromStdString(details.extAddr)).arg(details.extPort); + } + ipLabel->setText(ip_string); connLabel->setText(StatusDefs::connectStateString(details)); diff --git a/retroshare-gui/src/gui/feeds/PeerItem.h b/retroshare-gui/src/gui/feeds/PeerItem.h index d048ff8d5..6e17fbae3 100644 --- a/retroshare-gui/src/gui/feeds/PeerItem.h +++ b/retroshare-gui/src/gui/feeds/PeerItem.h @@ -43,7 +43,7 @@ public: void updateItemStatic(); - bool isSame(const RsPeerId &peerId, uint32_t type); + uint64_t uniqueIdentifier() const override; protected: /* FeedItem */ diff --git a/retroshare-gui/src/gui/feeds/PostedGroupItem.h b/retroshare-gui/src/gui/feeds/PostedGroupItem.h index 3b66afbcb..999abf652 100644 --- a/retroshare-gui/src/gui/feeds/PostedGroupItem.h +++ b/retroshare-gui/src/gui/feeds/PostedGroupItem.h @@ -42,6 +42,8 @@ public: bool setGroup(const RsPostedGroup &group); + uint64_t uniqueIdentifier() const override { return hash_64bits("PostedGroupItem " + groupId().toStdString()) ; } + protected: /* FeedItem */ virtual void doExpand(bool open); diff --git a/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp b/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp index a6a5d2d50..40914fc7e 100644 --- a/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp +++ b/retroshare-gui/src/gui/feeds/SecurityIpItem.cpp @@ -78,13 +78,9 @@ void SecurityIpItem::setup() updateItem(); } -bool SecurityIpItem::isSame(const RsPeerId &sslId, const std::string& ipAddr, const std::string& ipAddrReported, uint32_t type) +uint64_t SecurityIpItem::uniqueIdentifier() const { - if (mType == type && mSslId==sslId && mIpAddr == ipAddr && mIpAddrReported == ipAddrReported) { - return true; - } - - return false; + return hash_64bits("SecurityItem " + QString::number(mType).toStdString() + " " + mSslId.toStdString() + " " + mIpAddr + " " + mIpAddrReported) ; } void SecurityIpItem::updateItemStatic() diff --git a/retroshare-gui/src/gui/feeds/SecurityIpItem.h b/retroshare-gui/src/gui/feeds/SecurityIpItem.h index 2dc9dc0ca..d4648ab0a 100644 --- a/retroshare-gui/src/gui/feeds/SecurityIpItem.h +++ b/retroshare-gui/src/gui/feeds/SecurityIpItem.h @@ -43,7 +43,7 @@ public: void updateItemStatic(); - bool isSame(const RsPeerId &sslId, const std::string& ipAddr, const std::string& ipAddrReported, uint32_t type); + uint64_t uniqueIdentifier() const override; protected: /* FeedItem */ diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.cpp b/retroshare-gui/src/gui/feeds/SecurityItem.cpp index 722296ae5..b5aa9d8a4 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.cpp +++ b/retroshare-gui/src/gui/feeds/SecurityItem.cpp @@ -81,17 +81,11 @@ SecurityItem::SecurityItem(FeedHolder *parent, uint32_t feedId, const RsPgpId &g updateItem(); } - -bool SecurityItem::isSame(const RsPeerId &sslId, uint32_t type) +uint64_t SecurityItem::uniqueIdentifier() const { - if ((mSslId == sslId) && (mType == type)) - { - return true; - } - return false; + return hash_64bits("SecurityItem " + QString::number(mType).toStdString() + " " + mSslId.toStdString()); } - void SecurityItem::updateItemStatic() { if (!rsPeers) @@ -180,40 +174,47 @@ void SecurityItem::updateItem() std::cerr << std::endl; #endif - if(!RsAutoUpdatePage::eventsLocked()) { + if(!RsAutoUpdatePage::eventsLocked()) + { RsPeerDetails details; - /* first try sslid */ - if (!rsPeers->getPeerDetails(mSslId, details)) + /* first try sslid */; + if (!rsPeers->getPeerDetails(mSslId, details) && !rsPeers->getGPGDetails(mGpgId, details)) { - /* then gpgid */ - if(!rsPeers->getGPGDetails(mGpgId, details)) - { - /* it is very likely that we will end up here for some of the + /* it is very likely that we will end up here for some of the * Unknown peer cases.... so allow them here */ - /* set peer name */ - peerNameLabel->setText(QString("%1 (%2)").arg(tr("Unknown Peer"), QString::fromUtf8(mSslCn.c_str()))); + /* set peer name */ + peerNameLabel->setText(tr("A unknown peer")); - nameLabel->setText(QString::fromUtf8(mSslCn.c_str()) + " (" + QString::fromStdString(mGpgId.toStdString()) + ")"); - idLabel->setText(QString::fromStdString(mSslId.toStdString())); + nameLabel->setText(tr("Unknown") + " (" + tr("Profile ID: ") + QString::fromStdString(mGpgId.toStdString()) + ")"); + idLabel->setText(QString::fromStdString(mSslId.toStdString())); - statusLabel->setText(tr("Unknown Peer")); - trustLabel->setText(tr("Unknown Peer")); - locLabel->setText(tr("Unknown Peer")); - ipLabel->setText(QString::fromStdString(mIP)) ; //tr("Unknown Peer")); - connLabel->setText(tr("Unknown Peer")); + statusLabel->hide(); + typeLabel->hide(); - chatButton->hide(); - //quickmsgButton->hide(); - requestLabel->hide(); + trustLabel->hide(); + trustLeftLabel->hide(); - removeFriendButton->setEnabled(false); - removeFriendButton->hide(); - peerDetailsButton->setEnabled(false); + locLabel->hide(); + locLeftLabel->hide(); - return; - } + ipLabel->setText(QString::fromStdString(mIP)) ; + connLabel->hide(); + connLeftLabel->hide(); + + chatButton->hide(); + //quickmsgButton->hide(); + requestLabel->hide(); + + removeFriendButton->setEnabled(false); + removeFriendButton->hide(); + peerDetailsButton->setEnabled(false); + + friendRequesttoolButton->show(); + requestLabel->show(); + + return; } /* set peer name */ @@ -350,6 +351,7 @@ void SecurityItem::friendRequest() #endif ConnectFriendWizard *connectFriendWizard = new ConnectFriendWizard; + connectFriendWizard->setAttribute(Qt::WA_DeleteOnClose, true); connectFriendWizard->setGpgId(mGpgId, mSslId, true); connectFriendWizard->show(); diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.h b/retroshare-gui/src/gui/feeds/SecurityItem.h index 2af4af4a1..1c9bbe054 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.h +++ b/retroshare-gui/src/gui/feeds/SecurityItem.h @@ -42,7 +42,7 @@ public: void updateItemStatic(); - bool isSame(const RsPeerId &sslId, uint32_t type); + uint64_t uniqueIdentifier() const override; protected: /* FeedItem */ diff --git a/retroshare-gui/src/gui/feeds/SecurityItem.ui b/retroshare-gui/src/gui/feeds/SecurityItem.ui index 8e4d10967..54bb46645 100644 --- a/retroshare-gui/src/gui/feeds/SecurityItem.ui +++ b/retroshare-gui/src/gui/feeds/SecurityItem.ui @@ -6,8 +6,8 @@ 0 0 - 763 - 246 + 1196 + 491 @@ -354,7 +354,7 @@ - + 75 @@ -367,7 +367,7 @@ - + 75 @@ -380,7 +380,7 @@ - + 0 @@ -399,7 +399,7 @@ - + 75 @@ -412,7 +412,7 @@ - + 75 @@ -425,7 +425,7 @@ - + 75 @@ -578,8 +578,8 @@ - + diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp index 260121c7e..e4e20dfd8 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp @@ -351,7 +351,9 @@ void GxsIdChooser::setDefaultItem() if (def >= 0) { setCurrentIndex(def); +#ifdef IDCHOOSER_DEBUG std::cerr << "GxsIdChooser-002" << (void*)this << " setting current index to " << def << std::endl; +#endif } } @@ -363,7 +365,9 @@ bool GxsIdChooser::setChosenId(const RsGxsId &gxsId) int index = findData(id); if (index >= 0) { setCurrentIndex(index); +#ifdef IDCHOOSER_DEBUG std::cerr << "GxsIdChooser-001" << (void*)this << " setting current index to " << index << std::endl; +#endif return true; } return false; diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 915d490f8..f346b3470 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -50,6 +50,28 @@ public: GxsChannelDialog::GxsChannelDialog(QWidget *parent) : GxsGroupFrameDialog(rsGxsChannels, parent,true) { + mEventHandlerId = 0; + // Needs to be asynced because this function is likely to be called by another thread! + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); +} + +void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType == RsEventType::GXS_CHANNELS) + { + const RsGxsChannelEvent *e = dynamic_cast(event.get()); + + if(!e) + return; + + switch(e->mChannelEventCode) + { + case RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED: updateDisplay(true); + break; + default: + break; + } + } } GxsChannelDialog::~GxsChannelDialog() diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h index eedde4833..5d80be518 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.h @@ -74,6 +74,10 @@ private: virtual QWidget *createCommentHeaderWidget(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data virtual void loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata* &userdata); + + void handleEvent_main_thread(std::shared_ptr event); + + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp index 9a3afbc3c..d463170af 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp @@ -128,6 +128,35 @@ GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWid setAutoDownload(false); settingsChanged(); setGroupId(channelId); + + mEventHandlerId = 0; + // Needs to be asynced because this function is likely to be called by another thread! + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); +} + +void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType == RsEventType::GXS_CHANNELS) + { + const RsGxsChannelEvent *e = dynamic_cast(event.get()); + + if(!e) + return; + + switch(e->mChannelEventCode) + { + case RsChannelEventCode::UPDATED_CHANNEL: + case RsChannelEventCode::NEW_CHANNEL: + case RsChannelEventCode::UPDATED_MESSAGE: + case RsChannelEventCode::NEW_MESSAGE: + if(e->mChannelGroupId == mChannelGroupId) + updateDisplay(true); + break; + default: + break; + } + } } GxsChannelPostsWidget::~GxsChannelPostsWidget() @@ -712,6 +741,7 @@ bool GxsChannelPostsWidget::insertGroupData(const uint32_t &token, RsGroupMetaDa { insertChannelDetails(groups[0]); metaData = groups[0].mMeta; + mChannelGroupId = groups[0].mMeta.mGroupId; return true; } else @@ -721,6 +751,7 @@ bool GxsChannelPostsWidget::insertGroupData(const uint32_t &token, RsGroupMetaDa { insertChannelDetails(distant_group); metaData = distant_group.mMeta; + mChannelGroupId = distant_group.mMeta.mGroupId; return true ; } } diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h index 40160146c..a4723c18f 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.h @@ -97,11 +97,14 @@ private: void insertChannelPosts(std::vector &posts, GxsMessageFramePostThread *thread, bool related); void createPostItem(const RsGxsChannelPost &post, bool related); + void handleEvent_main_thread(std::shared_ptr event); private: QAction *mAutoDownloadAction; bool mUseThread; + RsGxsGroupId mChannelGroupId; + RsEventsHandlerId_t mEventHandlerId ; /* UI - from Designer */ Ui::GxsChannelPostsWidget *ui; diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 37681273d..f1306f79b 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -432,6 +432,32 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget #ifdef SUSPENDED_CODE ui->threadTreeWidget->enableColumnCustomize(true); #endif + + mEventHandlerId = 0; + // Needs to be asynced because this function is likely to be called by another thread! + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); +} + +void GxsForumThreadWidget::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType == RsEventType::GXS_FORUMS) + { + const RsGxsForumEvent *e = dynamic_cast(event.get()); + if(!e) return; + + switch(e->mForumEventCode) + { + case RsForumEventCode::UPDATED_FORUM: // [[fallthrough]]; + case RsForumEventCode::NEW_FORUM: // [[fallthrough]]; + case RsForumEventCode::UPDATED_MESSAGE: // [[fallthrough]]; + case RsForumEventCode::NEW_MESSAGE: + if(e->mForumGroupId == mForumGroup.mMeta.mGroupId) + updateDisplay(true); + break; + default: break; + } + } } void GxsForumThreadWidget::blank() diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 83fb0ea37..a548cda07 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -172,6 +172,8 @@ private: void updateMessageData(const RsGxsMessageId& msgId); void updateForumDescription(); + void handleEvent_main_thread(std::shared_ptr event); + private: RsGxsGroupId mLastForumID; RsGxsMessageId mThreadId; @@ -201,6 +203,7 @@ private: QList mSavedExpandedMessages; Ui::GxsForumThreadWidget *ui; + RsEventsHandlerId_t mEventHandlerId; }; #endif // GXSFORUMTHREADWIDGET_H diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 34c2818f1..aa4177a72 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -25,6 +25,7 @@ #include "GxsForumUserNotify.h" #include "gui/notifyqt.h" #include "gui/gxs/GxsGroupShareKey.h" +#include "util/qtthreadsutils.h" #include "gui/common/GroupTreeWidget.h" class GxsForumGroupInfoData : public RsUserdata @@ -41,6 +42,29 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent) : GxsGroupFrameDialog(rsGxsForums, parent) { mCountChildMsgs = true; + mEventHandlerId = 0; + // Needs to be asynced because this function is likely to be called by another thread! + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); +} + +void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr event) +{ + if(event->mType == RsEventType::GXS_FORUMS) + { + const RsGxsForumEvent *e = dynamic_cast(event.get()); + + if(!e) + return; + + switch(e->mForumEventCode) + { + case RsForumEventCode::SUBSCRIBE_STATUS_CHANGED: updateDisplay(true); + break; + default: + break; + } + } } GxsForumsDialog::~GxsForumsDialog() diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h index 39e182c88..6a21c8de9 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.h @@ -58,6 +58,10 @@ private: virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId); virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data virtual void loadGroupSummaryToken(const uint32_t &token, std::list &groupInfo, RsUserdata* &userdata); + + void handleEvent_main_thread(std::shared_ptr event); + + RsEventsHandlerId_t mEventHandlerId; }; #endif diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index 8f485b410..52da5b10f 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -584,16 +584,18 @@ void MessageComposer::recommendFriend(const std::set &sslIds, const R /* window will destroy itself! */ } -void MessageComposer::sendConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId &sslId, const QString &/*sslName*/) +void MessageComposer::addConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId &sslId, const QString &/*sslName*/) { - if (gpgId.isNull()) { + if (gpgId.isNull()) return; - } - RetroShareLink link = RetroShareLink::createUnknwonSslCertificate(sslId, gpgId); - if (link.valid() == false) { + // PGPId+SslId are always here. But if the peer is not a friend the SSL id cannot be used. + // (todo) If the PGP id doesn't get us a PGP key from the keyring, we need to create a short invite + + RetroShareLink link = RetroShareLink::createUnknownSslCertificate(sslId); + + if (!link.valid()) return; - } QString title = QString("%1 %2").arg(link.name(), tr("wants to be friends with you on RetroShare")); diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.h b/retroshare-gui/src/gui/msgs/MessageComposer.h index 1b0b2f2c5..7c2b4e13d 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.h +++ b/retroshare-gui/src/gui/msgs/MessageComposer.h @@ -62,7 +62,7 @@ public: static QString recommendMessage(); static void recommendFriend(const std::set &sslIds, const RsPeerId &to = RsPeerId(), const QString &msg = "", bool autoSend = false); - static void sendConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId &sslId, const QString &sslName); + static void addConnectAttemptMsg(const RsPgpId &gpgId, const RsPeerId &sslId, const QString &sslName); static void sendInvite(const RsGxsId &to, bool autoSend); #ifdef UNUSED_CODE static void sendChannelPublishKey(RsGxsChannelGroup &group); diff --git a/retroshare-gui/src/gui/notifyqt.cpp b/retroshare-gui/src/gui/notifyqt.cpp index 5d1a2396f..27a81546a 100644 --- a/retroshare-gui/src/gui/notifyqt.cpp +++ b/retroshare-gui/src/gui/notifyqt.cpp @@ -422,6 +422,7 @@ void NotifyQt::notifyPeerStatusChangedSummary() emit peerStatusChangedSummary(); } +#ifdef TO_REMOVE void NotifyQt::notifyGxsChange(const RsGxsChanges& changes) { { @@ -436,6 +437,7 @@ void NotifyQt::notifyGxsChange(const RsGxsChanges& changes) emit gxsChange(changes); } +#endif void NotifyQt::notifyOwnStatusMessageChanged() { @@ -492,20 +494,6 @@ void NotifyQt::notifyChatLobbyTimeShift(int shift) emit chatLobbyTimeShift(shift) ; } -void NotifyQt::notifyConnectionWithoutCert() -{ - { - QMutexLocker m(&_mutex) ; - if(!_enabled) - return ; - } - -#ifdef NOTIFY_DEBUG - std::cerr << "notifyQt: Received notifyConnectionWithoutCert" << std::endl; -#endif - emit connectionWithoutCert(); -} - void NotifyQt::handleChatLobbyTimeShift(int /*shift*/) { return ; // we say nothing. The help dialog of lobbies explains this already. @@ -750,27 +738,6 @@ void NotifyQt::notifyListChange(int list, int type) return; } -void NotifyQt::notifyPeerConnected(const std::string& peer_id) -{ - { - QMutexLocker m(&_mutex) ; - if(!_enabled) - return ; - } - - emit peerConnected(QString::fromStdString(peer_id)); -} -void NotifyQt::notifyPeerDisconnected(const std::string& peer_id) -{ - { - QMutexLocker m(&_mutex) ; - if(!_enabled) - return ; - } - - emit peerDisconnected(QString::fromStdString(peer_id)); -} - void NotifyQt::notifyListPreChange(int list, int /*type*/) { { diff --git a/retroshare-gui/src/gui/notifyqt.h b/retroshare-gui/src/gui/notifyqt.h index de0fb7aca..dd09bf4ea 100644 --- a/retroshare-gui/src/gui/notifyqt.h +++ b/retroshare-gui/src/gui/notifyqt.h @@ -56,12 +56,10 @@ class NotifyQt: public QObject, public NotifyClient static bool isAllDisable(); void enable() ; - virtual ~NotifyQt() { return; } + virtual ~NotifyQt() = default; void setNetworkDialog(NetworkDialog *c) { cDialog = c; } - virtual void notifyPeerConnected(const std::string& /* peer_id */); - virtual void notifyPeerDisconnected(const std::string& /* peer_id */); virtual void notifyListPreChange(int list, int type); virtual void notifyListChange(int list, int type); virtual void notifyErrorMsg(int list, int sev, std::string msg); @@ -76,7 +74,6 @@ class NotifyQt: public QObject, public NotifyClient virtual void notifyOwnAvatarChanged() ; virtual void notifyChatLobbyEvent(uint64_t /* lobby id */, uint32_t /* event type */, const RsGxsId & /*nickname*/, const std::string& /* any string */) ; virtual void notifyChatLobbyTimeShift(int time_shift) ; - void notifyConnectionWithoutCert(); virtual void notifyOwnStatusMessageChanged() ; virtual void notifyDiskFull(uint32_t loc,uint32_t size_in_mb) ; @@ -85,8 +82,6 @@ class NotifyQt: public QObject, public NotifyClient /* one or more peers has changed the states */ virtual void notifyPeerStatusChangedSummary(); - virtual void notifyGxsChange(const RsGxsChanges& change); - virtual void notifyHistoryChanged(uint32_t msgId, int type); virtual void notifyDiscInfoChanged() ; @@ -123,8 +118,6 @@ class NotifyQt: public QObject, public NotifyClient // It's beneficial to send info to the GUI using signals, because signals are thread-safe // as they get queued by Qt. // - void peerConnected(const QString&) const ; - void peerDisconnected(const QString&) const ; void hashingInfoChanged(const QString&) const ; void filesPreModChanged(bool) const ; void filesPostModChanged(bool) const ; diff --git a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp index 5dbbf1c5a..bd2d647f5 100644 --- a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp +++ b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp @@ -37,7 +37,14 @@ QMap updateBroadcastMap; RsGxsUpdateBroadcast::RsGxsUpdateBroadcast(RsGxsIfaceHelper *ifaceImpl) : QObject(NULL), mIfaceImpl(ifaceImpl) { - connect(NotifyQt::getInstance(), SIGNAL(gxsChange(RsGxsChanges)), this, SLOT(onChangesReceived(RsGxsChanges))); + mEventHandlerId = 0; // forces initialization in registerEventsHandler() + + rsEvents->registerEventsHandler( [this](std::shared_ptr event) + { + if(event->mType == RsEventType::GXS_CHANGES) + onChangesReceived(*dynamic_cast(event.get())); + + }, mEventHandlerId ); } void RsGxsUpdateBroadcast::cleanup() diff --git a/retroshare-gui/src/util/RsGxsUpdateBroadcast.h b/retroshare-gui/src/util/RsGxsUpdateBroadcast.h index 1a776f2c4..1383c18dd 100644 --- a/retroshare-gui/src/util/RsGxsUpdateBroadcast.h +++ b/retroshare-gui/src/util/RsGxsUpdateBroadcast.h @@ -24,6 +24,7 @@ #include #include +#include struct RsGxsIfaceHelper; struct RsGxsChanges; @@ -53,6 +54,7 @@ private: private: RsGxsIfaceHelper* mIfaceImpl; + RsEventsHandlerId_t mEventHandlerId ; }; #endif // RSGXSUPDATEBROADCAST_H diff --git a/retroshare-gui/src/util/TokenQueue.cpp b/retroshare-gui/src/util/TokenQueue.cpp index ac66d5c3c..4fad53fc5 100644 --- a/retroshare-gui/src/util/TokenQueue.cpp +++ b/retroshare-gui/src/util/TokenQueue.cpp @@ -34,7 +34,7 @@ TokenQueue::TokenQueue(RsTokenService *service, TokenResponse *resp) { mTrigger = new RsProtectedTimer(this); mTrigger->setSingleShot(true); - connect(mTrigger, SIGNAL(timeout()), this, SLOT(pollRequests())); + connect(mTrigger, SIGNAL(timeout()), this, SLOT(pollRequests()),Qt::QueuedConnection); } bool TokenQueue::requestGroupInfo(uint32_t &token, uint32_t anstype, const RsTokReqOptions &opts, std::list& ids, uint32_t usertype)