smartlist: move cell logic into ConversationCell

- moves cell initialization logic from SmartListViewController to
  ConversationCell
- initializes cells' avatars resulting in less flicker

Change-Id: I4cacd90f4f37d5c8f26e10be0191facaece6dc73
Reviewed-by: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
diff --git a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift
index ead1596..f7589ac 100644
--- a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift
+++ b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift
@@ -59,4 +59,92 @@
     override func prepareForReuse() {
         self.disposeBag = DisposeBag()
     }
+
+    func configureFromItem(_ item: ConversationSection.Item) {
+        item.userName.asObservable()
+            .observeOn(MainScheduler.instance)
+            .bind(to: self.nameLabel.rx.text)
+            .disposed(by: self.disposeBag)
+
+        // Avatar placeholder initial
+        self.fallbackAvatar.text = nil
+        self.fallbackAvatarImage.isHidden = true
+        let name = item.userName.value
+        let scanner = Scanner(string: name.toMD5HexString().prefixString())
+        var index: UInt64 = 0
+        if scanner.scanHexInt64(&index) {
+            self.fallbackAvatar.isHidden = false
+            self.fallbackAvatar.backgroundColor = avatarColors[Int(index)]
+            if item.conversation.value.recipientRingId != name {
+                self.fallbackAvatar.text = name.prefixString().capitalized
+            } else {
+                self.fallbackAvatarImage.isHidden = false
+            }
+        }
+
+        item.userName.asObservable()
+            .observeOn(MainScheduler.instance)
+            .filter({ [weak item] userName in
+                return userName != item?.conversation.value.recipientRingId
+            })
+            .map { value in value.prefixString().capitalized }
+            .bind(to: self.fallbackAvatar.rx.text)
+            .disposed(by: self.disposeBag)
+
+        item.userName.asObservable()
+            .observeOn(MainScheduler.instance)
+            .map { [weak item] userName in userName != item?.conversation.value.recipientRingId }
+            .bind(to: self.fallbackAvatarImage.rx.isHidden)
+            .disposed(by: self.disposeBag)
+
+        // UIColor that observes "best Id" prefix
+        item.userName.asObservable()
+            .observeOn(MainScheduler.instance)
+            .map { name in
+                let scanner = Scanner(string: name.toMD5HexString().prefixString())
+                var index: UInt64 = 0
+                if scanner.scanHexInt64(&index) {
+                    return avatarColors[Int(index)]
+                }
+                return defaultAvatarColor
+            }
+            .subscribe(onNext: { backgroundColor in
+                self.fallbackAvatar.backgroundColor = backgroundColor
+            })
+            .disposed(by: self.disposeBag)
+
+        // Set image if any
+        if let imageData = item.profileImageData.value {
+            if let image = UIImage(data: imageData) {
+                self.profileImage.image = image
+                self.fallbackAvatar.isHidden = true
+            }
+        } else {
+            self.fallbackAvatar.isHidden = false
+            self.profileImage.image = nil
+        }
+
+        item.profileImageData.asObservable()
+            .observeOn(MainScheduler.instance)
+            .subscribe(onNext: { data in
+                if let imageData = data, let image = UIImage(data: imageData) {
+                    self.fallbackAvatar.isHidden = true
+                    self.profileImage.image = image
+                } else {
+                    self.fallbackAvatar.isHidden = false
+                    self.profileImage.image = nil
+                }
+            }).disposed(by: self.disposeBag)
+
+        self.newMessagesLabel.text = item.unreadMessages
+        self.lastMessageDateLabel.text = item.lastMessageReceivedDate
+        self.newMessagesIndicator.isHidden = item.hideNewMessagesLabel
+        self.lastMessagePreviewLabel.text = item.lastMessage
+
+        item.contactPresence.asObservable()
+            .observeOn(MainScheduler.instance)
+            .map { value in !value }
+            .bind(to: self.presenceIndicator.rx.isHidden)
+            .disposed(by: self.disposeBag)
+    }
 }
diff --git a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
index 2e4d4bf..4b02401 100644
--- a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
+++ b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
@@ -53,8 +53,6 @@
     var viewModel: SmartlistViewModel!
     fileprivate let disposeBag = DisposeBag()
 
-    fileprivate var backgroundColorObservable: Observable<UIColor>!
-
     // MARK: functions
     override func viewDidLoad() {
         super.viewDidLoad()
@@ -140,101 +138,16 @@
     }
 
     func setupDataSources() {
-
         //Configure cells closure for the datasources
         let configureCell: (TableViewSectionedDataSource, UITableView, IndexPath, ConversationSection.Item)
             -> UITableViewCell = {
                 (   dataSource: TableViewSectionedDataSource<ConversationSection>,
                     tableView: UITableView,
                     indexPath: IndexPath,
-                    item: ConversationSection.Item) in
+                    conversationItem: ConversationSection.Item) in
 
                 let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ConversationCell.self)
-
-                item.userName.asObservable()
-                    .observeOn(MainScheduler.instance)
-                    .bind(to: cell.nameLabel.rx.text)
-                    .disposed(by: cell.disposeBag)
-
-                // Avatar placeholder initial
-                cell.fallbackAvatar.text = nil
-                cell.fallbackAvatarImage.isHidden = true
-                let name = item.userName.value
-                let scanner = Scanner(string: name.toMD5HexString().prefixString())
-                var index: UInt64 = 0
-                if scanner.scanHexInt64(&index) {
-                    cell.fallbackAvatar.isHidden = false
-                    cell.fallbackAvatar.backgroundColor = avatarColors[Int(index)]
-                    if item.conversation.value.recipientRingId != name {
-                        cell.fallbackAvatar.text = name.prefixString().capitalized
-                    } else {
-                        cell.fallbackAvatarImage.isHidden = false
-                    }
-                }
-
-                item.userName.asObservable()
-                    .observeOn(MainScheduler.instance)
-                    .filter({ [weak item] userName in
-                        return userName != item?.conversation.value.recipientRingId
-                    })
-                    .map { value in value.prefixString().capitalized }
-                    .bind(to: cell.fallbackAvatar.rx.text)
-                    .disposed(by: cell.disposeBag)
-
-                item.userName.asObservable()
-                    .observeOn(MainScheduler.instance)
-                    .map { [weak item] userName in userName != item?.conversation.value.recipientRingId }
-                    .bind(to: cell.fallbackAvatarImage.rx.isHidden)
-                    .disposed(by: cell.disposeBag)
-
-                // UIColor that observes "best Id" prefix
-                self.backgroundColorObservable = item.userName.asObservable()
-                    .observeOn(MainScheduler.instance)
-                    .map { name in
-                        let scanner = Scanner(string: name.toMD5HexString().prefixString())
-                        var index: UInt64 = 0
-                        if scanner.scanHexInt64(&index) {
-                            return avatarColors[Int(index)]
-                        }
-                        return defaultAvatarColor
-                    }
-
-                // Set placeholder avatar to backgroundColorObservable
-                self.backgroundColorObservable
-                    .subscribe(onNext: { backgroundColor in
-                        cell.fallbackAvatar.backgroundColor = backgroundColor
-                    })
-                    .disposed(by: cell.disposeBag)
-
-                // Set image if any
-                cell.fallbackAvatar.isHidden = false
-                cell.profileImage.image = nil
-
-                item.profileImageData.asObservable()
-                    .observeOn(MainScheduler.instance)
-                    .subscribe(onNext: { data in
-                        if let imageData = data {
-                            if let image = UIImage(data: imageData) {
-                                cell.profileImage.image = image
-                                cell.fallbackAvatar.isHidden = true
-                            }
-                        } else {
-                            cell.fallbackAvatar.isHidden = false
-                            cell.profileImage.image = nil
-                        }
-                    }).disposed(by: cell.disposeBag)
-
-                cell.newMessagesLabel.text = item.unreadMessages
-                cell.lastMessageDateLabel.text = item.lastMessageReceivedDate
-                cell.newMessagesIndicator.isHidden = item.hideNewMessagesLabel
-                cell.lastMessagePreviewLabel.text = item.lastMessage
-
-                item.contactPresence.asObservable()
-                    .observeOn(MainScheduler.instance)
-                    .map { value in !value }
-                    .bind(to: cell.presenceIndicator.rx.isHidden)
-                    .disposed(by: cell.disposeBag)
-
+                cell.configureFromItem(conversationItem)
                 return cell
         }