avatars: add fallback avatar image

- Draws a generic person overlay in the case of a ringId being the
  only available name.

- Sets the conversation's username to the contact's ringId at
  initialization, if no registered name is available.

- Sets the presence at conversation initialization.

Change-Id: I1874b57719398acd6aa096b645f540ce3a528cf0
Reviewed-by: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
diff --git a/Ring/Ring/Constants/Generated/Images.swift b/Ring/Ring/Constants/Generated/Images.swift
index 348eefb..2647401 100644
--- a/Ring/Ring/Constants/Generated/Images.swift
+++ b/Ring/Ring/Constants/Generated/Images.swift
@@ -52,6 +52,7 @@
   static let contactRequestIcon = ImageAsset(name: "contact_request_icon")
   static let conversationIcon = ImageAsset(name: "conversation_icon")
   static let device = ImageAsset(name: "device")
+  static let fallbackAvatar = ImageAsset(name: "fallback_avatar")
   static let icContactPicture = ImageAsset(name: "ic_contact_picture")
   static let logoRingBeta2Blanc = ImageAsset(name: "logo-ring-beta2-blanc")
   static let settingsIcon = ImageAsset(name: "settings_icon")
@@ -66,6 +67,7 @@
     contactRequestIcon,
     conversationIcon,
     device,
+    fallbackAvatar,
     icContactPicture,
     logoRingBeta2Blanc,
     settingsIcon,
diff --git a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift
index 088da47..8b1be22 100644
--- a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift
+++ b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift
@@ -26,6 +26,7 @@
 
     @IBOutlet weak var fallbackAvatar: UILabel!
     @IBOutlet weak var profileImageView: UIImageView!
+    @IBOutlet weak var fallbackAvatarImage: UIImageView!
     @IBOutlet weak var nameLabel: UILabel!
     @IBOutlet weak var acceptButton: UIButton!
     @IBOutlet weak var discardButton: UIButton!
diff --git a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib
index dc88762..b7603d2 100644
--- a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib
+++ b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib
@@ -32,6 +32,13 @@
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </label>
+                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="fallback_avatar" translatesAutoresizingMaskIntoConstraints="NO" id="B6v-9R-dRD" userLabel="Fallback image">
+                        <rect key="frame" x="16" y="16" width="40" height="40"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="40" id="3ok-c3-kW9"/>
+                            <constraint firstAttribute="width" constant="40" id="PkF-FM-Zff"/>
+                        </constraints>
+                    </imageView>
                     <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xS9-Kd-lrg">
                         <rect key="frame" x="16" y="16" width="40" height="40"/>
                         <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
@@ -121,6 +128,7 @@
                 <constraints>
                     <constraint firstItem="Pni-bm-rkr" firstAttribute="top" secondItem="Dla-OF-biH" secondAttribute="bottom" constant="4" id="0jS-6Q-w8N"/>
                     <constraint firstItem="xS9-Kd-lrg" firstAttribute="centerY" secondItem="YU4-Oq-lYT" secondAttribute="centerY" id="DPx-jS-V0h"/>
+                    <constraint firstItem="B6v-9R-dRD" firstAttribute="leading" secondItem="xS9-Kd-lrg" secondAttribute="leading" id="Dcd-fF-cHv"/>
                     <constraint firstItem="feR-9F-sZM" firstAttribute="top" secondItem="Dla-OF-biH" secondAttribute="bottom" constant="4" id="Gba-vQ-Ebp"/>
                     <constraint firstAttribute="bottom" secondItem="Pni-bm-rkr" secondAttribute="bottom" constant="8" id="KNE-9A-qWk"/>
                     <constraint firstItem="fWB-HR-tae" firstAttribute="top" secondItem="Dla-OF-biH" secondAttribute="bottom" constant="4" id="QMX-zx-zpZ"/>
@@ -130,6 +138,7 @@
                     <constraint firstItem="Dla-OF-biH" firstAttribute="top" secondItem="YU4-Oq-lYT" secondAttribute="top" constant="8" id="hqf-Iv-xvb"/>
                     <constraint firstItem="fWB-HR-tae" firstAttribute="leading" secondItem="feR-9F-sZM" secondAttribute="trailing" constant="4" id="lfX-2s-AsZ"/>
                     <constraint firstItem="xS9-Kd-lrg" firstAttribute="leading" secondItem="YU4-Oq-lYT" secondAttribute="leading" constant="16" id="ogz-Qb-1Pz"/>
+                    <constraint firstItem="B6v-9R-dRD" firstAttribute="top" secondItem="xS9-Kd-lrg" secondAttribute="top" id="sCh-oV-bKL"/>
                     <constraint firstAttribute="trailing" secondItem="Pni-bm-rkr" secondAttribute="trailing" constant="8" id="sDu-vC-6gU"/>
                     <constraint firstAttribute="trailing" secondItem="Dla-OF-biH" secondAttribute="trailing" constant="8" id="wFU-JT-uD3"/>
                     <constraint firstItem="Dla-OF-biH" firstAttribute="leading" secondItem="xS9-Kd-lrg" secondAttribute="trailing" constant="8" id="zIp-sT-nb3"/>
@@ -140,10 +149,14 @@
                 <outlet property="banButton" destination="Pni-bm-rkr" id="v1p-37-zfP"/>
                 <outlet property="discardButton" destination="fWB-HR-tae" id="ZMu-NC-hE4"/>
                 <outlet property="fallbackAvatar" destination="Wjc-Nn-INi" id="vCB-ug-eic"/>
+                <outlet property="fallbackAvatarImage" destination="B6v-9R-dRD" id="XV9-ww-vFG"/>
                 <outlet property="nameLabel" destination="Dla-OF-biH" id="tO5-og-I3P"/>
                 <outlet property="profileImageView" destination="xS9-Kd-lrg" id="Rxt-j1-fem"/>
             </connections>
             <point key="canvasLocation" x="177" y="-50"/>
         </tableViewCell>
     </objects>
+    <resources>
+        <image name="fallback_avatar" width="82" height="82"/>
+    </resources>
 </document>
diff --git a/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift b/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift
index 705db7f..8c34dec 100644
--- a/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift
+++ b/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift
@@ -75,6 +75,7 @@
 
                 // 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
@@ -83,6 +84,8 @@
                     cell.fallbackAvatar.backgroundColor = avatarColors[Int(index)]
                     if item.contactRequest.ringId != name {
                         cell.fallbackAvatar.text = name.prefixString().capitalized
+                    } else {
+                        cell.fallbackAvatarImage.isHidden = false
                     }
                 }
 
@@ -95,6 +98,12 @@
                     .bind(to: cell.fallbackAvatar.rx.text)
                     .disposed(by: cell.disposeBag)
 
+                item.userName.asObservable()
+                    .observeOn(MainScheduler.instance)
+                    .map { [weak item] userName in userName != item?.contactRequest.ringId }
+                    .bind(to: cell.fallbackAvatarImage.rx.isHidden)
+                    .disposed(by: cell.disposeBag)
+
                 // UIColor that observes "best Id" prefix
                 self.backgroundColorObservable = item.userName.asObservable()
                     .observeOn(MainScheduler.instance)
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
index 3b05761..35ed2c7 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCell.swift
@@ -38,6 +38,7 @@
     @IBOutlet weak var failedStatusLabel: UILabel!
     @IBOutlet weak var profileImage: UIImageView!
     @IBOutlet weak var fallbackAvatar: UILabel!
+    @IBOutlet weak var fallbackAvatarImage: UIImageView!
 
     var disposeBag = DisposeBag()
 
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
index 69890f1..c8c8a7c 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
@@ -48,6 +48,13 @@
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </label>
+                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="fallback_avatar" translatesAutoresizingMaskIntoConstraints="NO" id="tOS-Tt-QFy" userLabel="Fallback image">
+                        <rect key="frame" x="16" y="4" width="32" height="32"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="32" id="1UM-p9-Mmj"/>
+                            <constraint firstAttribute="width" constant="32" id="BIh-38-mEs"/>
+                        </constraints>
+                    </imageView>
                     <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WBd-CS-7Qv" userLabel="Top Corner">
                         <rect key="frame" x="64" y="8" width="15" height="15"/>
                         <color key="backgroundColor" red="1" green="0.0" blue="1" alpha="1" colorSpace="calibratedRGB"/>
@@ -123,12 +130,14 @@
                     <constraint firstItem="eza-Ni-w3g" firstAttribute="leading" secondItem="mhg-uK-iD9" secondAttribute="trailing" constant="16" id="Pdf-ru-PnO"/>
                     <constraint firstItem="zuX-zz-1Qq" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" constant="16" id="QoG-Zs-Lv7"/>
                     <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="kZJ-Ay-LTR" secondAttribute="trailing" constant="64" id="TCY-7X-mFs"/>
+                    <constraint firstItem="tOS-Tt-QFy" firstAttribute="leading" secondItem="F9a-6w-Efg" secondAttribute="leading" id="WwB-B4-ZBk"/>
                     <constraint firstItem="skH-sJ-Ip9" firstAttribute="trailing" secondItem="kZJ-Ay-LTR" secondAttribute="leading" constant="-16" id="YCa-xJ-gRb"/>
                     <constraint firstItem="zuX-zz-1Qq" firstAttribute="trailing" secondItem="mhg-uK-iD9" secondAttribute="leading" constant="-16" id="aUU-d6-Dse"/>
                     <constraint firstItem="F9a-6w-Efg" firstAttribute="leading" secondItem="skH-sJ-Ip9" secondAttribute="leading" id="fx8-vF-4od"/>
                     <constraint firstItem="mhg-uK-iD9" firstAttribute="centerX" secondItem="H2p-sc-9uM" secondAttribute="centerX" id="gD0-yo-bga"/>
                     <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" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="64" id="nWe-5k-Qpn"/>
+                    <constraint firstItem="tOS-Tt-QFy" firstAttribute="top" secondItem="F9a-6w-Efg" secondAttribute="top" id="uEa-kN-oWY"/>
                     <constraint firstItem="eza-Ni-w3g" firstAttribute="centerY" secondItem="mhg-uK-iD9" secondAttribute="centerY" id="vhB-Uv-04a"/>
                     <constraint firstItem="F9a-6w-Efg" firstAttribute="bottom" secondItem="skH-sJ-Ip9" secondAttribute="bottom" id="w03-vx-kON"/>
                     <constraint firstItem="zuX-zz-1Qq" firstAttribute="centerY" secondItem="mhg-uK-iD9" secondAttribute="centerY" id="xFW-jt-00h"/>
@@ -142,6 +151,7 @@
                 <outlet property="bubbleBottomConstraint" destination="1QQ-bu-6Bl" id="a4F-pf-cXL"/>
                 <outlet property="bubbleTopConstraint" destination="jhd-A8-c1o" id="40k-2d-6rW"/>
                 <outlet property="fallbackAvatar" destination="F9a-6w-Efg" id="JGo-mt-PVe"/>
+                <outlet property="fallbackAvatarImage" destination="tOS-Tt-QFy" id="Vts-Qp-g7I"/>
                 <outlet property="leftDivider" destination="zuX-zz-1Qq" id="9Jc-cV-VTA"/>
                 <outlet property="messageLabel" destination="lyR-7c-S2k" id="hd3-pz-Pwh"/>
                 <outlet property="profileImage" destination="skH-sJ-Ip9" id="pM2-t7-YhV"/>
@@ -152,4 +162,7 @@
             <point key="canvasLocation" x="-411" y="-132.5"/>
         </tableViewCell>
     </objects>
+    <resources>
+        <image name="fallback_avatar" width="82" height="82"/>
+    </resources>
 </document>
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
index 2c65754..159b442 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
@@ -446,6 +446,7 @@
 
                 // Set placeholder avatar
                 fallbackAvatar.text = nil
+                cell.fallbackAvatarImage.isHidden = true
                 let name = viewModel.userName.value
                 let scanner = Scanner(string: name.toMD5HexString().prefixString())
                 var index: UInt64 = 0
@@ -454,6 +455,8 @@
                     fallbackAvatar.backgroundColor = avatarColors[Int(index)]
                     if viewModel.conversation.value.recipientRingId != name {
                         fallbackAvatar.text = name.prefixString().capitalized
+                    } else {
+                        cell.fallbackAvatarImage.isHidden = true
                     }
                 }
 
@@ -474,6 +477,12 @@
                     .bind(to: fallbackAvatar.rx.text)
                     .disposed(by: cell.disposeBag)
 
+                viewModel.userName.asObservable()
+                    .observeOn(MainScheduler.instance)
+                    .map { [weak self] userName in userName != self?.viewModel.conversation.value.recipientRingId }
+                    .bind(to: cell.fallbackAvatarImage.rx.isHidden)
+                    .disposed(by: cell.disposeBag)
+
                 // Set image if any
                 cell.profileImage?.image = nil
                 if let imageData = viewModel.profileImageData {
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
index e93e64b..55afadf 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
@@ -106,6 +106,12 @@
                 }).disposed(by: self.disposeBag)
 
             // subscribe to presence updates for the conversation's associated contact
+            if let contactPresence = self.presenceService.contactPresence[contactRingId] {
+                self.contactPresence.value = contactPresence
+            } else {
+                self.log.warning("Contact presence unkown for: \(contactRingId)")
+                self.contactPresence.value = false
+            }
             self.presenceService
                 .sharedResponseStream
                 .filter({ presenceUpdateEvent in
@@ -114,7 +120,7 @@
                 })
                 .subscribe(onNext: { [unowned self] presenceUpdateEvent in
                     if let uri: String = presenceUpdateEvent.getEventInput(.uri) {
-                        self.contactPresence.onNext(self.presenceService.contactPresence[uri]!)
+                        self.contactPresence.value = self.presenceService.contactPresence[uri]!
                     }
                 })
                 .disposed(by: disposeBag)
@@ -122,7 +128,7 @@
             if let contactUserName = contact?.userName {
                 self.userName.value = contactUserName
             } else {
-
+                self.userName.value = contactRingId
                 // Return an observer for the username lookup
                 self.nameService.usernameLookupStatus
                     .filter({ lookupNameResponse in
@@ -158,7 +164,7 @@
 
     var inviteButtonIsAvailable = BehaviorSubject(value: true)
 
-    var contactPresence = BehaviorSubject(value: false)
+    var contactPresence = Variable<Bool>(false)
 
     var unreadMessages: String {
        return self.unreadMessagesCount.description
diff --git a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift
index 77434e5..ead1596 100644
--- a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift
+++ b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.swift
@@ -26,6 +26,7 @@
 
     @IBOutlet weak var fallbackAvatar: UILabel!
     @IBOutlet weak var profileImage: UIImageView!
+    @IBOutlet weak var fallbackAvatarImage: UIImageView!
     @IBOutlet weak var nameLabel: UILabel!
     @IBOutlet weak var newMessagesIndicator: UIView!
     @IBOutlet weak var newMessagesLabel: UILabel!
diff --git a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib
index 827912b..2edd178 100644
--- a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib
+++ b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib
@@ -44,6 +44,13 @@
                             </userDefinedRuntimeAttribute>
                         </userDefinedRuntimeAttributes>
                     </label>
+                    <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="fallback_avatar" translatesAutoresizingMaskIntoConstraints="NO" id="Rg3-gP-VHQ" userLabel="Fallback image">
+                        <rect key="frame" x="16" y="18" width="40" height="40"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="40" id="NNq-lB-xLS"/>
+                            <constraint firstAttribute="width" constant="40" id="fdG-Ph-C6j"/>
+                        </constraints>
+                    </imageView>
                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Yesterday" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Yv-cC-LKx">
                         <rect key="frame" x="281" y="31" width="61" height="15"/>
                         <fontDescription key="fontDescription" type="boldSystem" pointSize="12"/>
@@ -120,10 +127,12 @@
                     <constraint firstItem="JTE-eF-Y5s" firstAttribute="trailing" secondItem="pFB-Jn-TNP" secondAttribute="trailing" id="MgK-cd-QXM"/>
                     <constraint firstItem="Fpi-20-ZYV" firstAttribute="trailing" secondItem="pFB-Jn-TNP" secondAttribute="trailing" id="Oav-3c-X7k"/>
                     <constraint firstAttribute="trailing" secondItem="7Yv-cC-LKx" secondAttribute="trailing" constant="16" id="UOx-Og-IuZ"/>
+                    <constraint firstItem="Rg3-gP-VHQ" firstAttribute="leading" secondItem="e0z-cM-gKq" secondAttribute="leading" id="UVw-aO-f5u"/>
                     <constraint firstItem="JTE-eF-Y5s" firstAttribute="top" secondItem="pFB-Jn-TNP" secondAttribute="top" id="W3A-IX-eXJ"/>
                     <constraint firstItem="7Yv-cC-LKx" firstAttribute="top" relation="greaterThanOrEqual" secondItem="H2p-sc-9uM" secondAttribute="top" constant="8" id="Wei-7X-4zv"/>
                     <constraint firstItem="e0z-cM-gKq" firstAttribute="bottom" secondItem="pFB-Jn-TNP" secondAttribute="bottom" id="ZEj-AJ-OZO"/>
                     <constraint firstItem="e0z-cM-gKq" firstAttribute="trailing" secondItem="JTE-eF-Y5s" secondAttribute="trailing" id="fyt-Cw-MG2"/>
+                    <constraint firstItem="Rg3-gP-VHQ" firstAttribute="top" secondItem="e0z-cM-gKq" secondAttribute="top" id="j2s-YP-du8"/>
                     <constraint firstItem="eug-ak-r49" firstAttribute="trailing" secondItem="2fJ-Wf-1e0" secondAttribute="trailing" id="mdZ-Uh-312"/>
                     <constraint firstItem="2fJ-Wf-1e0" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="8" id="omS-kb-QbN"/>
                     <constraint firstAttribute="bottom" secondItem="eug-ak-r49" secondAttribute="bottom" constant="8" id="rzH-w5-tpt"/>
@@ -135,6 +144,7 @@
             </tableViewCellContentView>
             <connections>
                 <outlet property="fallbackAvatar" destination="e0z-cM-gKq" id="fHH-qP-bx3"/>
+                <outlet property="fallbackAvatarImage" destination="Rg3-gP-VHQ" id="Dk8-rq-MdX"/>
                 <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"/>
@@ -146,4 +156,7 @@
             <point key="canvasLocation" x="70" y="-92"/>
         </tableViewCell>
     </objects>
+    <resources>
+        <image name="fallback_avatar" width="82" height="82"/>
+    </resources>
 </document>
diff --git a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
index 4cf9975..35e43cb 100644
--- a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
+++ b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
@@ -153,6 +153,7 @@
 
                 // 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
@@ -161,6 +162,8 @@
                     cell.fallbackAvatar.backgroundColor = avatarColors[Int(index)]
                     if item.conversation.value.recipientRingId != name {
                         cell.fallbackAvatar.text = name.prefixString().capitalized
+                    } else {
+                        cell.fallbackAvatarImage.isHidden = false
                     }
                 }
 
@@ -173,6 +176,12 @@
                     .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)
diff --git a/Ring/Ring/Resources/Images.xcassets/fallback_avatar.imageset/Contents.json b/Ring/Ring/Resources/Images.xcassets/fallback_avatar.imageset/Contents.json
new file mode 100644
index 0000000..768b18b
--- /dev/null
+++ b/Ring/Ring/Resources/Images.xcassets/fallback_avatar.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "default_avatar_overlay.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
diff --git a/Ring/Ring/Resources/Images.xcassets/fallback_avatar.imageset/default_avatar_overlay.png b/Ring/Ring/Resources/Images.xcassets/fallback_avatar.imageset/default_avatar_overlay.png
new file mode 100644
index 0000000..2a0e16b
--- /dev/null
+++ b/Ring/Ring/Resources/Images.xcassets/fallback_avatar.imageset/default_avatar_overlay.png
Binary files differ