fixed forum/channel subscribe notifications

This commit is contained in:
csoler 2019-12-16 22:44:37 +01:00
parent 301874e756
commit a54cf981a6
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
9 changed files with 254 additions and 135 deletions

View File

@ -108,12 +108,13 @@ struct RsGxsChannelEvent: RsEvent
: RsEvent(RsEventType::GXS_CHANNELS), mChannelEventCode(UNKNOWN) {} : RsEvent(RsEventType::GXS_CHANNELS), mChannelEventCode(UNKNOWN) {}
enum ChannelEventCode: uint8_t { enum ChannelEventCode: uint8_t {
UNKNOWN = 0x00, UNKNOWN = 0x00,
NEW_CHANNEL = 0x01, // emitted when new channel is received NEW_CHANNEL = 0x01, // emitted when new channel is received
UPDATED_CHANNEL = 0x02, // emitted when existing channel is updated UPDATED_CHANNEL = 0x02, // emitted when existing channel is updated
NEW_MESSAGE = 0x03, // new message reeived in a particular channel (group and msg id) NEW_MESSAGE = 0x03, // new message reeived in a particular channel (group and msg id)
UPDATED_MESSAGE = 0x04, // existing message has been updated in a particular channel (group and msg id) UPDATED_MESSAGE = 0x04, // existing message has been updated in a particular channel (group and msg id)
RECEIVED_PUBLISH_KEY = 0x05, // publish key for this channel has been received. RECEIVED_PUBLISH_KEY = 0x05, // publish key for this channel has been received.
SUBSCRIBE_STATUS_CHANGED = 0x06, // subscription for channel mChannelGroupId changed.
}; };
ChannelEventCode mChannelEventCode; ChannelEventCode mChannelEventCode;

View File

@ -110,11 +110,12 @@ struct RsGxsForumEvent: RsEvent
: RsEvent(RsEventType::GXS_FORUMS), mForumEventCode(UNKNOWN) {} : RsEvent(RsEventType::GXS_FORUMS), mForumEventCode(UNKNOWN) {}
enum ForumEventCode: uint8_t { enum ForumEventCode: uint8_t {
UNKNOWN = 0x00, UNKNOWN = 0x00,
NEW_FORUM = 0x01, // emitted when new forum is received NEW_FORUM = 0x01, // emitted when new forum is received
UPDATED_FORUM = 0x02, // emitted when existing forum is updated UPDATED_FORUM = 0x02, // emitted when existing forum is updated
NEW_MESSAGE = 0x03, // new message reeived in a particular forum (group and msg id) NEW_MESSAGE = 0x03, // new message reeived in a particular forum (group and msg id)
UPDATED_MESSAGE = 0x04, // existing message has been updated in a particular forum (group and msg id) UPDATED_MESSAGE = 0x04, // existing message has been updated in a particular forum (group and msg id)
SUBSCRIBE_STATUS_CHANGED = 0x05, // forum was subscribed or unsubscribed
}; };
ForumEventCode mForumEventCode; ForumEventCode mForumEventCode;

View File

@ -256,13 +256,13 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit) for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1) for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
{ {
auto ev = std::make_shared<RsGxsChannelEvent>(); auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelMsgId = *mit1; ev->mChannelMsgId = *mit1;
ev->mChannelGroupId = mit->first; ev->mChannelGroupId = mit->first;
ev->mChannelEventCode = RsGxsChannelEvent::NEW_MESSAGE; ev->mChannelEventCode = RsGxsChannelEvent::NEW_MESSAGE;
rsEvents->sendEvent(ev); rsEvents->sendEvent(ev);
} }
} }
} }
@ -305,53 +305,67 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
{ {
switch (grpChange->getType()) switch (grpChange->getType())
{ {
default: default:
case RsGxsNotify::TYPE_PROCESSED: case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
case RsGxsNotify::TYPE_PUBLISHED: {
break; std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
case RsGxsNotify::TYPE_RECEIVED_NEW: for (git = grpList.begin(); git != grpList.end(); ++git)
{ {
/* group received */ auto ev = std::make_shared<RsGxsChannelEvent>();
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
RS_STACK_MUTEX(mKnownChannelsMutex);
for (git = grpList.begin(); git != grpList.end(); ++git)
{
if(mKnownChannels.find(*git) == mKnownChannels.end())
{
mKnownChannels.insert(std::make_pair(*git,time(NULL))) ;
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsChannelEvent>(); ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsGxsChannelEvent::SUBSCRIBE_STATUS_CHANGED;
ev->mChannelGroupId = *git; rsEvents->sendEvent(ev);
ev->mChannelEventCode = RsGxsChannelEvent::NEW_CHANNEL;
rsEvents->sendEvent(ev);
}
else
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;
}
break;
} }
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY: }
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
RS_STACK_MUTEX(mKnownChannelsMutex);
for (git = grpList.begin(); git != grpList.end(); ++git)
{ {
/* group received */ if(mKnownChannels.find(*git) == mKnownChannels.end())
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{ {
mKnownChannels.insert(std::make_pair(*git,time(NULL))) ;
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsChannelEvent>(); auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git; ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY; ev->mChannelEventCode = RsGxsChannelEvent::NEW_CHANNEL;
rsEvents->sendEvent(ev); rsEvents->sendEvent(ev);
} }
break; else
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;
} }
break;
}
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY;
rsEvents->sendEvent(ev);
}
break;
}
} }
} }
} }

View File

@ -53,7 +53,7 @@ p3GxsForums::p3GxsForums( RsGeneralDataService *gds,
RsGenExchange( gds, nes, new RsGxsForumSerialiser(), RsGenExchange( gds, nes, new RsGxsForumSerialiser(),
RS_SERVICE_GXS_TYPE_FORUMS, gixs, forumsAuthenPolicy()), RS_SERVICE_GXS_TYPE_FORUMS, gixs, forumsAuthenPolicy()),
RsGxsForums(static_cast<RsGxsIface&>(*this)), mGenToken(0), RsGxsForums(static_cast<RsGxsIface&>(*this)), mGenToken(0),
mGenActive(false), mGenCount(0) mGenActive(false), mGenCount(0), mKnownForumsMutex("GXS forums known forums timestamp cache")
{ {
// Test Data disabled in Repo. // Test Data disabled in Repo.
//RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD); //RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD);
@ -181,95 +181,143 @@ RsSerialiser* p3GxsForums::setupSerialiser()
void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes) void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
{ {
if (!changes.empty()) #ifdef GXSFORUMS_DEBUG
{ std::cerr << "p3GxsForums::notifyChanges() : " << changes.size() << "changes to notify" << std::endl;
if (rsEvents)
{
std::vector<RsGxsNotify*>::iterator it;
for(it = changes.begin(); it != changes.end(); ++it)
{
RsGxsNotify *c = *it;
switch (c->getType())
{
default:
case RsGxsNotify::TYPE_PROCESSED:
case RsGxsNotify::TYPE_PUBLISHED:
break;
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange*>(c);
if (msgChange)
{
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &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<RsGxsForumEvent>();
ev->mForumGroupId = mit->first;
ev->mForumMsgId = *mit1;
ev->mForumEventCode = RsGxsForumEvent::NEW_MESSAGE;
rsEvents->sendEvent(ev);
}
break;
}
RsGxsGroupChange *grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
if (grpChange)
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
if(mKnownForums.find(*git) == mKnownForums.end())
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsGxsForumEvent::NEW_FORUM;
rsEvents->sendEvent(ev);
mKnownForums.insert(std::make_pair(*git,time(NULL))) ;
IndicateConfigChanged();
}
else
std::cerr << "(II) Not notifying already known forum " << *git << std::endl;
}
break;
}
break;
}
#ifdef UNUSED
// (Cyril) There's no publish key system for forums now. As a GXS group, it is possible to add one, just like channels
// but the possibility is not offered by the API yet.
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
{
RsGxsGroupChange *grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
if (grpChange)
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
notify->AddFeedItem(RS_FEED_ITEM_FORUM_PUBLISHKEY, git->toStdString());
}
break;
}
break;
}
#endif #endif
std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); ++it)
{
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange)
{
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) /* message received */
if (rsEvents)
{
std::map<RsGxsGroupId, std::set<RsGxsMessageId> >& 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<RsGxsForumEvent>();
ev->mForumMsgId = *mit1;
ev->mForumGroupId = mit->first;
ev->mForumEventCode = RsGxsForumEvent::NEW_MESSAGE;
rsEvents->sendEvent(ev);
}
}
#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<RsGxsGroupId, std::set<RsGxsMessageId> > &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)
{
#ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
std::cerr << std::endl;
#endif
/* 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<RsGxsGroupChange*>(*it);
if (grpChange)
{
switch (grpChange->getType())
{
default:
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsGxsForumEvent::SUBSCRIBE_STATUS_CHANGED;
rsEvents->sendEvent(ev);
}
}
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::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(NULL))) ;
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsGxsForumEvent::NEW_FORUM;
rsEvents->sendEvent(ev);
}
else
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;
}
break;
}
#ifdef NOT_USED_YET
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
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); RsGxsIfaceHelper::receiveChanges(changes);

View File

@ -166,4 +166,5 @@ bool generateGroup(uint32_t &token, std::string groupName);
RsGxsMessageId mGenThreadId; RsGxsMessageId mGenThreadId;
std::map<RsGxsGroupId,rstime_t> mKnownForums ; std::map<RsGxsGroupId,rstime_t> mKnownForums ;
RsMutex mKnownForumsMutex;
}; };

View File

@ -50,6 +50,28 @@ public:
GxsChannelDialog::GxsChannelDialog(QWidget *parent) GxsChannelDialog::GxsChannelDialog(QWidget *parent)
: GxsGroupFrameDialog(rsGxsChannels, parent,true) : 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<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
}
void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
if(event->mType == RsEventType::GXS_CHANNELS)
{
const RsGxsChannelEvent *e = dynamic_cast<const RsGxsChannelEvent*>(event.get());
if(!e)
return;
switch(e->mChannelEventCode)
{
case RsGxsChannelEvent::SUBSCRIBE_STATUS_CHANGED: updateDisplay(true);
break;
default:
break;
}
}
} }
GxsChannelDialog::~GxsChannelDialog() GxsChannelDialog::~GxsChannelDialog()

View File

@ -74,6 +74,10 @@ private:
virtual QWidget *createCommentHeaderWidget(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId); virtual QWidget *createCommentHeaderWidget(const RsGxsGroupId &grpId, const RsGxsMessageId &msgId);
virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data
virtual void loadGroupSummaryToken(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo, RsUserdata* &userdata); virtual void loadGroupSummaryToken(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo, RsUserdata* &userdata);
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
RsEventsHandlerId_t mEventHandlerId;
}; };
#endif #endif

View File

@ -25,6 +25,7 @@
#include "GxsForumUserNotify.h" #include "GxsForumUserNotify.h"
#include "gui/notifyqt.h" #include "gui/notifyqt.h"
#include "gui/gxs/GxsGroupShareKey.h" #include "gui/gxs/GxsGroupShareKey.h"
#include "util/qtthreadsutils.h"
#include "gui/common/GroupTreeWidget.h" #include "gui/common/GroupTreeWidget.h"
class GxsForumGroupInfoData : public RsUserdata class GxsForumGroupInfoData : public RsUserdata
@ -41,6 +42,29 @@ GxsForumsDialog::GxsForumsDialog(QWidget *parent)
: GxsGroupFrameDialog(rsGxsForums, parent) : GxsGroupFrameDialog(rsGxsForums, parent)
{ {
mCountChildMsgs = true; 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<const RsEvent> event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId );
}
void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
{
if(event->mType == RsEventType::GXS_FORUMS)
{
const RsGxsForumEvent *e = dynamic_cast<const RsGxsForumEvent*>(event.get());
if(!e)
return;
switch(e->mForumEventCode)
{
case RsGxsForumEvent::SUBSCRIBE_STATUS_CHANGED: updateDisplay(true);
break;
default:
break;
}
}
} }
GxsForumsDialog::~GxsForumsDialog() GxsForumsDialog::~GxsForumsDialog()

View File

@ -58,6 +58,10 @@ private:
virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId); virtual GxsMessageFrameWidget *createMessageFrameWidget(const RsGxsGroupId &groupId);
virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data virtual uint32_t requestGroupSummaryType() { return GXS_REQUEST_TYPE_GROUP_DATA; } // request complete group data
virtual void loadGroupSummaryToken(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo, RsUserdata* &userdata); virtual void loadGroupSummaryToken(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo, RsUserdata* &userdata);
void handleEvent_main_thread(std::shared_ptr<const RsEvent> event);
RsEventsHandlerId_t mEventHandlerId;
}; };
#endif #endif