From 597d4be9de7903814c01631fbd4180a6f297ce92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robert=20P=C3=B6sel?= <robyer@seznam.cz>
Date: Mon, 1 Dec 2014 13:32:27 +0000
Subject: Facebook: More improvements for chatrooms

git-svn-id: http://svn.miranda-ng.org/main/trunk@11194 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
---
 protocols/FacebookRM/src/chat.cpp          | 96 ++++++++++++++----------------
 protocols/FacebookRM/src/communication.cpp |  9 +--
 protocols/FacebookRM/src/contacts.cpp      |  4 ++
 protocols/FacebookRM/src/process.cpp       | 21 +++----
 protocols/FacebookRM/src/proto.cpp         |  3 +-
 protocols/FacebookRM/src/proto.h           |  1 -
 6 files changed, 68 insertions(+), 66 deletions(-)

(limited to 'protocols')

diff --git a/protocols/FacebookRM/src/chat.cpp b/protocols/FacebookRM/src/chat.cpp
index b9f416a632..2fc753e6be 100644
--- a/protocols/FacebookRM/src/chat.cpp
+++ b/protocols/FacebookRM/src/chat.cpp
@@ -3,7 +3,7 @@
 Facebook plugin for Miranda Instant Messenger
 _____________________________________________
 
-Copyright � 2011-13 Robert P�sel
+Copyright � 2011-13 Robert P�sel
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -168,6 +168,9 @@ int FacebookProto::OnGCEvent(WPARAM wParam,LPARAM lParam)
 
 void FacebookProto::AddChatContact(const TCHAR *tchat_id, const char *id, const char *name)
 {
+	if (IsChatContact(tchat_id, id))
+		return;
+
 	ptrT tnick( mir_a2t_cp(name, CP_UTF8));
 	ptrT tid( mir_a2t(id));
 
@@ -272,43 +275,45 @@ void FacebookProto::AddChat(const TCHAR *tid, const TCHAR *tname)
 
 INT_PTR FacebookProto::OnJoinChat(WPARAM hContact, LPARAM suppress)
 {	
-	// TODO: load info from server + old history,...
+	if (!m_enableChat || IsSpecialChatRoom(hContact))
+		return 0;
 
 	ptrT idT( getTStringA(hContact, "ChatRoomID"));
 	ptrT nameT( getTStringA(hContact, "Nick"));
 
-	if (idT && nameT)
-		AddChat(idT, nameT);
-
-/*	GCSESSION gcw = {sizeof(gcw)};
-
-	// Create the group chat session
-	gcw.dwFlags   = GC_TCHAR;
-	gcw.iType     = GCW_PRIVMESS;
-	gcw.pszModule = m_szModuleName;
-	gcw.ptszName  = m_tszUserName;
-	gcw.ptszID    = m_tszUserName;
-	CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
-
-	if(m_iStatus != ID_STATUS_ONLINE)
+	if (!idT || !nameT)
 		return 0;
 
-	// Create a group
-	GCDEST gcd = { m_szModuleName, m_tszUserName, GC_EVENT_ADDGROUP };
-	GCEVENT gce = { sizeof(gce), &gcd };
-	gce.ptszStatus = TranslateT("Myself");
-	CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
-	gce.ptszStatus = TranslateT("Friend");
-	CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
-	gce.ptszStatus = TranslateT("User");
-	CallServiceSync(MS_GC_EVENT, NULL, reinterpret_cast<LPARAM>(&gce));
+	facebook_chatroom *fbc;
+	std::tstring tthread_id = ptrT(getTStringA(hContact, FACEBOOK_KEY_TID));
+	
+	std::map<std::tstring, facebook_chatroom*>::iterator it = facy.chat_rooms.find(tthread_id);
+	if (it != facy.chat_rooms.end()) {
+		fbc = it->second;
+	} else {
+		// We don't have this chat loaded in memory yet, lets load some info (name, list of users)
+		fbc = new facebook_chatroom(tthread_id);
+		LoadChatInfo(fbc);
+		facy.chat_rooms.insert(std::make_pair(tthread_id, fbc));
+	}
+	
+	// RM TODO: better use check if chatroom exists/is in db/is online... no?
+	// like: if (ChatIDToHContact(tthread_id) == NULL) {
+	ptrA users(GetChatUsers(tthread_id.c_str()));
+	if (users == NULL) {
+		// Add chatroom
+		AddChat(fbc->thread_id.c_str(), fbc->chat_name.c_str());
+
+		// Add chat contacts
+		for (std::map<std::string, std::string>::iterator jt = fbc->participants.begin(); jt != fbc->participants.end(); ++jt) {
+			AddChatContact(fbc->thread_id.c_str(), jt->first.c_str(), jt->second.c_str());
+		}
 
-	SetTopic("Omegle is a great way of meeting new friends!");
+		// Load last messages
+		delSetting(hContact, FACEBOOK_KEY_MESSAGE_ID); // We're creating new chatroom so we want load all recent messages
+		ForkThread(&FacebookProto::LoadLastMessages, new MCONTACT(hContact));
+	}
 
-	// Note: Initialization will finish up in SetChatStatus, called separately
-	if (!suppress)
-		SetChatStatus(m_iStatus);
-*/
 	return 0;
 }
 
@@ -324,30 +329,21 @@ INT_PTR FacebookProto::OnLeaveChat(WPARAM wParam,LPARAM)
 
 	CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,  reinterpret_cast<LPARAM>(&gce));
 	CallServiceSync(MS_GC_EVENT,SESSION_TERMINATE,reinterpret_cast<LPARAM>(&gce));
-	return 0;
-}
-
-/*
-void FacebookProto::SetChatStatus(int status)
-{
-	GCDEST gcd = { m_szModuleName, m_tszUserName, GC_EVENT_CONTROL };
-	GCEVENT gce = { sizeof(gce), &gcd };
-	gce.time = ::time(NULL);
 
-	if(status == ID_STATUS_ONLINE)
-	{
-		// Add self contact
-		AddChatContact(facy.nick_.c_str());
+	if (!wParam) {
+		facy.clear_chatrooms();
+	} else if (!IsSpecialChatRoom(wParam)) {
+		std::tstring tthread_id = ptrT(getTStringA(wParam, FACEBOOK_KEY_TID));
 
-		CallServiceSync(MS_GC_EVENT,SESSION_INITDONE,reinterpret_cast<LPARAM>(&gce));
-		CallServiceSync(MS_GC_EVENT,SESSION_ONLINE,  reinterpret_cast<LPARAM>(&gce));
-	}
-	else
-	{
-		CallServiceSync(MS_GC_EVENT,SESSION_OFFLINE,reinterpret_cast<LPARAM>(&gce));
+		std::map<std::tstring, facebook_chatroom*>::iterator it = facy.chat_rooms.find(tthread_id);
+		if (it != facy.chat_rooms.end()) {
+			delete it->second;
+			facy.chat_rooms.erase(it);
+		}
 	}
+
+	return 0;
 }
-*/
 
 int FacebookProto::OnGCMenuHook(WPARAM, LPARAM lParam)
 {
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp
index 773abb937a..c2eec7c6ee 100644
--- a/protocols/FacebookRM/src/communication.cpp
+++ b/protocols/FacebookRM/src/communication.cpp
@@ -1326,7 +1326,10 @@ int facebook_client::send_message(MCONTACT hContact, const std::string &message_
 		std::string mid = utils::text::source_get_value(&resp.data, 2, "\"message_id\":\"", "\"");
 		if (mid.empty())
 			mid = utils::text::source_get_value(&resp.data, 2, "\"mid\":\"", "\"");
-		parent->setString(hContact, FACEBOOK_KEY_MESSAGE_ID, mid.c_str());
+		
+		// For classic contacts remember last message id
+		if (!parent->isChatRoom(hContact))
+			parent->setString(hContact, FACEBOOK_KEY_MESSAGE_ID, mid.c_str());
 
 		// Remember last action timestamp
 		std::string timestamp = utils::text::source_get_value(&resp.data, 2, "\"timestamp\":", ",");
@@ -1339,9 +1342,7 @@ int facebook_client::send_message(MCONTACT hContact, const std::string &message_
 
 	case 1356003: // Contact is offline
 	{
-		MCONTACT hContact = parent->ContactIDToHContact(message_recipient);
-		if (hContact != NULL)
-  			parent->setWord(hContact, "Status", ID_STATUS_OFFLINE);
+		parent->setWord(hContact, "Status", ID_STATUS_OFFLINE);
 		return SEND_MESSAGE_ERROR;
 	}
 
diff --git a/protocols/FacebookRM/src/contacts.cpp b/protocols/FacebookRM/src/contacts.cpp
index 61acec9b56..44a41b8efe 100644
--- a/protocols/FacebookRM/src/contacts.cpp
+++ b/protocols/FacebookRM/src/contacts.cpp
@@ -328,6 +328,10 @@ void FacebookProto::LoadChatInfo(facebook_chatroom *fbc)
 
 MCONTACT FacebookProto::AddToContactList(facebook_user* fbu, ContactType type, bool force_add, bool add_temporarily)
 {
+	// Ignore self user completely
+	if (fbu->user_id == facy.self_.user_id)
+		return NULL;
+
 	// First, check if this contact exists (and if does, just return it)
 	if (!force_add) {
 		MCONTACT hContact = ContactIDToHContact(fbu->user_id);
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index bfb5904701..1e4f394e2d 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -463,10 +463,7 @@ void FacebookProto::LoadLastMessages(void *p)
 
 	bool isChat = isChatRoom(hContact);
 
-	if (IsSpecialChatRoom(hContact)) // e.g. nofitications
-		return;
-
-	if (isChat && !m_enableChat)
+	if (isChat && (!m_enableChat || IsSpecialChatRoom(hContact))) // disabled chats or special chatroom (e.g. nofitications)
 		return;
 
 	ptrA item_id(getStringA(hContact, isChat ? FACEBOOK_KEY_TID : FACEBOOK_KEY_ID));
@@ -721,9 +718,7 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo
 				setTString(hChatContact, FACEBOOK_KEY_TID, fbc->thread_id.c_str());
 
 				for (std::map<std::string, std::string>::iterator jt = fbc->participants.begin(); jt != fbc->participants.end(); ++jt) {
-					// If this contact isn't already in chat, add it
-					if (!IsChatContact(fbc->thread_id.c_str(), jt->first.c_str())) // TODO: is this needed?
-						AddChatContact(fbc->thread_id.c_str(), jt->first.c_str(), jt->second.c_str());
+					AddChatContact(fbc->thread_id.c_str(), jt->first.c_str(), jt->second.c_str());
 				}
 			}
 
@@ -737,8 +732,8 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo
 				continue;
 			}
 
-			// Save last (this) message ID
-			setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
+			// We don't want to save (this) message ID for chatrooms
+			// setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
 			setString(FACEBOOK_KEY_LAST_ACTION_TIMESTAMP, messages[i]->timestamp.c_str());
 			
 			// Save TID if not exists already
@@ -746,12 +741,18 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo
 			if (!tid || strcmp(tid, messages[i]->thread_id.c_str()))
 				setString(hChatContact, FACEBOOK_KEY_TID, messages[i]->thread_id.c_str());
 
+			// Try to map name of this chat participant to his id
+			std::map<std::string, std::string>::iterator jt = fbc->participants.find(messages[i]->user_id);
+			if (jt != fbc->participants.end()) {
+				messages[i]->sender_name = jt->second;
+			}
+
 			// TODO: support also system messages (rename chat, user quit, etc.)! (here? or it is somewhere else?
 			// ... we must add some new "type" field into facebook_message structure and use it also for Pokes and similar)
 			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);
+			// ForkThread(&FacebookProto::ReadMessageWorker, (void*)hChatContact); // FIXME: temporary disabled
 		} else {
 			// Single-user message
 			debugLogA("      Got message: %s", messages[i]->message_text.c_str());
diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp
index ec8ee11424..15c7a220fb 100644
--- a/protocols/FacebookRM/src/proto.cpp
+++ b/protocols/FacebookRM/src/proto.cpp
@@ -567,7 +567,8 @@ int FacebookProto::OnProcessSrmmEvent(WPARAM, LPARAM lParam)
 			return 0;
 
 		// Load last messages for this contact
-		ForkThread(&FacebookProto::LoadLastMessages, new MCONTACT(event->hContact));
+		if (!isChatRoom(event->hContact))
+			ForkThread(&FacebookProto::LoadLastMessages, new MCONTACT(event->hContact));
 	}
 
 	return 0;
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index e0c95cf8f9..ce78c98f4a 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -217,7 +217,6 @@ public:
 	bool IsChatContact(const TCHAR *chat_id, const char *id);
 	void AddChatContact(const TCHAR *chat_id, const char *id, const char *name);
 	void RemoveChatContact(const TCHAR *chat_id, const char *id, const char *name);
-	void SetChatStatus(const char *chat_id, int status);
 	char *GetChatUsers(const TCHAR *chat_id);
 	void ReceiveMessages(std::vector<facebook_message*> messages, bool local_timestamp, bool check_duplicates = false);
 	void LoadChatInfo(facebook_chatroom* fbc);
-- 
cgit v1.2.3