diff --git a/include/TimelineViewManager.h b/include/TimelineViewManager.h
index 3c539305298e6df2da6f6e10039e124e4c04f81f..20f409517e32f22f1c32fc87c9dc0ba583cfc85b 100644
--- a/include/TimelineViewManager.h
+++ b/include/TimelineViewManager.h
@@ -41,7 +41,10 @@ public:
 
 	static QString chooseRandomColor();
 	static QString getUserColor(const QString &userid);
+	static QString displayName(const QString &userid);
+
 	static QMap<QString, QString> NICK_COLORS;
+	static QMap<QString, QString> DISPLAY_NAMES;
 
 signals:
 	void unreadMessages(QString roomid, int count);
diff --git a/src/ChatPage.cc b/src/ChatPage.cc
index fbaf9ddd4f16e66045f8a9ee7fb18d3de1dade5e..8a9b29b075c65a072c8f17c7e9e48dfcfea955ce 100644
--- a/src/ChatPage.cc
+++ b/src/ChatPage.cc
@@ -23,6 +23,7 @@
 
 #include "ChatPage.h"
 #include "Sync.h"
+#include "TimelineViewManager.h"
 #include "UserInfoWidget.h"
 
 #include "AliasesEventContent.h"
@@ -31,6 +32,7 @@
 #include "CreateEventContent.h"
 #include "HistoryVisibilityEventContent.h"
 #include "JoinRulesEventContent.h"
+#include "MemberEventContent.h"
 #include "NameEventContent.h"
 #include "PowerLevelsEventContent.h"
 #include "TopicEventContent.h"
@@ -320,6 +322,18 @@ void ChatPage::updateRoomState(RoomState &room_state, const QJsonArray &events)
 				room_state.name = name;
 				break;
 			}
+			case events::EventType::RoomMember: {
+				events::StateEvent<events::MemberEventContent> member;
+				member.deserialize(event);
+
+				auto display_name = member.content().displayName();
+
+				if (display_name.isEmpty())
+					display_name = member.stateKey();
+
+				TimelineViewManager::DISPLAY_NAMES.insert(member.stateKey(), display_name);
+				break;
+			}
 			case events::EventType::RoomPowerLevels: {
 				events::StateEvent<events::PowerLevelsEventContent> power_levels;
 				power_levels.deserialize(event);
diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc
index b14dcf92bcf4cdfde3b9c116b8003f1b92bdce48..86d43b1fdf89fdcaf52ced50b1b831737283fd25 100644
--- a/src/MatrixClient.cc
+++ b/src/MatrixClient.cc
@@ -483,15 +483,14 @@ void MatrixClient::sendTextMessage(const QString &roomid, const QString &msg) no
 
 void MatrixClient::initialSync() noexcept
 {
-	QJsonArray excluded_event_types = {
-		QString("m.room.member"),
+	QJsonArray excluded_presence = {
+		QString("m.presence"),
 	};
 
 	QJsonObject filter{{"room",
 			    QJsonObject{{"timeline", QJsonObject{{"limit", 70}}},
-					{"state", QJsonObject{{"not_types", excluded_event_types}}},
 					{"ephemeral", QJsonObject{{"limit", 0}}}}},
-			   {"presence", QJsonObject{{"limit", 0}}}};
+			   {"presence", QJsonObject{{"not_types", excluded_presence}}}};
 
 	QUrlQuery query;
 	query.addQueryItem("full_state", "true");
diff --git a/src/TimelineItem.cc b/src/TimelineItem.cc
index 8d5e503aecb2a41da999b1133cb7f271781061b4..c16293b806cd41ad18b01314b5880e11585b0085 100644
--- a/src/TimelineItem.cc
+++ b/src/TimelineItem.cc
@@ -20,6 +20,7 @@
 
 #include "ImageItem.h"
 #include "TimelineItem.h"
+#include "TimelineViewManager.h"
 
 namespace events = matrix::events;
 namespace msgs = matrix::events::messages;
@@ -28,7 +29,7 @@ TimelineItem::TimelineItem(const QString &userid, const QString &color, const QS
     : QWidget(parent)
 {
 	generateTimestamp(QDateTime::currentDateTime());
-	generateBody(userid, color, body);
+	generateBody(TimelineViewManager::displayName(userid), color, body);
 	setupLayout();
 }
 
@@ -45,7 +46,7 @@ TimelineItem::TimelineItem(ImageItem *image, const events::MessageEvent<msgs::Im
 {
 	auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp());
 	generateTimestamp(timestamp);
-	generateBody(event.sender(), color, "");
+	generateBody(TimelineViewManager::displayName(event.sender()), color, "");
 
 	top_layout_ = new QHBoxLayout();
 	top_layout_->setMargin(0);
@@ -87,7 +88,7 @@ TimelineItem::TimelineItem(const events::MessageEvent<msgs::Notice> &event, bool
 	body = "<i style=\"color: #565E5E\">" + body + "</i>";
 
 	if (with_sender)
-		generateBody(event.sender(), color, body);
+		generateBody(TimelineViewManager::displayName(event.sender()), color, body);
 	else
 		generateBody(body);
 
@@ -103,7 +104,7 @@ TimelineItem::TimelineItem(const events::MessageEvent<msgs::Text> &event, bool w
 	generateTimestamp(timestamp);
 
 	if (with_sender)
-		generateBody(event.sender(), color, body);
+		generateBody(TimelineViewManager::displayName(event.sender()), color, body);
 	else
 		generateBody(body);
 
@@ -131,7 +132,11 @@ void TimelineItem::generateBody(const QString &body)
 
 void TimelineItem::generateBody(const QString &userid, const QString &color, const QString &body)
 {
-	auto sender = userid.split(":")[0].split("@")[1];
+	auto sender = userid;
+
+	// TODO: Fix this by using a UserId type.
+	if (userid.split(":")[0].split("@").size() > 1)
+		sender = userid.split(":")[0].split("@")[1];
 
 	content_label_ = new QLabel(this);
 	content_label_->setWordWrap(true);
diff --git a/src/TimelineViewManager.cc b/src/TimelineViewManager.cc
index bf3dd9971e7ebaf366825b8d664f05860dcbc6cc..84bf20b21578c4670e0ef02d94a4dc4491d4a7fd 100644
--- a/src/TimelineViewManager.cc
+++ b/src/TimelineViewManager.cc
@@ -129,6 +129,7 @@ void TimelineViewManager::setHistoryView(const QString &room_id)
 }
 
 QMap<QString, QString> TimelineViewManager::NICK_COLORS;
+QMap<QString, QString> TimelineViewManager::DISPLAY_NAMES;
 
 QString TimelineViewManager::chooseRandomColor()
 {
@@ -198,3 +199,11 @@ QString TimelineViewManager::getUserColor(const QString &userid)
 
 	return color;
 }
+
+QString TimelineViewManager::displayName(const QString &userid)
+{
+	if (DISPLAY_NAMES.contains(userid))
+		return DISPLAY_NAMES.value(userid);
+
+	return userid;
+}