diff options
author | Robert Pösel <robyer@seznam.cz> | 2014-11-20 11:49:22 +0000 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2014-11-20 11:49:22 +0000 |
commit | a75ba12d58c579bd1a193c01d452db6cb295ae7a (patch) | |
tree | 2a59001be2b9bf64b28651ea0765c0d319078959 /protocols/FacebookRM | |
parent | bf644e855744c674eedf7951ba1f85fd629a1066 (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.cpp | 43 | ||||
-rw-r--r-- | protocols/FacebookRM/src/communication.cpp | 4 | ||||
-rw-r--r-- | protocols/FacebookRM/src/entities.h | 2 | ||||
-rw-r--r-- | protocols/FacebookRM/src/json.cpp | 20 | ||||
-rw-r--r-- | protocols/FacebookRM/src/process.cpp | 67 | ||||
-rw-r--r-- | protocols/FacebookRM/src/proto.h | 5 |
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 |