Convert conversation list cells to use manual layout.

This commit is contained in:
Matthew Chen 2021-07-05 17:18:45 -03:00
parent 444a8ca651
commit 8704652e27
3 changed files with 88 additions and 348 deletions

View File

@ -111,7 +111,6 @@
3434AE1C22AEDE7D002EE04E /* ViewOnceMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3434AE1B22AEDE7D002EE04E /* ViewOnceMessageViewController.swift */; };
3437F63A2512835300AC1767 /* LinkedDevicesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3437F6392512835200AC1767 /* LinkedDevicesTableViewController.swift */; };
34386A51207D0C01009F5D9C /* ConversationListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34386A4D207D0C01009F5D9C /* ConversationListViewController.m */; };
34386A54207D271D009F5D9C /* NeverClearView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34386A53207D271C009F5D9C /* NeverClearView.swift */; };
343A65951FC47D5E000477A1 /* DebugUISyncMessages.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A65941FC47D5E000477A1 /* DebugUISyncMessages.m */; };
343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A65961FC4CFE6000477A1 /* ConversationScrollButton.m */; };
343D69AA260B870600F8638C /* ManualStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 343D69A9260B870600F8638C /* ManualStackView.swift */; };
@ -1141,7 +1140,6 @@
3437F6392512835200AC1767 /* LinkedDevicesTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LinkedDevicesTableViewController.swift; sourceTree = "<group>"; };
34386A4D207D0C01009F5D9C /* ConversationListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversationListViewController.m; sourceTree = "<group>"; };
34386A4F207D0C01009F5D9C /* ConversationListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversationListViewController.h; sourceTree = "<group>"; };
34386A53207D271C009F5D9C /* NeverClearView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NeverClearView.swift; sourceTree = "<group>"; };
343A65931FC47D5D000477A1 /* DebugUISyncMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUISyncMessages.h; sourceTree = "<group>"; };
343A65941FC47D5E000477A1 /* DebugUISyncMessages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUISyncMessages.m; sourceTree = "<group>"; };
343A65961FC4CFE6000477A1 /* ConversationScrollButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConversationScrollButton.m; sourceTree = "<group>"; };
@ -3454,7 +3452,6 @@
45E5A6981F61E6DD001E4A8A /* MarqueeLabel.swift */,
8829883A25B9FD6700DEE1E3 /* MockConversationView.swift */,
3236FCC32592B67B006D33B9 /* NameCollisionReviewCell.swift */,
34386A53207D271C009F5D9C /* NeverClearView.swift */,
34F308A01ECB469700BB7697 /* OWSBezierPathView.h */,
34F308A11ECB469700BB7697 /* OWSBezierPathView.m */,
459311FA1D75C948008DD4F0 /* OWSDeviceTableViewCell.h */,
@ -5513,7 +5510,6 @@
4C20B2B920CA10DE001BAC90 /* ConversationSearchViewController.swift in Sources */,
450D19131F85236600970622 /* RemoteVideoView.m in Sources */,
345772B6257E4E01001D7D44 /* CVViewStateSnapshot.swift in Sources */,
34386A54207D271D009F5D9C /* NeverClearView.swift in Sources */,
88A505F423DA16E10005C012 /* ExperienceUpgradeManager.swift in Sources */,
8811CF842295D8DA00FF6549 /* VolumeButtons.swift in Sources */,
88FBE954264B6849005F6C80 /* DonateMegaphone.swift in Sources */,

View File

@ -18,16 +18,12 @@ public class ConversationListCell: UITableViewCell {
private let snippetLabel = CVLabel()
private let dateTimeLabel = CVLabel()
private let messageStatusIconView = CVImageView()
// private let messageStatusWrapper = UIView.container()
private let typingIndicatorView = TypingIndicatorView()
// private let typingIndicatorWrapper = UIView.container()
private let muteIconView = CVImageView()
// private let muteIconWrapper = UIView.container()
private let unreadBadge = NeverClearView()
private let unreadBadge = NeverClearView(name: "unreadBadge")
private let unreadLabel = CVLabel()
// TODO:
private let outerHStack = ManualStackViewWithLayer(name: "outerHStack")
private let avatarStack = ManualStackView(name: "avatarStack")
private let vStack = ManualStackView(name: "vStack")
@ -36,8 +32,6 @@ public class ConversationListCell: UITableViewCell {
// The "Wrapper" shows either "snippet label" or "typing indicator".
private let bottomRowWrapper = ManualLayoutView(name: "bottomRowWrapper")
// private var heightConstraint: NSLayoutConstraint?
private var cvviews: [CVView] {
[
avatarView,
@ -101,7 +95,7 @@ public class ConversationListCell: UITableViewCell {
}
private var dateTimeFont: UIFont {
UIFont.ows_dynamicTypeCaption1Clamped
.ows_dynamicTypeCaption1Clamped
}
private var snippetFont: UIFont {
@ -124,8 +118,6 @@ public class ConversationListCell: UITableViewCell {
// This value is now larger than AvatarBuilder.standardAvatarSizePoints.
private static let avatarSize: UInt = 56
// private let avatarHSpacing: CGFloat = 12
// MARK: -
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
@ -141,111 +133,12 @@ public class ConversationListCell: UITableViewCell {
private func commonInit() {
self.backgroundColor = Theme.backgroundColor
// TODO:
self.preservesSuperviewLayoutMargins = false
self.contentView.preservesSuperviewLayoutMargins = false
// self.preservesSuperviewLayoutMargins = true
// self.contentView.preservesSuperviewLayoutMargins = true
contentView.addSubview(outerHStack)
// outerHStack.autoPinWidthToSuperviewMargins()
// outerHStack.autoPinEdge(toSuperviewEdge: .leading, withInset: 16)
outerHStack.shouldDeactivateConstraints = false
outerHStack.autoPinEdge(toSuperviewEdge: .leading)
// outerHStack.autoPinLeadingToSuperviewMargin()
outerHStack.autoPinTrailingToSuperviewMargin()
outerHStack.autoPinHeightToSuperview()
// TODO:
// contentView.addSubview(avatarView)
// avatarView.autoPinEdge(toSuperviewEdge: .leading, withInset: 16)
// avatarView.autoVCenterInSuperview()
// // Ensure that the cell's contents never overflow the cell bounds.
// avatarView.autoPinEdge(toSuperviewEdge: .top, withInset: 12, relation: .greaterThanOrEqual)
// avatarView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 12, relation: .greaterThanOrEqual)
// nameLabel.setContentHuggingHorizontalLow()
// dateTimeLabel.setContentHuggingHorizontalHigh()
// dateTimeLabel.setCompressionResistanceHorizontalHigh()
// typingIndicatorWrapper.setContentHuggingHorizontalHigh()
// typingIndicatorWrapper.setCompressionResistanceHorizontalHigh()
//
// messageStatusWrapper.setContentHuggingHorizontalHigh()
// messageStatusWrapper.setCompressionResistanceHorizontalHigh()
//
// muteIconWrapper.setContentHuggingHorizontalHigh()
// muteIconWrapper.setCompressionResistanceHorizontalHigh()
// muteIconView.setContentHuggingHorizontalHigh()
// muteIconView.setCompressionResistanceHorizontalHigh()
// muteIconWrapper.addSubview(muteIconView)
// muteIconView.autoPinEdgesToSuperviewEdges(withInsets: UIEdgeInsets(top: 0, leading: 0, bottom: 2, trailing: 0))
// let topRowSpacer = UIView.hStretchingSpacer()
//
// let topRowView = UIStackView(arrangedSubviews: [
// nameLabel,
// muteIconWrapper,
// topRowSpacer,
// dateTimeLabel
// ])
// topRowView.axis = .horizontal
// topRowView.alignment = .lastBaseline
// topRowView.spacing = 6
// snippetLabel.setContentHuggingHorizontalLow()
// snippetLabel.setCompressionResistanceHorizontalLow()
// let bottomRowView = UIStackView(arrangedSubviews: [
// typingIndicatorWrapper,
// snippetLabel,
// messageStatusWrapper
// ])
// bottomRowView.axis = .horizontal
// bottomRowView.alignment = .top
// bottomRowView.spacing = 6
// let vStackView = UIStackView(arrangedSubviews: [ topRowView, bottomRowView ])
// vStackView.axis = .vertical
// vStackView.spacing = 1
//
// contentView.addSubview(vStackView)
// vStackView.autoPinLeading(toTrailingEdgeOf: avatarView, offset: avatarHSpacing)
// vStackView.autoVCenterInSuperview()
// // Ensure that the cell's contents never overflow the cell bounds.
// vStackView.autoPinEdge(toSuperviewEdge: .top, withInset: 7, relation: .greaterThanOrEqual)
// vStackView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 9, relation: .greaterThanOrEqual)
// vStackView.autoPinTrailingToSuperviewMargin()
// vStackView.isUserInteractionEnabled = false
// messageStatusIconView.setContentHuggingHorizontalHigh()
// messageStatusIconView.setCompressionResistanceHorizontalHigh()
//// messageStatusWrapper.addSubview(messageStatusIconView)
// messageStatusIconView.autoPinWidthToSuperview()
// messageStatusIconView.autoVCenterInSuperview()
// unreadLabel.setContentHuggingHigh()
// unreadLabel.setCompressionResistanceHigh()
// TODO:
// unreadBadge.backgroundColor = .ows_accentBlue
// unreadBadge.addSubview(unreadLabel)
// unreadLabel.autoCenterInSuperview()
// unreadBadge.setContentHuggingHigh()
// unreadBadge.setCompressionResistanceHigh()
// contentView.addSubview(unreadBadge)
// typingIndicatorView.setContentHuggingHorizontalHigh()
// typingIndicatorView.setCompressionResistanceHorizontalHigh()
//// typingIndicatorWrapper.addSubview(typingIndicatorView)
// typingIndicatorView.autoPinWidthToSuperview()
// typingIndicatorView.autoVCenterInSuperview()
// TODO: ?
self.selectionStyle = .default
}
@ -258,39 +151,22 @@ public class ConversationListCell: UITableViewCell {
self.preservesSuperviewLayoutMargins = false
self.contentView.preservesSuperviewLayoutMargins = false
muteIconView.setTemplateImageName("bell-disabled-outline-24",
tintColor: Theme.primaryTextColor)
snippetLabel.numberOfLines = 2
snippetLabel.lineBreakMode = .byWordWrapping
unreadLabel.textColor = .ows_white
unreadLabel.lineBreakMode = .byTruncatingTail
unreadLabel.textAlignment = .center
self.configuration = configuration
// if true {
// outerHStack.backgroundColor = .orange
// outerHStack.addRedBorder()
//
// let fakeSize: CGFloat = 300
// let outerHStackConfig = self.outerHStackConfig
// let outerHStackSize = outerHStack.configure(config: outerHStackConfig,
// subviews: [ UIView() ],
// subviewInfos: [
// CGSize(width: 1, height: fakeSize).asManualSubviewInfo
// ]).measuredSize
//
// owsAssertDebug(heightConstraint == nil)
// let heightConstraint = outerHStack.autoSetDimension(.height, toSize: fakeSize)
// self.heightConstraint = heightConstraint
// heightConstraint.autoInstall()
//
//// Logger.verbose("outerHStackSize.height: \(outerHStackSize.height)")
//
// return
// }
let thread = configuration.thread
let tableWidth = configuration.tableWidth
let isBlocked = configuration.isBlocked
let topRowStackConfig = self.topRowStackConfig
let bottomRowStackConfig = self.bottomRowStackConfig
let vStackConfig = self.vStackConfig
let outerHStackConfig = self.outerHStackConfig
guard tableWidth > 0 else {
return
}
snippetLabel.numberOfLines = 2
snippetLabel.lineBreakMode = .byWordWrapping
avatarView.shouldLoadAsync = configuration.shouldLoadAvatarAsync
avatarView.configureWithSneakyTransaction(thread: thread.threadRecord)
@ -306,8 +182,6 @@ public class ConversationListCell: UITableViewCell {
name: TypingIndicatorsImpl.typingIndicatorStateDidChange,
object: nil)
// updateNameLabel()
// We update the fonts every time this cell is configured to ensure that
// changes to the dynamic type settings are reflected.
snippetLabel.font = snippetFont
@ -315,142 +189,11 @@ public class ConversationListCell: UITableViewCell {
let snippetLineHeight = CGFloat(ceil(1.1 * snippetFont.ows_semibold.lineHeight))
let muteIconSize: CGFloat = 16
// viewConstraints.append(contentsOf: [
// muteIconView.autoSetDimension(.width, toSize: muteIconSize),
// muteIconView.autoSetDimension(.height, toSize: muteIconSize),
//
// // These views should align with the first (of two) of the snippet,
// // so their a v-center within wrappers with the height of a single
// // snippet line.
// messageStatusWrapper.autoSetDimension(.height, toSize: snippetLineHeight),
// typingIndicatorWrapper.autoSetDimension(.height, toSize: snippetLineHeight)
// ])
updatePreview()
// if let labelDate = configuration.overrideDate ?? thread.conversationListInfo?.lastMessageDate {
// dateTimeLabel.text = DateUtil.formatDateShort(labelDate)
// } else {
// dateTimeLabel.text = nil
// }
//
// if hasUnreadStyle {
// dateTimeLabel.font = dateTimeFont.ows_semibold
// dateTimeLabel.textColor = Theme.primaryTextColor
// } else {
// dateTimeLabel.font = dateTimeFont
// dateTimeLabel.textColor = snippetColor
// }
var shouldHideStatusIndicator = false
// TODO:
if hasOverrideSnippet {
// If we're using the conversation list cell to render search results,
// don't show "unread badge" or "message status" indicator.
unreadBadge.isHidden = true
shouldHideStatusIndicator = true
} else if hasUnreadStyle {
// If there are unread messages, show the "unread badge."
unreadBadge.isHidden = false
let unreadCount = thread.unreadCount
if unreadCount > 0 {
unreadLabel.text = OWSFormat.formatUInt(unreadCount)
} else {
unreadLabel.text = nil
}
unreadLabel.font = unreadFont
let unreadBadgeHeight = ceil(unreadLabel.font.lineHeight * 1.5)
unreadBadge.layer.cornerRadius = unreadBadgeHeight / 2
unreadBadge.layer.borderColor = Theme.backgroundColor.cgColor
unreadBadge.layer.borderWidth = 2
// NSLayoutConstraint.autoSetPriority(.defaultHigh) {
// // This is a bit arbitrary, but it should scale with the size of dynamic text
// let minMargin = CeilEven(unreadBadgeHeight * 0.5)
//
//// viewConstraints.append(contentsOf: [
//// // badge sizing
//// unreadBadge.autoMatch(.width, to: .width, of: unreadLabel, withOffset: minMargin, relation: .greaterThanOrEqual),
//// unreadBadge.autoSetDimension(.width, toSize: unreadBadgeHeight, relation: .greaterThanOrEqual),
//// unreadBadge.autoSetDimension(.height, toSize: unreadBadgeHeight),
//// unreadBadge.autoPinEdge(.trailing, to: .trailing, of: avatarView, withOffset: 6),
//// unreadBadge.autoPinEdge(.top, to: .top, of: avatarView)
//// ])
// }
} else {
unreadBadge.isHidden = true
}
// if !shouldHideStatusIndicator,
// let outgoingMessage = thread.lastMessageForInbox as? TSOutgoingMessage {
// var statusIndicatorImage: UIImage?
// var messageStatusViewTintColor = snippetColor
// var shouldAnimateStatusIcon = false
//
// let messageStatus =
// MessageRecipientStatusUtils.recipientStatus(outgoingMessage: outgoingMessage)
// switch messageStatus {
// case .uploading, .sending:
// statusIndicatorImage = UIImage(named: "message_status_sending")
// shouldAnimateStatusIcon = true
// case .sent, .skipped:
// statusIndicatorImage = UIImage(named: "message_status_sent")
// shouldHideStatusIndicator = outgoingMessage.wasRemotelyDeleted
// case .delivered:
// statusIndicatorImage = UIImage(named: "message_status_delivered")
// shouldHideStatusIndicator = outgoingMessage.wasRemotelyDeleted
// case .read, .viewed:
// statusIndicatorImage = UIImage(named: "message_status_read")
// shouldHideStatusIndicator = outgoingMessage.wasRemotelyDeleted
// case .failed:
// statusIndicatorImage = UIImage(named: "error-outline-12")
// messageStatusViewTintColor = .ows_accentRed
// case .pending:
// statusIndicatorImage = UIImage(named: "error-outline-12")
// messageStatusViewTintColor = .ows_gray60
// }
//
// messageStatusIconView.image = statusIndicatorImage?.withRenderingMode(.alwaysTemplate)
// messageStatusIconView.tintColor = messageStatusViewTintColor
// messageStatusWrapper.isHidden = shouldHideStatusIndicator || statusIndicatorImage == nil
// if shouldAnimateStatusIcon {
// let animation = CABasicAnimation(keyPath: "transform.rotation.z")
// animation.toValue = NSNumber(value: Double.pi * 2)
// animation.duration = kSecondInterval * 1
// animation.isCumulative = true
// animation.repeatCount = .greatestFiniteMagnitude
// messageStatusIconView.layer.add(animation, forKey: "animation")
// } else {
// messageStatusIconView.layer.removeAllAnimations()
// }
// } else {
// messageStatusWrapper.isHidden = true
// }
// MARK: -
// let thread = configuration.thread
let tableWidth = configuration.tableWidth
let isBlocked = configuration.isBlocked
let topRowStackConfig = self.topRowStackConfig
let bottomRowStackConfig = self.bottomRowStackConfig
let vStackConfig = self.vStackConfig
let outerHStackConfig = self.outerHStackConfig
guard tableWidth > 0 else {
return
}
// Avatar
let avatarSize: CGSize = .square(CGFloat(ConversationListCell.avatarSize))
// let avatarStackConfig = ManualStackView.Config(axis: .horizontal,
// alignment: .center,
// spacing: 0,
// layoutMargins: UIEdgeInsets(hMargin: 0, vMargin: 12))
let avatarStackSize = avatarStack.configure(config: ManualStackView.Config(axis: .horizontal,
alignment: .center,
spacing: 0,
@ -458,6 +201,63 @@ public class ConversationListCell: UITableViewCell {
subviews: [ avatarView ],
subviewInfos: [ avatarSize.asManualSubviewInfo(hasFixedSize: true) ]).measuredSize
// Unread Indicator
// If there are unread messages, show the "unread badge."
var shouldHideStatusIndicator = false
func applyUnreadIndicator() {
// TODO:
guard !hasOverrideSnippet else {
// If we're using the conversation list cell to render search results,
// don't show "unread badge" or "message status" indicator.
shouldHideStatusIndicator = true
return
}
guard hasUnreadStyle else {
return
}
let unreadCount = thread.unreadCount
guard unreadCount > 0 else {
return
}
let unreadLabel = self.unreadLabel
unreadLabel.text = OWSFormat.formatUInt(unreadCount)
unreadLabel.textColor = .ows_white
unreadLabel.lineBreakMode = .byTruncatingTail
unreadLabel.textAlignment = .center
unreadLabel.font = unreadFont
unreadLabel.removeFromSuperview()
// TODO: Use CVText?
let unreadLabelSize = unreadLabel.sizeThatFits(.square(.greatestFiniteMagnitude))
let unreadBadge = self.unreadBadge
unreadBadge.backgroundColor = .ows_accentBlue
unreadBadge.addSubview(unreadLabel) { view in
// Center within badge.
unreadLabel.frame = CGRect(origin: (view.frame.size - unreadLabelSize).asPoint * 0.5,
size: unreadLabelSize)
}
unreadLabel.autoCenterInSuperview()
let unreadBadgeHeight = ceil(unreadLabel.font.lineHeight * 1.5)
unreadBadge.layer.cornerRadius = unreadBadgeHeight / 2
unreadBadge.layer.borderColor = Theme.backgroundColor.cgColor
unreadBadge.layer.borderWidth = 2
// This is a bit arbitrary, but it should scale with the size of dynamic text
let minMargin = CeilEven(unreadBadgeHeight * 0.5)
// Pill should be at least circular; can be wider.
let unreadBadgeSize = CGSize(width: max(unreadBadgeHeight,
unreadLabelSize.width + minMargin),
height: unreadBadgeHeight)
avatarStack.addSubview(unreadBadge) { view in
unreadBadge.frame = CGRect(origin: CGPoint(x: view.width - unreadBadgeSize.width + 6,
y: (view.height - avatarSize.height) * 0.5),
size: unreadBadgeSize)
}
}
applyUnreadIndicator()
let dateTimeLabelConfig: CVLabelConfig = {
var text: String = ""
if let labelDate = configuration.overrideDate ?? thread.conversationListInfo?.lastMessageDate {
@ -527,8 +327,11 @@ public class ConversationListCell: UITableViewCell {
let topRowStackSubviews: [UIView]
let topRowStackSubviewInfos: [ManualStackSubviewInfo]
if shouldShowMuteIndicator(forThread: thread, isBlocked: isBlocked) {
muteIconView.setTemplateImageName("bell-disabled-outline-24",
tintColor: Theme.primaryTextColor)
muteIconView.tintColor = snippetColor
let muteIconSize: CGFloat = 16
nameLabelMaxWidth -= muteIconSize + topRowStackConfig.spacing
let nameLabelSize = CVText.measureLabel(config: nameLabelConfig,
maxWidth: CGFloat.greatestFiniteMagnitude)
@ -605,10 +408,6 @@ public class ConversationListCell: UITableViewCell {
avatarStackSize.asManualSubviewInfo(hasFixedWidth: true),
vStackSize.asManualSubviewInfo
]).measuredSize
// owsAssertDebug(heightConstraint == nil)
// let heightConstraint = outerHStack.autoSetDimension(.height, toSize: outerHStackSize.height)
// self.heightConstraint = heightConstraint
// heightConstraint.autoInstall()
Logger.verbose("outerHStackSize.height: \(outerHStackSize.height)")
@ -712,19 +511,6 @@ public class ConversationListCell: UITableViewCell {
return StatusIndicator(view: messageStatusIconView, size: image.size)
}
// private static func configureStack(_ stack: ManualStackView,
// config: ManualStackView.Config,
// subviews: [UIView],
// subviewInfos: [ManualStackSubviewInfo]) {
// stack.configure(config: config, subviews: subviews, subviewInfos: subviewInfos)
//// let measurementBuilder = CVCellMeasurement.Builder()
//// let linkPreviewSize = Self.measure(maxWidth: maxWidth,
//// measurementBuilder: measurementBuilder,
//// state: state,
//// isDraft: isDraft)
//// let cellMeasurement = measurementBuilder.build()
// }
private var hasUnreadStyle: Bool {
guard let thread = thread else {
return false
@ -850,14 +636,10 @@ public class ConversationListCell: UITableViewCell {
}
configuration = nil
// messageStatusWrapper.isHidden = false
avatarView.image = nil
avatarView.reset()
typingIndicatorView.reset()
// heightConstraint?.autoRemove()
// heightConstraint = nil
NotificationCenter.default.removeObserver(self)
}
@ -890,35 +672,6 @@ public class ConversationListCell: UITableViewCell {
updatePreview()
}
// private func updateNameLabel() {
// AssertIsOnMainThread()
//
// nameLabel.font = nameFont
// nameLabel.textColor = Theme.primaryTextColor
//
// guard let thread = self.thread else {
// owsFailDebug("Missing thread.")
// nameLabel.attributedText = nil
// return
// }
//
// nameLabel.text = {
// if thread.threadRecord is TSContactThread {
// if thread.threadRecord.isNoteToSelf {
// return MessageStrings.noteToSelf
// } else {
// return thread.name
// }
// } else {
// if let name = thread.name.nilIfEmpty {
// return name
// } else {
// return MessageStrings.newGroupDefaultTitle
// }
// }
// }()
// }
// MARK: - Typing Indicators
private var shouldShowTypingIndicators: Bool {
@ -975,9 +728,18 @@ public class ConversationListCell: UITableViewCell {
typingIndicatorView.stopAnimation()
}
// TODO:
// muteIconWrapper.isHidden = !shouldShowMuteIndicator(forThread: configuration.thread,
// isBlocked: configuration.isBlocked)
muteIconView.tintColor = snippetColor
}
}
// MARK: -
class NeverClearView: ManualLayoutViewWithLayer {
override var backgroundColor: UIColor? {
didSet {
if backgroundColor?.cgColor.alpha == 0 {
backgroundColor = oldValue
}
}
}
}

View File

@ -1,18 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
// This view can be used to safely fill a region of a table
// or collection view cell. These cells change the background
// colors of their subviews when selected. This can inadvertently
// change the color of filled subviews. This view will
// reject a new background once its background has been set.
@objc class NeverClearView: UIView {
override var backgroundColor: UIColor? {
didSet {
if backgroundColor?.cgColor.alpha == 0 {
backgroundColor = oldValue
}
}
}
}