diff options
author | Robert Pösel <robyer@seznam.cz> | 2017-02-26 01:30:13 +0100 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2017-02-26 01:30:13 +0100 |
commit | 7b550e3c80a63cf7a063a28fc7b0ce020a47c51b (patch) | |
tree | 34fe26715f12e54bf1b1e54a633c42d356a5bd37 | |
parent | 33c7f1e7bc3517df2ea45bc68a164b6380167072 (diff) |
Facebook: Don't block main thread when refreshing user info
-rw-r--r-- | protocols/FacebookRM/src/contacts.cpp | 85 | ||||
-rw-r--r-- | protocols/FacebookRM/src/proto.cpp | 78 | ||||
-rw-r--r-- | protocols/FacebookRM/src/proto.h | 1 |
3 files changed, 88 insertions, 76 deletions
diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp index c072808eb4..cec21e5904 100644 --- a/protocols/FacebookRM/src/contacts.cpp +++ b/protocols/FacebookRM/src/contacts.cpp @@ -672,6 +672,91 @@ void FacebookProto::SendPokeWorker(void *p) delete id; } +void FacebookProto::RefreshUserInfo(void *data) +{ + if (data == NULL) + return; + + MCONTACT hContact = *(MCONTACT*)data; + delete (MCONTACT*)data; + + ptrA user_id(getStringA(hContact, FACEBOOK_KEY_ID)); + if (user_id == NULL || isOffline()) { + ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)0, 0); + return; + } + + facebook_user fbu; + fbu.user_id = user_id; + + LoadContactInfo(&fbu); + + // TODO: don't duplicate code this way, refactor all this userInfo loading + // TODO: load more info about user (authorization state,...) + + std::string homepage = FACEBOOK_URL_PROFILE + fbu.user_id; + setString(hContact, "Homepage", homepage.c_str()); + + if (!fbu.real_name.empty()) { + SaveName(hContact, &fbu); + } + + if (fbu.gender) { + setByte(hContact, "Gender", fbu.gender); + } + + int oldType = getByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, CONTACT_NONE); + // From server we won't get request/approve types, only none, so we don't want to overwrite and lost it in that case + if (fbu.type != CONTACT_NONE || (oldType != CONTACT_REQUEST && oldType != CONTACT_APPROVE)) { + if (oldType != fbu.type) { + setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, fbu.type); + } + } + + // If this contact is page, set it as invisible (if enabled in options) + if (getBool(FACEBOOK_KEY_PAGES_ALWAYS_ONLINE, DEFAULT_PAGES_ALWAYS_ONLINE) && fbu.type == CONTACT_PAGE) { + setWord(hContact, "Status", ID_STATUS_INVISIBLE); + } + + CheckAvatarChange(hContact, fbu.image_url); + + // Load additional info from profile page (e.g., birthday) + http::response resp = facy.sendRequest(new ProfileInfoRequest(facy.mbasicWorks, fbu.user_id.c_str())); + + if (resp.code == HTTP_CODE_OK) { + std::string birthday = utils::text::source_get_value(&resp.data, 4, ">Birthday</", "<td", ">", "</td>"); + birthday = utils::text::remove_html(birthday); + + std::string::size_type pos = birthday.find(" "); + std::string::size_type pos2 = birthday.find(","); + if (pos != std::string::npos) { + std::string month = birthday.substr(0, pos); + std::string day = birthday.substr(pos + 1, pos2 != std::string::npos ? pos2 - pos - 1 : std::string::npos); + + setByte(hContact, "BirthDay", atoi(day.c_str())); + + const static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + for (int i = 0; i < 12; i++) { + if (!mir_strcmp(months[i], month.c_str())) { + setByte(hContact, "BirthMonth", i + 1); + break; + } + } + + if (pos2 != std::string::npos) { + std::string year = birthday.substr(pos2 + 2, 4); + setWord(hContact, "BirthYear", atoi(year.c_str())); + } + else { + // We have to set ANY year, otherwise UserInfoEx shows completely wrong date + setWord(hContact, "BirthYear", 1800); + } + } + } + + ProtoBroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)0, 0); +} + HANDLE FacebookProto::GetAwayMsg(MCONTACT) { diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp index d92f8c8e5f..62adf63216 100644 --- a/protocols/FacebookRM/src/proto.cpp +++ b/protocols/FacebookRM/src/proto.cpp @@ -344,82 +344,8 @@ int FacebookProto::AuthDeny(MEVENT hDbEvent, const wchar_t *) int FacebookProto::GetInfo(MCONTACT hContact, int) { - ptrA user_id(getStringA(hContact, FACEBOOK_KEY_ID)); - if (user_id == NULL) - return 1; - - facebook_user fbu; - fbu.user_id = user_id; - - LoadContactInfo(&fbu); - - // TODO: don't duplicate code this way, refactor all this userInfo loading - // TODO: load more info about user (authorization state,...) - - std::string homepage = FACEBOOK_URL_PROFILE + fbu.user_id; - setString(hContact, "Homepage", homepage.c_str()); - - if (!fbu.real_name.empty()) { - SaveName(hContact, &fbu); - } - - if (fbu.gender) { - setByte(hContact, "Gender", fbu.gender); - } - - int oldType = getByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, CONTACT_NONE); - // From server we won't get request/approve types, only none, so we don't want to overwrite and lost it in that case - if (fbu.type != CONTACT_NONE || (oldType != CONTACT_REQUEST && oldType != CONTACT_APPROVE)) { - if (oldType != fbu.type) { - setByte(hContact, FACEBOOK_KEY_CONTACT_TYPE, fbu.type); - } - } - - // If this contact is page, set it as invisible (if enabled in options) - if (getBool(FACEBOOK_KEY_PAGES_ALWAYS_ONLINE, DEFAULT_PAGES_ALWAYS_ONLINE) && fbu.type == CONTACT_PAGE) { - setWord(hContact, "Status", ID_STATUS_INVISIBLE); - } - - CheckAvatarChange(hContact, fbu.image_url); - - // Load additional info from profile page (e.g., birthday) - if (isOffline()) - return 1; - - http::response resp = facy.sendRequest(new ProfileInfoRequest(facy.mbasicWorks, fbu.user_id.c_str())); - - if (resp.code == HTTP_CODE_OK) { - std::string birthday = utils::text::source_get_value(&resp.data, 4, ">Birthday</", "<td", ">", "</td>"); - birthday = utils::text::remove_html(birthday); - - std::string::size_type pos = birthday.find(" "); - std::string::size_type pos2 = birthday.find(","); - if (pos != std::string::npos) { - std::string month = birthday.substr(0, pos); - std::string day = birthday.substr(pos + 1, pos2 != std::string::npos ? pos2 - pos - 1 : std::string::npos); - - setByte(hContact, "BirthDay", atoi(day.c_str())); - - const static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - for (int i = 0; i < 12; i++) { - if (!mir_strcmp(months[i], month.c_str())) { - setByte(hContact, "BirthMonth", i + 1); - break; - } - } - - if (pos2 != std::string::npos) { - std::string year = birthday.substr(pos2 + 2, 4); - setWord(hContact, "BirthYear", atoi(year.c_str())); - } - else { - // We have to set ANY year, otherwise UserInfoEx shows completely wrong date - setWord(hContact, "BirthYear", 1800); - } - } - } - - return 1; + ForkThread(&FacebookProto::RefreshUserInfo, (void*)new MCONTACT(hContact)); + return 0; } ////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h index bcceed5864..2d46f0f7d6 100644 --- a/protocols/FacebookRM/src/proto.h +++ b/protocols/FacebookRM/src/proto.h @@ -195,6 +195,7 @@ public: void __cdecl CancelFriendsRequest(void*); void __cdecl SendPokeWorker(void*); void __cdecl IgnoreFriendshipRequest(void*); + void __cdecl RefreshUserInfo(void*); // Contacts handling bool IsMyContact(MCONTACT, bool include_chat = false); |