diff options
| author | Robert Pösel <robyer@seznam.cz> | 2014-04-05 09:03:20 +0000 | 
|---|---|---|
| committer | Robert Pösel <robyer@seznam.cz> | 2014-04-05 09:03:20 +0000 | 
| commit | 5e8e5ed54e602e0de3d328098ff828cba441b2a0 (patch) | |
| tree | 178212b37c358cb3f6d5b1c1f2ca195b49aa24d5 | |
| parent | 7e7e977e3dd74fe09c62d7b345bbbbecf33602a4 (diff) | |
Facebook: Correct implementation of managing number of unread notifications
git-svn-id: http://svn.miranda-ng.org/main/trunk@8858 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
| -rw-r--r-- | protocols/FacebookRM/src/client.h | 7 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/communication.cpp | 13 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/connection.cpp | 1 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/entities.h | 4 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/events.cpp | 16 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/json.cpp | 50 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/json.h | 4 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/process.cpp | 45 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/proto.cpp | 2 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/proto.h | 3 | 
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, ¬ifications, 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, ¬ifications[i]->link, ¬ifications[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), ¬ifications);
 +	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, ¬ifications[i]->link, ¬ifications[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();
  };
 | 
