Improved message selection indicators in chat.
• use SelectionIndicatorView in chat. • modify SelectionIndicatorView to allow to configure ring color. • improve legibility by using custom shade of gray for selection indicator in "not selected" state in chat when in light mode and with a wallpaper set.
This commit is contained in:
parent
b5838a1afc
commit
296aa8cc46
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user