From cfe0eba3404210bf649dd813532383e8a63356b2 Mon Sep 17 00:00:00 2001
From: Thibault Wittemberg <thibault.wittemberg@savoirfairelinux.com>
Date: Mon, 10 Jul 2017 17:20:28 -0400
Subject: [PATCH] ui: add theming basis

This commit adds Chameleon to theme the app and a custom
theming function to handle MessageBubbles

Change-Id: I58e4d2e30c9e81a444b3a22cef4429d64361426d
---
 Ring/Cartfile                                 |  1 +
 Ring/Cartfile.resolved                        |  1 +
 Ring/Ring.xcodeproj/project.pbxproj           | 37 +++++++---
 Ring/Ring/AppDelegate.swift                   |  5 ++
 Ring/Ring/Bridging/Ring-Bridging-Header.h     |  1 +
 Ring/Ring/Bridging/SystemAdapter.mm           |  2 +
 Ring/Ring/Constants/Generated/Strings.swift   |  2 +
 .../ConversationViewController.swift          | 41 +++++++++--
 Ring/Ring/Extensions/Chameleon+Ring.swift     | 58 +++++++++++++++
 Ring/Ring/Extensions/UIColor+Ring.swift       | 11 ++-
 Ring/Ring/Info.plist                          |  2 +-
 .../MainTabBar/MainTabBarViewController.swift |  2 -
 Ring/Ring/Messages/MessableBubble.swift       | 27 +++++++
 Ring/Ring/Messages/MessageCell.swift          | 70 -------------------
 Ring/Ring/Messages/MessageCellReceived.swift  | 29 ++++++++
 ...essageCell.xib => MessageCellReceived.xib} | 12 ++--
 Ring/Ring/Messages/MessageCellSent.swift      | 29 ++++++++
 Ring/Ring/Messages/MessageCellSent.xib        | 62 ++++++++++++++++
 Ring/Ring/Messages/MessageViewModel.swift     |  5 ++
 Ring/Ring/Resources/Main.storyboard           | 54 +++++++-------
 .../Resources/en.lproj/Localizable.strings    |  1 +
 Ring/Ring/Settings/MeViewController.swift     |  3 +
 22 files changed, 330 insertions(+), 125 deletions(-)
 create mode 100644 Ring/Ring/Extensions/Chameleon+Ring.swift
 create mode 100644 Ring/Ring/Messages/MessableBubble.swift
 delete mode 100644 Ring/Ring/Messages/MessageCell.swift
 create mode 100644 Ring/Ring/Messages/MessageCellReceived.swift
 rename Ring/Ring/Messages/{MessageCell.xib => MessageCellReceived.xib} (89%)
 create mode 100644 Ring/Ring/Messages/MessageCellSent.swift
 create mode 100644 Ring/Ring/Messages/MessageCellSent.xib

diff --git a/Ring/Cartfile b/Ring/Cartfile
index 2c88dc47e..71113d6da 100644
--- a/Ring/Cartfile
+++ b/Ring/Cartfile
@@ -3,3 +3,4 @@ github "RxSwiftCommunity/RxDataSources" == 1.0.3
 github "pkluz/PKHUD"
 github "AliSoftware/Reusable" ~> 4.0
 github "SwiftyBeaver/SwiftyBeaver"
+github "ViccAlexander/Chameleon"
diff --git a/Ring/Cartfile.resolved b/Ring/Cartfile.resolved
index d31aa67fc..a286e0b59 100644
--- a/Ring/Cartfile.resolved
+++ b/Ring/Cartfile.resolved
@@ -3,5 +3,6 @@ github "ReactiveX/RxSwift" "3.5.0"
 github "RxSwiftCommunity/RxDataSources" "1.0.4"
 github "RxSwiftCommunity/RxRealm" "0.6.0"
 github "SwiftyBeaver/SwiftyBeaver" "1.3.0"
+github "ViccAlexander/Chameleon" "2.2.0"
 github "pkluz/PKHUD" "4.2.3"
 github "realm/realm-cocoa" "v2.8.3"
diff --git a/Ring/Ring.xcodeproj/project.pbxproj b/Ring/Ring.xcodeproj/project.pbxproj
index 21d301575..af67e735b 100644
--- a/Ring/Ring.xcodeproj/project.pbxproj
+++ b/Ring/Ring.xcodeproj/project.pbxproj
@@ -93,6 +93,12 @@
 		04399B151D1C341A00E99CD9 /* libyaml-cpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */; };
 		1A1E476D1F0E808500EA9A36 /* Reusable.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1E476C1F0E808500EA9A36 /* Reusable.framework */; };
 		1A1E476F1F0E894600EA9A36 /* SwiftyBeaver.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A1E476E1F0E894600EA9A36 /* SwiftyBeaver.framework */; };
+		1A3CA32B1F102BB700283748 /* Chameleon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A3CA32A1F102BB700283748 /* Chameleon.framework */; };
+		1A3CA32D1F13DA7200283748 /* Chameleon+Ring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3CA32C1F13DA7200283748 /* Chameleon+Ring.swift */; };
+		1A3CA32F1F1400AF00283748 /* MessageCellReceived.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A3CA32E1F1400AF00283748 /* MessageCellReceived.xib */; };
+		1A3CA3351F140EB300283748 /* MessableBubble.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3CA3341F140EB300283748 /* MessableBubble.swift */; };
+		1A3CA3381F14133300283748 /* MessageCellSent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3CA3361F14133300283748 /* MessageCellSent.swift */; };
+		1A3CA3391F14133300283748 /* MessageCellSent.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A3CA3371F14133300283748 /* MessageCellSent.xib */; };
 		1A3D28A71F0EB9DB00B524EE /* Bool+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */; };
 		1A3D28A91F0EBF0200B524EE /* UIView+Ring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3D28A81F0EBF0200B524EE /* UIView+Ring.swift */; };
 		1A8306331F0EDAA50099D98C /* AccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A8306321F0EDAA50099D98C /* AccountTableViewCell.swift */; };
@@ -145,8 +151,7 @@
 		56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */; };
 		56BBC9CD1EDC5E7000CDAF8B /* MessageAccessoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9C71EDC5E7000CDAF8B /* MessageAccessoryView.swift */; };
 		56BBC9CE1EDC5E7000CDAF8B /* MessageAccessoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9C81EDC5E7000CDAF8B /* MessageAccessoryView.xib */; };
-		56BBC9CF1EDC5E7000CDAF8B /* MessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9C91EDC5E7000CDAF8B /* MessageCell.swift */; };
-		56BBC9D01EDC5E7000CDAF8B /* MessageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56BBC9CA1EDC5E7000CDAF8B /* MessageCell.xib */; };
+		56BBC9CF1EDC5E7000CDAF8B /* MessageCellReceived.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9C91EDC5E7000CDAF8B /* MessageCellReceived.swift */; };
 		56BBC9D21EDC5E7000CDAF8B /* MessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9CC1EDC5E7000CDAF8B /* MessageViewModel.swift */; };
 		56BBC9D41EDC7A6D00CDAF8B /* libargon2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 56BBC9D31EDC7A6D00CDAF8B /* libargon2.a */; };
 		56BBC9DF1EDDC9D300CDAF8B /* LookupNameResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BBC9DE1EDDC9D300CDAF8B /* LookupNameResponse.m */; };
@@ -274,6 +279,12 @@
 		04399AE31D1C341A00E99CD9 /* libyaml-cpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libyaml-cpp.a"; path = "../fat/lib/libyaml-cpp.a"; sourceTree = "<group>"; };
 		1A1E476C1F0E808500EA9A36 /* Reusable.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Reusable.framework; path = Carthage/Build/iOS/Reusable.framework; sourceTree = "<group>"; };
 		1A1E476E1F0E894600EA9A36 /* SwiftyBeaver.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyBeaver.framework; path = Carthage/Build/iOS/SwiftyBeaver.framework; sourceTree = "<group>"; };
+		1A3CA32A1F102BB700283748 /* Chameleon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Chameleon.framework; path = Carthage/Build/iOS/Chameleon.framework; sourceTree = "<group>"; };
+		1A3CA32C1F13DA7200283748 /* Chameleon+Ring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Chameleon+Ring.swift"; sourceTree = "<group>"; };
+		1A3CA32E1F1400AF00283748 /* MessageCellReceived.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCellReceived.xib; sourceTree = "<group>"; };
+		1A3CA3341F140EB300283748 /* MessableBubble.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessableBubble.swift; sourceTree = "<group>"; };
+		1A3CA3361F14133300283748 /* MessageCellSent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCellSent.swift; sourceTree = "<group>"; };
+		1A3CA3371F14133300283748 /* MessageCellSent.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCellSent.xib; sourceTree = "<group>"; };
 		1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bool+String.swift"; sourceTree = "<group>"; };
 		1A3D28A81F0EBF0200B524EE /* UIView+Ring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Ring.swift"; sourceTree = "<group>"; };
 		1A8306321F0EDAA50099D98C /* AccountTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTableViewCell.swift; sourceTree = "<group>"; };
@@ -332,8 +343,7 @@
 		56BBC9BE1ED7168400CDAF8B /* SmartlistViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SmartlistViewModel.swift; sourceTree = "<group>"; };
 		56BBC9C71EDC5E7000CDAF8B /* MessageAccessoryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageAccessoryView.swift; sourceTree = "<group>"; };
 		56BBC9C81EDC5E7000CDAF8B /* MessageAccessoryView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageAccessoryView.xib; sourceTree = "<group>"; };
-		56BBC9C91EDC5E7000CDAF8B /* MessageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCell.swift; sourceTree = "<group>"; };
-		56BBC9CA1EDC5E7000CDAF8B /* MessageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessageCell.xib; sourceTree = "<group>"; };
+		56BBC9C91EDC5E7000CDAF8B /* MessageCellReceived.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCellReceived.swift; sourceTree = "<group>"; };
 		56BBC9CC1EDC5E7000CDAF8B /* MessageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageViewModel.swift; sourceTree = "<group>"; };
 		56BBC9D31EDC7A6D00CDAF8B /* libargon2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libargon2.a; path = ../fat/lib/libargon2.a; sourceTree = "<group>"; };
 		56BBC9DD1EDDC9D300CDAF8B /* LookupNameResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LookupNameResponse.h; sourceTree = "<group>"; };
@@ -346,6 +356,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				1A3CA32B1F102BB700283748 /* Chameleon.framework in Frameworks */,
 				1A1E476F1F0E894600EA9A36 /* SwiftyBeaver.framework in Frameworks */,
 				1A1E476D1F0E808500EA9A36 /* Reusable.framework in Frameworks */,
 				56559B0E1EE8777600BF20E1 /* RxRealm.framework in Frameworks */,
@@ -467,6 +478,7 @@
 		02AED8171DD4C4B000F740BA /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				1A3CA32A1F102BB700283748 /* Chameleon.framework */,
 				1A1E476E1F0E894600EA9A36 /* SwiftyBeaver.framework */,
 				1A1E476C1F0E808500EA9A36 /* Reusable.framework */,
 				56559B0D1EE8777600BF20E1 /* RxRealm.framework */,
@@ -555,6 +567,7 @@
 				1A3D28A61F0EB9DB00B524EE /* Bool+String.swift */,
 				1A3D28A81F0EBF0200B524EE /* UIView+Ring.swift */,
 				1AABA7451F0FE9C000739605 /* UIColor+Ring.swift */,
+				1A3CA32C1F13DA7200283748 /* Chameleon+Ring.swift */,
 			);
 			path = Extensions;
 			sourceTree = "<group>";
@@ -782,10 +795,13 @@
 			children = (
 				56BBC9C71EDC5E7000CDAF8B /* MessageAccessoryView.swift */,
 				56BBC9C81EDC5E7000CDAF8B /* MessageAccessoryView.xib */,
-				56BBC9C91EDC5E7000CDAF8B /* MessageCell.swift */,
-				56BBC9CA1EDC5E7000CDAF8B /* MessageCell.xib */,
+				1A3CA32E1F1400AF00283748 /* MessageCellReceived.xib */,
+				56BBC9C91EDC5E7000CDAF8B /* MessageCellReceived.swift */,
+				1A3CA3361F14133300283748 /* MessageCellSent.swift */,
+				1A3CA3371F14133300283748 /* MessageCellSent.xib */,
 				56BBC9CC1EDC5E7000CDAF8B /* MessageViewModel.swift */,
 				56BBC9A51ED7151500CDAF8B /* MessageModel.swift */,
+				1A3CA3341F140EB300283748 /* MessableBubble.swift */,
 			);
 			path = Messages;
 			sourceTree = "<group>";
@@ -940,8 +956,9 @@
 				5669A7FE1EA904E4003C7B93 /* TextCell.xib in Resources */,
 				1ABE07DC1F0D915100D36361 /* Localizable.strings in Resources */,
 				56BBC9CE1EDC5E7000CDAF8B /* MessageAccessoryView.xib in Resources */,
+				1A3CA32F1F1400AF00283748 /* MessageCellReceived.xib in Resources */,
+				1A3CA3391F14133300283748 /* MessageCellSent.xib in Resources */,
 				04399A031D1C2D9D00E99CD9 /* Images.xcassets in Resources */,
-				56BBC9D01EDC5E7000CDAF8B /* MessageCell.xib in Resources */,
 				1ABE07E01F0D91A800D36361 /* Main.storyboard in Resources */,
 				5669A7FA1EA904AF003C7B93 /* SwitchCell.xib in Resources */,
 				56BBC9B51ED7156500CDAF8B /* ConversationCell.xib in Resources */,
@@ -983,6 +1000,7 @@
 				"$(SRCROOT)/Carthage/Build/iOS/RxRealm.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/Reusable.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/SwiftyBeaver.framework",
+				"$(SRCROOT)/Carthage/Build/iOS/Chameleon.framework",
 			);
 			name = "⚙️ Copy Frameworks";
 			outputPaths = (
@@ -1036,7 +1054,8 @@
 				02B22E091DF7585F000358C9 /* DaemonService.swift in Sources */,
 				0273C3061E0C68B100CF00BA /* CreateRingAccountViewController.swift in Sources */,
 				56BBC99F1ED714CB00CDAF8B /* MessagesAdapter.mm in Sources */,
-				56BBC9CF1EDC5E7000CDAF8B /* MessageCell.swift in Sources */,
+				1A3CA3351F140EB300283748 /* MessableBubble.swift in Sources */,
+				56BBC9CF1EDC5E7000CDAF8B /* MessageCellReceived.swift in Sources */,
 				02C9B63F1E1D4E8C00F82F0C /* ServiceEvent.swift in Sources */,
 				1A3D28A71F0EB9DB00B524EE /* Bool+String.swift in Sources */,
 				56BBC9D21EDC5E7000CDAF8B /* MessageViewModel.swift in Sources */,
@@ -1048,6 +1067,7 @@
 				56559B141EE89E7900BF20E1 /* DeviceModel.swift in Sources */,
 				56308BA71EA00E5700660275 /* NameRegistrationResponse.m in Sources */,
 				5628B4211F0C35C8008B1E11 /* WelcomeViewController.swift in Sources */,
+				1A3CA32D1F13DA7200283748 /* Chameleon+Ring.swift in Sources */,
 				5628B41C1F0C358D008B1E11 /* AccountDetailsViewController.swift in Sources */,
 				56AC64E11E80542300EA1AA9 /* TextFieldCell.swift in Sources */,
 				1ABE07E21F0D924700D36361 /* Strings.swift in Sources */,
@@ -1056,6 +1076,7 @@
 				56BBC9BF1ED7168400CDAF8B /* SmartlistViewModel.swift in Sources */,
 				02B22E011DF755E5000358C9 /* MainTabBarViewController.swift in Sources */,
 				564C44641E943E1E000F92B1 /* NameRegistrationAdapterDelegate.swift in Sources */,
+				1A3CA3381F14133300283748 /* MessageCellSent.swift in Sources */,
 				043999F71D1C2D9D00E99CD9 /* AppDelegate.swift in Sources */,
 				02B22DFC1DF755BB000358C9 /* AccountModel.swift in Sources */,
 				56AC64DF1E804ECC00EA1AA9 /* SwitchCell.swift in Sources */,
diff --git a/Ring/Ring/AppDelegate.swift b/Ring/Ring/AppDelegate.swift
index 575fcf958..354bcdbe0 100644
--- a/Ring/Ring/AppDelegate.swift
+++ b/Ring/Ring/AppDelegate.swift
@@ -23,6 +23,7 @@ import UIKit
 import RealmSwift
 import SwiftyBeaver
 import RxSwift
+import Chameleon
 
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -47,6 +48,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 
         SystemAdapter().registerConfigurationHandler()
         self.startDaemon()
+
+        Chameleon.setGlobalThemeUsingPrimaryColor(UIColor.ringMain, withSecondaryColor: UIColor.ringSecondary, andContentStyle: .light)
+        Chameleon.setRingThemeUsingPrimaryColor(UIColor.ringMain, withSecondaryColor: UIColor.ringSecondary, andContentStyle: .light)
+
         self.loadAccounts()
         return true
     }
diff --git a/Ring/Ring/Bridging/Ring-Bridging-Header.h b/Ring/Ring/Bridging/Ring-Bridging-Header.h
index 600ce0985..6e04dc036 100644
--- a/Ring/Ring/Bridging/Ring-Bridging-Header.h
+++ b/Ring/Ring/Bridging/Ring-Bridging-Header.h
@@ -30,3 +30,4 @@
 #import "RegistrationResponse.h"
 #import "NameRegistrationResponse.h"
 #import "MessagesAdapter.h"
+#import "Chameleon/Chameleon.h"
diff --git a/Ring/Ring/Bridging/SystemAdapter.mm b/Ring/Ring/Bridging/SystemAdapter.mm
index 53942ab01..00851a4bf 100644
--- a/Ring/Ring/Bridging/SystemAdapter.mm
+++ b/Ring/Ring/Bridging/SystemAdapter.mm
@@ -18,6 +18,8 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
+#import "Chameleon/Chameleon-Swift.h"
+
 #import "Ring-Swift.h"
 
 #import "SystemAdapter.h"
diff --git a/Ring/Ring/Constants/Generated/Strings.swift b/Ring/Ring/Constants/Generated/Strings.swift
index bbbad24b0..1baf6ed7e 100644
--- a/Ring/Ring/Constants/Generated/Strings.swift
+++ b/Ring/Ring/Constants/Generated/Strings.swift
@@ -63,6 +63,8 @@ enum L10n {
   enum Global {
     /// Home
     static let homeTabBarTitle = L10n.tr("global.homeTabBarTitle")
+    /// Me
+    static let meTabBarTitle = L10n.tr("global.meTabBarTitle")
     /// Ok
     static let ok = L10n.tr("global.ok")
   }
diff --git a/Ring/Ring/Conversations/ConversationViewController.swift b/Ring/Ring/Conversations/ConversationViewController.swift
index 81c3afdb4..79d7ae86a 100644
--- a/Ring/Ring/Conversations/ConversationViewController.swift
+++ b/Ring/Ring/Conversations/ConversationViewController.swift
@@ -26,6 +26,7 @@ class ConversationViewController: UIViewController, UITextFieldDelegate {
     let disposeBag = DisposeBag()
 
     var viewModel: ConversationViewModel?
+    var messageViewModels: [MessageViewModel]?
     var textFieldShouldEndEditing = false
     var bottomOffset: CGFloat = 0
 
@@ -92,20 +93,21 @@ class ConversationViewController: UIViewController, UITextFieldDelegate {
     }
 
     func setupTableView() {
+        self.tableView.dataSource = self
+
         self.tableView.estimatedRowHeight = 50
         self.tableView.rowHeight = UITableViewAutomaticDimension
         self.tableView.separatorStyle = .none
 
         //Register cell
-        self.tableView.register(cellType: MessageCell.self)
+        self.tableView.register(cellType: MessageCellSent.self)
+        self.tableView.register(cellType: MessageCellReceived.self)
 
         //Bind the TableView to the ViewModel
-        self.viewModel?.messages
-            .bind(to: tableView.rx.items(cellIdentifier: "MessageCell",
-                                         cellType: MessageCell.self)) { _, messageViewModel, cell in
-                cell.messageLabel.text = messageViewModel.content
-                cell.bubblePosition = messageViewModel.bubblePosition()
-        }.disposed(by: disposeBag)
+        self.viewModel?.messages.subscribe(onNext: { [weak self] (messageViewModels) in
+            self?.messageViewModels = messageViewModels
+            self?.tableView.reloadData()
+        }).disposed(by: self.disposeBag)
 
         //Scroll to bottom when reloaded
         self.tableView.rx.methodInvoked(#selector(UITableView.reloadData)).subscribe(onNext: { _ in
@@ -170,3 +172,28 @@ class ConversationViewController: UIViewController, UITextFieldDelegate {
     }
 
 }
+
+extension ConversationViewController: UITableViewDataSource {
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return self.messageViewModels?.count ?? 0
+    }
+
+    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+
+        if let messageViewModel = self.messageViewModels?[indexPath.row] {
+            if messageViewModel.bubblePosition() == .received {
+                let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellReceived.self)
+                cell.messageLabel.text = messageViewModel.content
+                return cell
+            }
+
+            let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)
+            cell.messageLabel.text = messageViewModel.content
+            return cell
+        }
+
+        return tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)
+
+    }
+
+}
diff --git a/Ring/Ring/Extensions/Chameleon+Ring.swift b/Ring/Ring/Extensions/Chameleon+Ring.swift
new file mode 100644
index 000000000..7e5710910
--- /dev/null
+++ b/Ring/Ring/Extensions/Chameleon+Ring.swift
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Thibault Wittemberg <thibault.wittemberg@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
+import Chameleon
+
+extension Chameleon {
+    static func setRingThemeUsingPrimaryColor (_ primaryColor: UIColor, withSecondaryColor secondaryColor: UIColor, andContentStyle contentStyle: UIContentStyle) {
+
+        var contentColor: UIColor
+        var secondaryContentColor: UIColor
+
+        switch contentStyle {
+        case .contrast:
+            contentColor = ContrastColorOf(primaryColor, returnFlat: false)
+            secondaryContentColor = ContrastColorOf(secondaryColor, returnFlat: false)
+            break
+        case .light:
+            contentColor = UIColor.white
+            secondaryContentColor = UIColor.white
+            break
+        case .dark:
+            contentColor = UIColor.flatBlackColorDark()
+            secondaryContentColor = UIColor.flatBlackColorDark()
+            break
+        }
+
+        UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).tintColor = UIColor.flatGray()
+
+        MessageBubble.appearance().tintColor = secondaryContentColor
+        MessageBubble.appearance().backgroundColor = secondaryColor
+
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellSent.self]).tintColor = contentColor
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellSent.self]).backgroundColor = primaryColor
+        UILabel.appearance(whenContainedInInstancesOf: [MessageBubble.self, MessageCellSent.self]).textColor = contentColor
+
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellReceived.self]).tintColor = secondaryContentColor
+        MessageBubble.appearance(whenContainedInInstancesOf: [MessageCellReceived.self]).backgroundColor = secondaryColor
+        UILabel.appearance(whenContainedInInstancesOf: [MessageBubble.self, MessageCellReceived.self]).textColor = secondaryContentColor
+    }
+}
diff --git a/Ring/Ring/Extensions/UIColor+Ring.swift b/Ring/Ring/Extensions/UIColor+Ring.swift
index 20d90c902..5d3f88917 100644
--- a/Ring/Ring/Extensions/UIColor+Ring.swift
+++ b/Ring/Ring/Extensions/UIColor+Ring.swift
@@ -23,9 +23,14 @@ import UIKit
 
 extension UIColor {
 
-    static let ringMain = UIColor(colorLiteralRed: 10.0/255.0,
-                                  green: 116.0/255.0,
-                                  blue: 137.0/255.0,
+    static let ringMain = UIColor(colorLiteralRed: 58.0/255.0,
+                                  green: 192.0/255.0,
+                                  blue: 210.0/255.0,
+                                  alpha: 1.0)
+
+    static let ringSecondary = UIColor(colorLiteralRed: 0.0/255.0,
+                                  green: 76.0/255.0,
+                                  blue: 96.0/255.0,
                                   alpha: 1.0)
 
 }
diff --git a/Ring/Ring/Info.plist b/Ring/Ring/Info.plist
index c2d681014..f46a248c3 100644
--- a/Ring/Ring/Info.plist
+++ b/Ring/Ring/Info.plist
@@ -54,6 +54,6 @@
 		<string>UIInterfaceOrientationLandscapeRight</string>
 	</array>
 	<key>UIViewControllerBasedStatusBarAppearance</key>
-	<true/>
+	<false/>
 </dict>
 </plist>
diff --git a/Ring/Ring/MainTabBar/MainTabBarViewController.swift b/Ring/Ring/MainTabBar/MainTabBarViewController.swift
index 0239ff339..db89f9dc4 100644
--- a/Ring/Ring/MainTabBar/MainTabBarViewController.swift
+++ b/Ring/Ring/MainTabBar/MainTabBarViewController.swift
@@ -25,8 +25,6 @@ class MainTabBarViewController: UITabBarController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        UITabBarItem.appearance()
-            .setTitleTextAttributes( [NSForegroundColorAttributeName: UIColor.ringMain], for: .selected)
     }
 
     override func viewDidAppear(_ animated: Bool) {
diff --git a/Ring/Ring/Messages/MessableBubble.swift b/Ring/Ring/Messages/MessableBubble.swift
new file mode 100644
index 000000000..1ce5f3849
--- /dev/null
+++ b/Ring/Ring/Messages/MessableBubble.swift
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Thibault Wittemberg <thibault.wittemberg@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
+import UIKit
+
+@IBDesignable
+class MessageBubble: UIView {
+    // just to make the UIView+Ring extension IBDesignable
+}
diff --git a/Ring/Ring/Messages/MessageCell.swift b/Ring/Ring/Messages/MessageCell.swift
deleted file mode 100644
index aeebe9a97..000000000
--- a/Ring/Ring/Messages/MessageCell.swift
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  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 Reusable
-
-enum BubblePosition {
-    case received
-    case sent
-}
-
-class MessageCell: UITableViewCell, NibReusable {
-
-    @IBOutlet weak var bubble: UIView!
-    @IBOutlet weak var messageLabel: UILabel!
-
-    @IBOutlet weak var minimumLeadingConstraint: NSLayoutConstraint!
-    @IBOutlet weak var containerLeadingConstraint: NSLayoutConstraint!
-
-    @IBOutlet weak var minimumTrailingConstraint: NSLayoutConstraint!
-    @IBOutlet weak var containerTrailingConstraint: NSLayoutConstraint!
-
-    var bubblePosition = BubblePosition.received {
-        didSet {
-            if bubblePosition == .sent {
-                self.minimumTrailingConstraint.priority = 1
-                self.containerTrailingConstraint.priority = 999
-                self.containerLeadingConstraint.priority = 1
-                self.minimumLeadingConstraint.priority = 999
-
-                self.bubble.backgroundColor = UIColor.ringMain
-                self.messageLabel.textColor = UIColor.white
-            } else {
-                self.minimumLeadingConstraint.priority = 1
-                self.containerLeadingConstraint.priority = 999
-                self.containerTrailingConstraint.priority = 1
-                self.minimumTrailingConstraint.priority = 999
-
-                self.bubble.backgroundColor = UIColor.lightGray
-                self.messageLabel.textColor = UIColor.black
-            }
-        }
-    }
-
-    override func awakeFromNib() {
-        super.awakeFromNib()
-        self.bubblePosition = .received
-    }
-
-    override func setSelected(_ selected: Bool, animated: Bool) {
-        super.setSelected(selected, animated: animated)
-    }
-}
diff --git a/Ring/Ring/Messages/MessageCellReceived.swift b/Ring/Ring/Messages/MessageCellReceived.swift
new file mode 100644
index 000000000..0b42e9a7c
--- /dev/null
+++ b/Ring/Ring/Messages/MessageCellReceived.swift
@@ -0,0 +1,29 @@
+/*
+ *  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 Reusable
+
+class MessageCellReceived: UITableViewCell, NibReusable {
+
+    @IBOutlet weak var bubble: MessageBubble!
+    @IBOutlet weak var messageLabel: UILabel!
+
+}
diff --git a/Ring/Ring/Messages/MessageCell.xib b/Ring/Ring/Messages/MessageCellReceived.xib
similarity index 89%
rename from Ring/Ring/Messages/MessageCell.xib
rename to Ring/Ring/Messages/MessageCellReceived.xib
index 65174d4a7..679b0e0e6 100644
--- a/Ring/Ring/Messages/MessageCell.xib
+++ b/Ring/Ring/Messages/MessageCellReceived.xib
@@ -11,14 +11,14 @@
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="60" id="KGk-i7-Jjw" customClass="MessageCell" customModule="Ring" customModuleProvider="target">
+        <tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" rowHeight="60" id="KGk-i7-Jjw" customClass="MessageCellReceived" customModule="Ring" customModuleProvider="target">
             <rect key="frame" x="0.0" y="0.0" width="510" height="47"/>
             <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="510" height="46.5"/>
                 <autoresizingMask key="autoresizingMask"/>
                 <subviews>
-                    <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kZJ-Ay-LTR">
+                    <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kZJ-Ay-LTR" customClass="MessageBubble" customModule="Ring" customModuleProvider="target">
                         <rect key="frame" x="16" y="8" width="152.5" height="30.5"/>
                         <subviews>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label Label Label Label " lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lyR-7c-S2k">
@@ -37,8 +37,8 @@
                             <constraint firstItem="lyR-7c-S2k" firstAttribute="top" secondItem="kZJ-Ay-LTR" secondAttribute="top" constant="4" id="ycc-WI-Jk6"/>
                         </constraints>
                         <userDefinedRuntimeAttributes>
-                            <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
-                                <integer key="value" value="5"/>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="4"/>
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </view>
@@ -54,11 +54,7 @@
             </tableViewCellContentView>
             <connections>
                 <outlet property="bubble" destination="kZJ-Ay-LTR" id="hdG-fG-L69"/>
-                <outlet property="containerLeadingConstraint" destination="nWe-5k-Qpn" id="Ahu-gW-4IY"/>
-                <outlet property="containerTrailingConstraint" destination="99Y-bR-Ioq" id="JJr-pE-UfA"/>
                 <outlet property="messageLabel" destination="lyR-7c-S2k" id="hd3-pz-Pwh"/>
-                <outlet property="minimumLeadingConstraint" destination="Eso-cy-OYs" id="jhV-mE-FMA"/>
-                <outlet property="minimumTrailingConstraint" destination="TCY-7X-mFs" id="xj3-4A-I9G"/>
             </connections>
             <point key="canvasLocation" x="-411" y="-132"/>
         </tableViewCell>
diff --git a/Ring/Ring/Messages/MessageCellSent.swift b/Ring/Ring/Messages/MessageCellSent.swift
new file mode 100644
index 000000000..336836d6f
--- /dev/null
+++ b/Ring/Ring/Messages/MessageCellSent.swift
@@ -0,0 +1,29 @@
+/*
+ *  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 Reusable
+
+class MessageCellSent: UITableViewCell, NibReusable {
+
+    @IBOutlet weak var bubble: MessageBubble!
+    @IBOutlet weak var messageLabel: UILabel!
+
+}
diff --git a/Ring/Ring/Messages/MessageCellSent.xib b/Ring/Ring/Messages/MessageCellSent.xib
new file mode 100644
index 000000000..5fe0dd295
--- /dev/null
+++ b/Ring/Ring/Messages/MessageCellSent.xib
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" 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="12089"/>
+        <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="none" indentationWidth="10" rowHeight="60" id="KGk-i7-Jjw" customClass="MessageCellSent" customModule="Ring" customModuleProvider="target">
+            <rect key="frame" x="0.0" y="0.0" width="510" height="47"/>
+            <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="510" height="46.5"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view clipsSubviews="YES" contentMode="scaleToFill" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kZJ-Ay-LTR" customClass="MessageBubble" customModule="Ring" customModuleProvider="target">
+                        <rect key="frame" x="341.5" y="8" width="152.5" height="30.5"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label Label Label Label " lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lyR-7c-S2k">
+                                <rect key="frame" x="8" y="4" width="136.5" height="22.5"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <nil key="textColor"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="30" id="1Kj-UZ-gu7"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="leading" secondItem="kZJ-Ay-LTR" secondAttribute="leading" constant="8" id="8m5-sR-xnh"/>
+                            <constraint firstAttribute="bottom" secondItem="lyR-7c-S2k" secondAttribute="bottom" constant="4" id="gwN-uX-PWd"/>
+                            <constraint firstAttribute="trailing" secondItem="lyR-7c-S2k" secondAttribute="trailing" constant="8" id="uzV-kG-oGN"/>
+                            <constraint firstItem="lyR-7c-S2k" firstAttribute="top" secondItem="kZJ-Ay-LTR" secondAttribute="top" constant="4" id="ycc-WI-Jk6"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="4"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="bottom" secondItem="kZJ-Ay-LTR" secondAttribute="bottom" constant="8" id="1QQ-bu-6Bl"/>
+                    <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" priority="1" constant="64" id="99Y-bR-Ioq"/>
+                    <constraint firstItem="kZJ-Ay-LTR" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" priority="1" constant="16" id="Eso-cy-OYs"/>
+                    <constraint firstAttribute="trailing" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" constant="16" id="TCY-7X-mFs"/>
+                    <constraint firstItem="kZJ-Ay-LTR" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="8" id="jhd-A8-c1o"/>
+                    <constraint firstItem="kZJ-Ay-LTR" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="64" id="nWe-5k-Qpn"/>
+                </constraints>
+            </tableViewCellContentView>
+            <connections>
+                <outlet property="bubble" destination="kZJ-Ay-LTR" id="hdG-fG-L69"/>
+                <outlet property="messageLabel" destination="lyR-7c-S2k" id="hd3-pz-Pwh"/>
+            </connections>
+            <point key="canvasLocation" x="-411" y="-132"/>
+        </tableViewCell>
+    </objects>
+</document>
diff --git a/Ring/Ring/Messages/MessageViewModel.swift b/Ring/Ring/Messages/MessageViewModel.swift
index 254af6c28..927daaf89 100644
--- a/Ring/Ring/Messages/MessageViewModel.swift
+++ b/Ring/Ring/Messages/MessageViewModel.swift
@@ -20,6 +20,11 @@
 
 import RxSwift
 
+enum BubblePosition {
+    case received
+    case sent
+}
+
 class MessageViewModel {
 
     fileprivate let accountService = AppDelegate.accountService
diff --git a/Ring/Ring/Resources/Main.storyboard b/Ring/Ring/Resources/Main.storyboard
index 559936750..16887270e 100644
--- a/Ring/Ring/Resources/Main.storyboard
+++ b/Ring/Ring/Resources/Main.storyboard
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qdG-Sd-QaE">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" 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>
@@ -18,29 +18,19 @@
                         <viewControllerLayoutGuide type="top" id="pI3-q9-zKr"/>
                         <viewControllerLayoutGuide type="bottom" id="37a-rZ-qQK"/>
                     </layoutGuides>
-                    <view key="view" contentMode="scaleToFill" id="5d9-Wo-lnI">
-                        <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
+                    <view key="view" contentMode="scaleToFill" misplaced="YES" id="5d9-Wo-lnI">
+                        <rect key="frame" x="0.0" y="64" width="320" height="504"/>
                         <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">
-                                <rect key="frame" x="16" y="102" width="180" height="64"/>
-                                <constraints>
-                                    <constraint firstAttribute="width" constant="180" id="CUM-z9-ubY"/>
-                                    <constraint firstAttribute="height" constant="64" id="qTZ-Qf-EMe"/>
-                                </constraints>
-                                <fontDescription key="fontDescription" type="system" pointSize="22"/>
-                                <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                                <nil key="highlightedColor"/>
-                            </label>
                             <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="PYw-q1-MgO">
-                                <rect key="frame" x="105" y="149" width="110" height="110"/>
+                                <rect key="frame" x="105" y="85" width="110" height="110"/>
                                 <constraints>
                                     <constraint firstAttribute="width" constant="110" id="JL8-2N-trX"/>
                                     <constraint firstAttribute="height" constant="110" id="sfn-3N-dGV"/>
                                 </constraints>
                             </imageView>
                             <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="w6i-WA-dDu">
-                                <rect key="frame" x="0.0" y="301" width="320" height="218"/>
+                                <rect key="frame" x="0.0" y="237" width="320" height="218"/>
                                 <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                 <constraints>
                                     <constraint firstAttribute="height" constant="218" id="1Nb-4o-17J"/>
@@ -50,7 +40,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.5"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
                                             <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 +86,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.5"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
                                             <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">
@@ -126,6 +116,16 @@
                                     <outlet property="delegate" destination="Adn-sB-m3h" id="paE-u4-bF2"/>
                                 </connections>
                             </tableView>
+                            <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="20" width="180" height="64"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="180" id="CUM-z9-ubY"/>
+                                    <constraint firstAttribute="height" constant="64" id="qTZ-Qf-EMe"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="22"/>
+                                <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
                         </subviews>
                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                         <constraints>
@@ -135,9 +135,10 @@
                             <constraint firstItem="37a-rZ-qQK" firstAttribute="top" secondItem="w6i-WA-dDu" secondAttribute="bottom" id="Kgu-hy-eYU"/>
                             <constraint firstItem="w6i-WA-dDu" firstAttribute="centerX" secondItem="PYw-q1-MgO" secondAttribute="centerX" id="NhE-xV-NPT"/>
                             <constraint firstItem="vcL-Nj-NcH" firstAttribute="leading" secondItem="5d9-Wo-lnI" secondAttribute="leadingMargin" id="k8C-mb-o4x"/>
-                            <constraint firstItem="vcL-Nj-NcH" firstAttribute="top" secondItem="pI3-q9-zKr" secondAttribute="bottom" constant="38" id="rrl-Pm-vva"/>
+                            <constraint firstItem="vcL-Nj-NcH" firstAttribute="top" secondItem="pI3-q9-zKr" secondAttribute="bottom" constant="20" id="rrl-Pm-vva"/>
                         </constraints>
                     </view>
+                    <extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
                     <tabBarItem key="tabBarItem" title="Me" id="K9k-MS-meT"/>
                     <navigationItem key="navigationItem" id="ncw-EB-hXe">
                         <barButtonItem key="rightBarButtonItem" systemItem="edit" id="UKS-Qs-jTc"/>
@@ -160,12 +161,12 @@
                         <viewControllerLayoutGuide type="top" id="4Js-Hd-F7A"/>
                         <viewControllerLayoutGuide type="bottom" id="1SM-kJ-lna"/>
                     </layoutGuides>
-                    <view key="view" contentMode="scaleToFill" id="uEm-4u-10U">
-                        <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
+                    <view key="view" contentMode="scaleToFill" misplaced="YES" id="uEm-4u-10U">
+                        <rect key="frame" x="0.0" y="64" width="320" height="504"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
                             <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Details" textAlignment="natural" lineBreakMode="clip" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.25" translatesAutoresizingMaskIntoConstraints="NO" id="fEM-NK-AEk">
-                                <rect key="frame" x="16" y="84" width="288" height="16"/>
+                                <rect key="frame" x="16" y="20" width="288" height="16"/>
                                 <fontDescription key="fontDescription" type="system" pointSize="13"/>
                                 <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                 <nil key="highlightedColor"/>
@@ -173,11 +174,12 @@
                         </subviews>
                         <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                         <constraints>
-                            <constraint firstItem="fEM-NK-AEk" firstAttribute="trailing" secondItem="uEm-4u-10U" secondAttribute="trailingMargin" id="DOV-pz-GeB"/>
-                            <constraint firstItem="fEM-NK-AEk" firstAttribute="leading" secondItem="uEm-4u-10U" secondAttribute="leadingMargin" id="L3x-kW-NoX"/>
+                            <constraint firstItem="fEM-NK-AEk" firstAttribute="trailing" secondItem="uEm-4u-10U" secondAttribute="trailingMargin" id="LjA-mF-o27"/>
+                            <constraint firstItem="fEM-NK-AEk" firstAttribute="leading" secondItem="uEm-4u-10U" secondAttribute="leadingMargin" id="XZm-Fg-mcn"/>
                             <constraint firstItem="fEM-NK-AEk" firstAttribute="top" secondItem="4Js-Hd-F7A" secondAttribute="bottom" constant="20" id="jFe-Ha-jzG"/>
                         </constraints>
                     </view>
+                    <extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
                     <navigationItem key="navigationItem" title="Details" id="Pno-a9-G1I"/>
                     <connections>
                         <outlet property="detailsLabel" destination="fEM-NK-AEk" id="nCN-kQ-UTS"/>
@@ -233,7 +235,7 @@
                         <viewControllerLayoutGuide type="top" id="s1e-Lp-B2j"/>
                         <viewControllerLayoutGuide type="bottom" id="aoH-Yk-Qrn"/>
                     </layoutGuides>
-                    <view key="view" contentMode="scaleToFill" id="khr-49-0iv">
+                    <view key="view" contentMode="scaleToFill" misplaced="YES" id="khr-49-0iv">
                         <rect key="frame" x="0.0" y="64" width="320" height="504"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <subviews>
@@ -255,7 +257,7 @@
                                 <rect key="frame" x="0.0" y="44" width="320" height="411"/>
                                 <subviews>
                                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No conversations" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tuk-H4-adP">
-                                        <rect key="frame" x="93.5" y="195" width="133" height="21"/>
+                                        <rect key="frame" x="94" y="195" width="133" height="21"/>
                                         <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                         <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
                                         <nil key="highlightedColor"/>
@@ -336,7 +338,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="8rX-Qa-Ypu" id="7vA-nx-B3h">
-                                            <rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
+                                            <rect key="frame" x="0.0" y="0.0" width="320" height="43"/>
                                             <autoresizingMask key="autoresizingMask"/>
                                         </tableViewCellContentView>
                                     </tableViewCell>
diff --git a/Ring/Ring/Resources/en.lproj/Localizable.strings b/Ring/Ring/Resources/en.lproj/Localizable.strings
index 8521f9322..268b65288 100644
--- a/Ring/Ring/Resources/en.lproj/Localizable.strings
+++ b/Ring/Ring/Resources/en.lproj/Localizable.strings
@@ -20,6 +20,7 @@
 
 // Global
 "global.homeTabBarTitle" = "Home";
+"global.meTabBarTitle" = "Me";
 "global.ok" = "Ok";
 
 // Smartlist
diff --git a/Ring/Ring/Settings/MeViewController.swift b/Ring/Ring/Settings/MeViewController.swift
index d57fdd462..8c80ae36b 100644
--- a/Ring/Ring/Settings/MeViewController.swift
+++ b/Ring/Ring/Settings/MeViewController.swift
@@ -32,6 +32,9 @@ class MeViewController: UIViewController, UITableViewDelegate, UITableViewDataSo
     override func viewDidLoad() {
         super.viewDidLoad()
 
+        self.title = L10n.Global.meTabBarTitle.smartString
+        self.navigationItem.title = L10n.Global.meTabBarTitle.smartString
+
         if !accountService.accounts.isEmpty {
             //            let acc = accountService.accounts[0]
             //            nameLabel.text = acc.displayName
-- 
GitLab