conversations: set fallback avatar's color based on known username
- Sets the conversation cells' fallback avatar colors based on
the username known when initializing. This should avoid the
color flickering except when a lookup is actually in progress.
- Uses the value of the username known at cell init to set
the fallback avatar's intitial.
- Removes the use of the fallback avatar initial in the case of
the ringId being the best name. For now, no character is shown.
Change-Id: Ib42cc1c8aa31783c77f986a6a32976fa74b48d57
diff --git a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift
index 5ab2526..088da47 100644
--- a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift
+++ b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.swift
@@ -31,6 +31,18 @@
@IBOutlet weak var discardButton: UIButton!
@IBOutlet weak var banButton: UIButton!
+ override func setSelected(_ selected: Bool, animated: Bool) {
+ let fallbackAvatarBGColor = self.fallbackAvatar.backgroundColor
+ super.setSelected(selected, animated: animated)
+ self.fallbackAvatar.backgroundColor = fallbackAvatarBGColor
+ }
+
+ override func setHighlighted(_ highlighted: Bool, animated: Bool) {
+ let fallbackAvatarBGColor = self.fallbackAvatar.backgroundColor
+ super.setSelected(highlighted, animated: animated)
+ self.fallbackAvatar.backgroundColor = fallbackAvatarBGColor
+ }
+
var disposeBag = DisposeBag()
override func prepareForReuse() {
diff --git a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib
index a9707de..dc88762 100644
--- a/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib
+++ b/Ring/Ring/Features/ContactRequests/Cells/ContactRequestCell.xib
@@ -18,7 +18,7 @@
<rect key="frame" x="0.0" y="0.0" width="470" height="71.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="R" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wjc-Nn-INi" userLabel="Fallback Avatar">
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wjc-Nn-INi" userLabel="Fallback Avatar">
<rect key="frame" x="16" y="16" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="1" green="0.5" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
diff --git a/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift b/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift
index 1a427d5..705db7f 100644
--- a/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift
+++ b/Ring/Ring/Features/ContactRequests/ContactRequestsViewController.swift
@@ -74,8 +74,23 @@
.disposed(by: cell.disposeBag)
// Avatar placeholder initial
+ cell.fallbackAvatar.text = nil
+ 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.contactRequest.ringId != name {
+ cell.fallbackAvatar.text = name.prefixString().capitalized
+ }
+ }
+
item.userName.asObservable()
.observeOn(MainScheduler.instance)
+ .filter({ [weak item] userName in
+ return userName != item?.contactRequest.ringId
+ })
.map { value in value.prefixString().capitalized }
.bind(to: cell.fallbackAvatar.rx.text)
.disposed(by: cell.disposeBag)
diff --git a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
index 3f5401a..69890f1 100644
--- a/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
+++ b/Ring/Ring/Features/Conversations/Conversation/Cells/MessageCellReceived.xib
@@ -31,7 +31,7 @@
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="R" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="F9a-6w-Efg" userLabel="Fallback Avatar">
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="F9a-6w-Efg" userLabel="Fallback Avatar">
<rect key="frame" x="16" y="4" width="32" height="32"/>
<color key="backgroundColor" red="1" green="0.5" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
index 3d5c8f1..deacaad 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewController.swift
@@ -47,7 +47,7 @@
var bottomOffset: CGFloat = 0
let scrollOffsetThreshold: CGFloat = 600
- fileprivate var backgroundColorObservable: Observable<UIColor>!
+ fileprivate var fallbackBGColorObservable: Observable<UIColor>!
override func viewDidLoad() {
super.viewDidLoad()
@@ -93,7 +93,7 @@
self.viewModel.userName.asObservable().bind(to: self.navigationItem.rx.title).disposed(by: disposeBag)
// UIColor that observes "best Id" prefix
- self.backgroundColorObservable = viewModel.userName.asObservable()
+ self.fallbackBGColorObservable = viewModel.userName.asObservable()
.observeOn(MainScheduler.instance)
.map { name in
let scanner = Scanner(string: name.toMD5HexString().prefixString())
@@ -443,20 +443,36 @@
if messageVM.sequencing == .lastOfSequence || messageVM.sequencing == .singleMessage {
cell.profileImage?.isHidden = false
+ // Set placeholder avatar
+ fallbackAvatar.text = nil
+ let name = viewModel.userName.value
+ let scanner = Scanner(string: name.toMD5HexString().prefixString())
+ var index: UInt64 = 0
+ if scanner.scanHexInt64(&index) {
+ fallbackAvatar.isHidden = false
+ fallbackAvatar.backgroundColor = avatarColors[Int(index)]
+ if viewModel.conversation.recipientRingId != name {
+ fallbackAvatar.text = name.prefixString().capitalized
+ }
+ }
+
+ // Observe in case of a lookup
+ self.fallbackBGColorObservable
+ .subscribe(onNext: { [weak fallbackAvatar] backgroundColor in
+ fallbackAvatar?.backgroundColor = backgroundColor
+ })
+ .disposed(by: cell.disposeBag)
+
// Avatar placeholder initial
viewModel.userName.asObservable()
.observeOn(MainScheduler.instance)
+ .filter({ [weak self] userName in
+ return userName != self?.viewModel.conversation.recipientRingId
+ })
.map { value in value.prefixString().capitalized }
.bind(to: fallbackAvatar.rx.text)
.disposed(by: cell.disposeBag)
- // Set placeholder avatar to backgroundColorObservable
- self.backgroundColorObservable
- .subscribe(onNext: { backgroundColor in
- fallbackAvatar.backgroundColor = backgroundColor
- })
- .disposed(by: cell.disposeBag)
-
// Set image if any
cell.profileImage?.image = nil
if let imageData = viewModel.profileImageData {
@@ -479,19 +495,13 @@
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)
- formatCell(withCell: cell, cellForRowAt: indexPath, withMessageVM: messageViewModel)
- return cell
- } else if messageViewModel.bubblePosition() == .sent {
- let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)
- formatCell(withCell: cell, cellForRowAt: indexPath, withMessageVM: messageViewModel)
- return cell
- } else if messageViewModel.bubblePosition() == .generated {
- let cell = tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellGenerated.self)
- formatCell(withCell: cell, cellForRowAt: indexPath, withMessageVM: messageViewModel)
- return cell
- }
+ let type = messageViewModel.bubblePosition() == .received ? MessageCellReceived.self :
+ messageViewModel.bubblePosition() == .sent ? MessageCellSent.self :
+ messageViewModel.bubblePosition() == .generated ? MessageCellGenerated.self :
+ MessageCellGenerated.self
+ let cell = tableView.dequeueReusableCell(for: indexPath, cellType: type)
+ formatCell(withCell: cell, cellForRowAt: indexPath, withMessageVM: messageViewModel)
+ return cell
}
return tableView.dequeueReusableCell(for: indexPath, cellType: MessageCellSent.self)
diff --git a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
index 1987d40..7db0d96 100644
--- a/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
+++ b/Ring/Ring/Features/Conversations/Conversation/ConversationViewModel.swift
@@ -112,7 +112,7 @@
.disposed(by: disposeBag)
if let contactUserName = contact?.userName {
- self.userName.onNext(contactUserName)
+ self.userName.value = contactUserName
} else {
let recipientRingId = self.conversation.recipientRingId
@@ -124,10 +124,10 @@
lookupNameResponse.address == recipientRingId
}).subscribe(onNext: { [unowned self] lookupNameResponse in
if let name = lookupNameResponse.name, !name.isEmpty {
- self.userName.onNext(name)
+ self.userName.value = name
contact?.userName = name
} else if let address = lookupNameResponse.address {
- self.userName.onNext(address)
+ self.userName.value = address
}
}).disposed(by: disposeBag)
@@ -154,7 +154,7 @@
var messages: Observable<[MessageViewModel]>!
- var userName = BehaviorSubject(value: "")
+ var userName = Variable<String>("")
var profileImageData: Data?
diff --git a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib
index 5a700a4..827912b 100644
--- a/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib
+++ b/Ring/Ring/Features/Conversations/SmartList/Cells/ConversationCell.xib
@@ -31,7 +31,7 @@
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="R" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e0z-cM-gKq" userLabel="Fallback Avatar">
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="e0z-cM-gKq" userLabel="Fallback Avatar">
<rect key="frame" x="16" y="18" width="40" height="40"/>
<color key="backgroundColor" red="1" green="0.5" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
diff --git a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
index c018734..2fd81bc 100644
--- a/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
+++ b/Ring/Ring/Features/Conversations/SmartList/SmartlistViewController.swift
@@ -152,8 +152,23 @@
.disposed(by: cell.disposeBag)
// Avatar placeholder initial
+ cell.fallbackAvatar.text = nil
+ 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.recipientRingId != name {
+ cell.fallbackAvatar.text = name.prefixString().capitalized
+ }
+ }
+
item.userName.asObservable()
.observeOn(MainScheduler.instance)
+ .filter({ [weak item] userName in
+ return userName != item?.conversation.recipientRingId
+ })
.map { value in value.prefixString().capitalized }
.bind(to: cell.fallbackAvatar.rx.text)
.disposed(by: cell.disposeBag)