diff --git a/Signal/ConversationView/CellViews/MessageSelectionView.swift b/Signal/ConversationView/CellViews/MessageSelectionView.swift index 2c3083e543..20769b4e2d 100644 --- a/Signal/ConversationView/CellViews/MessageSelectionView.swift +++ b/Signal/ConversationView/CellViews/MessageSelectionView.swift @@ -6,63 +6,41 @@ import SignalServiceKit import SignalUI +/// ManualLayoutView wrapper around SelectionIndicatorView. class MessageSelectionView: ManualLayoutView { - var isSelected: Bool = false { - didSet { - selectedView.isHidden = !isSelected - unselectedView.isHidden = isSelected + private let selectionIndicatorView = SelectionIndicatorView(style: .list) + + var isSelected: Bool { + get { + selectionIndicatorView.isSelected + } + set { + selectionIndicatorView.isSelected = newValue } } init() { super.init(name: "MessageSelectionView") - addSubviewToCenterOnSuperview(selectedView, size: .square(Self.circleDiameter)) - addSubviewToCenterOnSuperview(unselectedView, size: .square(Self.circleDiameter)) - - addLayoutBlock { view in - guard let selectionView = view as? MessageSelectionView else { return } - selectionView.checkmarkIcon.center = selectionView.selectedView.bounds.center - } - - selectedView.isHidden = !isSelected + addSubviewToFillSuperviewEdges(selectionIndicatorView) } static var preferredSize: CGSize { - CGSize(square: ConversationStyle.selectionViewWidth) + CGSize(square: SelectionIndicatorView.preferredSize) } - private static var circleDiameter: CGFloat { - // 22 dp as per spec - ConversationStyle.selectionViewWidth - 2 - } - - private static var emptyCheckmarkStrokeLineWidth: CGFloat { 2 } - - private lazy var checkmarkIcon: UIImageView = { - let imageView = UIImageView(image: UIImage(named: "check-compact")) - imageView.contentMode = .scaleAspectFit - imageView.tintColor = .white - return imageView - }() - - private lazy var selectedView: UIView = { - let circleView = CircleView(frame: .init(origin: .zero, size: .square(MessageSelectionView.circleDiameter))) - circleView.addSubview(checkmarkIcon) - return circleView - }() - - private lazy var unselectedView: UIView = { - let circleView = RingView() - circleView.lineWidth = MessageSelectionView.emptyCheckmarkStrokeLineWidth - return circleView - }() - func updateStyle(conversationStyle: ConversationStyle) { - AssertIsOnMainThread() - - selectedView.backgroundColor = conversationStyle.chatColorValue.asChatUIElementTintColor() - unselectedView.tintColor = UIColor.Signal.tertiaryLabel + selectionIndicatorView.fillColor = conversationStyle.chatColorValue.asChatUIElementTintColor() + // Less transparent empty circle when there's a wallpaper and we're in light theme + // to improve legibility over darker wallpapers. + if + conversationStyle.isDarkThemeEnabled == false, + conversationStyle.hasWallpaper + { + selectionIndicatorView.unselectedListIndicatorColor = UIColor(rgbHex: 0x808080, alpha: 0.5) + } else { + selectionIndicatorView.unselectedListIndicatorColor = nil // reset to default + } } } diff --git a/SignalUI/Views/SelectionIndicatorView.swift b/SignalUI/Views/SelectionIndicatorView.swift index 80036da5a4..5c028bf0ec 100644 --- a/SignalUI/Views/SelectionIndicatorView.swift +++ b/SignalUI/Views/SelectionIndicatorView.swift @@ -45,7 +45,8 @@ public class SelectionIndicatorView: UIView { // MARK: Layout - private static let preferredSize: CGFloat = 24 + // For `MessageSelectionView` to use. + public static let preferredSize: CGFloat = 24 private static let ringStrokeWidth: CGFloat = 2 @@ -114,7 +115,7 @@ public class SelectionIndicatorView: UIView { // MARK: Appearance - /// Color that fills the selection ring and is the background for checkmark image. + /// Color that fills the selection ring and is the background for checkmark image. Defaut is `UIColor.Signal.accent`. public var fillColor: UIColor = .Signal.accent { didSet { selectedView.backgroundColor = fillColor @@ -122,10 +123,10 @@ public class SelectionIndicatorView: UIView { } private var effectiveFillColor: UIColor { - isEnabled ? fillColor : .Signal.tertiaryLabel + isEnabled ? fillColor : unselectedListIndicatorColor } - /// Color for the ckeckmark image and outer ring for media-style indicators. + /// Color for the checkmark symbol and outer ring when `style` is `media`. Default is `white`. public var strokeColor: UIColor = .white { didSet { checkmarkIcon.tintColor = strokeColor @@ -135,11 +136,25 @@ public class SelectionIndicatorView: UIView { } } + private var _unselectedColor: UIColor = .Signal.tertiaryLabel + + /// Colors of the emty circle when `style` is `list`. Defaults to `UIColor.Signal.tertiaryLabel`. + public var unselectedListIndicatorColor: UIColor! { + get { _unselectedColor } + set { + owsAssertDebug(style == .list, "Invalid access") + _unselectedColor = newValue ?? .Signal.tertiaryLabel + if case .list = style { + innerRing.tintColor = unselectedListIndicatorColor + } + } + } + private lazy var innerRing: UIView = { owsAssertDebug(style == .list, "Invalid access") let ringView = RingView() ringView.lineWidth = SelectionIndicatorView.ringStrokeWidth - ringView.tintColor = .Signal.tertiaryLabel + ringView.tintColor = unselectedListIndicatorColor return ringView }()