summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/FacebookRM/src/client.h7
-rw-r--r--protocols/FacebookRM/src/communication.cpp13
-rw-r--r--protocols/FacebookRM/src/connection.cpp1
-rw-r--r--protocols/FacebookRM/src/entities.h4
-rw-r--r--protocols/FacebookRM/src/events.cpp16
-rw-r--r--protocols/FacebookRM/src/json.cpp50
-rw-r--r--protocols/FacebookRM/src/json.h4
-rw-r--r--protocols/FacebookRM/src/process.cpp45
-rw-r--r--protocols/FacebookRM/src/proto.cpp2
-rw-r--r--protocols/FacebookRM/src/proto.h3
10 files changed, 77 insertions, 68 deletions
diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h
index c2980556c0..bbd7eb45dc 100644
--- a/protocols/FacebookRM/src/client.h
+++ b/protocols/FacebookRM/src/client.h
@@ -41,7 +41,7 @@ public:
chat_sequence_num_ = chat_channel_host_ = chat_channel_partition_ = \
dtsg_ = logout_hash_ = chat_sticky_num_ = chat_conn_num_ = chat_clientid_ = "";
- msgid_ = error_count_ = last_feeds_update_ = last_notification_time_ = notifications_count_ = 0;
+ msgid_ = error_count_ = last_feeds_update_ = last_notification_time_ = 0;
https_ = is_idle_ = invisible_ = is_typing_ = false;
@@ -82,7 +82,6 @@ public:
bool https_;
time_t last_feeds_update_;
unsigned __int64 last_notification_time_;
- int notifications_count_;
int msgid_;
////////////////////////////////////////////////////////////
@@ -100,6 +99,7 @@ public:
std::map<std::string, std::string> cookies;
std::map<std::string, std::string> pages;
std::map<std::tstring, facebook_chatroom> chat_rooms;
+ std::map<std::string, facebook_notification*> notifications;
std::string get_newsfeed_type();
std::string get_server_type();
@@ -107,7 +107,8 @@ public:
char* load_cookies();
void store_headers(http::response* resp, NETLIBHTTPHEADER* headers, int headers_count);
- void clear_cookies();
+ void clear_cookies();
+ void clear_notifications();
////////////////////////////////////////////////////////////
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp
index e1facb8016..901d731074 100644
--- a/protocols/FacebookRM/src/communication.cpp
+++ b/protocols/FacebookRM/src/communication.cpp
@@ -679,6 +679,19 @@ void facebook_client::clear_cookies()
cookies.clear();
}
+void facebook_client::clear_notifications()
+{
+ 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
+
+ delete it->second;
+ it = notifications.erase(it);
+ }
+
+ notifications.clear();
+}
+
void loginError(FacebookProto *proto, std::string error_str) {
error_str = utils::text::trim(
utils::text::special_expressions_decode(
diff --git a/protocols/FacebookRM/src/connection.cpp b/protocols/FacebookRM/src/connection.cpp
index dff3474234..abe78a324a 100644
--- a/protocols/FacebookRM/src/connection.cpp
+++ b/protocols/FacebookRM/src/connection.cpp
@@ -51,6 +51,7 @@ void FacebookProto::ChangeStatus(void*)
facy.logout();
facy.clear_cookies();
+ facy.clear_notifications();
facy.buddies.clear();
facy.messages_ignore.clear();
facy.pages.clear();
diff --git a/protocols/FacebookRM/src/entities.h b/protocols/FacebookRM/src/entities.h
index 14a62ef0eb..ecb54136bb 100644
--- a/protocols/FacebookRM/src/entities.h
+++ b/protocols/FacebookRM/src/entities.h
@@ -135,10 +135,14 @@ struct facebook_notification
std::string text;
std::string link;
std::string id;
+ bool seen;
+ HWND hWndPopup;
facebook_notification()
{
this->user_id = this->text = this->link = this->id = "";
+ this->seen = false;
+ this->hWndPopup = NULL;
}
};
diff --git a/protocols/FacebookRM/src/events.cpp b/protocols/FacebookRM/src/events.cpp
index 19a9c68701..e1e3ac560f 100644
--- a/protocols/FacebookRM/src/events.cpp
+++ b/protocols/FacebookRM/src/events.cpp
@@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "common.h"
-void FacebookProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWORD flags, std::string *url, std::string *notification_id)
+HWND FacebookProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWORD flags, std::string *url, std::string *notification_id)
{
char name[256];
@@ -30,14 +30,14 @@ void FacebookProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWO
{
case FACEBOOK_EVENT_CLIENT:
if (!getByte(FACEBOOK_KEY_EVENT_CLIENT_ENABLE, DEFAULT_EVENT_CLIENT_ENABLE))
- return;
+ return NULL;
mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Client");
flags |= NIIF_WARNING;
break;
case FACEBOOK_EVENT_NEWSFEED:
if (!getByte(FACEBOOK_KEY_EVENT_FEEDS_ENABLE, DEFAULT_EVENT_FEEDS_ENABLE))
- return;
+ return NULL;
mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Newsfeed");
SkinPlaySound("NewsFeed");
flags |= NIIF_INFO;
@@ -45,7 +45,7 @@ void FacebookProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWO
case FACEBOOK_EVENT_NOTIFICATION:
if (!getByte(FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE, DEFAULT_EVENT_NOTIFICATIONS_ENABLE))
- return;
+ return NULL;
mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Notification");
SkinPlaySound("Notification");
flags |= NIIF_INFO;
@@ -53,7 +53,7 @@ void FacebookProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWO
case FACEBOOK_EVENT_OTHER:
if (!getByte(FACEBOOK_KEY_EVENT_OTHER_ENABLE, DEFAULT_EVENT_OTHER_ENABLE))
- return;
+ return NULL;
mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Other");
SkinPlaySound("OtherEvent");
flags |= NIIF_INFO;
@@ -87,7 +87,7 @@ void FacebookProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWO
}
if (CallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&pd) == 0)
- return;
+ return NULL; // TODO: return popup window handle (to allow closing them)
}
} else {
if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY))
@@ -105,10 +105,12 @@ void FacebookProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWO
err.tszInfo = info;
err.uTimeout = 10000;
if (CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM) & err) == 0)
- return;
+ return NULL;
}
}
if (FLAG_CONTAINS(flags, FACEBOOK_EVENT_CLIENT))
MessageBox(NULL, info, title, MB_OK | MB_ICONINFORMATION);
+
+ return NULL;
}
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp
index dc824d0cbf..110a82d127 100644
--- a/protocols/FacebookRM/src/json.cpp
+++ b/protocols/FacebookRM/src/json.cpp
@@ -225,7 +225,7 @@ int facebook_json_parser::parse_friends(void* data, std::map< std::string, faceb
}
-int facebook_json_parser::parse_notifications(void *data, std::vector< facebook_notification* > *notifications)
+int facebook_json_parser::parse_notifications(void *data, std::map< std::string, facebook_notification* > *notifications)
{
std::string jsonData = static_cast< std::string* >(data)->substr(9);
@@ -265,7 +265,10 @@ int facebook_json_parser::parse_notifications(void *data, std::vector< facebook_
notification->link = utils::text::source_get_value(&text, 3, "<a ", "href=\"", "\"");
notification->text = utils::text::remove_html(utils::text::source_get_value(&text, 1, "<abbr"));
- notifications->push_back(notification);
+ if (notifications->find(notification->id) == notifications->end())
+ notifications->insert(std::make_pair(notification->id, notification));
+ else
+ delete notification;
}
json_delete(root);
@@ -365,7 +368,7 @@ void parseAttachments(FacebookProto *proto, std::string *message_text, JSONNODE
}
}
-int facebook_json_parser::parse_messages(void* data, std::vector< facebook_message* >* messages, std::vector< facebook_notification* >* notifications, bool inboxOnly)
+int facebook_json_parser::parse_messages(void* data, std::vector< facebook_message* >* messages, std::map< std::string, facebook_notification* >* notifications, bool inboxOnly)
{
// remove old received messages from map
for (std::map<std::string, bool>::iterator it = proto->facy.messages_ignore.begin(); it != proto->facy.messages_ignore.end();) {
@@ -599,20 +602,10 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
messages->push_back(message);
}
}
- } else if (t == "notifications_read") {
- JSONNODE *alerts = json_get(it, "alert_ids");
- proto->facy.notifications_count_ -= json_size(alerts);
-
- if (proto->facy.notifications_count_ < 0)
- proto->facy.notifications_count_ = 0;
} else if (t == "notification_json") {
// event notification
JSONNODE *nodes = json_get(it, "nodes");
- proto->facy.notifications_count_ += json_size(nodes);
- if (!proto->getByte(FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE, DEFAULT_EVENT_NOTIFICATIONS_ENABLE))
- continue;
-
for (unsigned int j = 0; j < json_size(nodes); j++) {
JSONNODE *itNodes = json_at(nodes, j);
@@ -645,7 +638,10 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
if (pos != std::string::npos)
notification->id = notification->id.substr(pos+1);
- notifications->push_back(notification);
+ if (notifications->find(notification->id) == notifications->end())
+ notifications->insert(std::make_pair(notification->id, notification));
+ else
+ delete notification;
}
}
} else if (t == "typ") {
@@ -706,14 +702,6 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
/* if (!text.empty()) {
proto->NotifyEvent()
}*/
- } else if (t == "inbox") {
- // count of unread/unseen messages - pretty useless info for us
- /* JSONNODE *unread_ = json_get(it, "unread");
- JSONNODE *unseen_ = json_get(it, "unseen");
- JSONNODE *other_unread_ = json_get(it, "other_unread");
- JSONNODE *other_unseen_ = json_get(it, "other_unseen");
- JSONNODE *seen_timestamp_ = json_get(it, "seen_timestamp"); */
- continue;
} else if (t == "mercury") {
// rename multi user chat, ...
@@ -741,12 +729,20 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
proto->UpdateChat(thread_id.c_str(), NULL, NULL, message.c_str());
}
} else if (t == "notifications_read") {
- // TODO: close popups with these IDs
- JSONNODE *alert_ids = json_get(it, "alert_ids");
- for (unsigned int n = 0; n < json_size(alert_ids); n++) {
- JSONNODE *idItr = json_at(alert_ids, n);
+ JSONNODE *alerts = json_get(it, "alert_ids");
- // PUDeletePopup(hWndPopup);
+ for (unsigned int j = 0; j < json_size(alerts); j++) {
+ JSONNODE *itAlerts = json_at(alerts, j);
+ std::string id = json_as_pstring(itAlerts);
+
+ std::map<std::string, facebook_notification*>::iterator it = notifications->find(id);
+ if (it != notifications->end()) {
+ if (it->second->hWndPopup != NULL)
+ PUDeletePopup(it->second->hWndPopup); // close popup
+
+ delete it->second;
+ notifications->erase(it);
+ }
}
} else
continue;
diff --git a/protocols/FacebookRM/src/json.h b/protocols/FacebookRM/src/json.h
index 33f5538559..70001e4a31 100644
--- a/protocols/FacebookRM/src/json.h
+++ b/protocols/FacebookRM/src/json.h
@@ -32,8 +32,8 @@ public:
FacebookProto* proto;
int parse_buddy_list(void*, List::List< facebook_user >*);
int parse_friends(void*, std::map< std::string, facebook_user* >*);
- int parse_notifications(void*, std::vector< facebook_notification* >*);
- int parse_messages(void*, std::vector< facebook_message* >*, std::vector< facebook_notification* >*, bool inboxOnly);
+ int parse_notifications(void*, std::map< std::string, facebook_notification* >*);
+ int parse_messages(void*, std::vector< facebook_message* >*, std::map< std::string, facebook_notification* >*, bool inboxOnly);
int parse_unread_threads(void*, std::vector< std::string >*, bool inboxOnly);
int parse_thread_messages(void*, std::vector< facebook_message* >*, std::map< std::string, facebook_chatroom* >*, bool unreadOnly, bool inboxOnly, int limit);
int parse_thread_info(void* data, std::string* user_id);
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index 0fd44897ce..c8a3fc7d6b 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -497,7 +497,6 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo
messages.clear();
}
-// TODO: combine processmessages and processunreadmessages? (behavior of showing messages to user should be the same)
void FacebookProto::ProcessMessages(void* data)
{
if (data == NULL)
@@ -516,24 +515,16 @@ void FacebookProto::ProcessMessages(void* data)
CODE_BLOCK_TRY
std::vector< facebook_message* > messages;
- std::vector< facebook_notification* > notifications;
facebook_json_parser* p = new facebook_json_parser(this);
- p->parse_messages(data, &messages, &notifications, inboxOnly);
+ p->parse_messages(data, &messages, &facy.notifications, inboxOnly);
delete p;
bool local_timestamp = getBool(FACEBOOK_KEY_LOCAL_TIMESTAMP, 0);
ReceiveMessages(messages, local_timestamp);
- for(std::vector<facebook_notification*>::size_type i=0; i<notifications.size(); i++)
- {
- debugLogA(" Got notification: %s", notifications[i]->text.c_str());
- ptrT szText( mir_utf8decodeT(notifications[i]->text.c_str()));
- NotifyEvent(m_tszUserName, szText, ContactIDToHContact(notifications[i]->user_id), FACEBOOK_EVENT_NOTIFICATION, &notifications[i]->link, &notifications[i]->id);
- delete notifications[i];
- }
- notifications.clear();
+ ShowNotifications();
debugLogA("***** Messages processed");
@@ -547,6 +538,20 @@ exit:
delete resp;
}
+void FacebookProto::ShowNotifications() {
+ if (!getByte(FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE, DEFAULT_EVENT_NOTIFICATIONS_ENABLE))
+ return;
+
+ for (std::map<std::string, facebook_notification*>::iterator it = facy.notifications.begin(); it != facy.notifications.end(); ++it) {
+ if (it->second != NULL && !it->second->seen) {
+ debugLogA(" Got 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;
+ }
+ }
+}
+
void FacebookProto::ProcessNotifications(void*)
{
if (isOffline())
@@ -568,25 +573,11 @@ void FacebookProto::ProcessNotifications(void*)
CODE_BLOCK_TRY
- std::vector< facebook_notification* > notifications;
-
facebook_json_parser* p = new facebook_json_parser(this);
- p->parse_notifications(&(resp.data), &notifications);
+ p->parse_notifications(&(resp.data), &facy.notifications);
delete p;
- facy.notifications_count_ = notifications.size();
-
- if (!getByte(FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE, DEFAULT_EVENT_NOTIFICATIONS_ENABLE))
- return;
-
- for(std::vector<facebook_notification*>::size_type i=0; i<notifications.size(); i++)
- {
- debugLogA(" Got notification: %s", notifications[i]->text.c_str());
- ptrT szText( mir_utf8decodeT(notifications[i]->text.c_str()));
- NotifyEvent(m_tszUserName, szText, ContactIDToHContact(notifications[i]->user_id), FACEBOOK_EVENT_NOTIFICATION, &notifications[i]->link, &notifications[i]->id);
- delete notifications[i];
- }
- notifications.clear();
+ ShowNotifications();
debugLogA("***** Notifications processed");
diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp
index fc837ffaad..3a5b5d38dd 100644
--- a/protocols/FacebookRM/src/proto.cpp
+++ b/protocols/FacebookRM/src/proto.cpp
@@ -385,7 +385,7 @@ INT_PTR FacebookProto::GetNotificationsCount(WPARAM wParam, LPARAM lParam)
if (isOffline())
return 0;
- return facy.notifications_count_;
+ return facy.notifications.size();
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index 49c9102367..346ece4193 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -235,5 +235,6 @@ public:
static void CALLBACK APC_callback(ULONG_PTR p);
// Information providing
- void NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWORD flags, std::string *url = NULL, std::string *notification_id = NULL);
+ HWND NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWORD flags, std::string *url = NULL, std::string *notification_id = NULL);
+ void ShowNotifications();
};