summaryrefslogtreecommitdiff
path: root/protocols/FacebookRM
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2014-11-20 11:49:22 +0000
committerRobert Pösel <robyer@seznam.cz>2014-11-20 11:49:22 +0000
commita75ba12d58c579bd1a193c01d452db6cb295ae7a (patch)
tree2a59001be2b9bf64b28651ea0765c0d319078959 /protocols/FacebookRM
parentbf644e855744c674eedf7951ba1f85fd629a1066 (diff)
Facebook: Refactor whole groupchat with notifications
This fix crash on right-click to notification popup and problem with not working notifications count in statusbar git-svn-id: http://svn.miranda-ng.org/main/trunk@11028 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/FacebookRM')
-rw-r--r--protocols/FacebookRM/src/chat.cpp43
-rw-r--r--protocols/FacebookRM/src/communication.cpp4
-rw-r--r--protocols/FacebookRM/src/entities.h2
-rw-r--r--protocols/FacebookRM/src/json.cpp20
-rw-r--r--protocols/FacebookRM/src/process.cpp67
-rw-r--r--protocols/FacebookRM/src/proto.h5
6 files changed, 75 insertions, 66 deletions
diff --git a/protocols/FacebookRM/src/chat.cpp b/protocols/FacebookRM/src/chat.cpp
index 684abe0671..d7d725917a 100644
--- a/protocols/FacebookRM/src/chat.cpp
+++ b/protocols/FacebookRM/src/chat.cpp
@@ -385,10 +385,51 @@ int FacebookProto::OnGCMenuHook(WPARAM, LPARAM lParam)
return 0;
}
-bool FacebookProto::isSpecialChatRoom(MCONTACT hContact) {
+bool FacebookProto::IsSpecialChatRoom(MCONTACT hContact) {
if (!isChatRoom(hContact))
return false;
ptrT idT(getTStringA(hContact, "ChatRoomID"));
return idT && !_tcscmp(idT, _T(FACEBOOK_NOTIFICATIONS_CHATROOM));
+}
+
+void FacebookProto::PrepareNotificationsChatRoom() {
+ if (!getBool(FACEBOOK_KEY_NOTIFICATIONS_CHATROOM, DEFAULT_NOTIFICATIONS_CHATROOM))
+ return;
+
+ // Prepare notifications chatroom if not exists
+ TCHAR *gidT = _T(FACEBOOK_NOTIFICATIONS_CHATROOM);
+
+ MCONTACT hNotificationsChatRoom = ChatIDToHContact(gidT);
+ if (hNotificationsChatRoom == NULL || getDword(hNotificationsChatRoom, "Status", ID_STATUS_OFFLINE) != ID_STATUS_ONLINE) {
+ TCHAR nameT[200];
+ mir_sntprintf(nameT, SIZEOF(nameT), _T("%s: %s"), m_tszUserName, TranslateT("Notifications"));
+
+ // Create the group chat session
+ GCSESSION gcw = { sizeof(gcw) };
+ gcw.iType = GCW_PRIVMESS;
+ gcw.ptszID = gidT;
+ gcw.pszModule = m_szModuleName;
+ gcw.ptszName = nameT;
+ CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
+
+ // Send setting events
+ GCDEST gcd = { m_szModuleName, gidT, GC_EVENT_CONTROL };
+ GCEVENT gce = { sizeof(gce), &gcd };
+ gce.time = ::time(NULL);
+
+ CallServiceSync(MS_GC_EVENT, WINDOW_HIDDEN, reinterpret_cast<LPARAM>(&gce));
+ CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
+ }
+}
+
+void FacebookProto::UpdateNotificationsChatRoom(facebook_notification *notification) {
+ if (!getBool(FACEBOOK_KEY_NOTIFICATIONS_CHATROOM, DEFAULT_NOTIFICATIONS_CHATROOM))
+ return;
+
+ char *name = _T2A(TranslateT("Notification"), CP_UTF8);
+
+ std::stringstream text;
+ text << notification->text << "\n\n" << notification->link;
+ UpdateChat(_T(FACEBOOK_NOTIFICATIONS_CHATROOM), name /*notification->second->user_id.c_str()*/, name, text.str().c_str(), notification->time, notification->seen);
} \ No newline at end of file
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp
index 11c4e066d8..398093fe3f 100644
--- a/protocols/FacebookRM/src/communication.cpp
+++ b/protocols/FacebookRM/src/communication.cpp
@@ -718,7 +718,9 @@ void facebook_client::clear_cookies()
}
void facebook_client::clear_notifications()
-{
+{
+ ScopedLock s(notifications_lock_);
+
for (std::map<std::string, facebook_notification*>::iterator it = notifications.begin(); it != notifications.end(); ) {
if (it->second->hWndPopup != NULL)
PUDeletePopup(it->second->hWndPopup); // close popup
diff --git a/protocols/FacebookRM/src/entities.h b/protocols/FacebookRM/src/entities.h
index d4e86bc652..35c062d4af 100644
--- a/protocols/FacebookRM/src/entities.h
+++ b/protocols/FacebookRM/src/entities.h
@@ -150,7 +150,6 @@ struct facebook_notification
std::string id;
time_t time;
bool seen;
- bool written;
HWND hWndPopup;
facebook_notification()
@@ -158,7 +157,6 @@ struct facebook_notification
this->user_id = this->text = this->link = this->id = "";
this->time = 0;
this->seen = false;
- this->written = false;
this->hWndPopup = NULL;
}
};
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp
index e6654517c2..8c0de1bd22 100644
--- a/protocols/FacebookRM/src/json.cpp
+++ b/protocols/FacebookRM/src/json.cpp
@@ -250,6 +250,9 @@ int facebook_json_parser::parse_notifications(void *data, std::map< std::string,
// check if we should use use local_timestamp for unread messages and use it for notifications time too
bool local_timestamp = proto->getBool(FACEBOOK_KEY_LOCAL_TIMESTAMP_UNREAD, 0);
+ // Create notifications chatroom (if it doesn't exists), because we will be writing to it new notifications here
+ proto->PrepareNotificationsChatRoom();
+
for (unsigned int i = 0; i < json_size(list); i++) {
JSONNODE *it = json_at(list, i);
const char *id = json_name(it);
@@ -272,7 +275,11 @@ int facebook_json_parser::parse_notifications(void *data, std::map< std::string,
notification->seen = (json_as_int(unread) == 0);
notification->time = local_timestamp ? ::time(NULL) : utils::time::fix_timestamp(json_as_float(time));
- if (notifications->find(notification->id) == notifications->end())
+ // Write notification to chatroom
+ proto->UpdateNotificationsChatRoom(notification);
+
+ // If it's unseen, remember it, otherwise forget it
+ if (notifications->find(notification->id) == notifications->end() && !notification->seen)
notifications->insert(std::make_pair(notification->id, notification));
else
delete notification;
@@ -572,6 +579,9 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
// check if we should use use local_timestamp for unread messages and use it for notifications time too
bool local_timestamp = proto->getBool(FACEBOOK_KEY_LOCAL_TIMESTAMP_UNREAD, 0);
+ // Create notifications chatroom (if it doesn't exists), because we will be writing to it new notifications here
+ proto->PrepareNotificationsChatRoom();
+
for (unsigned int j = 0; j < json_size(nodes); j++) {
JSONNODE *itNodes = json_at(nodes, j);
@@ -605,7 +615,11 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
if (pos != std::string::npos)
notification->id = notification->id.substr(pos+1);
- if (notifications->find(notification->id) == notifications->end())
+ // Write notification to chatroom
+ proto->UpdateNotificationsChatRoom(notification);
+
+ // If it's unseen, remember it, otherwise forget it (here it will always be unseen)
+ if (notifications->find(notification->id) == notifications->end() && !notification->seen)
notifications->insert(std::make_pair(notification->id, notification));
else
delete notification;
@@ -769,6 +783,8 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
}
}
} else if (t == "notifications_read" || t == "notifications_seen") {
+ ScopedLock s(proto->facy.notifications_lock_);
+
JSONNODE *alerts = json_get(it, "alert_ids");
for (unsigned int j = 0; j < json_size(alerts); j++) {
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index 97340db7ca..93692db613 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -463,7 +463,7 @@ void FacebookProto::LoadLastMessages(void *p)
bool isChat = isChatRoom(hContact);
- if (isSpecialChatRoom(hContact)) // e.g. nofitications
+ if (IsSpecialChatRoom(hContact)) // e.g. nofitications
return;
if (isChat && !m_enableChat)
@@ -873,67 +873,16 @@ exit:
void FacebookProto::ShowNotifications() {
ScopedLock s(facy.notifications_lock_);
- bool showPopups = getBool(FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE, DEFAULT_EVENT_NOTIFICATIONS_ENABLE);
- bool useChatRoom = getBool(FACEBOOK_KEY_NOTIFICATIONS_CHATROOM, DEFAULT_NOTIFICATIONS_CHATROOM);
-
- char *notificationName = _T2A(TranslateT("Notification"), CP_UTF8);
-
- if (useChatRoom) {
- // Prepare chatroom if not exists
- TCHAR *gidT = _T(FACEBOOK_NOTIFICATIONS_CHATROOM);
-
- MCONTACT hNotificationsChatRoom = ChatIDToHContact(gidT);
- if (hNotificationsChatRoom == NULL || getDword(hNotificationsChatRoom, "Status", ID_STATUS_OFFLINE) != ID_STATUS_ONLINE) {
- TCHAR nameT[200];
- mir_sntprintf(nameT, SIZEOF(nameT), _T("%s: %s"), m_tszUserName, TranslateT("Notifications"));
-
- // Create the group chat session
- GCSESSION gcw = { sizeof(gcw) };
- gcw.iType = GCW_PRIVMESS;
- gcw.ptszID = gidT;
- gcw.pszModule = m_szModuleName;
- gcw.ptszName = nameT;
- CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
-
- // Send setting events
- GCDEST gcd = { m_szModuleName, gidT, GC_EVENT_CONTROL };
- GCEVENT gce = { sizeof(gce), &gcd };
- gce.time = ::time(NULL);
-
- CallServiceSync(MS_GC_EVENT, WINDOW_HIDDEN, reinterpret_cast<LPARAM>(&gce));
- CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, reinterpret_cast<LPARAM>(&gce));
- }
-
- hNotificationsChatRoom = ChatIDToHContact(gidT);
- useChatRoom = (hNotificationsChatRoom != NULL && getDword(hNotificationsChatRoom, "Status", ID_STATUS_OFFLINE) == ID_STATUS_ONLINE);
- }
+ if (!getBool(FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE, DEFAULT_EVENT_NOTIFICATIONS_ENABLE))
+ return;
// Show popups for unseen notifications and/or write them to chatroom
for (std::map<std::string, facebook_notification*>::iterator it = facy.notifications.begin(); it != facy.notifications.end(); ++it) {
- if (it->second != NULL) {
- if (useChatRoom && !it->second->written) {
- it->second->written = true;
-
- std::stringstream text;
- text << it->second->text << "\n\n" << it->second->link;
- UpdateChat(_T(FACEBOOK_NOTIFICATIONS_CHATROOM), ""/*it->second->user_id.c_str()*/, notificationName, text.str().c_str(), it->second->time, it->second->seen);
- }
-
- if (showPopups && !it->second->seen) {
- it->second->seen = true;
-
- debugLogA(" Showing popup for notification: %s", it->second->text.c_str());
- ptrT szText(mir_utf8decodeT(it->second->text.c_str()));
- it->second->hWndPopup = NotifyEvent(m_tszUserName, szText, ContactIDToHContact(it->second->user_id), FACEBOOK_EVENT_NOTIFICATION, &it->second->link, &it->second->id);
- }
- }
- }
-
- // Remove old seen and processed (without hWndPopup handle) notifications from map
- for (std::map<std::string, facebook_notification*>::iterator it = facy.notifications.begin(); it != facy.notifications.end();) {
- if (it->second != NULL && it->second->seen && it->second->hWndPopup == NULL) {
- delete it->second;
- it = facy.notifications.erase(it);
+ if (it->second != NULL && !it->second->seen) {
+ debugLogA(" Showing popup for notification: %s", it->second->text.c_str());
+ ptrT szText(mir_utf8decodeT(it->second->text.c_str()));
+ it->second->hWndPopup = NotifyEvent(m_tszUserName, szText, ContactIDToHContact(it->second->user_id), FACEBOOK_EVENT_NOTIFICATION, &it->second->link, &it->second->id);
+ it->second->seen = true;
}
}
}
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index 78f30c2563..98b7d0e7cb 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -222,7 +222,10 @@ public:
void ReceiveMessages(std::vector<facebook_message*> messages, bool local_timestamp, bool check_duplicates = false);
void LoadChatInfo(facebook_chatroom* fbc);
void LoadParticipantsNames(facebook_chatroom *fbc);
- bool isSpecialChatRoom(MCONTACT hContact);
+
+ bool IsSpecialChatRoom(MCONTACT hContact);
+ void PrepareNotificationsChatRoom();
+ void UpdateNotificationsChatRoom(facebook_notification *notification);
// Connection client
facebook_client facy; // TODO: Refactor to "client" and make dynamic