From 556d6a85c9d5f4e2d29b94526689568b4081c006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Mon, 1 Dec 2014 22:24:48 +0000 Subject: Facebook: Optimize marking chat messages as read Not mark as read every single message when loading history messages. git-svn-id: http://svn.miranda-ng.org/main/trunk@11206 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/FacebookRM/src/client.h | 2 +- protocols/FacebookRM/src/messages.cpp | 33 ++++++++++++++++++++++++--------- protocols/FacebookRM/src/process.cpp | 21 +++++++++++++-------- protocols/FacebookRM/src/proto.cpp | 19 +++++++++---------- 4 files changed, 47 insertions(+), 28 deletions(-) (limited to 'protocols') diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h index d69c311363..e84aa3ad08 100644 --- a/protocols/FacebookRM/src/client.h +++ b/protocols/FacebookRM/src/client.h @@ -108,7 +108,7 @@ public: std::string get_server_type(); std::string get_privacy_type(); - std::map ignore_read; + std::set ignore_read; std::set typers; // store info about typing contacts, because Facebook doesn't send "stopped typing" event when there is actual message being sent std::map readers; diff --git a/protocols/FacebookRM/src/messages.cpp b/protocols/FacebookRM/src/messages.cpp index d25514fb4a..fb415825be 100644 --- a/protocols/FacebookRM/src/messages.cpp +++ b/protocols/FacebookRM/src/messages.cpp @@ -175,21 +175,36 @@ void FacebookProto::ReadMessageWorker(void *p) if (p == NULL) return; - MCONTACT hContact = (MCONTACT)p; - - if (getBool(FACEBOOK_KEY_KEEP_UNREAD, 0) || getBool(hContact, FACEBOOK_KEY_KEEP_UNREAD, 0)) + if (getBool(FACEBOOK_KEY_KEEP_UNREAD, 0)) return; - // mark message read (also send seen info) - const char *value = (isChatRoom(hContact) ? FACEBOOK_KEY_TID : FACEBOOK_KEY_ID); - ptrA id( getStringA(hContact, value)); - if (id == NULL) + std::set *hContacts = (std::set*)p; + + if (hContacts->empty()) { + delete hContacts; return; + } - std::string data = "ids[" + utils::url::encode(std::string(id)) + "]=true"; - data += "&fb_dtsg=" + facy.dtsg_; + std::string data = "fb_dtsg=" + facy.dtsg_; data += "&__user=" + facy.self_.user_id; data += "&__a=1&__dyn=&__req=&ttstamp=" + facy.ttstamp(); + + for (std::set::iterator it = hContacts->begin(); it != hContacts->end(); ++it) { + MCONTACT hContact = *it; + + if (getBool(hContact, FACEBOOK_KEY_KEEP_UNREAD, 0)) + continue; + + // mark message read (also send seen info) + const char *value = (isChatRoom(hContact) ? FACEBOOK_KEY_TID : FACEBOOK_KEY_ID); + ptrA id(getStringA(hContact, value)); + if (id == NULL) + continue; + + data += "&ids[" + utils::url::encode(std::string(id)) + "]=true"; + } + hContacts->clear(); + delete hContacts; facy.flap(REQUEST_MARK_READ, &data); } diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp index b4e182842e..d7e676324b 100644 --- a/protocols/FacebookRM/src/process.cpp +++ b/protocols/FacebookRM/src/process.cpp @@ -492,9 +492,9 @@ void FacebookProto::LoadLastMessages(void *p) facy.handle_error("LoadLastMessages"); return; } - + // Temporarily disable marking messages as read for this contact - facy.ignore_read.insert(std::make_pair(hContact, true)); + facy.ignore_read.insert(hContact); CODE_BLOCK_TRY @@ -547,11 +547,8 @@ CODE_BLOCK_END facy.handle_success("LoadLastMessages"); // Enable marking messages as read for this contact - std::map::iterator it = facy.ignore_read.find(hContact); - if (it != facy.ignore_read.end()) { - it->second = false; - } - + facy.ignore_read.erase(hContact); + // And force mark read OnDbEventRead(hContact, NULL); } @@ -676,6 +673,8 @@ void FacebookProto::ReceiveMessages(std::vector messages, boo } } + std::set *hChatContacts = new std::set(); + for(std::vector::size_type i = 0; i < messages.size(); i++) { DWORD timestamp = local_timestamp || !messages[i]->time ? ::time(NULL) : messages[i]->time; @@ -752,7 +751,7 @@ void FacebookProto::ReceiveMessages(std::vector messages, boo UpdateChat(tthread_id.c_str(), messages[i]->user_id.c_str(), messages[i]->sender_name.c_str(), messages[i]->message_text.c_str(), timestamp); // Automatically mark message as read because chatroom doesn't support onRead event (yet) - ForkThread(&FacebookProto::ReadMessageWorker, (void*)hChatContact); + hChatContacts->insert(hChatContact); // std::set checks duplicates at insert automatically } else { // Single-user message debugLogA(" Got message: %s", messages[i]->message_text.c_str()); @@ -823,6 +822,12 @@ void FacebookProto::ReceiveMessages(std::vector messages, boo delete messages[i]; } messages.clear(); + + if (!hChatContacts->empty()) { + ForkThread(&FacebookProto::ReadMessageWorker, (void*)hChatContacts); + } else { + delete hChatContacts; + } } void FacebookProto::ProcessMessages(void* data) diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp index b10a5821b5..a5443be932 100644 --- a/protocols/FacebookRM/src/proto.cpp +++ b/protocols/FacebookRM/src/proto.cpp @@ -538,17 +538,16 @@ INT_PTR FacebookProto::OnMind(WPARAM wParam, LPARAM lParam) int FacebookProto::OnDbEventRead(WPARAM contactID, LPARAM dbei) { - std::map::iterator it = facy.ignore_read.find(contactID); - if (it != facy.ignore_read.end()) { - if (it->second) // it's TRUE, so we ignore this - return 0; - else // it's FALSE, so we just remove it from list - facy.ignore_read.erase(it); - } + if (isOffline() || !IsMyContact(contactID, false)) // ignore chats + return 0; - if ((IsMyContact(contactID, true)) && !isOffline()) { - ForkThread(&FacebookProto::ReadMessageWorker, (void*)contactID); - } + if (facy.ignore_read.find(contactID) != facy.ignore_read.end()) + return 0; // it's there, so we ignore this + + std::set *hContacts = new std::set(); + hContacts->insert(contactID); + + ForkThread(&FacebookProto::ReadMessageWorker, (void*)hContacts); return 0; } -- cgit v1.2.3