From 497b2005968483daecd2f4025b0f9e171b0e5272 Mon Sep 17 00:00:00 2001
From: Silbino Goncalves Matado <silbino.gmatado@savoirfairelinux.com>
Date: Mon, 24 Apr 2017 17:12:01 -0400
Subject: [PATCH] Smartlist: Add the conversations list for received messages

Add adapter and service for messages (send, receive and statuses)

Add the smartlist to see the users that sent messages

Add lookup address into NameService to get the user name from the
RingId

Change-Id: I512bfafc7d3e77888a3560a183a085434220337b
---
 Ring/Cartfile                                 |   1 +
 Ring/Cartfile.resolved                        |   3 +-
 Ring/Ring.xcodeproj/project.pbxproj           | 102 +++++++++++++++-
 Ring/Ring/AppDelegate.swift                   |   1 +
 .../ic_contact_picture.imageset/Contents.json |  21 ++++
 .../ic_contact_picture.png                    | Bin 0 -> 4599 bytes
 Ring/Ring/Base.lproj/Main.storyboard          |  31 +++--
 Ring/Ring/Bridging/Ring-Bridging-Header.h     |   1 +
 Ring/Ring/Colors.swift                        |  28 +++++
 Ring/Ring/ContactHelper.swift                 |  59 ++++++++++
 Ring/Ring/ContactModel.swift                  |  34 ++++++
 Ring/Ring/ConversationCell.swift              |  47 ++++++++
 Ring/Ring/ConversationCell.xib                | 111 ++++++++++++++++++
 Ring/Ring/ConversationModel.swift             |  32 +++++
 Ring/Ring/ConversationViewModel.swift         |  99 ++++++++++++++++
 Ring/Ring/ConversationsService.swift          |  76 ++++++++++++
 Ring/Ring/Extensions/Date+Helpers.swift       |  31 +++++
 Ring/Ring/Global.strings                      |  21 ++++
 .../MainTabBar/MainTabBarViewController.swift |   6 +
 Ring/Ring/MessageModel.swift                  |  37 ++++++
 Ring/Ring/MessagesAdapter.h                   |  43 +++++++
 Ring/Ring/MessagesAdapter.mm                  | 102 ++++++++++++++++
 Ring/Ring/MessagesAdapterDelegate.swift       |  28 +++++
 Ring/Ring/NameRegistrationAdapter.h           |   4 +
 Ring/Ring/NameRegistrationAdapter.mm          |   4 +
 Ring/Ring/NameService.swift                   |  16 ++-
 Ring/Ring/Smartlist.strings                   |  22 ++++
 Ring/Ring/SmartlistViewController.swift       |  76 ++++++++++++
 Ring/Ring/SmartlistViewModel.swift            |  66 +++++++++++
 29 files changed, 1086 insertions(+), 16 deletions(-)
 create mode 100644 Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/Contents.json
 create mode 100644 Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/ic_contact_picture.png
 create mode 100644 Ring/Ring/Colors.swift
 create mode 100644 Ring/Ring/ContactHelper.swift
 create mode 100644 Ring/Ring/ContactModel.swift
 create mode 100644 Ring/Ring/ConversationCell.swift
 create mode 100644 Ring/Ring/ConversationCell.xib
 create mode 100644 Ring/Ring/ConversationModel.swift
 create mode 100644 Ring/Ring/ConversationViewModel.swift
 create mode 100644 Ring/Ring/ConversationsService.swift
 create mode 100644 Ring/Ring/Extensions/Date+Helpers.swift
 create mode 100644 Ring/Ring/Global.strings
 create mode 100644 Ring/Ring/MessageModel.swift
 create mode 100644 Ring/Ring/MessagesAdapter.h
 create mode 100644 Ring/Ring/MessagesAdapter.mm
 create mode 100644 Ring/Ring/MessagesAdapterDelegate.swift
 create mode 100644 Ring/Ring/Smartlist.strings
 create mode 100644 Ring/Ring/SmartlistViewController.swift
 create mode 100644 Ring/Ring/SmartlistViewModel.swift

diff --git a/Ring/Cartfile b/Ring/Cartfile
index 79d55a06e..e336d1898 100644
--- a/Ring/Cartfile
+++ b/Ring/Cartfile
@@ -1,2 +1,3 @@
 github "ReactiveX/RxSwift" == 3.0.1
+github "RxSwiftCommunity/RxDataSources" ~> 1.0
 github "pkluz/PKHUD" ~> 4.0
diff --git a/Ring/Cartfile.resolved b/Ring/Cartfile.resolved
index 8c2f05780..306fc01f4 100644
--- a/Ring/Cartfile.resolved
+++ b/Ring/Cartfile.resolved
@@ -1,2 +1,3 @@
-github "pkluz/PKHUD" "4.2.1"
 github "ReactiveX/RxSwift" "3.0.1"
+github "RxSwiftCommunity/RxDataSources" "1.0.3"
+github "pkluz/PKHUD" "4.2.3"
diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index 57383a8de..2777f220a 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -115,6 +115,7 @@
 		564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */; };
 		564C44621E943DE6000F92B1 /* NameService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44611E943DE6000F92B1 /* NameService.swift */; };
 		564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564C44631E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift */; };
+		56559B171EEED50D00BF20E1 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56559B161EEED50D00BF20E1 /* Colors.swift */; };
 		5669A7FA1EA904AF003C7B93 /* SwitchCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5669A7F91EA904AF003C7B93 /* SwitchCell.xib */; };
 		5669A7FC1EA904D2003C7B93 /* TextFieldCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5669A7FB1EA904D2003C7B93 /* TextFieldCell.xib */; };
 		5669A7FE1EA904E4003C7B93 /* TextCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5669A7FD1EA904E4003C7B93 /* TextCell.xib */; };
@@ -126,8 +127,23 @@
 		56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E01E80542300EA1AA9 /* TextFieldCell.swift */; };
 		56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC64E21E805F0200EA1AA9 /* TextCell.swift */; };
 		56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */; };
+		56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */; };
+		56BBC9A21ED714DF00CDAF8B /* MessagesAdapterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */; };
+		56BBC9A31ED714DF00CDAF8B /* ConversationsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */; };
+		56BBC9A61ED7151500CDAF8B /* MessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A51ED7151500CDAF8B /* MessageModel.swift */; };
+		56BBC9A81ED7152300CDAF8B /* SmartlistViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9A71ED7152300CDAF8B /* SmartlistViewController.swift */; };
+		56BBC9AA1ED7153800CDAF8B /* Global.strings in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9A91ED7153800CDAF8B /* Global.strings */; };
+		56BBC9AC1ED7154300CDAF8B /* Smartlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */; };
+		56BBC9B01ED7155700CDAF8B /* ConversationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */; };
+		56BBC9B41ED7156500CDAF8B /* ConversationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */; };
+		56BBC9B51ED7156500CDAF8B /* ConversationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9B31ED7156500CDAF8B /* ConversationCell.xib */; };
+		56BBC9B91ED715FE00CDAF8B /* ContactModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9B71ED715FE00CDAF8B /* ContactModel.swift */; };
+		56BBC9BA1ED715FE00CDAF8B /* ContactHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */; };
+		56BBC9BC1ED7161200CDAF8B /* Date+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */; };
+		56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */; };
 		56BBC9C51ED8BF3300CDAF8B /* libargon2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56BBC9C41ED8BF3300CDAF8B /* libargon2.a */; };
-		56BBC9DA1EDDC0B400CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */; };
+		56BBC9DB1EDDC7F700CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */; };
+		56BBC9DC1EDDC82600CDAF8B /* ConversationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -269,6 +285,7 @@
 		564C445F1E943C37000F92B1 /* NameRegistrationAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NameRegistrationAdapter.mm; sourceTree = "<group>"; };
 		564C44611E943DE6000F92B1 /* NameService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NameService.swift; sourceTree = "<group>"; };
 		564C44631E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NameRegistrationAdapterDelegate.swift; sourceTree = "<group>"; };
+		56559B161EEED50D00BF20E1 /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
 		5669A7F91EA904AF003C7B93 /* SwitchCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SwitchCell.xib; sourceTree = "<group>"; };
 		5669A7FB1EA904D2003C7B93 /* TextFieldCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextFieldCell.xib; sourceTree = "<group>"; };
 		5669A7FD1EA904E4003C7B93 /* TextCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextCell.xib; sourceTree = "<group>"; };
@@ -280,6 +297,22 @@
 		56AC64E01E80542300EA1AA9 /* TextFieldCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = "<group>"; };
 		56AC64E21E805F0200EA1AA9 /* TextCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextCell.swift; sourceTree = "<group>"; };
 		56AC650D1E85694D00EA1AA9 /* RoundedTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedTextField.swift; sourceTree = "<group>"; };
+		56BBC99D1ED714CB00CDAF8B /* MessagesAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagesAdapter.h; sourceTree = "<group>"; };
+		56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MessagesAdapter.mm; sourceTree = "<group>"; };
+		56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesAdapterDelegate.swift; sourceTree = "<group>"; };
+		56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationsService.swift; sourceTree = "<group>"; };
+		56BBC9A51ED7151500CDAF8B /* MessageModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageModel.swift; sourceTree = "<group>"; };
+		56BBC9A71ED7152300CDAF8B /* SmartlistViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartlistViewController.swift; sourceTree = "<group>"; };
+		56BBC9A91ED7153800CDAF8B /* Global.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Global.strings; sourceTree = "<group>"; };
+		56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Smartlist.strings; sourceTree = "<group>"; };
+		56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationModel.swift; sourceTree = "<group>"; };
+		56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationViewModel.swift; sourceTree = "<group>"; };
+		56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConversationCell.swift; sourceTree = "<group>"; };
+		56BBC9B31ED7156500CDAF8B /* ConversationCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConversationCell.xib; sourceTree = "<group>"; };
+		56BBC9B71ED715FE00CDAF8B /* ContactModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactModel.swift; sourceTree = "<group>"; };
+		56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactHelper.swift; sourceTree = "<group>"; };
+		56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Helpers.swift"; path = "Extensions/Date+Helpers.swift"; sourceTree = "<group>"; };
+		56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartlistViewModel.swift; sourceTree = "<group>"; };
 		56BBC9C41ED8BF3300CDAF8B /* libargon2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libargon2.a; path = ../fat/lib/libargon2.a; sourceTree = "<group>"; };
 		56BBC9D81EDDC0B400CDAF8B /* LookupNameResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookupNameResponse.h; sourceTree = "<group>"; };
 		56BBC9D91EDDC0B400CDAF8B /* LookupNameResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LookupNameResponse.m; sourceTree = "<group>"; };
@@ -427,6 +460,8 @@
 		02E1A0261DDE4C2E00D75B59 /* Services */ = {
 			isa = PBXGroup;
 			children = (
+				56BBC9A01ED714DF00CDAF8B /* MessagesAdapterDelegate.swift */,
+				56BBC9A11ED714DF00CDAF8B /* ConversationsService.swift */,
 				02B22E081DF7585F000358C9 /* DaemonService.swift */,
 				02B22DFE1DF755DB000358C9 /* AccountsService.swift */,
 				0273C2FE1E0C438F00CF00BA /* AccountAdapterDelegate.swift */,
@@ -453,6 +488,8 @@
 		02EFCACF1E0C3DD600FD8ED1 /* Bridging */ = {
 			isa = PBXGroup;
 			children = (
+				56BBC99D1ED714CB00CDAF8B /* MessagesAdapter.h */,
+				56BBC99E1ED714CB00CDAF8B /* MessagesAdapter.mm */,
 				04399AA91D1C304300E99CD9 /* Ring-Bridging-Header.h */,
 				557086501E8ADB9D001A7CE4 /* SystemAdapter.h */,
 				557086511E8ADB9D001A7CE4 /* SystemAdapter.mm */,
@@ -497,6 +534,7 @@
 		043866391D2307C000E06CE2 /* Extensions */ = {
 			isa = PBXGroup;
 			children = (
+				56BBC9BB1ED7161200CDAF8B /* Date+Helpers.swift */,
 				043866371D2304A700E06CE2 /* BoolStringExtension.swift */,
 			);
 			name = Extensions;
@@ -529,6 +567,10 @@
 		043999F51D1C2D9D00E99CD9 /* Ring */ = {
 			isa = PBXGroup;
 			children = (
+				56BBC9BD1ED7165800CDAF8B /* Smartlist */,
+				56BBC9B61ED7158600CDAF8B /* Contacts */,
+				56BBC9AD1ED7154800CDAF8B /* Conversations */,
+				56BBC9A41ED7150200CDAF8B /* Messages */,
 				564C44571E8D7F68000F92B1 /* Constants */,
 				56AC64D61E80121200EA1AA9 /* Internationalization */,
 				0273C3021E0C689600CF00BA /* Walkthrough */,
@@ -671,6 +713,7 @@
 			children = (
 				564C44581E8D7F8F000F92B1 /* LocalizedStringTableNames.swift */,
 				564C445A1E8EA44E000F92B1 /* Durations.swift */,
+				56559B161EEED50D00BF20E1 /* Colors.swift */,
 			);
 			name = Constants;
 			sourceTree = "<group>";
@@ -678,6 +721,8 @@
 		56AC64D61E80121200EA1AA9 /* Internationalization */ = {
 			isa = PBXGroup;
 			children = (
+				56BBC9AB1ED7154300CDAF8B /* Smartlist.strings */,
+				56BBC9A91ED7153800CDAF8B /* Global.strings */,
 				56AC64DB1E8012CA00EA1AA9 /* Walkthrough.strings */,
 			);
 			name = Internationalization;
@@ -696,6 +741,43 @@
 			name = Cells;
 			sourceTree = "<group>";
 		};
+		56BBC9A41ED7150200CDAF8B /* Messages */ = {
+			isa = PBXGroup;
+			children = (
+				56BBC9A51ED7151500CDAF8B /* MessageModel.swift */,
+			);
+			name = Messages;
+			sourceTree = "<group>";
+		};
+		56BBC9AD1ED7154800CDAF8B /* Conversations */ = {
+			isa = PBXGroup;
+			children = (
+				56BBC9B21ED7156500CDAF8B /* ConversationCell.swift */,
+				56BBC9B31ED7156500CDAF8B /* ConversationCell.xib */,
+				56BBC9AE1ED7155700CDAF8B /* ConversationModel.swift */,
+				56BBC9AF1ED7155700CDAF8B /* ConversationViewModel.swift */,
+			);
+			name = Conversations;
+			sourceTree = "<group>";
+		};
+		56BBC9B61ED7158600CDAF8B /* Contacts */ = {
+			isa = PBXGroup;
+			children = (
+				56BBC9B71ED715FE00CDAF8B /* ContactModel.swift */,
+				56BBC9B81ED715FE00CDAF8B /* ContactHelper.swift */,
+			);
+			name = Contacts;
+			sourceTree = "<group>";
+		};
+		56BBC9BD1ED7165800CDAF8B /* Smartlist */ = {
+			isa = PBXGroup;
+			children = (
+				56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */,
+				56BBC9A71ED7152300CDAF8B /* SmartlistViewController.swift */,
+			);
+			name = Smartlist;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
@@ -809,9 +891,12 @@
 				02B22E031DF755F7000358C9 /* WalkthroughStoryboard.storyboard in Resources */,
 				5669A7FE1EA904E4003C7B93 /* TextCell.xib in Resources */,
 				04399A061D1C2D9D00E99CD9 /* LaunchScreen.storyboard in Resources */,
+				56BBC9AC1ED7154300CDAF8B /* Smartlist.strings in Resources */,
+				56BBC9AA1ED7153800CDAF8B /* Global.strings in Resources */,
 				04399A031D1C2D9D00E99CD9 /* Assets.xcassets in Resources */,
 				04399A011D1C2D9D00E99CD9 /* Main.storyboard in Resources */,
 				5669A7FA1EA904AF003C7B93 /* SwitchCell.xib in Resources */,
+				56BBC9B51ED7156500CDAF8B /* ConversationCell.xib in Resources */,
 				5669A7FC1EA904D2003C7B93 /* TextFieldCell.xib in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -856,41 +941,54 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				56BBC9DC1EDDC82600CDAF8B /* ConversationViewModel.swift in Sources */,
 				557086521E8ADB9D001A7CE4 /* SystemAdapter.mm in Sources */,
 				5669A8031EAA58E6003C7B93 /* LinkDeviceToAccountViewController.swift in Sources */,
 				0273C3051E0C68B100CF00BA /* CreateProfileViewController.swift in Sources */,
 				02E1A0251DDE4ABA00D75B59 /* BoolStringExtension.swift in Sources */,
 				04399AAC1D1C304300E99CD9 /* AccountAdapter.mm in Sources */,
 				02DD80C81E1EAD70009A3510 /* AccountConfigModel.swift in Sources */,
-				56BBC9DA1EDDC0B400CDAF8B /* LookupNameResponse.m in Sources */,
 				02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */,
 				0273C3061E0C68B100CF00BA /* CreateRingAccountViewController.swift in Sources */,
+				56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */,
 				02C9B63F1E1D4E8C00F82F0C /* ServiceEvent.swift in Sources */,
 				02DD80CD1E1EB2E4009A3510 /* ConfigKeyModel.swift in Sources */,
+				56BBC9A81ED7152300CDAF8B /* SmartlistViewController.swift in Sources */,
 				5516C29F1E71CEFF009D3D2D /* AccountModelHelper.swift in Sources */,
 				56308BA71EA00E5700660275 /* NameRegistrationResponse.m in Sources */,
 				56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */,
 				56AC64E31E805F0200EA1AA9 /* TextCell.swift in Sources */,
 				56AC650E1E85694D00EA1AA9 /* RoundedTextField.swift in Sources */,
+				56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */,
 				02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */,
+				56BBC9DB1EDDC7F700CDAF8B /* LookupNameResponse.m in Sources */,
 				564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */,
 				043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */,
 				02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */,
 				043866331D22CE8C00E06CE2 /* MeViewController.swift in Sources */,
 				56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */,
+				56BBC9B91ED715FE00CDAF8B /* ContactModel.swift in Sources */,
+				56BBC9BA1ED715FE00CDAF8B /* ContactHelper.swift in Sources */,
 				04399AAE1D1C304300E99CD9 /* Utils.mm in Sources */,
+				56BBC9A31ED714DF00CDAF8B /* ConversationsService.swift in Sources */,
+				56BBC9B01ED7155700CDAF8B /* ConversationModel.swift in Sources */,
 				563AEC771EA664C0003A5641 /* RegistrationResponse.m in Sources */,
 				02B22DFD1DF755BB000358C9 /* CreateRingAccountViewModel.swift in Sources */,
 				043999FA1D1C2D9D00E99CD9 /* Ring.xcdatamodeld in Sources */,
 				564C445B1E8EA44E000F92B1 /* Durations.swift in Sources */,
 				0438663B1D2313B700E06CE2 /* AccountDetailsViewController.swift in Sources */,
 				02DD80CA1E1EAF1A009A3510 /* AccountCredentialsModel.swift in Sources */,
+				56559B171EEED50D00BF20E1 /* Colors.swift in Sources */,
 				0273C3081E0C68BF00CF00BA /* RoundedButton.swift in Sources */,
+				56BBC9BC1ED7161200CDAF8B /* Date+Helpers.swift in Sources */,
 				564C44621E943DE6000F92B1 /* NameService.swift in Sources */,
 				043866361D22D06500E06CE2 /* AccountTableViewCell.swift in Sources */,
 				04399AAD1D1C304300E99CD9 /* DRingAdapter.mm in Sources */,
 				0273C2FF1E0C438F00CF00BA /* AccountAdapterDelegate.swift in Sources */,
 				02B22DFF1DF755DB000358C9 /* AccountsService.swift in Sources */,
+				56BBC9A61ED7151500CDAF8B /* MessageModel.swift in Sources */,
+				56BBC9A21ED714DF00CDAF8B /* MessagesAdapterDelegate.swift in Sources */,
+				56BBC9B41ED7156500CDAF8B /* ConversationCell.swift in Sources */,
 				564C44601E943C37000F92B1 /* NameRegistrationAdapter.mm in Sources */,
 				564C44591E8D7F8F000F92B1 /* LocalizedStringTableNames.swift in Sources */,
 				56AC64D51E7C7F4000EA1AA9 /* WelcomeViewController.swift in Sources */,
diff --git a/Ring/Ring/AppDelegate.swift b/Ring/Ring/AppDelegate.swift
index e670d0351..1baaf7479 100644
--- a/Ring/Ring/AppDelegate.swift
+++ b/Ring/Ring/AppDelegate.swift
@@ -29,6 +29,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
     static let daemonService = DaemonService(dRingAdaptor: DRingAdapter())
     static let accountService = AccountsService(withAccountAdapter: AccountAdapter())
     static let nameService = NameService(withNameRegistrationAdapter: NameRegistrationAdapter())
+    static let conversationsService = ConversationsService(withMessageAdapter: MessagesAdapter())
 
     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
         SystemAdapter().registerConfigurationHandler()
diff --git a/Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/Contents.json b/Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/Contents.json
new file mode 100644
index 000000000..f8e96decf
--- /dev/null
+++ b/Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "ic_contact_picture.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/ic_contact_picture.png b/Ring/Ring/Assets.xcassets/ic_contact_picture.imageset/ic_contact_picture.png
new file mode 100644
index 0000000000000000000000000000000000000000..b84a9511860c02c2da725d0e2f94a24675eb81c7
GIT binary patch
literal 4599
zcmeAS@N?(olHy`uVBq!ia0y~yU}ykg4mJh`hQoG=rx_R+Sc;uILpV4%IBGajIv5xP
z*Lk`)hE&XXJGZhV<a+IK`|oFaOl~nMeslHk$Z<+KZYCihaonu5z%N($_YzO(-zu?w
zQP#PS(~9TrSozjs+vLf`RZ*AbUA~o>{77}{#^4QxLfr*tl(r}^J8{gEJ+dfP`RtkB
zU;7gUD_YVjZ#URIKQr;mv%A&%XZ@c2{oU^G-+#v*J=@mtXz?u19al<3CObS;`o$7p
z>F{moba4-+OL|jZu~ae27ubCXN)MD_&U9KX82fGWq8}VyonQY?snpobdgQEo_3=e9
z-4`NS4CFPKjC``z%DU<v(wh=;VRp#DyO;fDU74n;GLLbJY1P7PNw59lS8O{(ZmoHt
zaN@t>Ew){gPe+E{NZveeg$ECF#CH8o!C!Yd_!n=KQoNk!`S(KCBiWL=(-Y?L&oI89
zzkNYt!8XR6mD&#1<(Yp5CoH*JwCD*>SLuseQPae)-qc-YKPQtR^|x5_KamYw%d>j=
zxTaJ!E_HoxnJe&e4u81I#--mFTb4IQmYp_abyeN<XU3&R<#Urb&KWd(dQ~m>Rmb3Z
zo~GDF=|KC0pJ#f@xHn#BFbnr}%+wd$b>)6n4%1&xuk^Q@y&G)VHq?b{N#08r{F!|q
zx0~(x1NW2KD&;nZ-*)d>n|G&*S!4A+?xp{D70-X#HrJPV*EioVk=$*Y0$=kiSaXqk
z?s<hz-!)85-}2RASz711`@QG8`S(*@o3BY6ST-vu=9B$`w1`V_kAk~1`XdbM6aJZR
z-1AK^=8eRgKPzT*UMdd^`)#^e+UPykhhtXahnN53xgxx5Yhm^WA?dDthq-6vxjlU*
zabQ=iXU~;*=ZYIse&yTNvA^sOn)TdxSJGqN1v&9nUiI7$^A5k>w^eiT>E8^ixo-EY
zxe~#ABg9z9e82mQ<cz(|F=_mJf7R9`UW;6;Wpa+;lveS<zlsJoH(0TA9#`bJ<NI=s
znzEMhF@|k#PbxmR$>w9YWS=A3BZG`?O<gP5eAkcmZ2RKpdtTVwc<|izNi|dUP26-!
z@ne|Ce8x4mr@O3rfA(PYK3<Na59(%re?9r}O0_cP3a{%Diu>8ZjwvTh*rB0%^}AL6
zn&P8Tj&Ils{NH*j@E?t-6Ifi)@Fw&8(I|^;jt`!_au0m9KRLHV;IN>}z9XL|l`qnj
z*vpu+O7qy+;~Xmkr^_DkIVXJK*@jIoGE7<*?Pi@~T2=V*^}%!HDmN>>m`7~a*PP`P
z*vDuU&ywaAeynjvZ0?R&-HfQ^cY}CbBOLnv`Ck<2{38|+Rx7@Of05Q>7Mpe5_oeLj
zywfjk+o4uzn>=Z%l&^-K07K(9zgWMpva-2<`=9Y$U#))rtjdDfqETtAOghWA?68?M
zS^4#u-q1{yY*Wss$4qtBu3K49bKPZqy4ZuxMN8f<I3I7i^<RpW_^qxplhU=i{7=4_
zDe9RLl)^Xj<T`ofNfLACKe4M%DEqfiQ`3{X^KI7CxsSfyQ9CMZ`JDgClPj`cFI=)b
zn=x~llF#y^zg0e5ZuFD=!F+2=zLnnISuP*$`F@xCcz*7jCt+D@8n?bmeLGk5^y*n@
z!dEWyuDPCLb#cbAOOKMxtuh}tF3|oV)Oq3OfrX3iY-TIBYY3Y)v21z%$1h=R%dSet
zY@fMg;pbBh>UVE2oLcRyc%#!{+4m1A>(lo|URBpN4fFb>R+Ieb1lQ(U295T7y!U=D
z{~z7Zv1m`3xF7HJPrJ_ldH%%kcR2sa6P_1Cmbp({rfGVnY1-4Nm&Lc&{XXz<so0iO
zmfM=T`!?@4|83szX_mg?p4_e_6#-En?x*+M{&wTT8rFpSEmwX`>(h;2W3{Qpr9ww6
z^4O<Ix)1NYim!=08#hO6>FhU_)miVJOkO<cPTz&l%TI3yZu<Q}rsS@)yJ^!;w=arI
zk0#cd95&yxGmF*hcFL+H8J?bY@8Sa%_((iC>N;Jo{Zf`x>$G(*g0H45m0Pgey#1cT
zHqJ}yT(665T9onpYx`k-rm3&<eZ@t1^TNCH9UU)Z&gGx5Y9-Umsq?p2=G`+3n(XHi
zm3Q{Xoc`NseupNVV=rLcFaPet^YskTuedHWvmf4<&VQ-o_LaNBzA_J`Jsud(-~UQH
zUH?~HW}d8b`uT_w&dN7CLi9CHs@GX$z1W!FFE!2f$l9|j-h2x^^Y_UGrS2`98Ld;q
zOuyLv`1!n=(}wSq=G^n~Py5!)c=1(dTeN%24)rSA&vEk%nx?Dw?5J52EWXS1s6oP|
zrQ!_swl|YfC#+$r<oWTgl>N8Bsbi%g%T-c}cHjDP^l~#-+b!LrELB&(?UL&jpXWFE
zs`0}2QU|w+Sp@BC2)2@sh_+bvN$qV7U&;4(8xyY<isX7;_u+}nW>7lU`Sfzg`DDw;
zqh+TJy4m~Z^gX|5Sk_`%`+rXsLuzlFNc@(V0Q)s^#yRU<jjN|!UU<53*XFfmXH!>P
zt&KgoUaBEWzch&LocM9R@-q%sGQzIOzdx{V`5MKF+VEu?f8Sw}+45p>NJ5d<CEu9=
zi!MID|FiwF?&loQg-^WV<4qYJ#zh}#NzVA?$lAH(o1CE4oU`k5PHc~6_liwtNDY15
zz_j~I%=vERP3LZ|J;-7eYubBu+SxyMXJqEAmF5j!$1p2&bD-cxi?h<jD<%sIPCU1>
z)SbU*;bqJ1TNmgwon}+8IK{vfG)dN2qIY`3iNdwJKDwk9uRhF_(Ok>p@Nh-tw}pAR
zTkcBnDD2p{wRm;<@8!-(QJN;wOT`#6Y?fxXY>O=9TI6`h{{L$w-S2O5V;)7g2PLX0
zc|G3u_oqeXk++w2HMGbxXLzMPE|Z*f;bel5#(nERWsP&6D$950%_~^@<;jlV9W%Oi
zEX!W-{MOpXQg@=9a(9(D-_bk#`IltZCACb2on^0gu*LSP^_;$Vrg*o^zRW34vNTK&
z=1E=`n6l!~?73$Y>n}V!wni;$fg4ZFqE?nKJ0{6lc81j-n5TNbW1<XiNxE$jXWW4)
zM@~!=z7qUqngPR2DGl{AzVWUl)A`Ppoi<>Yn^)g=S1GS!QV#FaJtg{Y8UOCNEA>cK
zp-AgogWzYusjCzNRsA=#JagC}>#*Q(p6<p=Z}=sqUAXBo$&}?d@2*w5YxeO+S#Qg#
zzj2?_;!mKK4f`(Uw`JKK4Jz)({@O=eE;*XI(tG-^5MRrD!&HX2{WoR_NGE4%$k=`k
zyZq9-#rx&+h}(C}&gJnkFM4q?;M~3=|E~XZ*)b`uTW`+d&Fa_lWSNz|WN=J-<1eoL
zzv@-fU%QgPp!ctHC4T6zFIW=IT=-2nyuW^n|B{P&k{3UmdfDx`+tj6H#b+sv<JJl5
z_TLZ;{TDr(bDeGFy-4pje;1w0YIw~1;Njx*xm)83na}-X{{4Y{uIb);@?Ph%J1qX+
zzIw@YZTOS6pYP@zI)8r4mRoBTlUkCcR;cYRb!n(tyYuaayGlw6eyh(noqj`CDM_T=
zRD{#;K-HfUD_1rwW)HWv-u3+ff6C3Z%1I?xS2UI#$deVk_*VYvgV%R+xA#bI-0(5v
z&hCoHF71f*8*`2&iuiqt+w0``xA1v|e*E#)hPczMe(F1~^Sf|+d(ASLBGeMK`>M;4
z)^n22|5Q!AYjkMil7AHk@^}M-dV`8AP1amWGZZXNKg@Z&k~@~;#n#gF==9rbmAzIy
z$g22JCf(|Cw9#0%xbMfG-EXd4oZiabZ&_6!C6{X*)5&{f+pSfqUZ1|1@*Y>LW4an^
zE6RH|x6dP1n$;;kK|98*;ey(c_BSCSqO$uu_wT)sSADCjaav@kyU@9C#-smEM_>3}
z8ueqZZ&6ax*?s5p-d{Qzwz&3HM6vE(zVbgj?RwJs|8J>#ioCzAq!w1<>9;zMhiO|&
z{MFL$?<ziic<FL7p-OkwwtuJAhx5(5xJ~6$%>mJ<-OK7WzufY4vh&?tGMcw)SFk*P
z65Q7&W>g!__BWh2!8cI<!~QajuJ*0IXS=U&FKM~Ub5Nx!NL#vP!MwD@*=$Phzs%PP
z+j2i*oqCvv)lJE*(rM3gW2a6{dz!cG<gYzV3#-M%LZ<Y{1bJp0Za?DqWb3~AxN1)A
z`)}OZ<c~Z4Y_fNc`m}NTCwKF8a<c*-1odo;_H%f0BwE}`YF|wKq6u>QF9+YA^We_E
zPMa;yPVG7R{C#5T*7J>jnwM@;QZ!z=a8tpZnKxhFYqcnrw*LQ)@BX`=Uyr+AzBV^|
z`-}}7=Qr;8QC-X5YS?fp=18rC=-XqL)C_eNzbkln<J_JLZGxQ!FD~)_`eVKPoxRnR
zYwI-2x?egA+?{&9OLG2KTZw<nx~n7k|4bBJ_3P+ktMIrvyUR1(UU4nD_w<h7iF4oH
z&E?LX&GnM^#{5rlCwJ>;N7nv*_(6WniSs_<SLC}MZ2#m|w?u!|I^DA#v7Sj~b`4Pz
zCT<GYpDg7s-t&_s^>c#Zi(jrg4x8UH%VRIt9a(i~(o5SrVRPP}FUSto&ArZ~$MWUY
zo4ve}W~@CmKA9h7AKrWM|Mt==#mi1|9yTv3-gbIUQ=obBb7r36Y~!y#TMzHI$@`%`
z&0O!#lKtD+ZdsMF7tEHNwQj-AUFOq$ZUxSoy6MoBG8vc3>g#=%RvoLH_QW~pP0GtN
zw*$1^=)O3%_|@5~-hr#`@We7Ksqia1H~-Saj*I(0UXq%yOR<_S?ebgs)GX&+I;pOn
z`%nL6whx<nbr1U*qab01m-mz#ce0-Jn{j4icf$$J^YfgoWNjb&W+mA!J!*c3O`}P0
z+cy>o8K-$us|+l*D?AQ+SHrM9D7pDF*W{BvhKEh}w<mmf&t{dGz^tL0#ZY-sz?0#y
z@weBTKf7mlJ#4!=^FW4y(|qGfjl)K-c-H-@d^amr-to8KgSS7@dp<}=O^RAC{<JUL
zBE48keL=#CxH;B+XG9ju#7HUp{psP?bA}-={z~tp^@9E>ew&`J*{`DiH|-Ah2@a7I
z*0ks8lO9=0hPyWPop?Ound=h`;h#FUH%;nqoPS*9)YDgaGwqk&Tzf^g_PjjD^dRNi
z&&A3fTubu5wXkC5Q&qv=?k?tMZ$15Mr}avL>85>tQRuX2%k=#+?33SJ<NAK??0xCr
zL|5J={|#m-U6eeq>X4jEv~ch18~tki_smRHPu|je%90+|Reo{u&&AtZLp?6KDf|dn
zGX3A`qe%<*{8DsTE4`s+*>=ZgB0bD=<{DmZ<S5D5{Yw9m<VBgrhHnN-UGv>;`{iio
zp7y%O@Upy4lA*P3qs9LAgXj7=Szo57J)NsAG~M{&&j>5|N0C`~4L-{^-v9dj+xJgy
z;XH-e&ENl8NIWb&|7&xnav4v-t>_$`Uyf^Xk33J@4C-v1lvj$`edR^j)|cJO*{}F+
z_&xpZi-KcYx9Z8-_K0svQh#f^^p3s#v*m3+=IFkgf4_DAbGrq*-aov)ynnsSo0{Yc
z2~YHw_wWkyXqU3w`F`~B&x9%ccR}6Oou?X@Y}R%ElD#}>N)YEO^Y=C^dRez$-(mUE
z<K52p_`A--cbOl3r4py?zS?zD-66W^(dDhI$*b6{??;I6)FytKar(2q`-Lx4-Ae2v
zUgn2KmCTAee`<Y7y5+@G>xVyQ3p#&txcczBPTI>g%5GP)cg)_}k;0hIR4y6&UH4pH
z`uRC^4_*c?=Dq88T*SUwu#kB_%fCB4zw#a9*!QiQ^2%&iQgF<=sX>fOuf#L>7i@mR
zkjBsS$3ydLhvZy-F_&8%Cz=neZ#Z&lVY>a>1L0GG-p{((p}H_k$%wH+G{Wk_&Sr)W
zoF77$UTKiC{g~u=r8nr6Mu69gX&16xXLEWnR50$i+;xs!x=GhHh4F(_!Reh%{0Ek|
z?E6~1Cg;kh9o9>)_$`q5p~tyLe?emjqdnWR$h$uiig#@7=wX}3D5qZ7?2zoradvu*
zyXNnpZ`Mlp;#|apKAD@C^PIH|Ver>lDl_%tl`@x<ogFy>g0Xpic0v=YU5^OH+Z<O?
zI;!+(RmYFqw|dDO9Ve<dW1q^jFV+ooDQaBL+|Sgxt^Ps!f&7O0KrhR({mSmr4)HE2
zY#-DQgflKrdu+wN$M=QdcBikxlisQb9b?c_R?<t5TzK`^(gQVbPD_a~Xf@^@s6G(3
zG{k9bt;!t6nEs9>%-tN4hvyzJQMkS2nI6;c2Hh5`+V&u=h0l$I?lBxvR65LY)<i7k
zm!+hH>j{H4#+422s|&kiTfWJ^VA6}Jn#&}`!Fu!>Gq0Cr{q(CDKkGaAm3R|37pOBZ
PFfe$!`njxgN@xNAg#+oo

literal 0
HcmV?d00001

diff --git a/Ring/Ring/Base.lproj/Main.storyboard b/Ring/Ring/Base.lproj/Main.storyboard
index cee4ad0e1..e764877f8 100644
--- a/Ring/Ring/Base.lproj/Main.storyboard
+++ b/Ring/Ring/Base.lproj/Main.storyboard
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
     <device id="retina4_0" orientation="portrait">
         <adaptation id="fullscreen"/>
     </device>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -22,7 +22,7 @@
                         <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
-                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PERSON 
PLACEHOLDER" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vcL-Nj-NcH">
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PERSON  PLACEHOLDER" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vcL-Nj-NcH">
                                 <rect key="frame" x="16" y="102" width="180" height="64"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="180" id="CUM-z9-ubY"/>
@@ -50,7 +50,7 @@
                                         <rect key="frame" x="0.0" y="28" width="320" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="i1O-Yc-WGd" id="Bz1-A3-Z3f">
-                                            <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
                                                 <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bm0-lC-K2F">
@@ -96,7 +96,7 @@
                                         <rect key="frame" x="0.0" y="72" width="320" height="44"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Ok2-8L-eMm" id="m64-AI-t2h">
-                                            <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                             <subviews>
                                                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kZv-uf-BsD" userLabel="Account Name Label">
@@ -192,9 +192,11 @@
             <objects>
                 <navigationController id="acv-jH-RCt" sceneMemberID="viewController">
                     <tabBarItem key="tabBarItem" title="Me" id="jo3-1i-bFH"/>
-                    <navigationBar key="navigationBar" contentMode="scaleToFill" id="tAT-cg-hut">
+                    <navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" id="tAT-cg-hut">
                         <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
+                        <color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <color key="barTintColor" red="0.039215686270000001" green="0.4549019608" blue="0.53725490200000003" alpha="1" colorSpace="calibratedRGB"/>
                     </navigationBar>
                     <connections>
                         <segue destination="Adn-sB-m3h" kind="relationship" relationship="rootViewController" id="yoa-Sb-o2W"/>
@@ -204,14 +206,16 @@
             </objects>
             <point key="canvasLocation" x="-954" y="-438"/>
         </scene>
-        <!--Item-->
+        <!--Home-->
         <scene sceneID="RrV-5t-V1t">
             <objects>
                 <navigationController id="m3Y-hs-SzS" sceneMemberID="viewController">
-                    <tabBarItem key="tabBarItem" title="Item" id="vc8-sv-IF0"/>
-                    <navigationBar key="navigationBar" contentMode="scaleToFill" id="G6y-tt-W3p">
+                    <tabBarItem key="tabBarItem" title="Home" id="vc8-sv-IF0"/>
+                    <navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" id="G6y-tt-W3p">
                         <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
+                        <color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <color key="barTintColor" red="0.039215686270000001" green="0.4549019608" blue="0.53725490200000003" alpha="1" colorSpace="calibratedRGB"/>
                     </navigationBar>
                     <connections>
                         <segue destination="NIj-Cd-aWO" kind="relationship" relationship="rootViewController" id="GUx-m9-dbP"/>
@@ -224,7 +228,7 @@
         <!--Home-->
         <scene sceneID="UuZ-iE-GB0">
             <objects>
-                <viewController title="Home" id="NIj-Cd-aWO" sceneMemberID="viewController">
+                <viewController title="Home" id="NIj-Cd-aWO" customClass="SmartlistViewController" customModule="Ring" customModuleProvider="target" sceneMemberID="viewController">
                     <layoutGuides>
                         <viewControllerLayoutGuide type="top" id="s1e-Lp-B2j"/>
                         <viewControllerLayoutGuide type="bottom" id="aoH-Yk-Qrn"/>
@@ -241,8 +245,10 @@
                         </subviews>
                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                     </view>
-                    <tabBarItem key="tabBarItem" title="Home" id="1QA-0Y-BFL"/>
                     <navigationItem key="navigationItem" id="b8m-eG-Q9D"/>
+                    <connections>
+                        <outlet property="tableView" destination="B6Y-MZ-L7L" id="dXp-J4-x68"/>
+                    </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="rzQ-ll-5bo" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
@@ -256,6 +262,7 @@
                         <rect key="frame" x="0.0" y="0.0" width="320" height="49"/>
                         <autoresizingMask key="autoresizingMask"/>
                         <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                        <color key="tintColor" red="0.039215686270000001" green="0.4549019608" blue="0.53725490200000003" alpha="1" colorSpace="calibratedRGB"/>
                     </tabBar>
                     <connections>
                         <segue destination="m3Y-hs-SzS" kind="relationship" relationship="viewControllers" id="tnG-cB-lXh"/>
diff --git a/Ring/Ring/Bridging/Ring-Bridging-Header.h b/Ring/Ring/Bridging/Ring-Bridging-Header.h
index b0aecf060..600ce0985 100644
--- a/Ring/Ring/Bridging/Ring-Bridging-Header.h
+++ b/Ring/Ring/Bridging/Ring-Bridging-Header.h
@@ -29,3 +29,4 @@
 #import "LookupNameResponse.h"
 #import "RegistrationResponse.h"
 #import "NameRegistrationResponse.h"
+#import "MessagesAdapter.h"
diff --git a/Ring/Ring/Colors.swift b/Ring/Ring/Colors.swift
new file mode 100644
index 000000000..94d112f16
--- /dev/null
+++ b/Ring/Ring/Colors.swift
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+
+class Colors {
+    static let ringMainColor = UIColor(colorLiteralRed: 10.0/255.0,
+                                       green: 116.0/255.0,
+                                       blue: 137.0/255.0,
+                                       alpha: 1.0)
+}
diff --git a/Ring/Ring/ContactHelper.swift b/Ring/Ring/ContactHelper.swift
new file mode 100644
index 000000000..67378a955
--- /dev/null
+++ b/Ring/Ring/ContactHelper.swift
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+
+import RxSwift
+
+class ContactHelper {
+
+    fileprivate static var cache = [String : String]()
+
+    static func lookupUserName(forRingId ringId: String, nameService: NameService, disposeBag: DisposeBag) -> Variable<String> {
+
+        let userName = Variable("")
+
+        if ContactHelper.cache[ringId] == nil {
+
+            //Lookup the user name observer
+            nameService.usernameLookupStatus
+                .observeOn(MainScheduler.instance)
+                .filter({ lookupNameResponse in
+                    return lookupNameResponse.address != nil && lookupNameResponse.address == ringId
+                }).subscribe(onNext: { lookupNameResponse in
+                    if lookupNameResponse.state == .found {
+                        self.cache[ringId] = lookupNameResponse.name
+                        userName.value = lookupNameResponse.name
+                    } else {
+                        self.cache[ringId] = lookupNameResponse.address
+                        userName.value = lookupNameResponse.address
+                    }
+                }).addDisposableTo(disposeBag)
+
+            nameService.lookupAddress(withAccount: "", nameserver: "", address: ringId)
+
+        } else {
+             userName.value = self.cache[ringId]!
+        }
+
+        return userName
+    }
+
+}
diff --git a/Ring/Ring/ContactModel.swift b/Ring/Ring/ContactModel.swift
new file mode 100644
index 000000000..f4a8f16e1
--- /dev/null
+++ b/Ring/Ring/ContactModel.swift
@@ -0,0 +1,34 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+
+class ContactModel {
+
+    var ringId: String
+
+    init(withRingId ringId: String) {
+        self.ringId = ringId
+    }
+
+    public static func ==(lhs: ContactModel, rhs: ContactModel) -> Bool {
+        return lhs.ringId == rhs.ringId
+    }
+}
diff --git a/Ring/Ring/ConversationCell.swift b/Ring/Ring/ConversationCell.swift
new file mode 100644
index 000000000..d3fd4fd62
--- /dev/null
+++ b/Ring/Ring/ConversationCell.swift
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+import RxSwift
+
+class ConversationCell: UITableViewCell {
+
+    @IBOutlet weak var profileImage: UIImageView!
+    @IBOutlet weak var nameLabel: UILabel!
+    @IBOutlet weak var newMessagesIndicator: UIView!
+    @IBOutlet weak var newMessagesLabel: UILabel!
+    @IBOutlet weak var lastMessageDateLabel: UILabel!
+    @IBOutlet weak var lastMessagePreviewLabel: UILabel!
+
+    override func awakeFromNib() {
+        super.awakeFromNib()
+
+    }
+
+    override func setSelected(_ selected: Bool, animated: Bool) {
+        super.setSelected(selected, animated: animated)
+        self.newMessagesIndicator.backgroundColor = UIColor.red
+    }
+
+    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
+        super.setHighlighted(highlighted, animated: animated)
+        self.newMessagesIndicator.backgroundColor = UIColor.red
+    }
+}
diff --git a/Ring/Ring/ConversationCell.xib b/Ring/Ring/ConversationCell.xib
new file mode 100644
index 000000000..c48708bf6
--- /dev/null
+++ b/Ring/Ring/ConversationCell.xib
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ConversationCellId" rowHeight="76" id="KGk-i7-Jjw" customClass="ConversationCell" customModule="Ring" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="358" height="76"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="358" height="75.5"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_contact_picture" translatesAutoresizingMaskIntoConstraints="NO" id="pFB-Jn-TNP">
+                        <rect key="frame" x="16" y="18" width="40" height="40"/>
+                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstAttribute="width" constant="40" id="Ptm-nU-6Xi"/>
+                            <constraint firstAttribute="height" constant="40" id="eES-QW-paO"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+                                <integer key="value" value="20"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </imageView>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Yesterday" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Yv-cC-LKx">
+                        <rect key="frame" x="281" y="30.5" width="61" height="14.5"/>
+                        <fontDescription key="fontDescription" type="boldSystem" pointSize="12"/>
+                        <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2fJ-Wf-1e0">
+                        <rect key="frame" x="60" y="4" width="217" height="41"/>
+                        <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                        <nil key="textColor"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eug-ak-r49">
+                        <rect key="frame" x="60" y="49" width="282" height="22.5"/>
+                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                        <nil key="textColor"/>
+                        <nil key="highlightedColor"/>
+                    </label>
+                    <view clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="JTE-eF-Y5s">
+                        <rect key="frame" x="42" y="18" width="14" height="14"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="P5S-4k-0yx">
+                                <rect key="frame" x="0.0" y="0.0" width="14" height="14"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" relation="greaterThanOrEqual" constant="14" id="VEi-Hm-z85"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="10"/>
+                                <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstItem="P5S-4k-0yx" firstAttribute="top" secondItem="JTE-eF-Y5s" secondAttribute="top" id="BH8-rD-0Oo"/>
+                            <constraint firstAttribute="height" constant="14" id="Qxc-Mv-ssH"/>
+                            <constraint firstItem="P5S-4k-0yx" firstAttribute="leading" secondItem="JTE-eF-Y5s" secondAttribute="leading" id="ZE1-mR-DoI"/>
+                            <constraint firstAttribute="trailing" secondItem="P5S-4k-0yx" secondAttribute="trailing" id="a9D-mE-0qK"/>
+                            <constraint firstAttribute="bottom" secondItem="P5S-4k-0yx" secondAttribute="bottom" id="qMW-uw-IoS"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+                                <integer key="value" value="6"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstItem="2fJ-Wf-1e0" firstAttribute="leading" secondItem="pFB-Jn-TNP" secondAttribute="trailing" constant="4" id="2NV-6m-dri"/>
+                    <constraint firstItem="eug-ak-r49" firstAttribute="leading" secondItem="pFB-Jn-TNP" secondAttribute="trailing" constant="4" id="9ah-Ed-RlY"/>
+                    <constraint firstItem="pFB-Jn-TNP" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="9mO-5E-3lA"/>
+                    <constraint firstItem="7Yv-cC-LKx" firstAttribute="leading" secondItem="2fJ-Wf-1e0" secondAttribute="trailing" constant="4" id="BzU-Ya-2ME"/>
+                    <constraint firstAttribute="trailing" secondItem="eug-ak-r49" secondAttribute="trailing" constant="16" id="ITl-14-BeZ"/>
+                    <constraint firstItem="JTE-eF-Y5s" firstAttribute="trailing" secondItem="pFB-Jn-TNP" secondAttribute="trailing" id="MgK-cd-QXM"/>
+                    <constraint firstAttribute="trailing" secondItem="7Yv-cC-LKx" secondAttribute="trailing" constant="16" id="UOx-Og-IuZ"/>
+                    <constraint firstItem="JTE-eF-Y5s" firstAttribute="top" secondItem="pFB-Jn-TNP" secondAttribute="top" id="W3A-IX-eXJ"/>
+                    <constraint firstItem="2fJ-Wf-1e0" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="4" id="omS-kb-QbN"/>
+                    <constraint firstItem="eug-ak-r49" firstAttribute="top" secondItem="7Yv-cC-LKx" secondAttribute="bottom" constant="4" id="oox-mY-e8b"/>
+                    <constraint firstAttribute="bottom" secondItem="eug-ak-r49" secondAttribute="bottom" constant="4" id="rzH-w5-tpt"/>
+                    <constraint firstItem="eug-ak-r49" firstAttribute="top" secondItem="2fJ-Wf-1e0" secondAttribute="bottom" constant="4" id="se0-Ur-K7G"/>
+                    <constraint firstItem="pFB-Jn-TNP" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="suq-ak-BYg"/>
+                    <constraint firstItem="7Yv-cC-LKx" firstAttribute="centerY" secondItem="H2p-sc-9uM" secondAttribute="centerY" id="xVO-gP-WdP"/>
+                </constraints>
+            </tableViewCellContentView>
+            <connections>
+                <outlet property="lastMessageDateLabel" destination="7Yv-cC-LKx" id="pFf-hW-zD8"/>
+                <outlet property="lastMessagePreviewLabel" destination="eug-ak-r49" id="3jj-Lx-jbU"/>
+                <outlet property="nameLabel" destination="2fJ-Wf-1e0" id="0Mb-yC-vh6"/>
+                <outlet property="newMessagesIndicator" destination="JTE-eF-Y5s" id="9kR-8x-Zpk"/>
+                <outlet property="newMessagesLabel" destination="P5S-4k-0yx" id="WlA-Z8-sNC"/>
+                <outlet property="profileImage" destination="pFB-Jn-TNP" id="zuf-CZ-9wL"/>
+            </connections>
+            <point key="canvasLocation" x="70" y="-92"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="ic_contact_picture" width="128" height="128"/>
+    </resources>
+</document>
diff --git a/Ring/Ring/ConversationModel.swift b/Ring/Ring/ConversationModel.swift
new file mode 100644
index 000000000..d1624cda7
--- /dev/null
+++ b/Ring/Ring/ConversationModel.swift
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+class ConversationModel {
+
+    var messages = [MessageModel]()
+    var recipient: ContactModel
+    var accountId: String
+
+    init(withRecipient recipient: ContactModel, accountId: String) {
+        self.recipient = recipient
+        self.accountId = accountId
+    }
+
+}
diff --git a/Ring/Ring/ConversationViewModel.swift b/Ring/Ring/ConversationViewModel.swift
new file mode 100644
index 000000000..19537035c
--- /dev/null
+++ b/Ring/Ring/ConversationViewModel.swift
@@ -0,0 +1,99 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+import RxSwift
+
+class ConversationViewModel {
+
+    let conversation: ConversationModel
+    let userName: Observable<String>
+
+    //Displays the entire date ( for messages received before the current week )
+    private let dateFormatter = DateFormatter()
+
+    //Displays the hour of the message reception ( for messages received today )
+    private let hourFormatter = DateFormatter()
+
+    private let disposeBag = DisposeBag()
+
+    init(withConversation conversation: ConversationModel) {
+        self.conversation = conversation
+        dateFormatter.dateStyle = .medium
+        hourFormatter.dateFormat = "HH:mm"
+
+        self.userName = ContactHelper.lookupUserName(forRingId: self.conversation.recipient.ringId,
+                                                nameService: AppDelegate.nameService,
+                                                disposeBag: self.disposeBag).asObservable()
+    }
+
+    var unreadMessages: String {
+       return self.unreadMessagesCount.description
+    }
+
+    fileprivate var unreadMessagesCount: Int {
+        return self.conversation.messages.filter({ message in
+            return message.status != .read
+        }).count
+    }
+
+    var hasUnreadMessages: Bool {
+        return conversation.messages.count > 0
+    }
+
+    var lastMessage: String {
+        if let lastMessage = conversation.messages.last?.content {
+            return lastMessage
+        } else {
+            return ""
+        }
+    }
+
+    var lastMessageReceivedDate: String {
+
+        guard let lastMessageDate = self.conversation.messages.last?.receivedDate else {
+            return ""
+        }
+
+        let dateToday = Date()
+
+        //Get components from today date
+        let todayWeekOfYear = Calendar.current.component(.weekOfYear, from: dateToday)
+        let todayDay = Calendar.current.component(.day, from: dateToday)
+        let todayMonth = Calendar.current.component(.month, from: dateToday)
+        let todayYear = Calendar.current.component(.year, from: dateToday)
+
+        //Get components from last message date
+        let weekOfYear = Calendar.current.component(.weekOfYear, from: lastMessageDate)
+        let day = Calendar.current.component(.day, from: lastMessageDate)
+        let month = Calendar.current.component(.month, from: lastMessageDate)
+        let year = Calendar.current.component(.year, from: lastMessageDate)
+
+        if todayDay == day && todayMonth == month && todayYear == year {
+            return hourFormatter.string(from: lastMessageDate)
+        } else if day == todayDay - 1 {
+            return NSLocalizedString("Yesterday", tableName: "Smartlist", comment: "")
+        } else if todayYear == year && todayWeekOfYear == weekOfYear {
+            return lastMessageDate.dayOfWeek()
+        } else {
+            return dateFormatter.string(from: lastMessageDate)
+        }
+    }
+}
diff --git a/Ring/Ring/ConversationsService.swift b/Ring/Ring/ConversationsService.swift
new file mode 100644
index 000000000..0d77c07f2
--- /dev/null
+++ b/Ring/Ring/ConversationsService.swift
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+import RxSwift
+
+class ConversationsService: MessagesAdapterDelegate {
+
+    fileprivate let messageAdapter :MessagesAdapter
+    fileprivate let disposeBag = DisposeBag()
+    fileprivate let textPlainMIMEType = "text/plain"
+
+    let conversations = Variable([ConversationModel]())
+
+    init(withMessageAdapter messageAdapter: MessagesAdapter) {
+        self.messageAdapter = messageAdapter
+        MessagesAdapter.delegate = self
+    }
+
+    func status(forMessageId messageId: UInt64) -> MessageStatus {
+        return self.messageAdapter.status(forMessageId: messageId)
+    }
+
+    //MARK: Message Adapter delegate
+
+    func didReceiveMessage(_ message: Dictionary<String, String>, from senderAccount: String,
+                           to receiverAccountId: String) {
+
+        if let content = message[textPlainMIMEType] {
+            let message = MessageModel(withId: nil, receivedDate: Date(), content: content, author: senderAccount)
+
+            //Get conversations for this sender
+            var currentConversation = conversations.value.filter({ conversation in
+                return conversation.recipient.ringId == senderAccount
+            }).first
+
+            //Get the current array of conversations
+            var currentConversations = self.conversations.value
+
+            //Create a new conversation for this sender if not exists
+            if currentConversation == nil {
+                currentConversation = ConversationModel(withRecipient: ContactModel(withRingId: senderAccount), accountId: receiverAccountId)
+                currentConversations.append(currentConversation!)
+            }
+
+            //Add the received message into the conversation
+            currentConversation?.messages.append(message)
+
+            //Upate the value of the Variable
+            self.conversations.value = currentConversations
+        }
+    }
+
+    func messageStatusChanged(_ status: MessageStatus, for messageId: UInt64,
+                              from senderAccountId: String, to receiverAccount: String) {
+
+        print("messageStatusChanged: \(status.rawValue) for: \(messageId) from: \(senderAccountId) to: \(receiverAccount)")
+    }
+}
diff --git a/Ring/Ring/Extensions/Date+Helpers.swift b/Ring/Ring/Extensions/Date+Helpers.swift
new file mode 100644
index 000000000..19a58ed73
--- /dev/null
+++ b/Ring/Ring/Extensions/Date+Helpers.swift
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+extension Date {
+    func dayNumberOfWeek() -> Int? {
+        return Calendar.current.dateComponents([.weekday], from: self).weekday
+    }
+
+    func dayOfWeek() -> String {
+        let dateFormatter = DateFormatter()
+        dateFormatter.dateFormat = "EEEE"
+        return dateFormatter.string(from: self)
+    }
+}
diff --git a/Ring/Ring/Global.strings b/Ring/Ring/Global.strings
new file mode 100644
index 000000000..0cc9f97f3
--- /dev/null
+++ b/Ring/Ring/Global.strings
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+"HomeTabBarTitle" = "Home";
diff --git a/Ring/Ring/MainTabBar/MainTabBarViewController.swift b/Ring/Ring/MainTabBar/MainTabBarViewController.swift
index 678d30a0b..72cdb8bfa 100644
--- a/Ring/Ring/MainTabBar/MainTabBarViewController.swift
+++ b/Ring/Ring/MainTabBar/MainTabBarViewController.swift
@@ -23,6 +23,12 @@ import UIKit
 class MainTabBarViewController: UITabBarController {
     fileprivate let accountService = AppDelegate.accountService
 
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        UITabBarItem.appearance()
+            .setTitleTextAttributes( [NSForegroundColorAttributeName : Colors.ringMainColor], for: .selected)
+    }
+
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
         if !accountService.hasAccounts() {
diff --git a/Ring/Ring/MessageModel.swift b/Ring/Ring/MessageModel.swift
new file mode 100644
index 000000000..000e4858c
--- /dev/null
+++ b/Ring/Ring/MessageModel.swift
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+class MessageModel {
+
+    var id: UInt64?
+    var receivedDate: Date
+    var content: String
+    var author: String
+    var status: MessageStatus
+
+    init(withId id: UInt64?, receivedDate: Date, content: String, author: String) {
+        self.id = id
+        self.receivedDate = receivedDate
+        self.content = content
+        self.author = author
+        self.status = .unknown
+    }
+
+}
diff --git a/Ring/Ring/MessagesAdapter.h b/Ring/Ring/MessagesAdapter.h
new file mode 100644
index 000000000..4cc6c8553
--- /dev/null
+++ b/Ring/Ring/MessagesAdapter.h
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#import <Foundation/Foundation.h>
+
+typedef NS_ENUM(int, MessageStatus)  {
+    MessageStatusUnknown = 0,
+    MessageStatusIdle,
+    MessageStatusSending,
+    MessageStatusSent,
+    MessageStatusRead,
+    MessageStatusFailure
+};
+
+@protocol MessagesAdapterDelegate;
+
+@interface MessagesAdapter : NSObject
+
+@property (class, nonatomic, weak) id <MessagesAdapterDelegate> delegate;
+
+- (NSUInteger)sendMessageWithContent:(NSDictionary*)content withAccountId:(NSString*)accountId
+                       to:(NSString*)toAccountId;
+
+- (MessageStatus)statusForMessageId:(uint64_t)messageId;
+
+@end
diff --git a/Ring/Ring/MessagesAdapter.mm b/Ring/Ring/MessagesAdapter.mm
new file mode 100644
index 000000000..69f90d4a3
--- /dev/null
+++ b/Ring/Ring/MessagesAdapter.mm
@@ -0,0 +1,102 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#import "MessagesAdapter.h"
+
+#import "Ring-Swift.h"
+#import "Utils.h"
+#import "dring/configurationmanager_interface.h"
+
+@implementation MessagesAdapter
+
+using namespace DRing;
+
+/// Static delegate that will receive the propagated daemon events
+static id <MessagesAdapterDelegate> _delegate;
+
+#pragma mark Init
+- (id)init {
+    if (self = [super init]) {
+        [self registerConfigurationHandler];
+    }
+    return self;
+}
+#pragma mark -
+
+#pragma mark Callbacks registration
+- (void)registerConfigurationHandler {
+    std::map<std::string, std::shared_ptr<CallbackWrapperBase>> confHandlers;
+
+    confHandlers.insert(exportable_callback<ConfigurationSignal::IncomingAccountMessage>([&](const std::string& account_id,
+                                                                                             const std::string& from,
+                                                                                             const std::map<std::string,
+                                                                                             std::string>& payloads) {
+        if (MessagesAdapter.delegate) {
+            NSDictionary* message = [Utils mapToDictionnary:payloads];
+            NSString* fromAccount = [NSString stringWithUTF8String:from.c_str()];
+            NSString* toAccountId = [NSString stringWithUTF8String:account_id.c_str()];
+            [MessagesAdapter.delegate didReceiveMessage:message from:fromAccount to:toAccountId];
+        }
+    }));
+
+    confHandlers.insert(exportable_callback<ConfigurationSignal::AccountMessageStatusChanged>([&](const std::string& account_id, uint64_t message_id, const std::string& to, int state) {
+        if (MessagesAdapter.delegate) {
+            NSString* fromAccountId = [NSString stringWithUTF8String:account_id.c_str()];
+            NSString* toAccount = [NSString stringWithUTF8String:to.c_str()];
+            [MessagesAdapter.delegate messageStatusChanged:(MessageStatus)state
+                                                       for:message_id from:fromAccountId
+                                                        to:toAccount];
+        }
+    }));
+
+    confHandlers.insert(exportable_callback<DebugSignal::MessageSend>([&](const std::string& message) {
+        if (MessagesAdapter.delegate) {
+            NSString* messageSend = [NSString stringWithUTF8String:message.c_str()];
+            NSLog(@"MessageSend = %@",messageSend);
+        }
+    }));
+
+    registerConfHandlers(confHandlers);
+}
+#pragma mark -
+
+- (NSUInteger)sendMessageWithContent:(NSDictionary*)content withAccountId:(NSString*)accountId
+                       to:(NSString*)toAccountId {
+
+    return (NSUInteger) sendAccountTextMessage(std::string([accountId UTF8String]),
+                           std::string([toAccountId UTF8String]),
+                           [Utils dictionnaryToMap:content]);
+}
+
+- (MessageStatus)statusForMessageId:(uint64_t)messageId {
+    return (MessageStatus)getMessageStatus(messageId);
+}
+
+#pragma mark AccountAdapterDelegate
++ (id <MessagesAdapterDelegate>)delegate {
+    return _delegate;
+}
+
++ (void) setDelegate:(id<MessagesAdapterDelegate>)delegate {
+    _delegate = delegate;
+}
+#pragma mark -
+
+@end
diff --git a/Ring/Ring/MessagesAdapterDelegate.swift b/Ring/Ring/MessagesAdapterDelegate.swift
new file mode 100644
index 000000000..dc50514e3
--- /dev/null
+++ b/Ring/Ring/MessagesAdapterDelegate.swift
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+@objc protocol MessagesAdapterDelegate {
+
+    func didReceiveMessage(_ message: Dictionary<String, String>, from senderAccount: String,
+                           to receiverAccountId: String)
+
+    func messageStatusChanged(_ status: MessageStatus, for messageId: UInt64, from senderAccountId: String,
+                              to receiverAccount: String)
+}
diff --git a/Ring/Ring/NameRegistrationAdapter.h b/Ring/Ring/NameRegistrationAdapter.h
index 2147523a9..6806055bb 100644
--- a/Ring/Ring/NameRegistrationAdapter.h
+++ b/Ring/Ring/NameRegistrationAdapter.h
@@ -32,4 +32,8 @@
 - (void)registerNameWithAccount:(NSString*)account password:(NSString*)password
                            name:(NSString*)name;
 
+- (void)lookupAddressWithAccount:(NSString*)account nameserver:(NSString*)nameserver
+                         address:(NSString*)address;
+
+
 @end
diff --git a/Ring/Ring/NameRegistrationAdapter.mm b/Ring/Ring/NameRegistrationAdapter.mm
index 84a5881f6..99a9a0357 100644
--- a/Ring/Ring/NameRegistrationAdapter.mm
+++ b/Ring/Ring/NameRegistrationAdapter.mm
@@ -79,6 +79,10 @@ static id <NameRegistrationAdapterDelegate> _delegate;
     lookupName(std::string([account UTF8String]),std::string([nameserver UTF8String]),std::string([name UTF8String]));
 }
 
+- (void)lookupAddressWithAccount:(NSString*)account nameserver:(NSString*)nameserver address:(NSString*)address {
+    lookupAddress(std::string([account UTF8String]), std::string([nameserver UTF8String]), std::string([address UTF8String]));
+}
+
 - (void)registerNameWithAccount:(NSString*)account password:(NSString*)password name:(NSString*)name {
     registerName(std::string([account UTF8String]), std::string([password UTF8String]), std::string([name UTF8String]));
 }
diff --git a/Ring/Ring/NameService.swift b/Ring/Ring/NameService.swift
index 214fd00ed..c15dceb81 100644
--- a/Ring/Ring/NameService.swift
+++ b/Ring/Ring/NameService.swift
@@ -44,7 +44,7 @@ class NameService: NameRegistrationAdapterDelegate {
     fileprivate let lookupNameCallDelay = 0.5
 
     /**
-     Status of the current username lookup request
+     Status of the current username validation request
      */
     var usernameValidationStatus = PublishSubject<UsernameValidationStatus>()
 
@@ -53,6 +53,11 @@ class NameService: NameRegistrationAdapterDelegate {
         NameRegistrationAdapter.delegate = self
     }
 
+    /**
+     Status of the current username lookup request
+     */
+    var usernameLookupStatus = PublishSubject<LookupNameResponse>()
+
     /**
     Make a username lookup request to the daemon
      */
@@ -75,6 +80,13 @@ class NameService: NameRegistrationAdapterDelegate {
         }
     }
 
+    /**
+     Make an address lookup request to the daemon
+    */
+    func lookupAddress(withAccount account: String, nameserver: String, address: String) {
+        self.nameRegistrationAdapter.lookupAddress(withAccount: account, nameserver: nameserver, address: address)
+    }
+
     /**
      Register the username into the the blockchain
      */
@@ -95,6 +107,8 @@ class NameService: NameRegistrationAdapterDelegate {
         } else {
             print("Lookup name error")
         }
+
+        usernameLookupStatus.onNext(response)
     }
 
     internal func nameRegistrationEnded(with response: NameRegistrationResponse) {
diff --git a/Ring/Ring/Smartlist.strings b/Ring/Ring/Smartlist.strings
new file mode 100644
index 000000000..e7d37ca1d
--- /dev/null
+++ b/Ring/Ring/Smartlist.strings
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+"Yesterday" = "Yesterday";
+
diff --git a/Ring/Ring/SmartlistViewController.swift b/Ring/Ring/SmartlistViewController.swift
new file mode 100644
index 000000000..9a76c1117
--- /dev/null
+++ b/Ring/Ring/SmartlistViewController.swift
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+import RxSwift
+import RxDataSources
+
+class SmartlistViewController: UIViewController, UITableViewDelegate {
+
+    @IBOutlet weak var tableView: UITableView!
+
+    fileprivate let viewModel = SmartlistViewModel(withConversationsService: AppDelegate.conversationsService)
+    fileprivate let disposeBag = DisposeBag()
+    fileprivate let SmartlistRowHeight :CGFloat = 64.0
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        self.setupUI()
+        self.setupTableView()
+    }
+
+    func setupUI() {
+
+        let title = NSLocalizedString("HomeTabBarTitle", tableName: "Global", comment: "")
+
+        self.title = title
+        self.navigationItem.title = title
+    }
+
+    func setupTableView() {
+
+        //Set row height
+        self.tableView.rowHeight = SmartlistRowHeight
+
+        //Register Cell
+        self.tableView.register(UINib.init(nibName: "ConversationCell", bundle: nil), forCellReuseIdentifier: "ConversationCellId")
+
+        //Bind the TableView to the ViewModel
+        self.viewModel.conversationsObservable.bindTo(tableView.rx.items(cellIdentifier: "ConversationCellId", cellType: ConversationCell.self) ) { index, viewModel, cell in
+            viewModel.userName.bindTo(cell.nameLabel.rx.text).addDisposableTo(self.disposeBag)
+            cell.newMessagesLabel.text = viewModel.unreadMessages
+            cell.lastMessageDateLabel.text = viewModel.lastMessageReceivedDate
+            cell.newMessagesIndicator.isHidden = !viewModel.hasUnreadMessages
+            cell.lastMessagePreviewLabel.text = viewModel.lastMessage
+        }.addDisposableTo(disposeBag)
+
+        self.tableView.rx.itemSelected.asObservable().subscribe(onNext: { indexPath in
+            self.tableView.deselectRow(at: indexPath, animated: true)
+        }).addDisposableTo(disposeBag)
+    }
+
+    // MARK: - Navigation
+
+    // In a storyboard-based application, you will often want to do a little preparation before navigation
+    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
+
+    }
+
+}
diff --git a/Ring/Ring/SmartlistViewModel.swift b/Ring/Ring/SmartlistViewModel.swift
new file mode 100644
index 000000000..3c0ab418b
--- /dev/null
+++ b/Ring/Ring/SmartlistViewModel.swift
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ *  Author: Silbino Gonçalves Matado <silbino.gmatado@savoirfairelinux.com>
+ *
+ *  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
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+import UIKit
+import RxSwift
+
+class SmartlistViewModel: NSObject {
+
+    fileprivate let conversationsService: ConversationsService
+    fileprivate var conversationViewModels :[ConversationViewModel]
+
+    let conversationsObservable :Observable<[ConversationViewModel]>
+
+    init(withConversationsService conversationsService: ConversationsService) {
+        self.conversationsService = conversationsService
+
+        var conversationViewModels = [ConversationViewModel]()
+        self.conversationViewModels = conversationViewModels
+
+        //Create observable from sorted conversations and flatMap them to view models
+        self.conversationsObservable = self.conversationsService.conversations.asObservable().map({ conversations in
+            return conversations.sorted(by: { conversation1, conversations2 in
+
+                guard let lastMessage1 = conversation1.messages.last,
+                let lastMessage2 = conversations2.messages.last else {
+                    return true
+                }
+
+                return lastMessage1.receivedDate > lastMessage2.receivedDate
+            }).flatMap({ conversationModel in
+
+                var conversationViewModel: ConversationViewModel?
+
+                //Get the current ConversationViewModel if exists or create it
+                if let foundConversationViewModel = conversationViewModels.filter({ conversationViewModel in
+                    return conversationViewModel.conversation === conversationModel
+                }).first {
+                    conversationViewModel = foundConversationViewModel
+                } else {
+                    conversationViewModel = ConversationViewModel(withConversation: conversationModel)
+                    conversationViewModels.append(conversationViewModel!)
+                }
+
+                return conversationViewModel
+            })
+        }).observeOn(MainScheduler.instance)
+    }
+
+}
-- 
GitLab