Commit 768e8b7a authored by Andreas Traczyk's avatar Andreas Traczyk

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
parent 3797064a
......@@ -31,6 +31,18 @@ class ContactRequestCell: UITableViewCell, NibReusable {
@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() {
......
......@@ -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"/>
......
......@@ -74,8 +74,23 @@ class ContactRequestsViewController: UIViewController, StoryboardBased, ViewMode
.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)
......
......@@ -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>
......
......@@ -47,7 +47,7 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
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 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
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 @@ class ConversationViewController: UIViewController, UITextFieldDelegate, Storybo
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 @@ extension ConversationViewController: UITableViewDataSource {
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)
......
......@@ -112,7 +112,7 @@ class ConversationViewModel: ViewModel {
.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 @@ class ConversationViewModel: ViewModel {
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 @@ class ConversationViewModel: ViewModel {
var messages: Observable<[MessageViewModel]>!
var userName = BehaviorSubject(value: "")
var userName = Variable<String>("")
var profileImageData: Data?
......
......@@ -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"/>
......
......@@ -152,8 +152,23 @@ class SmartlistViewController: UIViewController, StoryboardBased, ViewModelBased
.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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment