From 2316553cb5a191e0e8b098bb5b39fba0d9e37b13 Mon Sep 17 00:00:00 2001
From: Catalin Badea <catalin.badea392@gmail.com>
Date: Thu, 2 Aug 2012 18:01:55 +0300
Subject: use local db when joining a muc.


diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index bdc9b20..68be032 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -196,10 +196,10 @@ void MUCController::rejoin() {
 		}
 		//FIXME: check for received activity
 		if (lastActivity_ == boost::posix_time::not_a_date_time) {
-			muc_->joinAs(nick_);
-		} else {
-			muc_->joinWithContextSince(nick_, lastActivity_);
+			lastActivity_ = historyController_->getLastTimeStampFromMUC(selfJID_, toJID_);
 		}
+
+		muc_->joinWithContextSince(nick_, lastActivity_);
 	}
 }
 
@@ -275,6 +275,9 @@ void MUCController::handleJoinComplete(const std::string& nick) {
 	std::string joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick);
 	nick_ = nick;
 	chatWindow_->addSystemMessage(joinMessage);
+
+	addRecentLogs();
+
 	clearPresenceQueue();
 	shouldJoinOnReconnect_ = true;
 	setEnabled(true);
@@ -788,4 +791,15 @@ void MUCController::logMessage(const std::string& message, const JID& fromJID, c
 	}
 }
 
+void MUCController::addRecentLogs() {
+	std::vector<HistoryMessage> messages = historyController_->getMUCContext(selfJID_, toJID_, lastActivity_);
+
+	foreach (const HistoryMessage& message, messages) {
+		bool senderIsSelf = nick_ == message.getFromJID().getResource();
+
+		// the chatWindow uses utc timestamps
+		addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), std::string(avatarManager_->getAvatarPath(message.getFromJID()).string()), message.getTime() - boost::posix_time::hours(message.getOffset()));
+	}
+}
+
 }
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index 0c6cfa4..0ade758 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -106,6 +106,7 @@ namespace Swift {
 			void handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes);
 			void handleInviteToMUCWindowDismissed();
 			void handleInviteToMUCWindowCompleted();
+			void addRecentLogs();
 
 		private:
 			MUC::ref muc_;
diff --git a/Swift/Controllers/HistoryController.cpp b/Swift/Controllers/HistoryController.cpp
index 7461a1e..6ab1235 100644
--- a/Swift/Controllers/HistoryController.cpp
+++ b/Swift/Controllers/HistoryController.cpp
@@ -35,6 +35,11 @@ std::vector<HistoryMessage> HistoryController::getMessagesFromDate(const JID& se
 	return localHistory_->getMessagesFromDate(selfJID, contactJID, type, date);
 }
 
+std::vector<HistoryMessage> HistoryController::getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const {
+	boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp);
+	return getMessagesFromDate(selfJID, mucJID, HistoryMessage::Groupchat, localTime.date());
+}
+
 std::vector<HistoryMessage> HistoryController::getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
 	return localHistory_->getMessagesFromPreviousDate(selfJID, contactJID, type, date);
 }
@@ -47,4 +52,8 @@ ContactsMap HistoryController::getContacts(const JID& selfJID, HistoryMessage::T
 	return localHistory_->getContacts(selfJID, type, keyword);
 }
 
+boost::posix_time::ptime HistoryController::getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) {
+	return localHistory_->getLastTimeStampFromMUC(selfJID, mucJID);
+}
+
 }
diff --git a/Swift/Controllers/HistoryController.h b/Swift/Controllers/HistoryController.h
index 00ad752..f231724 100644
--- a/Swift/Controllers/HistoryController.h
+++ b/Swift/Controllers/HistoryController.h
@@ -27,6 +27,9 @@ namespace Swift {
 			std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
 			std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
 			ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword = std::string()) const;
+			std::vector<HistoryMessage> getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const;
+
+			boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID);
 
 			boost::signal<void (const HistoryMessage&)> onNewMessage;
 
diff --git a/Swiften/History/HistoryManager.h b/Swiften/History/HistoryManager.h
index 104f0ad..33e9143 100644
--- a/Swiften/History/HistoryManager.h
+++ b/Swiften/History/HistoryManager.h
@@ -29,5 +29,6 @@ namespace Swift {
 			virtual std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0;
 			virtual std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const = 0;
 			virtual ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const = 0;
+			virtual boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const = 0;
 	};
 }
diff --git a/Swiften/History/SQLiteHistoryManager.cpp b/Swiften/History/SQLiteHistoryManager.cpp
index 3b90219..e385b1e 100644
--- a/Swiften/History/SQLiteHistoryManager.cpp
+++ b/Swiften/History/SQLiteHistoryManager.cpp
@@ -136,7 +136,10 @@ std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromDate(const JID&
 		int secondsSinceEpoch(sqlite3_column_int(selectStatement, 6));
 		boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch));
 
-		result.push_back(HistoryMessage(message, (fromJID ? *fromJID : JID()), (toJID ? *toJID : JID()), type, time));
+		// offset from utc
+		int offset = sqlite3_column_int(selectStatement, 7);
+
+		result.push_back(HistoryMessage(message, (fromJID ? *fromJID : JID()), (toJID ? *toJID : JID()), type, time, offset));
 		r = sqlite3_step(selectStatement);
 	}
 	if (r != SQLITE_DONE) {
@@ -336,4 +339,36 @@ std::vector<HistoryMessage> SQLiteHistoryManager::getMessagesFromPreviousDate(co
 	return getMessagesFromDate(selfJID, contactJID, type, previousDate);
 }
 
+boost::posix_time::ptime SQLiteHistoryManager::getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const {
+	boost::optional<int> selfID = getIDFromJID(selfJID.toBare());
+	boost::optional<int> mucID = getIDFromJID(mucJID.toBare());
+
+	if (!selfID || !mucID) {
+		// JIDs missing from the database
+		return boost::posix_time::ptime(boost::posix_time::not_a_date_time);
+	}
+
+
+	sqlite3_stmt* selectStatement;
+	std::string selectQuery = "SELECT messages.'time', messages.'offset' from messages WHERE type=1 AND (toBare=" +
+				boost::lexical_cast<std::string>(*selfID) + " AND fromBare=" +
+				boost::lexical_cast<std::string>(*mucID) + ") ORDER BY time DESC LIMIT 1";
+
+	int r = sqlite3_prepare(db_, selectQuery.c_str(), selectQuery.size(), &selectStatement, NULL);
+	if (r != SQLITE_OK) {
+		std::cout << "Error: " << sqlite3_errmsg(db_) << std::endl;
+	}
+
+	r = sqlite3_step(selectStatement);
+	if (r == SQLITE_ROW) {
+		int secondsSinceEpoch(sqlite3_column_int(selectStatement, 0));
+		boost::posix_time::ptime time(boost::gregorian::date(1970, 1, 1), boost::posix_time::seconds(secondsSinceEpoch));
+		int offset = sqlite3_column_int(selectStatement, 1);
+
+		return time - boost::posix_time::hours(offset);
+	}
+
+	return boost::posix_time::ptime(boost::posix_time::not_a_date_time);
+}
+
 }
diff --git a/Swiften/History/SQLiteHistoryManager.h b/Swiften/History/SQLiteHistoryManager.h
index 8b08e6b..b74fbde 100644
--- a/Swiften/History/SQLiteHistoryManager.h
+++ b/Swiften/History/SQLiteHistoryManager.h
@@ -23,6 +23,7 @@ namespace Swift {
 			std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
 			std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
 			std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+			boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) const;
 
 		private:
 			boost::gregorian::date getNextDateWithLogs(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date, bool reverseOrder) const;
-- 
cgit v0.10.2-6-g49f6