summaryrefslogtreecommitdiff
path: root/protocols/FacebookRM
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2012-05-25 18:11:53 +0000
committerRobert Pösel <robyer@seznam.cz>2012-05-25 18:11:53 +0000
commit1aa7fb19562f9462311e55dc0b9a7fac18c31180 (patch)
treeabe836fdcac52cf7291cec5a682ce414ebab176d /protocols/FacebookRM
parente45307525555ee23035c0d87fbac3ed8ce5a31e8 (diff)
Updated Facebook RM
git-svn-id: http://svn.miranda-ng.org/main/trunk@176 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/FacebookRM')
-rw-r--r--protocols/FacebookRM/communication.cpp82
-rw-r--r--protocols/FacebookRM/connection.cpp5
-rw-r--r--protocols/FacebookRM/constants.h6
-rw-r--r--protocols/FacebookRM/contacts.cpp120
-rw-r--r--protocols/FacebookRM/db.h56
-rw-r--r--protocols/FacebookRM/facebook.rc5
-rw-r--r--protocols/FacebookRM/facebook_10.vcxproj5
-rw-r--r--protocols/FacebookRM/facebook_10.vcxproj.filters7
-rw-r--r--protocols/FacebookRM/icons/addFriend.icobin2550 -> 0 bytes
-rw-r--r--protocols/FacebookRM/icons/removeFriend.icobin2550 -> 0 bytes
-rw-r--r--protocols/FacebookRM/json.cpp2
-rw-r--r--protocols/FacebookRM/messages.cpp5
-rw-r--r--protocols/FacebookRM/process.cpp104
-rw-r--r--protocols/FacebookRM/proto.cpp179
-rw-r--r--protocols/FacebookRM/proto.h9
-rw-r--r--protocols/FacebookRM/resource.h7
-rw-r--r--protocols/FacebookRM/stubs.cpp10
-rw-r--r--protocols/FacebookRM/theme.cpp177
-rw-r--r--protocols/FacebookRM/theme.h10
19 files changed, 391 insertions, 398 deletions
diff --git a/protocols/FacebookRM/communication.cpp b/protocols/FacebookRM/communication.cpp
index 5b2cb60ace..2e4dfc81f0 100644
--- a/protocols/FacebookRM/communication.cpp
+++ b/protocols/FacebookRM/communication.cpp
@@ -653,11 +653,9 @@ bool facebook_client::login(const std::string &username,const std::string &passw
flap( FACEBOOK_REQUEST_HOME, NULL );
// Prepare login data
- std::string data = "charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&locale=en&email=";
- data += utils::url::encode( username );
- data += "&pass=";
- data += utils::url::encode( password );
- data += "&pass_placeHolder=Password&login=Login&persistent=1";
+ std::string data = "charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&locale=en&pass_placeHolder=Password&login=Login&persistent=1";
+ data += "&email=" + utils::url::encode( username );
+ data += "&pass=" + utils::url::encode( password );
// Send validation
http::response resp = flap( FACEBOOK_REQUEST_LOGIN, &data );
@@ -681,14 +679,9 @@ bool facebook_client::login(const std::string &username,const std::string &passw
resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE );
std::string inner_data = "machine_name=MirandaIM&submit[Save%20Device]=Save%20Device";
- inner_data += "&post_form_id=";
- inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" );
-
- inner_data += "&lsd=";
- inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"lsd\"", "value=\"", "\"" );
-
- inner_data += "&nh=";
- inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\"" );
+ inner_data += "&post_form_id=" + utils::text::source_get_value(&resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" );
+ inner_data += "&lsd=" + utils::text::source_get_value(&resp.data, 3, "name=\"lsd\"", "value=\"", "\"" );
+ inner_data += "&nh=" + utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\"" );
resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE, &inner_data );
validate_response(&resp);
@@ -778,12 +771,9 @@ bool facebook_client::logout( )
handle_entry( "logout" );
- std::string data = "post_form_id=";
- data += ( this->post_form_id_.length( ) ) ? this->post_form_id_ : "0";
- data += "&fb_dtsg=";
- data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0";
- data += "&ref=mb&h=";
- data += this->logout_hash_;
+ std::string data = "post_form_id=" + (this->post_form_id_.length() ? this->post_form_id_ : "0");
+ data += "&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0");
+ data += "&ref=mb&h=" + this->logout_hash_;
http::response resp = flap( FACEBOOK_REQUEST_LOGOUT, &data );
@@ -918,13 +908,9 @@ bool facebook_client::chat_state( bool online )
std::string data = "visibility=";
data += ( online ) ? "1" : "0";
- data += "&window_id=0";
- data += "&post_form_id=";
- data += ( post_form_id_.length( ) ) ? post_form_id_ : "0";
- data += "&post_form_id_source=AsyncRequest";
- data += "&fb_dtsg=" + this->dtsg_;
- data += "&lsd=&phstamp=0&__user=";
- data += self_.user_id;
+ data += "&window_id=0&post_form_id=" + (post_form_id_.length() ? post_form_id_ : "0");
+ data += "&post_form_id_source=AsyncRequest&fb_dtsg=" + this->dtsg_;
+ data += "&lsd=&phstamp=0&__user=" + self_.user_id;
http::response resp = flap( FACEBOOK_REQUEST_VISIBILITY, &data );
return handle_success( "chat_state" );
@@ -1262,16 +1248,10 @@ void facebook_client::close_chat( std::string message_recipient )
can't close it so soon. But maybe this didnt help also. */
Sleep(300);
- std::string data = "close_chat=";
- data += message_recipient;
- data += "&window_id=0";
- data += "&post_form_id=";
- data += ( post_form_id_.length( ) ) ? post_form_id_ : "0";
- data += "&post_form_id_source=AsyncRequest";
- data += "&fb_dtsg=";
- data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0";
- data += "&__user=";
- data += self_.user_id;
+ std::string data = "close_chat=" + message_recipient;
+ data += "&window_id=0&post_form_id=" + (post_form_id_.length() ? post_form_id_ : "0");
+ data += "&post_form_id_source=AsyncRequest&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0");
+ data += "&__user=" + self_.user_id;
http::response resp = flap( FACEBOOK_REQUEST_TABS, &data );
}
@@ -1280,14 +1260,11 @@ void facebook_client::chat_mark_read( std::string message_recipient )
{
// TODO RM: optimalization?
- std::string data = "action=chatMarkRead&other_user=";
- data += message_recipient;
- data += "&post_form_id=";
- data += ( post_form_id_.length( ) ) ? post_form_id_ : "0";
- data += "&fb_dtsg=";
- data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0";
- data += "&post_form_id_source=AsyncRequest&lsd=&__user=";
- data += self_.user_id;
+ std::string data = "action=chatMarkRead";
+ data += "&other_user=" + message_recipient;
+ data += "&post_form_id=" + (post_form_id_.length() ? post_form_id_ : "0");
+ data += "&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0");
+ data += "&post_form_id_source=AsyncRequest&lsd=&__user=" + self_.user_id;
http::response resp = flap( FACEBOOK_REQUEST_ASYNC, &data );
}
@@ -1296,19 +1273,16 @@ bool facebook_client::set_status(const std::string &status_text)
{
handle_entry( "set_status" );
- std::string data = "post_form_id_source=AsyncRequest&post_form_id=";
- data += ( this->post_form_id_.length( ) ) ? this->post_form_id_ : "0";
- data += "&fb_dtsg=";
- data += ( this->dtsg_.length( ) ) ? this->dtsg_ : "0";
- data += "&target_id=";
- data += this->self_.user_id;
+ std::string data = "post_form_id_source=AsyncRequest";
+ data += "&post_form_id=" + (this->post_form_id_.length() ? this->post_form_id_ : "0");
+ data += "&fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0");
+ data += "&target_id=" + this->self_.user_id;
if ( status_text.length( ) )
{
- data += "&action=PROFILE_UPDATE&app_id=&hey_kid_im_a_composer=true&display_context=profile&_log_display_context=profile&ajax_log=1&status=";
- data += utils::url::encode( status_text );
- data += "&profile_id=";
- data += this->self_.user_id;
+ data += "&action=PROFILE_UPDATE&app_id=&hey_kid_im_a_composer=true&display_context=profile&_log_display_context=profile&ajax_log=1";
+ data += "&status=" + utils::url::encode( status_text );
+ data += "&profile_id=" + this->self_.user_id;
}
http::response resp = flap( FACEBOOK_REQUEST_STATUS_SET, &data );
diff --git a/protocols/FacebookRM/connection.cpp b/protocols/FacebookRM/connection.cpp
index 14b5c181c1..5d955d917f 100644
--- a/protocols/FacebookRM/connection.cpp
+++ b/protocols/FacebookRM/connection.cpp
@@ -191,7 +191,7 @@ void FacebookProto::UpdateLoop(void *)
time_t tim = ::time(NULL);
LOG( ">>>>> Entering Facebook::UpdateLoop[%d]", tim );
- for ( int i = -1; !isOffline(); i = ++i % 100 )
+ for ( int i = -1; !isOffline(); i = ++i % 50 )
{
if ( i != -1 ) {
if ( !facy.invisible_ )
@@ -202,7 +202,7 @@ void FacebookProto::UpdateLoop(void *)
if ( !facy.feeds( ) )
break;
- if ( i == 99 )
+ if ( i == 49 )
ForkThread( &FacebookProto::ProcessFriendRequests, this, NULL );
LOG( "***** FacebookProto::UpdateLoop[%d] going to sleep...", tim );
@@ -217,7 +217,6 @@ void FacebookProto::UpdateLoop(void *)
void FacebookProto::MessageLoop(void *)
{
- //ScopedLock s(message_loop_lock_); // TODO: Required?
time_t tim = ::time(NULL);
LOG( ">>>>> Entering Facebook::MessageLoop[%d]", tim );
diff --git a/protocols/FacebookRM/constants.h b/protocols/FacebookRM/constants.h
index 93ae6022ee..e647cabf62 100644
--- a/protocols/FacebookRM/constants.h
+++ b/protocols/FacebookRM/constants.h
@@ -111,6 +111,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define FACEBOOK_RECV_MESSAGE 1
#define FACEBOOK_SEND_MESSAGE 2
+// Contact types
+#define FACEBOOK_CONTACT_FRIEND 1 // contact that IS on our server list
+#define FACEBOOK_CONTACT_NONE 2 // contact that ISN'T on our server list
+#define FACEBOOK_CONTACT_REQUEST 3 // contact that we asked for friendship
+#define FACEBOOK_CONTACT_APPROVE 4 // contact that is asking us for approval of friendship
+
// News Feed types
static const struct
{
diff --git a/protocols/FacebookRM/contacts.cpp b/protocols/FacebookRM/contacts.cpp
index 0f1759e628..23a6ca4455 100644
--- a/protocols/FacebookRM/contacts.cpp
+++ b/protocols/FacebookRM/contacts.cpp
@@ -63,7 +63,7 @@ HANDLE FacebookProto::ContactIDToHContact(std::string user_id)
return 0;
}
-HANDLE FacebookProto::AddToContactList(facebook_user* fbu, bool dont_check, const char *new_name)
+HANDLE FacebookProto::AddToContactList(facebook_user* fbu, BYTE type, bool dont_check, const char *new_name)
{
HANDLE hContact;
@@ -96,11 +96,13 @@ HANDLE FacebookProto::AddToContactList(facebook_user* fbu, bool dont_check, cons
DBFreeVariant(&dbv);
}
- if (strlen(new_name) > 0) {
+ if (strlen(new_name) > 0)
+ {
DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, new_name);
DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NICK, new_name);
- DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 1); // We suppose he is not on server list
- }
+ }
+
+ DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, type);
if (getByte(FACEBOOK_KEY_DISABLE_STATUS_NOTIFY, 0))
CallService(MS_IGNORE_IGNORE, (WPARAM)hContact, (LPARAM)IGNOREEVENT_USERONLINE);
@@ -155,20 +157,23 @@ void FacebookProto::DeleteContactFromServer(void *data)
// Process result data
facy.validate_response(&resp);
- if (resp.data.find("\"success\":true", 0) != std::string::npos) {
-
- // TODO: do only when operation is successful
+ if (resp.data.find("\"payload\":null", 0) != std::string::npos)
+ {
facebook_user* fbu = facy.buddies.find( id );
- if (fbu != NULL) {
- fbu->deleted = true;
- // TODO: change type of contact in database...
- DBWriteContactSettingWord(fbu->handle, m_szModuleName, "Status", ID_STATUS_OFFLINE); // set offline status
-
- // TODO: if not in actual buddies list, search in database...
- DBWriteContactSettingDword(fbu->handle, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL)); // set deleted time
+ if (fbu != NULL)
+ fbu->deleted = true;
+
+ HANDLE hContact = ContactIDToHContact(id);
+
+ // If contact wasn't deleted from database
+ if (hContact != NULL)
+ {
+ DBWriteContactSettingWord(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE);
+ DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_NONE);
+ DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL));
}
- NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact was sucessfully removed from your server list."), NULL, FACEBOOK_EVENT_OTHER, NULL);
+ NotifyEvent(TranslateT("Deleting contact"), TranslateT("Contact was sucessfully removed from your server list."), NULL, FACEBOOK_EVENT_OTHER, NULL);
} else {
facy.client_notify( TranslateT("Error occured when removing contact from server.") );
}
@@ -184,32 +189,34 @@ void FacebookProto::AddContactToServer(void *data)
if ( data == NULL )
return;
- std::string *id = (std::string*)data;
+ std::string id = (*(std::string*)data);
+ delete data;
std::string query = "action=add_friend&how_found=profile_button&ref_param=ts&outgoing_id=&unwanted=&logging_location=&no_flyout_on_click=false&ego_log_data=&post_form_id_source=AsyncRequest&lsd=&fb_dtsg=";
query += facy.dtsg_;
query += "&post_form_id=";
query += facy.post_form_id_;
query += "&to_friend=";
- query += *id;
+ query += id;
query += "&__user=";
query += facy.self_.user_id;
- delete data;
-
// Get unread inbox threads
http::response resp = facy.flap( FACEBOOK_REQUEST_REQUEST_FRIEND, &query );
// Process result data
facy.validate_response(&resp);
- if (resp.data.find("\"success\":true", 0) != std::string::npos) {
- /*facebook_user* fbu = facy.buddies.find( id );
- if (fbu != NULL) {
- // TODO: change type of contact in database...
- // TODO: if not in actual buddies list, search in database...
- }*/
+ if (resp.data.find("\"success\":true", 0) != std::string::npos)
+ {
+ HANDLE hContact = ContactIDToHContact(id);
+ // If contact wasn't deleted from database
+ if (hContact != NULL)
+ {
+ DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_REQUEST);
+ }
+
NotifyEvent(TranslateT("Adding contact"), TranslateT("Request for friendship was sent successfully."), NULL, FACEBOOK_EVENT_OTHER, NULL);
} else {
facy.client_notify( TranslateT("Error occured when requesting friendship.") );
@@ -227,38 +234,27 @@ void FacebookProto::ApproveContactToServer(void *data)
if ( data == NULL )
return;
- std::string *id = (std::string*)data;
-
+ HANDLE hContact = (*(HANDLE*)data);
+ delete data;
+
std::string post_data = "fb_dtsg=" + facy.dtsg_;
post_data += "&charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&confirm_button=";
- std::string get_data;
-
- HANDLE *hContact = (HANDLE*)data;
+ std::string get_data = "id=";
DBVARIANT dbv;
- if (!DBGetContactSettingString(*hContact, m_szModuleName, FACEBOOK_KEY_APPROVE, &dbv))
+ if (!DBGetContactSettingString(hContact, m_szModuleName, FACEBOOK_KEY_ID, &dbv))
{
- get_data = dbv.pszVal;
+ get_data += dbv.pszVal;
DBFreeVariant(&dbv);
- }
-
- // replace absolute link to params only
- utils::text::replace_first(&get_data, "/a/notifications.php?", "&");
+ }
http::response resp = facy.flap( FACEBOOK_REQUEST_APPROVE_FRIEND, &post_data, &get_data );
// Process result data
facy.validate_response(&resp);
- if (resp.code != HTTP_CODE_OK)
- facy.handle_error( "ApproveContactToServer" );
- else {
- NotifyEvent(TranslateT("Adding contact"), TranslateT("Contact was added to your server list."), NULL, FACEBOOK_EVENT_OTHER, NULL);
- DBDeleteContactSetting(*hContact, m_szModuleName, FACEBOOK_KEY_APPROVE);
- }
-
- delete data;
+ DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_FRIEND);
}
HANDLE FacebookProto::GetAwayMsg(HANDLE hContact)
@@ -266,41 +262,9 @@ HANDLE FacebookProto::GetAwayMsg(HANDLE hContact)
return 0; // Status messages are disabled
}
-int FacebookProto::OnContactDeleted(WPARAM wparam,LPARAM)
+int FacebookProto::OnContactDeleted(WPARAM wParam,LPARAM)
{
- HANDLE hContact = (HANDLE)wparam;
-
- DBVARIANT dbv;
- char str[256];
-
- if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) {
- mir_snprintf(str,SIZEOF(str),Translate("Do you want to delete contact '%s' from server list?"), dbv.pszVal);
- DBFreeVariant(&dbv);
- } else if( !DBGetContactSettingUTF8String(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) {
- mir_snprintf(str,SIZEOF(str),Translate("Do you want to delete contact '%s' from server list?"), dbv.pszVal);
- DBFreeVariant(&dbv);
- }
-
- TCHAR *text = mir_a2t_cp(str, CP_UTF8);
- if (MessageBox( 0, text, m_tszUserName, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) == IDYES) {
-
- if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) )
- {
- if (!isOffline()) { // TODO: is this needed?
- std::string* id = new std::string(dbv.pszVal);
-
- facebook_user* fbu = facy.buddies.find( (*id) );
- if (fbu != NULL) {
- fbu->handle = NULL;
- }
-
- ForkThread( &FacebookProto::DeleteContactFromServer, this, ( void* )id );
- DBFreeVariant(&dbv);
- }
- }
-
- }
- mir_free(text);
+ CancelFriendship(wParam, 1);
return 0;
}
diff --git a/protocols/FacebookRM/db.h b/protocols/FacebookRM/db.h
index cadddef8ca..c397522f3c 100644
--- a/protocols/FacebookRM/db.h
+++ b/protocols/FacebookRM/db.h
@@ -38,37 +38,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define deleteSetting( setting ) DBDeleteContactSetting( NULL, m_szModuleName, setting )
// DB keys
-#define FACEBOOK_KEY_LOGIN "Email"
-#define FACEBOOK_KEY_ID "ID"
-#define FACEBOOK_KEY_NAME "RealName"
-#define FACEBOOK_KEY_NICK "Nick"
-#define FACEBOOK_KEY_PASS "Password"
-#define FACEBOOK_KEY_UPD_NAMES "UpdateNames"
-#define FACEBOOK_KEY_DEVICE_ID "DeviceID"
-#define FACEBOOK_KEY_AV_URL "AvatarURL"
-#define FACEBOOK_KEY_DELETED "Deleted"
-#define FACEBOOK_KEY_CONTACT_TYPE "ContactType"
-#define FACEBOOK_KEY_APPROVE "ApproveAction"
-
-#define FACEBOOK_KEY_DEF_GROUP "DefaultGroup"
-#define FACEBOOK_KEY_FORCE_HTTPS "ForceHTTPS"
+#define FACEBOOK_KEY_LOGIN "Email"
+#define FACEBOOK_KEY_ID "ID"
+#define FACEBOOK_KEY_NAME "RealName"
+#define FACEBOOK_KEY_NICK "Nick"
+#define FACEBOOK_KEY_PASS "Password"
+#define FACEBOOK_KEY_UPD_NAMES "UpdateNames"
+#define FACEBOOK_KEY_DEVICE_ID "DeviceID"
+#define FACEBOOK_KEY_AV_URL "AvatarURL"
+#define FACEBOOK_KEY_DELETED "Deleted"
+#define FACEBOOK_KEY_CONTACT_TYPE "ContactType"
+#define FACEBOOK_KEY_DEF_GROUP "DefaultGroup"
+#define FACEBOOK_KEY_FORCE_HTTPS "ForceHTTPS"
#define FACEBOOK_KEY_FORCE_HTTPS_CHANNEL "ForceHTTPSChannel"
#define FACEBOOK_KEY_CLOSE_WINDOWS_ENABLE "CloseChatEnable"
-#define FACEBOOK_KEY_SET_MIRANDA_STATUS "SetMirandaStatus"
-#define FACEBOOK_KEY_LOGGING_ENABLE "LoggingEnable"
-#define FACEBOOK_KEY_SYSTRAY_NOTIFY "UseSystrayNotify"
-#define FACEBOOK_KEY_DISABLE_STATUS_NOTIFY "DisableStatusNotify"
-#define FACEBOOK_KEY_PARSE_MESSAGES "ParseUnreadMessages"
-#define FACEBOOK_KEY_BIG_AVATARS "UseBigAvatars"
-#define FACEBOOK_KEY_DISCONNECT_CHAT "DisconnectChatEnable"
-#define FACEBOOK_KEY_MAP_STATUSES "MapStatuses"
-#define FACEBOOK_KEY_LOAD_MOBILE "LoadMobile"
-#define FACEBOOK_KEY_ENABLE_GROUPCHATS "GroupchatsEnable"
-
-#define FACEBOOK_KEY_POLL_RATE "PollRate" // [HIDDEN]
-#define FACEBOOK_KEY_TIMEOUTS_LIMIT "TimeoutsLimit" // [HIDDEN]
-#define FACEBOOK_KEY_DISABLE_LOGOUT "DisableLogout" // [HIDDEN]
-#define FACEBOOK_KEY_VALIDATE_RESPONSE "ValidateResponse" // [HIDDEN] - 0 = standard, 1 = always, 2 = never
+#define FACEBOOK_KEY_SET_MIRANDA_STATUS "SetMirandaStatus"
+#define FACEBOOK_KEY_LOGGING_ENABLE "LoggingEnable"
+#define FACEBOOK_KEY_SYSTRAY_NOTIFY "UseSystrayNotify"
+#define FACEBOOK_KEY_DISABLE_STATUS_NOTIFY "DisableStatusNotify"
+#define FACEBOOK_KEY_PARSE_MESSAGES "ParseUnreadMessages"
+#define FACEBOOK_KEY_BIG_AVATARS "UseBigAvatars"
+#define FACEBOOK_KEY_DISCONNECT_CHAT "DisconnectChatEnable"
+#define FACEBOOK_KEY_MAP_STATUSES "MapStatuses"
+#define FACEBOOK_KEY_LOAD_MOBILE "LoadMobile"
+#define FACEBOOK_KEY_ENABLE_GROUPCHATS "GroupchatsEnable"
+
+#define FACEBOOK_KEY_POLL_RATE "PollRate" // [HIDDEN]
+#define FACEBOOK_KEY_TIMEOUTS_LIMIT "TimeoutsLimit" // [HIDDEN]
+#define FACEBOOK_KEY_DISABLE_LOGOUT "DisableLogout" // [HIDDEN]
+#define FACEBOOK_KEY_VALIDATE_RESPONSE "ValidateResponse" // [HIDDEN] - 0 = standard, 1 = always, 2 = never
#define FACEBOOK_KEY_EVENT_NOTIFICATIONS_ENABLE "EventNotificationsEnable"
#define FACEBOOK_KEY_EVENT_FEEDS_ENABLE "EventFeedsEnable"
diff --git a/protocols/FacebookRM/facebook.rc b/protocols/FacebookRM/facebook.rc
index 7f66333cbc..ae7489daa4 100644
--- a/protocols/FacebookRM/facebook.rc
+++ b/protocols/FacebookRM/facebook.rc
@@ -53,8 +53,9 @@ END
// remains consistent on all systems.
IDI_FACEBOOK ICON "icons/facebook.ico"
IDI_MIND ICON "icons/mind.ico"
-IDI_ADDFRIEND ICON "icons/addFriend.ico"
-IDI_REMOVEFRIEND ICON "icons/removeFriend.ico"
+IDI_AUTH_GRANT ICON "icons/auth_grant.ico"
+IDI_AUTH_ASK ICON "icons/auth_ask.ico"
+IDI_AUTH_REVOKE ICON "icons/auth_revoke.ico"
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/protocols/FacebookRM/facebook_10.vcxproj b/protocols/FacebookRM/facebook_10.vcxproj
index 0fea434eeb..198c8e647b 100644
--- a/protocols/FacebookRM/facebook_10.vcxproj
+++ b/protocols/FacebookRM/facebook_10.vcxproj
@@ -310,8 +310,9 @@
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
- <None Include="icons\addFriend.ico" />
- <None Include="icons\removeFriend.ico" />
+ <None Include="icons\auth_ask.ico" />
+ <None Include="icons\auth_grant.ico" />
+ <None Include="icons\auth_revoke.ico" />
<None Include="JSON_CAJUN\elements.inl" />
<None Include="JSON_CAJUN\reader.inl" />
<None Include="JSON_CAJUN\writer.inl" />
diff --git a/protocols/FacebookRM/facebook_10.vcxproj.filters b/protocols/FacebookRM/facebook_10.vcxproj.filters
index fc92cf1075..5ddb449d60 100644
--- a/protocols/FacebookRM/facebook_10.vcxproj.filters
+++ b/protocols/FacebookRM/facebook_10.vcxproj.filters
@@ -142,10 +142,13 @@
<None Include="icons\mind.ico">
<Filter>Resource Files</Filter>
</None>
- <None Include="icons\addFriend.ico">
+ <None Include="icons\auth_ask.ico">
<Filter>Resource Files</Filter>
</None>
- <None Include="icons\removeFriend.ico">
+ <None Include="icons\auth_grant.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="icons\auth_revoke.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
diff --git a/protocols/FacebookRM/icons/addFriend.ico b/protocols/FacebookRM/icons/addFriend.ico
deleted file mode 100644
index d8879d15bb..0000000000
--- a/protocols/FacebookRM/icons/addFriend.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/FacebookRM/icons/removeFriend.ico b/protocols/FacebookRM/icons/removeFriend.ico
deleted file mode 100644
index 9639a9c728..0000000000
--- a/protocols/FacebookRM/icons/removeFriend.ico
+++ /dev/null
Binary files differ
diff --git a/protocols/FacebookRM/json.cpp b/protocols/FacebookRM/json.cpp
index 2231596882..bb92cb4434 100644
--- a/protocols/FacebookRM/json.cpp
+++ b/protocols/FacebookRM/json.cpp
@@ -503,7 +503,7 @@ int facebook_json_parser::parse_messages( void* data, std::vector< facebook_mess
facebook_user fbu;
fbu.user_id = user_id;
- HANDLE hContact = proto->AddToContactList(&fbu);
+ HANDLE hContact = proto->AddToContactList(&fbu, FACEBOOK_CONTACT_FRIEND);
if ( DBGetContactSettingWord(hContact,proto->m_szModuleName,"Status", 0) == ID_STATUS_OFFLINE )
DBWriteContactSettingWord(hContact,proto->m_szModuleName,"Status",ID_STATUS_ONLINE);
diff --git a/protocols/FacebookRM/messages.cpp b/protocols/FacebookRM/messages.cpp
index d8fd7e6d58..072ae88b4f 100644
--- a/protocols/FacebookRM/messages.cpp
+++ b/protocols/FacebookRM/messages.cpp
@@ -114,8 +114,9 @@ void FacebookProto::SendTypingWorker(void *p)
send_typing *typing = static_cast<send_typing*>(p);
- // Dont send typing notifications to contacts, that are offline
- if ( DBGetContactSettingWord(typing->hContact,m_szModuleName,"Status", 0) == ID_STATUS_OFFLINE )
+ // Dont send typing notifications to contacts, that are offline or not friends
+ if ( DBGetContactSettingWord(typing->hContact,m_szModuleName,"Status", 0) == ID_STATUS_OFFLINE
+ || DBGetContactSettingByte(typing->hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND)
return;
// TODO RM: maybe better send typing optimalization
diff --git a/protocols/FacebookRM/process.cpp b/protocols/FacebookRM/process.cpp
index 4dd98c5678..4c51141cb1 100644
--- a/protocols/FacebookRM/process.cpp
+++ b/protocols/FacebookRM/process.cpp
@@ -52,7 +52,7 @@ void FacebookProto::ProcessBuddyList( void* data )
{
fbu = i->data;
- if (fbu->handle && !fbu->deleted)
+ if (fbu->handle)
DBWriteContactSettingWord(fbu->handle, m_szModuleName, "Status", ID_STATUS_OFFLINE);
std::string to_delete( i->key );
@@ -63,7 +63,7 @@ void FacebookProto::ProcessBuddyList( void* data )
i = i->next;
if (!fbu->handle) { // just been added
- fbu->handle = AddToContactList(fbu);
+ fbu->handle = AddToContactList(fbu, FACEBOOK_CONTACT_FRIEND);
if (!fbu->real_name.empty()) {
DBWriteContactSettingUTF8String(fbu->handle,m_szModuleName,FACEBOOK_KEY_NAME,fbu->real_name.c_str());
@@ -75,8 +75,9 @@ void FacebookProto::ProcessBuddyList( void* data )
DBWriteContactSettingWord(fbu->handle,m_szModuleName,"Status", fbu->status_id );
}
- if (DBGetContactSettingByte(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE, 0)) {
- DBDeleteContactSetting(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE); // Set type "on server-list" contact
+ if (DBGetContactSettingByte(fbu->handle, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND) {
+ DBWriteContactSettingByte(fbu->handle, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_FRIEND);
+ // TODO: remove that popup and use "Contact added you" event?
}
// Wasn't contact removed from "server-list" someday?
@@ -156,15 +157,6 @@ void FacebookProto::ProcessFriendList( void* data )
if ( DBGetContactSettingByte(hContact, m_szModuleName, "Gender", 0) != fbu->gender )
DBWriteContactSettingByte(hContact, m_szModuleName, "Gender", fbu->gender);
- // TODO: Remove in next version
- if( !DBGetContactSettingString(hContact, m_szModuleName, "MirVer", &dbv) ) {
- update_required = strcmp( dbv.pszVal, FACEBOOK_NAME ) != 0;
- DBFreeVariant(&dbv);
- }
- if (update_required) {
- DBWriteContactSettingString(hContact, m_szModuleName, "MirVer", FACEBOOK_NAME);
- }
-
// Update real name
if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) )
{
@@ -177,8 +169,9 @@ void FacebookProto::ProcessFriendList( void* data )
DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NICK, fbu->real_name.c_str());
}
- if (DBGetContactSettingByte(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE, 0)) {
- DBDeleteContactSetting(fbu->handle,m_szModuleName,FACEBOOK_KEY_CONTACT_TYPE); // Has type "on server-list" contact
+ if (DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND) {
+ DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_FRIEND);
+ // TODO: remove that popup and use "Contact added you" event?
}
// Wasn't contact removed from "server-list" someday?
@@ -202,11 +195,13 @@ void FacebookProto::ProcessFriendList( void* data )
} else {
// Contact was removed from "server-list", notify it
- // Wasnt we already been notified about this contact?
- if ( !DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0)
- && !DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) ) { // And is this contact "on-server" contact?
+ // Wasnt we already been notified about this contact? And was this real friend?
+ if (!DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0)
+ && DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) == FACEBOOK_CONTACT_FRIEND)
+ {
DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL));
+ DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_NONE);
std::string contactname = id;
if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) {
@@ -231,7 +226,7 @@ void FacebookProto::ProcessFriendList( void* data )
{
facebook_user *fbu = iter->second;
- HANDLE hContact = AddToContactList(fbu, true); // This contact is surely new
+ HANDLE hContact = AddToContactList(fbu, FACEBOOK_CONTACT_FRIEND, true); // This contact is surely new
DBWriteContactSettingByte(hContact, m_szModuleName, "Gender", fbu->gender );
DBWriteContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, fbu->real_name.c_str());
@@ -313,7 +308,7 @@ void FacebookProto::ProcessUnreadMessages( void* )
facebook_user fbu;
fbu.user_id = user_id;
- HANDLE hContact = AddToContactList(&fbu);
+ HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE);
// TODO: if contact is newly added, get his user info
// TODO: maybe create new "receiveMsg" function and use it for offline and channel messages?
@@ -431,7 +426,7 @@ void FacebookProto::ProcessMessages( void* data )
facebook_user fbu;
fbu.user_id = messages[i]->user_id;
- HANDLE hContact = AddToContactList(&fbu, false, messages[i]->sender_name.c_str());
+ HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE, false, messages[i]->sender_name.c_str());
// TODO: if contact is newly added, get his user info
// TODO: maybe create new "receiveMsg" function and use it for offline and channel messages?
@@ -568,7 +563,8 @@ void FacebookProto::ProcessFriendRequests( void* )
last = true;
}
- std::string get = utils::text::source_get_value(&req, 3, "<form", "action=\"", "\">");
+ std::string get = utils::text::source_get_value(&req, 3, "<form", "action=\"", "\">");
+ std::string time = utils::text::source_get_value2(&get, "seenrequesttime=", "&\"");
facebook_user *fbu = new facebook_user();
fbu->real_name = utils::text::source_get_value(&req, 2, "class=\"actor\">", "</");
@@ -576,37 +572,49 @@ void FacebookProto::ProcessFriendRequests( void* )
if (fbu->user_id.length() && fbu->real_name.length())
{
- HANDLE hContact = AddToContactList(fbu, false, fbu->real_name.c_str());
- DBWriteContactSettingString(hContact, m_szModuleName, FACEBOOK_KEY_APPROVE, get.c_str());
+ HANDLE hContact = AddToContactList(fbu, FACEBOOK_CONTACT_APPROVE, false, fbu->real_name.c_str());
+ DBWriteContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, FACEBOOK_CONTACT_APPROVE);
- LOG(" Friendship request from: %s (%s)", fbu->real_name.c_str(), fbu->user_id.c_str());
+ bool seen = false;
- /* TODO: How to write event for auth requests etc.? */
-/* CCSDATA ccs;
- PROTORECVEVENT pre;
+ DBVARIANT dbv;
+ if (!DBGetContactSettingString(hContact, m_szModuleName, "RequestTime", &dbv)) {
+ seen = !strcmp(dbv.pszVal, time.c_str());
+ DBFreeVariant(&dbv);
+ }
- ccs.szProtoService = PSR_AUTH;
- ccs.hContact = hContact;
- ccs.wParam = 0;
- ccs.lParam = (LPARAM)&pre;
- pre.flags |= PREF_UTF;
- pre.timestamp = ::time(NULL);
- pre.lParam = sizeof(DWORD) + sizeof(HANDLE) + fbu->real_name.length() + 5;
-
- char* pCurBlob = (char*)alloca(pre.lParam);
- pre.szMessage = pCurBlob;
-
- *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID
- *(PHANDLE)pCurBlob = hContact; pCurBlob += sizeof(HANDLE); // Contact Handle
- strcpy(pCurBlob, fbu->real_name.c_str()); pCurBlob += fbu->real_name.length() + 1; // Nickname
- *pCurBlob = '\0'; pCurBlob++; // First Name
- *pCurBlob = '\0'; pCurBlob++; // Last Name
- *pCurBlob = '\0'; pCurBlob++; // E-mail
- *pCurBlob = '\0'; // Reason
-
- CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs); */
+ if (!seen) {
+ // This is new request
+ DBWriteContactSettingString(hContact, m_szModuleName, "RequestTime", time.c_str());
+
+ //blob is: uin( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), first( ASCIIZ ), last( ASCIIZ ), email( ASCIIZ ), reason( ASCIIZ )
+ //blob is: 0( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ )
+ DBEVENTINFO dbei = {0};
+ dbei.cbSize = sizeof( DBEVENTINFO );
+ dbei.szModule = m_szModuleName;
+ dbei.timestamp = ::time( NULL );
+ dbei.flags = 0; //DBEF_UTF;
+ dbei.eventType = EVENTTYPE_AUTHREQUEST;
+ dbei.cbBlob = (DWORD)(sizeof( DWORD )+ sizeof( HANDLE ) + fbu->real_name.length() + 5);
+
+ PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob );
+ *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID
+ *(PHANDLE)pCurBlob = hContact; pCurBlob += sizeof(HANDLE); // Contact Handle
+ strcpy((char*)pCurBlob, fbu->real_name.c_str()); pCurBlob += fbu->real_name.length()+1; // Nickname
+ *pCurBlob = '\0'; pCurBlob++; // First Name
+ *pCurBlob = '\0'; pCurBlob++; // Last Name
+ *pCurBlob = '\0'; pCurBlob++; // E-mail
+ *pCurBlob = '\0'; // Reason
+
+ CallService(MS_DB_EVENT_ADD, (WPARAM)NULL, (LPARAM)&dbei);
+
+ LOG(" (New) Friendship request from: %s (%s) [%s]", fbu->real_name.c_str(), fbu->user_id.c_str(), time.c_str());
+ } else {
+ LOG(" (Old) Friendship request from: %s (%s) [%s]", fbu->real_name.c_str(), fbu->user_id.c_str(), time.c_str());
+ }
} else {
LOG(" !!! Wrong friendship request");
+ LOG(req.c_str());
}
}
diff --git a/protocols/FacebookRM/proto.cpp b/protocols/FacebookRM/proto.cpp
index 14a9dcfedc..fd203dffb2 100644
--- a/protocols/FacebookRM/proto.cpp
+++ b/protocols/FacebookRM/proto.cpp
@@ -96,7 +96,6 @@ FacebookProto::~FacebookProto( )
CloseHandle( avatar_lock_ );
CloseHandle( log_lock_ );
CloseHandle( update_loop_lock_ );
- //CloseHandle( this->message_loop_lock_ );
CloseHandle( facy.buddies_lock_ );
CloseHandle( facy.send_message_lock_ );
CloseHandle( facy.fcb_conn_lock_ );
@@ -114,7 +113,7 @@ DWORD_PTR FacebookProto::GetCaps( int type, HANDLE hContact )
{
case PFLAGNUM_1: // TODO: Other caps available: PF1_BASICSEARCH, PF1_SEARCHBYEMAIL
{
- DWORD_PTR flags = PF1_IM | PF1_CHAT | PF1_SERVERCLIST | PF1_AUTHREQ | PF1_ADDED | PF1_BASICSEARCH | PF1_USERIDISEMAIL | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | PF1_ADDSEARCHRES; // | PF1_VISLIST | PF1_INVISLIST;
+ DWORD_PTR flags = PF1_IM | PF1_CHAT | PF1_SERVERCLIST | PF1_AUTHREQ | /*PF1_ADDED |*/ PF1_BASICSEARCH | PF1_USERIDISEMAIL | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | PF1_ADDSEARCHRES; // | PF1_VISLIST | PF1_INVISLIST;
if ( getByte( FACEBOOK_KEY_SET_MIRANDA_STATUS, 0 ) )
return flags |= PF1_MODEMSG;
@@ -262,7 +261,7 @@ HANDLE FacebookProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
fbu.real_name += " ";
fbu.real_name += surname;
- HANDLE hContact = AddToContactList(&fbu, false, fbu.real_name.c_str());
+ HANDLE hContact = AddToContactList(&fbu, FACEBOOK_CONTACT_NONE, false, fbu.real_name.c_str());
if (hContact) {
if (flags & PALF_TEMPORARY)
{
@@ -285,7 +284,18 @@ HANDLE FacebookProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
int FacebookProto::AuthRequest(HANDLE hContact,const PROTOCHAR *message)
{
- return AddFriend((WPARAM)hContact, NULL);
+ return RequestFriendship((WPARAM)hContact, NULL);
+}
+
+int FacebookProto::Authorize(HANDLE hContact)
+{
+ return ApproveFriendship((WPARAM)hContact, NULL);
+}
+
+int FacebookProto::AuthDeny(HANDLE hContact,const PROTOCHAR *reason)
+{
+ // TODO: hide from facebook requests list
+ return 0;
}
//////////////////////////////////////////////////////////////////////////////
@@ -378,18 +388,6 @@ int FacebookProto::OnPreShutdown(WPARAM wParam,LPARAM lParam)
return 0;
}
-int FacebookProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam)
-{
- HANDLE hContact = reinterpret_cast<HANDLE>(wParam);
- if(IsMyContact(hContact/*, true*/)) {
- bool hide = (DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0)
- || DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) );
- ShowContactMenus(true, hide);
- }
-
- return 0;
-}
-
int FacebookProto::OnOptionsInit(WPARAM wParam,LPARAM lParam)
{
OPTIONSDIALOGPAGE odp = {sizeof(odp)};
@@ -422,55 +420,6 @@ int FacebookProto::OnOptionsInit(WPARAM wParam,LPARAM lParam)
return 0;
}
-int FacebookProto::OnBuildStatusMenu(WPARAM wParam,LPARAM lParam)
-{
- char text[200];
- strcpy(text,m_szModuleName);
- char *tDest = text+strlen(text);
-
- HGENMENU hRoot;
- CLISTMENUITEM mi = {sizeof(mi)};
- mi.pszService = text;
-
- hRoot = MO_GetProtoRootMenu(m_szModuleName);
- if (hRoot == NULL)
- {
- mi.popupPosition = 500085000;
- mi.hParentMenu = HGENMENU_ROOT;
- mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED | ( this->isOnline() ? 0 : CMIF_GRAYED );
- mi.icolibItem = GetIconHandle( "facebook" );
- mi.ptszName = m_tszUserName;
- hRoot = m_hMenuRoot = reinterpret_cast<HGENMENU>( CallService(
- MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast<LPARAM>(&mi)) );
- } else {
- if ( m_hMenuRoot )
- CallService( MS_CLIST_REMOVEMAINMENUITEM, ( WPARAM )m_hMenuRoot, 0 );
- m_hMenuRoot = NULL;
- }
-
- mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP | ( this->isOnline() ? 0 : CMIF_GRAYED );
- mi.position = 201001;
-
- CreateProtoService(m_szModuleName,"/Mind",&FacebookProto::OnMind,this);
- strcpy(tDest,"/Mind");
- mi.hParentMenu = hRoot;
- mi.pszName = LPGEN("Mind...");
- mi.icolibItem = GetIconHandle("mind");
- m_hStatusMind = reinterpret_cast<HGENMENU>( CallService(
- MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast<LPARAM>(&mi)) );
-
- CreateProtoService(m_szModuleName,"/VisitProfile",&FacebookProto::VisitProfile,this);
- strcpy(tDest,"/VisitProfile");
- mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP;
- mi.pszName = LPGEN("Visit Profile");
- mi.icolibItem = GetIconHandle("homepage");
- // TODO RM: remember and properly free in destructor?
- /*m_hStatusMind = */reinterpret_cast<HGENMENU>( CallService(
- MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast<LPARAM>(&mi)) );
-
- return 0;
-}
-
int FacebookProto::OnMind(WPARAM,LPARAM)
{
HWND hDlg = CreateDialogParam( g_hInstance, MAKEINTRESOURCE( IDD_MIND ),
@@ -488,57 +437,75 @@ int FacebookProto::VisitProfile(WPARAM wParam,LPARAM lParam)
{
CallService(MS_UTILS_OPENURL,1,reinterpret_cast<LPARAM>(dbv.pszVal));
DBFreeVariant(&dbv);
+ }
+ else if (DBGetContactSettingByte(hContact,m_szModuleName,"ChatRoom",0))
+ {
+ std::string url = FACEBOOK_URL_GROUP;
+ if (!DBGetContactSettingString(hContact,m_szModuleName,"ChatRoomID",&dbv)) {
+ url += dbv.pszVal;
+ DBFreeVariant(&dbv);
+ }
+ CallService(MS_UTILS_OPENURL,1,reinterpret_cast<LPARAM>(url.c_str()));
} else {
- // self contact, probably
// TODO: why isn't wParam == 0 when is status menu moved to main menu?
CallService(MS_UTILS_OPENURL,1,reinterpret_cast<LPARAM>(FACEBOOK_URL_PROFILE));
- return 0;
}
return 0;
}
-int FacebookProto::RemoveFriend(WPARAM wParam,LPARAM lParam)
+int FacebookProto::CancelFriendship(WPARAM wParam,LPARAM lParam)
{
- if (wParam == NULL)
- { // self contact
- // CallService(MS_UTILS_OPENURL,1,reinterpret_cast<LPARAM>(FACEBOOK_URL_PROFILE));
- return 0;
- }
-
- if (isOffline())
+ if (wParam == NULL || isOffline())
return 0;
- if (MessageBox( 0, TranslateT("Are you sure?"), TranslateT("Delete contact from server list"), MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) != IDYES)
- return 0;
+ bool deleting = (lParam == 1);
HANDLE hContact = reinterpret_cast<HANDLE>(wParam);
- DBVARIANT dbv;
- if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) )
- {
- if (!isOffline()) {
+ // Ignore groupchats and, if deleting, also not-friends
+ if (DBGetContactSettingByte(hContact, m_szModuleName, "ChatRoom", 0)
+ || (deleting && DBGetContactSettingByte(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0) != FACEBOOK_CONTACT_FRIEND))
+ return 0;
+
+ DBVARIANT dbv;
+ char str[256];
+
+ if ( !DBGetContactSettingUTF8String(hContact, m_szModuleName, FACEBOOK_KEY_NAME, &dbv) ) {
+ mir_snprintf(str,SIZEOF(str),Translate("Do you want to cancel your friendship with '%s'?"), dbv.pszVal);
+ DBFreeVariant(&dbv);
+ } else if( !DBGetContactSettingUTF8String(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) ) {
+ mir_snprintf(str,SIZEOF(str),Translate("Do you want to cancel your friendship with '%s'?"), dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+
+ TCHAR *text = mir_a2t_cp(str, CP_UTF8);
+ if (MessageBox( 0, text, m_tszUserName, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2 ) == IDYES) {
+
+ if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) )
+ {
std::string* id = new std::string(dbv.pszVal);
+
+ if (deleting) {
+ facebook_user* fbu = facy.buddies.find( (*id) );
+ if (fbu != NULL) {
+ fbu->handle = NULL;
+ }
+ }
+
ForkThread( &FacebookProto::DeleteContactFromServer, this, ( void* )id );
DBFreeVariant(&dbv);
-
- if ( !DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, 0) )
- DBWriteContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_DELETED, ::time(NULL));
}
+
}
+ mir_free(text);
return 0;
}
-int FacebookProto::AddFriend(WPARAM wParam,LPARAM lParam)
+int FacebookProto::RequestFriendship(WPARAM wParam,LPARAM lParam)
{
- if (wParam == NULL)
- { // self contact
-// CallService(MS_UTILS_OPENURL,1,reinterpret_cast<LPARAM>(FACEBOOK_URL_PROFILE));
- return 0;
- }
-
- if (isOffline())
+ if (wParam == NULL || isOffline())
return 0;
HANDLE hContact = reinterpret_cast<HANDLE>(wParam);
@@ -546,25 +513,17 @@ int FacebookProto::AddFriend(WPARAM wParam,LPARAM lParam)
DBVARIANT dbv;
if( !DBGetContactSettingString(hContact,m_szModuleName,FACEBOOK_KEY_ID,&dbv) )
{
- if (!isOffline()) {
- std::string* id = new std::string(dbv.pszVal);
- ForkThread( &FacebookProto::AddContactToServer, this, ( void* )id );
- DBFreeVariant(&dbv);
- }
+ std::string* id = new std::string(dbv.pszVal);
+ ForkThread( &FacebookProto::AddContactToServer, this, ( void* )id );
+ DBFreeVariant(&dbv);
}
return 0;
}
-int FacebookProto::ApproveFriend(WPARAM wParam,LPARAM lParam)
+int FacebookProto::ApproveFriendship(WPARAM wParam,LPARAM lParam)
{
- if (wParam == NULL)
- { // self contact
-// CallService(MS_UTILS_OPENURL,1,reinterpret_cast<LPARAM>(FACEBOOK_URL_PROFILE));
- return 0;
- }
-
- if (isOffline())
+ if (wParam == NULL || isOffline())
return 0;
HANDLE *hContact = new HANDLE(reinterpret_cast<HANDLE>(wParam));
@@ -572,13 +531,3 @@ int FacebookProto::ApproveFriend(WPARAM wParam,LPARAM lParam)
return 0;
}
-
-void FacebookProto::ToggleStatusMenuItems( BOOL bEnable )
-{
- CLISTMENUITEM clmi = { 0 };
- clmi.cbSize = sizeof( CLISTMENUITEM );
- clmi.flags = CMIM_FLAGS | (( bEnable ) ? 0 : CMIF_GRAYED);
-
- CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hMenuRoot, ( LPARAM )&clmi );
- CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hStatusMind, ( LPARAM )&clmi );
-}
diff --git a/protocols/FacebookRM/proto.h b/protocols/FacebookRM/proto.h
index bacdc5c109..d4966874ce 100644
--- a/protocols/FacebookRM/proto.h
+++ b/protocols/FacebookRM/proto.h
@@ -116,9 +116,9 @@ public:
int __cdecl GetAvatarInfo(WPARAM, LPARAM );
int __cdecl GetAvatarCaps(WPARAM, LPARAM );
int __cdecl VisitProfile(WPARAM, LPARAM );
- int __cdecl RemoveFriend(WPARAM, LPARAM );
- int __cdecl AddFriend(WPARAM, LPARAM );
- int __cdecl ApproveFriend(WPARAM, LPARAM );
+ int __cdecl CancelFriendship(WPARAM, LPARAM );
+ int __cdecl RequestFriendship(WPARAM, LPARAM );
+ int __cdecl ApproveFriendship(WPARAM, LPARAM );
// Events
int __cdecl OnModulesLoaded(WPARAM, LPARAM);
@@ -166,7 +166,7 @@ public:
// Contacts handling
bool IsMyContact(HANDLE, bool include_chat = false);
HANDLE ContactIDToHContact(std::string);
- HANDLE AddToContactList(facebook_user*, bool dont_check = false, const char *new_name = "");
+ HANDLE AddToContactList(facebook_user*, BYTE type, bool dont_check = false, const char *new_name = "");
void SetAllContactStatuses(int);
// Chats handling
@@ -195,7 +195,6 @@ public:
HANDLE avatar_lock_;
HANDLE log_lock_;
HANDLE update_loop_lock_;
- //HANDLE message_loop_lock_;
HANDLE m_hNetlibUser;
diff --git a/protocols/FacebookRM/resource.h b/protocols/FacebookRM/resource.h
index 14ff2d1e6b..887119bd4b 100644
--- a/protocols/FacebookRM/resource.h
+++ b/protocols/FacebookRM/resource.h
@@ -4,8 +4,9 @@
//
#define IDI_FACEBOOK 101
#define IDI_MIND 102
-#define IDI_ADDFRIEND 103
-#define IDI_REMOVEFRIEND 104
+#define IDI_AUTH_GRANT 103
+#define IDI_AUTH_ASK 104
+#define IDI_AUTH_REVOKE 105
#define IDD_FACEBOOKACCOUNT 111
#define IDD_MIND 112
#define IDD_OPTIONS 113
@@ -61,7 +62,7 @@
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 121
+#define _APS_NEXT_RESOURCE_VALUE 126
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1202
#define _APS_NEXT_SYMED_VALUE 131
diff --git a/protocols/FacebookRM/stubs.cpp b/protocols/FacebookRM/stubs.cpp
index 2bbb2ffb3b..6237a39129 100644
--- a/protocols/FacebookRM/stubs.cpp
+++ b/protocols/FacebookRM/stubs.cpp
@@ -27,16 +27,6 @@ HANDLE FacebookProto::AddToListByEvent(int flags,int iContact,HANDLE hDbEvent)
return 0;
}
-int FacebookProto::Authorize(HANDLE hContact)
-{
- return 0;
-}
-
-int FacebookProto::AuthDeny(HANDLE hContact,const PROTOCHAR *reason)
-{
- return 0;
-}
-
int FacebookProto::AuthRecv(HANDLE hContact,PROTORECVEVENT *)
{
return 0;
diff --git a/protocols/FacebookRM/theme.cpp b/protocols/FacebookRM/theme.cpp
index ddf612e4d6..fd8d0be032 100644
--- a/protocols/FacebookRM/theme.cpp
+++ b/protocols/FacebookRM/theme.cpp
@@ -33,13 +33,15 @@ struct
}
static const icons[] =
{
- { "facebook", LPGEN("Facebook Icon"), IDI_FACEBOOK },
- { "mind", LPGEN("Mind"), IDI_MIND },
- { "removeFriend", LPGEN("Remove from server"), IDI_REMOVEFRIEND },
- { "addFriend", LPGEN("Request friendship"), IDI_ADDFRIEND },
- { "approveFriend", LPGEN("Approve friendship"), 0, "core_main_8" }, // TODO: add better icon
+ { "facebook", LPGEN("Facebook Icon"), IDI_FACEBOOK },
+ { "mind", LPGEN("Mind"), IDI_MIND },
- { "homepage", LPGEN("Visit Profile"), 0, "core_main_2" },
+ { "authRevoke", LPGEN("Cancel friendship"), IDI_AUTH_REVOKE },
+ //{ "authRevokeReq", LPGEN("Cancel friendship request"), IDI_AUTH_REVOKE },
+ { "authAsk", LPGEN("Request friendship"), IDI_AUTH_ASK },
+ { "authGrant", LPGEN("Approve friendship"), IDI_AUTH_GRANT },
+
+ { "homepage", LPGEN("Visit Profile"), 0, "core_main_2" },
};
static HANDLE hIconLibItem[SIZEOF(icons)];
@@ -107,7 +109,9 @@ char *GetIconDescription(const char* name)
}
// Contact List menu stuff
-HANDLE g_hMenuItems[5];
+HANDLE hHookPreBuildMenu;
+HANDLE g_hContactMenuItems[CMITEMS_COUNT];
+HANDLE g_hContactMenuSvc[CMITEMS_COUNT];
// Helper functions
static FacebookProto * GetInstanceByHContact(HANDLE hContact)
@@ -133,13 +137,15 @@ INT_PTR GlobalService(WPARAM wParam,LPARAM lParam)
static int PrebuildContactMenu(WPARAM wParam,LPARAM lParam)
{
- ShowContactMenus(false);
+ for (size_t i=0; i<SIZEOF(g_hContactMenuItems); i++)
+ {
+ EnableMenuItem(g_hContactMenuItems[i], false);
+ }
FacebookProto *proto = GetInstanceByHContact(reinterpret_cast<HANDLE>(wParam));
return proto ? proto->OnPrebuildContactMenu(wParam,lParam) : 0;
}
-HANDLE hHookPreBuildMenu, sVisitProfile, sAddFriend, sRemoveFriend, sApproveFriend;
void InitContactMenus()
{
hHookPreBuildMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU,PrebuildContactMenu);
@@ -151,56 +157,141 @@ void InitContactMenus()
mi.icolibItem = GetIconHandle("homepage");
mi.pszName = GetIconDescription("homepage");
mi.pszService = "FacebookProto/VisitProfile";
- sVisitProfile = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::VisitProfile>);
- g_hMenuItems[1] = reinterpret_cast<HANDLE>(
+ g_hContactMenuSvc[CMI_VISIT_PROFILE] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::VisitProfile>);
+ g_hContactMenuItems[CMI_VISIT_PROFILE] = reinterpret_cast<HANDLE>(
CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) );
- mi.position=-2000006000;
- mi.icolibItem = GetIconHandle("removeFriend");
- mi.pszName = GetIconDescription("removeFriend");
- mi.pszService = "FacebookProto/RemoveFriend";
- sRemoveFriend = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::RemoveFriend>);
- g_hMenuItems[2] = reinterpret_cast<HANDLE>(
+ mi.position=-2000006001;
+ mi.icolibItem = GetIconHandle("authRevoke");
+ mi.pszName = GetIconDescription("authRevoke");
+ mi.pszService = "FacebookProto/CancelFriendship";
+ g_hContactMenuSvc[CMI_AUTH_REVOKE] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::CancelFriendship>);
+ g_hContactMenuItems[CMI_AUTH_REVOKE] = reinterpret_cast<HANDLE>(
CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) );
- mi.position=-2000006000;
- mi.icolibItem = GetIconHandle("addFriend");
- mi.pszName = GetIconDescription("addFriend");
- mi.pszService = "FacebookProto/AddFriend";
- sAddFriend = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::AddFriend>);
- g_hMenuItems[3] = reinterpret_cast<HANDLE>(
+ /* mi.position=-2000006001;
+ mi.icolibItem = GetIconHandle("authRevokeReq");
+ mi.pszName = GetIconDescription("authRevokeReq");
+ mi.pszService = "FacebookProto/CancelFriendshipRequest";
+ g_hContactMenuSvc[CMI_AUTH_REVOKE_REQ] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::CancelFriendshipRequest>);
+ g_hContactMenuItems[CMI_AUTH_REVOKE_REQ] = reinterpret_cast<HANDLE>(
+ CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) ); */
+
+ mi.position=-2000006002;
+ mi.icolibItem = GetIconHandle("authAsk");
+ mi.pszName = GetIconDescription("authAsk");
+ mi.pszService = "FacebookProto/RequestFriendship";
+ g_hContactMenuSvc[CMI_AUTH_ASK] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::RequestFriendship>);
+ g_hContactMenuItems[CMI_AUTH_ASK] = reinterpret_cast<HANDLE>(
CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) );
- mi.position=-2000006000;
- mi.icolibItem = GetIconHandle("approveFriend");
- mi.pszName = GetIconDescription("approveFriend");
- mi.pszService = "FacebookProto/ApproveFriend";
- sApproveFriend = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::ApproveFriend>);
- g_hMenuItems[4] = reinterpret_cast<HANDLE>(
+ mi.position=-2000006003;
+ mi.icolibItem = GetIconHandle("authGrant");
+ mi.pszName = GetIconDescription("authGrant");
+ mi.pszService = "FacebookProto/ApproveFriendship";
+ g_hContactMenuSvc[CMI_AUTH_GRANT] = CreateServiceFunction(mi.pszService,GlobalService<&FacebookProto::ApproveFriendship>);
+ g_hContactMenuItems[CMI_AUTH_GRANT] = reinterpret_cast<HANDLE>(
CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi) );
}
void UninitContactMenus()
{
- for(size_t i=0; i<SIZEOF(g_hMenuItems); i++)
- CallService(MS_CLIST_REMOVECONTACTMENUITEM,(WPARAM)g_hMenuItems[i],0);
+ for(size_t i=0; i<SIZEOF(g_hContactMenuItems); i++)
+ CallService(MS_CLIST_REMOVECONTACTMENUITEM,(WPARAM)g_hContactMenuItems[i],0);
+
+ for(size_t i=0; i<SIZEOF(g_hContactMenuSvc); i++)
+ DestroyServiceFunction(g_hContactMenuSvc[i]);
+
UnhookEvent(hHookPreBuildMenu);
- DestroyServiceFunction(sVisitProfile);
- DestroyServiceFunction(sRemoveFriend);
- DestroyServiceFunction(sAddFriend);
- DestroyServiceFunction(sApproveFriend);
}
-void ShowContactMenus(bool show, bool deleted)
+void EnableMenuItem(HANDLE hMenuItem, bool enable)
{
- for(size_t i=0; i<SIZEOF(g_hMenuItems); i++)
+ CLISTMENUITEM clmi = {0};
+ clmi.cbSize = sizeof(CLISTMENUITEM);
+ clmi.flags = CMIM_FLAGS;
+ if (!enable)
+ clmi.flags |= CMIF_HIDDEN;
+
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&clmi);
+}
+
+int FacebookProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam)
+{
+ HANDLE hContact = reinterpret_cast<HANDLE>(wParam);
+
+ EnableMenuItem(g_hContactMenuItems[CMI_VISIT_PROFILE], true);
+
+ if (!isOffline() && !DBGetContactSettingByte(hContact, m_szModuleName, "ChatRoom", 0))
{
- CLISTMENUITEM item = { sizeof(item) };
- item.flags = CMIM_FLAGS;
- if(!show || (i == 3 && !deleted) || (i == 2 && deleted) || (i == 4 && !deleted)) // 2 = REMOVE CONTACT; 3 = ADD CONTACT; 4 = APPROVE CONTACT
- item.flags |= CMIF_HIDDEN;
+ bool ctrlPressed = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
+
+ BYTE type = DBGetContactSettingDword(hContact, m_szModuleName, FACEBOOK_KEY_CONTACT_TYPE, 0);
+
+ EnableMenuItem(g_hContactMenuItems[CMI_AUTH_ASK], ctrlPressed || type == FACEBOOK_CONTACT_NONE || !type);
+ EnableMenuItem(g_hContactMenuItems[CMI_AUTH_GRANT], ctrlPressed || type == FACEBOOK_CONTACT_APPROVE);
+ EnableMenuItem(g_hContactMenuItems[CMI_AUTH_REVOKE], ctrlPressed || type == FACEBOOK_CONTACT_FRIEND);
+ //EnableMenuItem(g_hContactMenuItems[CMI_AUTH_CANCEL], ctrlPressed || type == FACEBOOK_CONTACT_REQUEST);
+ }
- CallService(MS_CLIST_MODIFYMENUITEM,reinterpret_cast<WPARAM>(g_hMenuItems[i]),
- reinterpret_cast<LPARAM>(&item));
+ return 0;
+}
+
+int FacebookProto::OnBuildStatusMenu(WPARAM wParam,LPARAM lParam)
+{
+ char text[200];
+ strcpy(text,m_szModuleName);
+ char *tDest = text+strlen(text);
+
+ HGENMENU hRoot;
+ CLISTMENUITEM mi = {sizeof(mi)};
+ mi.pszService = text;
+
+ hRoot = MO_GetProtoRootMenu(m_szModuleName);
+ if (hRoot == NULL)
+ {
+ mi.popupPosition = 500085000;
+ mi.hParentMenu = HGENMENU_ROOT;
+ mi.flags = CMIF_ICONFROMICOLIB | CMIF_ROOTPOPUP | CMIF_TCHAR | CMIF_KEEPUNTRANSLATED | ( this->isOnline() ? 0 : CMIF_GRAYED );
+ mi.icolibItem = GetIconHandle( "facebook" );
+ mi.ptszName = m_tszUserName;
+ hRoot = m_hMenuRoot = reinterpret_cast<HGENMENU>( CallService(
+ MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast<LPARAM>(&mi)) );
+ } else {
+ if ( m_hMenuRoot )
+ CallService( MS_CLIST_REMOVEMAINMENUITEM, ( WPARAM )m_hMenuRoot, 0 );
+ m_hMenuRoot = NULL;
}
+
+ mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP | ( this->isOnline() ? 0 : CMIF_GRAYED );
+ mi.position = 201001;
+
+ CreateProtoService(m_szModuleName,"/Mind",&FacebookProto::OnMind,this);
+ strcpy(tDest,"/Mind");
+ mi.hParentMenu = hRoot;
+ mi.pszName = LPGEN("Mind...");
+ mi.icolibItem = GetIconHandle("mind");
+ m_hStatusMind = reinterpret_cast<HGENMENU>( CallService(
+ MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast<LPARAM>(&mi)) );
+
+ CreateProtoService(m_szModuleName,"/VisitProfile",&FacebookProto::VisitProfile,this);
+ strcpy(tDest,"/VisitProfile");
+ mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP;
+ mi.pszName = LPGEN("Visit Profile");
+ mi.icolibItem = GetIconHandle("homepage");
+ // TODO RM: remember and properly free in destructor?
+ /*m_hStatusMind = */reinterpret_cast<HGENMENU>( CallService(
+ MS_CLIST_ADDPROTOMENUITEM,0,reinterpret_cast<LPARAM>(&mi)) );
+
+ return 0;
+}
+
+void FacebookProto::ToggleStatusMenuItems( BOOL bEnable )
+{
+ CLISTMENUITEM clmi = { 0 };
+ clmi.cbSize = sizeof( CLISTMENUITEM );
+ clmi.flags = CMIM_FLAGS | (( bEnable ) ? 0 : CMIF_GRAYED);
+
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hMenuRoot, ( LPARAM )&clmi );
+ CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )m_hStatusMind, ( LPARAM )&clmi );
}
diff --git a/protocols/FacebookRM/theme.h b/protocols/FacebookRM/theme.h
index 4330c35dce..e6bf689676 100644
--- a/protocols/FacebookRM/theme.h
+++ b/protocols/FacebookRM/theme.h
@@ -27,4 +27,12 @@ HANDLE GetIconHandle(const char *name);
void InitContactMenus(void);
void UninitContactMenus(void);
-void ShowContactMenus(bool show, bool deleted = false);
+void EnableMenuItem(HANDLE hMenuItem, bool enable);
+
+/* Contact menu item indexes */
+#define CMI_VISIT_PROFILE 0
+#define CMI_AUTH_REVOKE 1
+#define CMI_AUTH_ASK 2
+#define CMI_AUTH_GRANT 3
+
+#define CMITEMS_COUNT 4 \ No newline at end of file