Replace ConversationColors with "avatar colors".

This commit is contained in:
Matthew Chen 2021-05-18 14:08:06 -03:00
parent 281d835899
commit 8c0196077f
26 changed files with 116 additions and 885 deletions

View File

@ -186,9 +186,7 @@
34684DB125C2228D00C5A93C /* indeterminate_spinner_blue.json in Resources */ = {isa = PBXBuildFile; fileRef = 34684DAD25C2228D00C5A93C /* indeterminate_spinner_blue.json */; };
34684DB225C2228D00C5A93C /* indeterminate_spinner_white.json in Resources */ = {isa = PBXBuildFile; fileRef = 34684DAE25C2228D00C5A93C /* indeterminate_spinner_white.json */; };
346941A1215D2EE400B5BFAD /* Theme.h in Headers */ = {isa = PBXBuildFile; fileRef = 3469419D215D2EE400B5BFAD /* Theme.h */; settings = {ATTRIBUTES = (Public, ); }; };
346941A2215D2EE400B5BFAD /* OWSConversationColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3469419E215D2EE400B5BFAD /* OWSConversationColor.m */; };
346941A3215D2EE400B5BFAD /* Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 3469419F215D2EE400B5BFAD /* Theme.m */; };
346941A4215D2EE400B5BFAD /* OWSConversationColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 346941A0215D2EE400B5BFAD /* OWSConversationColor.h */; settings = {ATTRIBUTES = (Public, ); }; };
346B4A772369BFC600B56007 /* PermissiveGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346B4A762369BFC600B56007 /* PermissiveGestureRecognizer.swift */; };
346B66311F4E29B200E5122F /* CropScaleImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346B66301F4E29B200E5122F /* CropScaleImageViewController.swift */; };
346C19DF25ACDF0B00061D3A /* DataSettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346C19DE25ACDF0B00061D3A /* DataSettingsTableViewController.swift */; };
@ -599,7 +597,6 @@
4C10B1BC23176D250099396B /* test-mp3.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 34C6B0A71FA0E46F00D35993 /* test-mp3.mp3 */; };
4C10B1C723176DD60099396B /* SDSPerformanceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C10B1C623176DD60099396B /* SDSPerformanceTest.swift */; };
4C10B1C9231778880099396B /* PerformanceBaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C10B1C8231778880099396B /* PerformanceBaseTest.swift */; };
4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */; };
4C1885D2218F8E1C00B67051 /* PhotoGridViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1885D1218F8E1C00B67051 /* PhotoGridViewCell.swift */; };
4C19A0FC227B356F007A0C7F /* DebugUIMessages+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C19A0FB227B356F007A0C7F /* DebugUIMessages+OWS.swift */; };
4C20B2B720CA0034001BAC90 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542DF51208B82E9007B4E76 /* ThreadViewModel.swift */; };
@ -1225,9 +1222,7 @@
34684DAD25C2228D00C5A93C /* indeterminate_spinner_blue.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = indeterminate_spinner_blue.json; sourceTree = "<group>"; };
34684DAE25C2228D00C5A93C /* indeterminate_spinner_white.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = indeterminate_spinner_white.json; sourceTree = "<group>"; };
3469419D215D2EE400B5BFAD /* Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Theme.h; sourceTree = "<group>"; };
3469419E215D2EE400B5BFAD /* OWSConversationColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSConversationColor.m; sourceTree = "<group>"; };
3469419F215D2EE400B5BFAD /* Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Theme.m; sourceTree = "<group>"; };
346941A0215D2EE400B5BFAD /* OWSConversationColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationColor.h; sourceTree = "<group>"; };
346B4A762369BFC600B56007 /* PermissiveGestureRecognizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PermissiveGestureRecognizer.swift; sourceTree = "<group>"; };
346B66301F4E29B200E5122F /* CropScaleImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CropScaleImageViewController.swift; sourceTree = "<group>"; };
346C19DE25ACDF0B00061D3A /* DataSettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataSettingsTableViewController.swift; sourceTree = "<group>"; };
@ -1658,7 +1653,6 @@
4C10B1C323176D250099396B /* SignalPerformanceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SignalPerformanceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4C10B1C623176DD60099396B /* SDSPerformanceTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDSPerformanceTest.swift; sourceTree = "<group>"; };
4C10B1C8231778880099396B /* PerformanceBaseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceBaseTest.swift; sourceTree = "<group>"; };
4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = "<group>"; };
4C1885D1218F8E1C00B67051 /* PhotoGridViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoGridViewCell.swift; sourceTree = "<group>"; };
4C19A0FB227B356F007A0C7F /* DebugUIMessages+OWS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DebugUIMessages+OWS.swift"; sourceTree = "<group>"; };
4C1D2333218B692800A0598F /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = translations/ko.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -2680,8 +2674,6 @@
isa = PBXGroup;
children = (
343DA0002645CA720000833C /* ChatColors.swift */,
346941A0215D2EE400B5BFAD /* OWSConversationColor.h */,
3469419E215D2EE400B5BFAD /* OWSConversationColor.m */,
3469419D215D2EE400B5BFAD /* Theme.h */,
3469419F215D2EE400B5BFAD /* Theme.m */,
4C29587F233AE23000AAB2AA /* Theme+OWS.swift */,
@ -2881,7 +2873,6 @@
34D5CCA71EAE3D30005515DB /* AvatarViewHelper.h */,
34D5CCA81EAE3D30005515DB /* AvatarViewHelper.m */,
4C46361022EB98EC00185951 /* CameraFirstNavigationController.swift */,
4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */,
348BB25C20A0C5530047AEC2 /* ContactShareViewHelper.swift */,
34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */,
34E88D252098C5AE00A608F4 /* ContactViewController.swift */,
@ -4150,7 +4141,6 @@
346941A1215D2EE400B5BFAD /* Theme.h in Headers */,
346129E21FD5C0BE00532771 /* VersionMigrations.h in Headers */,
453518961FC63DBF00210559 /* SignalMessaging.h in Headers */,
346941A4215D2EE400B5BFAD /* OWSConversationColor.h in Headers */,
3461295A1FD1D74C00532771 /* Environment.h in Headers */,
450C801020AD1AE400F3A091 /* OWSWindowManager.h in Headers */,
34480B631FD0A98800BC14EF /* UIView+OWS.h in Headers */,
@ -4893,7 +4883,6 @@
3498A0A824DC936300CA492C /* ContactsViewHelper.swift in Sources */,
88EFF4F625AD1C82000FAFBA /* ThemeHeaderView.swift in Sources */,
4C046AA7236148880035B234 /* OWSGroupSyncProcessingJobQueue.swift in Sources */,
346941A2215D2EE400B5BFAD /* OWSConversationColor.m in Sources */,
34AC0A17211B39EA00997B47 /* VideoPlayerView.swift in Sources */,
4C9D347F23689E06006A4307 /* IncomingContactSyncJobQueue.swift in Sources */,
4C35B08A23F8A9D2003EB937 /* MessageRequestPendingReceipts.swift in Sources */,
@ -5378,7 +5367,6 @@
34848D6325D44EBD00E5034B /* PaymentsTransferInViewController.swift in Sources */,
4C21D5D8223AC60F00EF8A77 /* PhotoCapture.swift in Sources */,
8871B16F25F007DE00D4E070 /* ProfileSettingsViewController.swift in Sources */,
4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */,
4CC1ECFB211A553000CC13BE /* AppUpdateNag.swift in Sources */,
4C30E226234FB033009558B7 /* SecondaryLinkingQRCodeViewController.swift in Sources */,
3448E16022134C89004B052E /* OnboardingSplashViewController.swift in Sources */,

View File

@ -212,8 +212,8 @@ class GroupCallLocalMemberView: GroupCallMemberView {
return owsFailDebug("missing local address")
}
let conversationColorName = databaseStorage.uiRead { transaction in
return self.contactsManager.conversationColorName(for: localAddress, transaction: transaction)
let chatColorValue = databaseStorage.read { transaction in
ChatColors.chatColorForRendering(address: localAddress, transaction: transaction)
}
backgroundAvatarView.image = profileManager.localProfileAvatarImage()

View File

@ -1,245 +0,0 @@
//
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
import Foundation
@objc
class OWSColorPickerAccessoryView: NeverClearView {
override var intrinsicContentSize: CGSize {
return CGSize(square: kSwatchSize)
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
return self.intrinsicContentSize
}
let kSwatchSize: CGFloat = 24
@objc
required init(color: UIColor) {
super.init(frame: .zero)
let circleView = CircleView(diameter: kSwatchSize)
circleView.backgroundColor = color
addSubview(circleView)
circleView.autoPinEdgesToSuperviewEdges()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// MARK: -
protocol ColorViewDelegate: class {
func colorViewWasTapped(_ colorView: ColorView)
}
class ColorView: UIView {
public weak var delegate: ColorViewDelegate?
public let conversationColor: OWSConversationColor
private let swatchView: CircleView
private let selectedRing: CircleView
public var isSelected: Bool = false {
didSet {
self.selectedRing.isHidden = !isSelected
}
}
required init(conversationColor: OWSConversationColor) {
self.conversationColor = conversationColor
self.swatchView = CircleView()
self.selectedRing = CircleView()
super.init(frame: .zero)
self.addSubview(selectedRing)
self.addSubview(swatchView)
// Selected Ring
let cellHeight: CGFloat = ScaleFromIPhone5(60)
selectedRing.autoSetDimensions(to: CGSize(square: cellHeight))
selectedRing.layer.borderColor = Theme.secondaryTextAndIconColor.cgColor
selectedRing.layer.borderWidth = 2
selectedRing.autoPinEdgesToSuperviewEdges()
selectedRing.isHidden = true
// Color Swatch
swatchView.backgroundColor = conversationColor.primaryColor
let swatchSize: CGFloat = ScaleFromIPhone5(46)
swatchView.autoSetDimensions(to: CGSize(square: swatchSize))
swatchView.autoCenterInSuperview()
// gestures
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTap))
self.addGestureRecognizer(tapGesture)
}
required init?(coder aDecoder: NSCoder) {
notImplemented()
}
// MARK: Actions
@objc
func didTap() {
delegate?.colorViewWasTapped(self)
}
}
@objc
protocol ColorPickerDelegate: class {
func colorPicker(_ colorPicker: ColorPicker, didPickConversationColor conversationColor: OWSConversationColor)
}
@objc(OWSColorPicker)
class ColorPicker: NSObject, ColorPickerViewDelegate {
@objc
public weak var delegate: ColorPickerDelegate?
@objc
let sheetViewController: SheetViewController
@objc
init(thread: TSThread) {
let colorName = thread.conversationColorName
let currentConversationColor = OWSConversationColor.conversationColorOrDefault(colorName: colorName)
sheetViewController = SheetViewController()
super.init()
let colorPickerView = ColorPickerView(thread: thread)
colorPickerView.delegate = self
colorPickerView.select(conversationColor: currentConversationColor)
sheetViewController.contentView.addSubview(colorPickerView)
colorPickerView.autoPinEdgesToSuperviewEdges()
}
// MARK: ColorPickerViewDelegate
func colorPickerView(_ colorPickerView: ColorPickerView, didPickConversationColor conversationColor: OWSConversationColor) {
self.delegate?.colorPicker(self, didPickConversationColor: conversationColor)
}
}
protocol ColorPickerViewDelegate: class {
func colorPickerView(_ colorPickerView: ColorPickerView, didPickConversationColor conversationColor: OWSConversationColor)
}
class ColorPickerView: UIView, ColorViewDelegate {
private let thread: TSThread
private let colorViews: [ColorView]
weak var delegate: ColorPickerViewDelegate?
let mockConversationView = MockConversationView(
model: MockConversationView.MockModel(items: [
.incoming(text: NSLocalizedString(
"COLOR_PICKER_DEMO_MESSAGE_2",
comment: "The second of two messages demonstrating the chosen conversation color, by rendering this message in an incoming message bubble."
)),
.outgoing(text: NSLocalizedString(
"COLOR_PICKER_DEMO_MESSAGE_1",
comment: "The first of two messages demonstrating the chosen conversation color, by rendering this message in an outgoing message bubble."
))
]),
hasWallpaper: false,
customChatColor: nil
)
init(thread: TSThread) {
self.thread = thread
let allConversationColors = OWSConversationColor.conversationColorNames.map { OWSConversationColor.conversationColorOrDefault(colorName: $0) }
self.colorViews = allConversationColors.map { ColorView(conversationColor: $0) }
super.init(frame: .zero)
mockConversationView.conversationColor = thread.conversationColorName
colorViews.forEach { $0.delegate = self }
let headerView = self.buildHeaderView()
let paletteView = self.buildPaletteView(colorViews: colorViews)
let rowsStackView = UIStackView(arrangedSubviews: [headerView, mockConversationView, paletteView])
rowsStackView.axis = .vertical
addSubview(rowsStackView)
rowsStackView.autoPinEdgesToSuperviewEdges()
}
required init?(coder aDecoder: NSCoder) {
notImplemented()
}
// MARK: ColorViewDelegate
func colorViewWasTapped(_ colorView: ColorView) {
self.select(conversationColor: colorView.conversationColor)
self.delegate?.colorPickerView(self, didPickConversationColor: colorView.conversationColor)
mockConversationView.conversationColor = colorView.conversationColor.name
}
fileprivate func select(conversationColor selectedConversationColor: OWSConversationColor) {
colorViews.forEach { colorView in
colorView.isSelected = colorView.conversationColor == selectedConversationColor
}
}
// MARK: View Building
private func buildHeaderView() -> UIView {
let headerView = UIView()
headerView.layoutMargins = UIEdgeInsets(top: 15, left: 16, bottom: 15, right: 16)
let titleLabel = UILabel()
titleLabel.text = NSLocalizedString("COLOR_PICKER_SHEET_TITLE", comment: "Modal Sheet title when picking a conversation color.")
titleLabel.textAlignment = .center
titleLabel.font = UIFont.ows_dynamicTypeBody.ows_semibold
titleLabel.textColor = Theme.primaryTextColor
headerView.addSubview(titleLabel)
titleLabel.autoPinEdgesToSuperviewMargins()
let bottomBorderView = UIView()
bottomBorderView.backgroundColor = Theme.hairlineColor
headerView.addSubview(bottomBorderView)
bottomBorderView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .top)
bottomBorderView.autoSetDimension(.height, toSize: CGHairlineWidth())
return headerView
}
private func buildPaletteView(colorViews: [ColorView]) -> UIView {
let paletteView = UIView()
let paletteMargin = ScaleFromIPhone5(12)
paletteView.layoutMargins = UIEdgeInsets(top: paletteMargin, left: paletteMargin, bottom: 0, right: paletteMargin)
let kRowLength = 4
let rows: [UIView] = colorViews.chunked(by: kRowLength).map { colorViewsInRow in
let row = UIStackView(arrangedSubviews: colorViewsInRow)
row.distribution = UIStackView.Distribution.equalSpacing
return row
}
let rowsStackView = UIStackView(arrangedSubviews: rows)
rowsStackView.axis = .vertical
rowsStackView.spacing = ScaleFromIPhone5To7Plus(12, 30)
paletteView.addSubview(rowsStackView)
rowsStackView.autoPinEdgesToSuperviewMargins()
// no-op gesture to keep taps from dismissing SheetView
paletteView.addGestureRecognizer(UITapGestureRecognizer(target: nil, action: nil))
return paletteView
}
}

View File

@ -36,9 +36,9 @@ public class CVAvatarBuilder: Dependencies {
if let avatar = cache[cacheKey] {
return avatar
}
let colorName = contactsManager.conversationColorName(for: address, transaction: transaction)
let avatarColor = ChatColors.avatarColor(forAddress: address, transaction: transaction)
guard let rawAvatar = OWSContactAvatarBuilder(address: address,
colorName: colorName,
avatarColor: avatarColor,
diameter: diameter,
localUserDisplayMode: localUserDisplayMode,
transaction: transaction).build(with: transaction) else {

View File

@ -201,8 +201,12 @@ class GroupInviteLinksActionSheet: ActionSheetController {
}
private func loadDefaultContent() {
let avatarColor = databaseStorage.read { transaction in
ChatColors.avatarColor(forGroupId: groupV2ContextInfo.groupId,
transaction: transaction)
}
avatarView.image = OWSGroupAvatarBuilder.defaultAvatar(forGroupId: groupV2ContextInfo.groupId,
conversationColorName: ConversationColorName.default.rawValue,
avatarColor: avatarColor,
diameter: Self.avatarSize)
groupTitleLabel.text = NSLocalizedString("GROUP_LINK_ACTION_SHEET_VIEW_LOADING_TITLE",
comment: "Label indicating that the group info is being loaded in the 'group invite link' action sheet.")

View File

@ -67,10 +67,6 @@ extension ConversationSettingsViewController {
addSystemContactItemIfNecessary(to: mainSection)
addSafetyNumberItemIfNecessary(to: mainSection)
if DebugFlags.shouldShowColorPicker {
addColorPickerItems(to: mainSection)
}
contents.addSection(mainSection)
addAllMediaSectionIfNecessary(to: contents)
@ -313,27 +309,6 @@ extension ConversationSettingsViewController {
))
}
private func addColorPickerItems(to section: OWSTableSection) {
section.add(OWSTableItem(customCellBlock: { [weak self] in
guard let self = self else {
owsFailDebug("Missing self")
return OWSTableItem.newCell()
}
let colorName = self.thread.conversationColorName
let currentColor = OWSConversationColor.conversationColorOrDefault(colorName: colorName).themeColor
let title = NSLocalizedString("CONVERSATION_SETTINGS_CONVERSATION_COLOR",
comment: "Label for table cell which leads to picking a new conversation color")
return self.buildCell(name: title,
icon: .settingsColorPalette,
disclosureIconColor: currentColor,
accessibilityIdentifier: UIView.accessibilityIdentifier(in: self, name: "conversation_color"))
},
actionBlock: { [weak self] in
self?.showColorPicker()
}))
}
private func buildBlockAndLeaveSection() -> OWSTableSection {
let section = OWSTableSection()

View File

@ -61,9 +61,6 @@ class ConversationSettingsViewController: OWSTableViewController2 {
var disappearingMessagesConfiguration: OWSDisappearingMessagesConfiguration
var avatarView: UIImageView?
// This is currently disabled behind a feature flag.
private var colorPicker: ColorPicker?
var isShowingAllGroupMembers = false
var isShowingAllMutualGroups = false
@ -158,12 +155,6 @@ class ConversationSettingsViewController: OWSTableViewController2 {
backgroundTopView.autoSetDimension(.height, toSize: backgroundTopSize)
backgroundTopView.autoPinEdge(.bottom, to: .top, of: tableView, withOffset: 0)
if DebugFlags.shouldShowColorPicker {
let colorPicker = ColorPicker(thread: self.thread)
colorPicker.delegate = self
self.colorPicker = colorPicker
}
tableView.register(ContactTableViewCell.self, forCellReuseIdentifier: ContactTableViewCell.reuseIdentifier)
observeNotifications()
@ -946,43 +937,6 @@ extension ConversationSettingsViewController: CNContactViewControllerDelegate {
// MARK: -
extension ConversationSettingsViewController: ColorPickerDelegate {
func showColorPicker() {
guard let colorPicker = colorPicker else {
owsFailDebug("Missing colorPicker.")
return
}
let sheetViewController = colorPicker.sheetViewController
sheetViewController.dismissHandler = { [weak self] _ in
self?.dismiss(animated: true)
}
self.present(sheetViewController, animated: true) {
Logger.info("presented sheet view")
}
}
public func colorPicker(_ colorPicker: ColorPicker, didPickConversationColor conversationColor: OWSConversationColor) {
Logger.debug("picked color: \(conversationColor.name)")
databaseStorage.write { transaction in
self.thread.updateConversationColorName(conversationColor.name, transaction: transaction)
}
contactsManagerImpl.removeAllFromAvatarCache()
contactsManagerImpl.clearColorNameCache()
updateTableContents()
conversationSettingsViewDelegate?.conversationColorWasUpdated()
DispatchQueue.global().async {
let operation = ConversationConfigurationSyncOperation(thread: self.thread)
assert(operation.isReady)
operation.start()
}
}
}
// MARK: -
extension ConversationSettingsViewController: GroupAttributesViewControllerDelegate {
func groupAttributesDidUpdate() {
reloadThreadAndUpdateContent()

View File

@ -25,7 +25,6 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[];
#import <SignalMessaging/OWSBubbleView.h>
#import <SignalMessaging/OWSContactAvatarBuilder.h>
#import <SignalMessaging/OWSContactsManager.h>
#import <SignalMessaging/OWSConversationColor.h>
#import <SignalMessaging/OWSGroupAvatarBuilder.h>
#import <SignalMessaging/OWSMessageTextView.h>
#import <SignalMessaging/OWSNavigationController.h>

View File

@ -370,7 +370,7 @@ public class ConversationAvatarView: AvatarImageView {
switch content {
case .contact(let contactThread):
return buildContactAvatar(address: contactThread.contactAddress,
conversationColorName: contactThread.conversationColorName,
avatarColor: ChatColors.avatarColor(forThread: contactThread),
diameter: diameter,
localUserDisplayMode: configuration.localUserDisplayMode,
transaction: transaction)
@ -379,10 +379,9 @@ public class ConversationAvatarView: AvatarImageView {
diameter: diameter,
transaction: transaction)
case .unknownContact(let contactAddress):
let conversationColorName = TSContactThread.conversationColorName(forContactAddress: contactAddress,
transaction: transaction)
let avatarColor = ChatColors.avatarColor(forAddress: contactAddress, transaction: transaction)
return buildContactAvatar(address: contactAddress,
conversationColorName: conversationColorName,
avatarColor: avatarColor,
diameter: diameter,
localUserDisplayMode: configuration.localUserDisplayMode,
transaction: transaction)
@ -402,12 +401,12 @@ public class ConversationAvatarView: AvatarImageView {
}
private static func buildContactAvatar(address: SignalServiceAddress,
conversationColorName: ConversationColorName,
avatarColor: UIColor,
diameter: UInt,
localUserDisplayMode: LocalUserDisplayMode,
transaction: SDSAnyReadTransaction) -> UIImage? {
let builder = OWSContactAvatarBuilder(address: address,
colorName: conversationColorName,
avatarColor: avatarColor,
diameter: diameter,
localUserDisplayMode: localUserDisplayMode,
transaction: transaction)

View File

@ -75,9 +75,12 @@ public class NonContactTableViewCell: UITableViewCell {
if isRegistered {
let address = SignalServiceAddress(phoneNumber: phoneNumber)
let avatarColor = databaseStorage.read { transaction in
ChatColors.avatarColor(forAddress: address, transaction: transaction)
}
let avatarBuilder = OWSContactAvatarBuilder(
address: address,
colorName: TSThread.stableColorNameForNewConversation(with: address.stringForDisplay),
avatarColor: avatarColor,
diameter: 48,
localUserDisplayMode: .asUser
)

View File

@ -113,7 +113,7 @@ public struct ChatColorValue: Equatable, Codable {
}
public static var placeholderValue: ChatColorValue {
ChatColors.noWallpaperAutoChatColor
ChatColors.defaultChatColorValue
}
// MARK: - Equatable
@ -253,7 +253,7 @@ public class ChatColors: NSObject, Dependencies {
}
public static var allValuesSorted: [ChatColorValue] { Self.chatColors.allValuesSorted }
public static var noWallpaperAutoChatColor: ChatColorValue { Self.value_ultramarine }
public static var defaultChatColorValue: ChatColorValue { Self.value_ultramarine }
public static func autoChatColor(forThread thread: TSThread?,
transaction: SDSAnyReadTransaction) -> ChatColorValue {
@ -261,7 +261,7 @@ public class ChatColors: NSObject, Dependencies {
wallpaper != .photo {
return autoChatColor(forWallpaper: wallpaper)
} else {
return Self.noWallpaperAutoChatColor
return Self.defaultChatColorValue
}
}
@ -304,6 +304,14 @@ public class ChatColors: NSObject, Dependencies {
}
}
public static func chatColorForRendering(address: SignalServiceAddress,
transaction: SDSAnyReadTransaction) -> ChatColorValue {
guard let thread = TSContactThread.getWithContactAddress(address, transaction: transaction) else {
return Self.defaultChatColorValue
}
return chatColorForRendering(thread: thread, transaction: transaction)
}
public static func setChatColorSetting(_ value: ChatColorValue?,
thread: TSThread,
transaction: SDSAnyWriteTransaction) {
@ -615,7 +623,12 @@ public extension ChatColors {
return GroupNameColors(colorMap: colorMap, defaultColor: defaultColor)
}
private struct GroupNameColorValue {
private static var defaultGroupNameColor: UIColor {
let isDarkThemeEnabled = Theme.isDarkThemeEnabled
return Self.groupNameColorValues.first!.color(isDarkThemeEnabled: isDarkThemeEnabled)
}
fileprivate struct GroupNameColorValue {
let lightTheme: UIColor
let darkTheme: UIColor
@ -625,7 +638,7 @@ public extension ChatColors {
}
// In descending order of contrast with the other values.
private static let groupNameColorValues: [GroupNameColorValue] = [
fileprivate static let groupNameColorValues: [GroupNameColorValue] = [
GroupNameColorValue(lightTheme: UIColor(rgbHex: 0xD00B0B),
darkTheme: UIColor(rgbHex: 0xF76E6E)),
GroupNameColorValue(lightTheme: UIColor(rgbHex: 0x067906),
@ -700,3 +713,52 @@ public extension ChatColors {
darkTheme: UIColor(rgbHex: 0xF76E85))
]
}
// MARK: - Avatar Colors
@objc
public extension ChatColors {
static var defaultAvatarColor: UIColor {
Self.defaultGroupNameColor
}
static func avatarColor(forAddress address: SignalServiceAddress,
transaction: SDSAnyReadTransaction) -> UIColor {
guard let thread = TSContactThread.getWithContactAddress(address,
transaction: transaction) else {
guard let seed = address.serviceIdentifier else {
owsFailDebug("Missing serviceIdentifier.")
return Self.defaultAvatarColor
}
return avatarColor(forSeed: seed)
}
return avatarColor(forThread: thread)
}
static func avatarColor(forThread thread: TSThread) -> UIColor {
avatarColor(forSeed: thread.uniqueId)
}
static func avatarColor(forGroupModel groupModel: TSGroupModel,
transaction: SDSAnyReadTransaction) -> UIColor {
avatarColor(forGroupId: groupModel.groupId, transaction: transaction)
}
static func avatarColor(forGroupId groupId: Data,
transaction: SDSAnyReadTransaction) -> UIColor {
let threadUniqueId = TSGroupThread.threadId(forGroupId: groupId,
transaction: transaction)
return avatarColor(forSeed: groupId)
}
static func avatarColor(forSeed seed: String) -> UIColor {
let hash = seed.hash
let values = Self.groupNameColorValues
guard let value = values[safe: hash % values.count] else {
owsFailDebug("Could not determine avatar color.")
return Self.defaultAvatarColor
}
let isDarkThemeEnabled = Theme.isDarkThemeEnabled
return value.color(isDarkThemeEnabled: isDarkThemeEnabled)
}
}

View File

@ -1,82 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <SignalServiceKit/TSThread.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface OWSConversationColor : NSObject
@property (nonatomic, readonly) ConversationColorName name;
@property (nonatomic, readonly) UIColor *primaryColor;
@property (nonatomic, readonly) UIColor *shadeColor;
@property (nonatomic, readonly) UIColor *tintColor;
@property (nonatomic, readonly) UIColor *themeColor;
+ (OWSConversationColor *)conversationColorWithName:(ConversationColorName)name
primaryColor:(UIColor *)primaryColor
shadeColor:(UIColor *)shadeColor
tintColor:(UIColor *)tintColor;
#pragma mark - Conversation Colors
@property (class, readonly, nonatomic) UIColor *ows_crimsonColor;
@property (class, readonly, nonatomic) UIColor *ows_vermilionColor;
@property (class, readonly, nonatomic) UIColor *ows_burlapColor;
@property (class, readonly, nonatomic) UIColor *ows_forestColor;
@property (class, readonly, nonatomic) UIColor *ows_wintergreenColor;
@property (class, readonly, nonatomic) UIColor *ows_tealColor;
@property (class, readonly, nonatomic) UIColor *ows_blueColor;
@property (class, readonly, nonatomic) UIColor *ows_indigoColor;
@property (class, readonly, nonatomic) UIColor *ows_violetColor;
@property (class, readonly, nonatomic) UIColor *ows_plumColor;
@property (class, readonly, nonatomic) UIColor *ows_taupeColor;
@property (class, readonly, nonatomic) UIColor *ows_steelColor;
#pragma mark - Conversation Colors (Tint)
@property (class, readonly, nonatomic) UIColor *ows_crimsonTintColor;
@property (class, readonly, nonatomic) UIColor *ows_vermilionTintColor;
@property (class, readonly, nonatomic) UIColor *ows_burlapTintColor;
@property (class, readonly, nonatomic) UIColor *ows_forestTintColor;
@property (class, readonly, nonatomic) UIColor *ows_wintergreenTintColor;
@property (class, readonly, nonatomic) UIColor *ows_tealTintColor;
@property (class, readonly, nonatomic) UIColor *ows_blueTintColor;
@property (class, readonly, nonatomic) UIColor *ows_indigoTintColor;
@property (class, readonly, nonatomic) UIColor *ows_violetTintColor;
@property (class, readonly, nonatomic) UIColor *ows_plumTintColor;
@property (class, readonly, nonatomic) UIColor *ows_taupeTintColor;
@property (class, readonly, nonatomic) UIColor *ows_steelTintColor;
#pragma mark - Conversation Colors (Shade)
@property (class, readonly, nonatomic) UIColor *ows_crimsonShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_vermilionShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_burlapShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_forestShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_wintergreenShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_tealShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_blueShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_indigoShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_violetShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_plumShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_taupeShadeColor;
@property (class, readonly, nonatomic) UIColor *ows_steelShadeColor;
#pragma mark - Conversation Colors
+ (nullable OWSConversationColor *)conversationColorForColorName:(ConversationColorName)colorName
NS_SWIFT_NAME(conversationColor(colorName:));
// If the conversation color name is valid, return its colors.
// Otherwise return the "default" conversation colors.
+ (OWSConversationColor *)conversationColorOrDefaultForColorName:(ConversationColorName)conversationColorName
NS_SWIFT_NAME(conversationColorOrDefault(colorName:));
@property (class, readonly, nonatomic) NSArray<ConversationColorName> *conversationColorNames;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,359 +0,0 @@
//
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
//
#import "OWSConversationColor.h"
#import "Theme.h"
#import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN
@interface OWSConversationColor ()
@property (nonatomic) ConversationColorName name;
@property (nonatomic) UIColor *primaryColor;
@property (nonatomic) UIColor *shadeColor;
@property (nonatomic) UIColor *tintColor;
@end
#pragma mark -
@implementation OWSConversationColor
+ (OWSConversationColor *)conversationColorWithName:(ConversationColorName)name
primaryColor:(UIColor *)primaryColor
shadeColor:(UIColor *)shadeColor
tintColor:(UIColor *)tintColor
{
OWSConversationColor *instance = [OWSConversationColor new];
instance.name = name;
instance.primaryColor = primaryColor;
instance.shadeColor = shadeColor;
instance.tintColor = tintColor;
return instance;
}
#pragma mark -
- (UIColor *)themeColor
{
return Theme.isDarkThemeEnabled ? self.shadeColor : self.primaryColor;
}
- (BOOL)isEqual:(id)other
{
if (![other isKindOfClass:[OWSConversationColor class]]) {
return NO;
}
OWSConversationColor *otherColor = (OWSConversationColor *)other;
return [self.name isEqual:otherColor.name];
}
#pragma mark - Conversation Color (Primary)
+ (UIColor *)ows_crimsonColor
{
return [UIColor colorWithRGBHex:0xCC163D];
}
+ (UIColor *)ows_vermilionColor
{
return [UIColor colorWithRGBHex:0xC73800];
}
+ (UIColor *)ows_burlapColor
{
return [UIColor colorWithRGBHex:0x746C53];
}
+ (UIColor *)ows_forestColor
{
return [UIColor colorWithRGBHex:0x3B7845];
}
+ (UIColor *)ows_wintergreenColor
{
return [UIColor colorWithRGBHex:0x1C8260];
}
+ (UIColor *)ows_tealColor
{
return [UIColor colorWithRGBHex:0x067589];
}
+ (UIColor *)ows_blueColor
{
return [UIColor colorWithRGBHex:0x336BA3];
}
+ (UIColor *)ows_indigoColor
{
return [UIColor colorWithRGBHex:0x5951C8];
}
+ (UIColor *)ows_violetColor
{
return [UIColor colorWithRGBHex:0x862CAF];
}
+ (UIColor *)ows_plumColor
{
return [UIColor colorWithRGBHex:0xA23474];
}
+ (UIColor *)ows_taupeColor
{
return [UIColor colorWithRGBHex:0x895D66];
}
+ (UIColor *)ows_steelColor
{
return [UIColor colorWithRGBHex:0x6B6B78];
}
#pragma mark - Conversation Colors (Tint)
+ (UIColor *)ows_crimsonTintColor
{
return [UIColor colorWithRGBHex:0xEDA6AE];
}
+ (UIColor *)ows_vermilionTintColor
{
return [UIColor colorWithRGBHex:0xEBA78E];
}
+ (UIColor *)ows_burlapTintColor
{
return [UIColor colorWithRGBHex:0xC4B997];
}
+ (UIColor *)ows_forestTintColor
{
return [UIColor colorWithRGBHex:0x8FCC9A];
}
+ (UIColor *)ows_wintergreenTintColor
{
return [UIColor colorWithRGBHex:0x9BCFBD];
}
+ (UIColor *)ows_tealTintColor
{
return [UIColor colorWithRGBHex:0xA5CAD5];
}
+ (UIColor *)ows_blueTintColor
{
return [UIColor colorWithRGBHex:0xADC8E1];
}
+ (UIColor *)ows_indigoTintColor
{
return [UIColor colorWithRGBHex:0xC2C1E7];
}
+ (UIColor *)ows_violetTintColor
{
return [UIColor colorWithRGBHex:0xCDADDC];
}
+ (UIColor *)ows_plumTintColor
{
return [UIColor colorWithRGBHex:0xDCB2CA];
}
+ (UIColor *)ows_taupeTintColor
{
return [UIColor colorWithRGBHex:0xCFB5BB];
}
+ (UIColor *)ows_steelTintColor
{
return [UIColor colorWithRGBHex:0xBEBEC6];
}
#pragma mark - Conversation Colors (Shade)
+ (UIColor *)ows_crimsonShadeColor
{
return [UIColor colorWithRGBHex:0x8A0F29];
}
+ (UIColor *)ows_vermilionShadeColor
{
return [UIColor colorWithRGBHex:0x872600];
}
+ (UIColor *)ows_burlapShadeColor
{
return [UIColor colorWithRGBHex:0x58513C];
}
+ (UIColor *)ows_forestShadeColor
{
return [UIColor colorWithRGBHex:0x2B5934];
}
+ (UIColor *)ows_wintergreenShadeColor
{
return [UIColor colorWithRGBHex:0x36544A];
}
+ (UIColor *)ows_tealShadeColor
{
return [UIColor colorWithRGBHex:0x055968];
}
+ (UIColor *)ows_blueShadeColor
{
return [UIColor colorWithRGBHex:0x285480];
}
+ (UIColor *)ows_indigoShadeColor
{
return [UIColor colorWithRGBHex:0x4840A0];
}
+ (UIColor *)ows_violetShadeColor
{
return [UIColor colorWithRGBHex:0x6B248A];
}
+ (UIColor *)ows_plumShadeColor
{
return [UIColor colorWithRGBHex:0x881B5B];
}
+ (UIColor *)ows_taupeShadeColor
{
return [UIColor colorWithRGBHex:0x6A4E54];
}
+ (UIColor *)ows_steelShadeColor
{
return [UIColor colorWithRGBHex:0x5A5A63];
}
+ (NSArray<OWSConversationColor *> *)allConversationColors
{
static NSArray<OWSConversationColor *> *allConversationColors;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Order here affects the order in the conversation color picker.
allConversationColors = @[
[OWSConversationColor conversationColorWithName:ConversationColorNameCrimson
primaryColor:self.ows_crimsonColor
shadeColor:self.ows_crimsonShadeColor
tintColor:self.ows_crimsonTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameVermilion
primaryColor:self.ows_vermilionColor
shadeColor:self.ows_vermilionShadeColor
tintColor:self.ows_vermilionTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameBurlap
primaryColor:self.ows_burlapColor
shadeColor:self.ows_burlapShadeColor
tintColor:self.ows_burlapTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameForest
primaryColor:self.ows_forestColor
shadeColor:self.ows_forestShadeColor
tintColor:self.ows_forestTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameWintergreen
primaryColor:self.ows_wintergreenColor
shadeColor:self.ows_wintergreenShadeColor
tintColor:self.ows_wintergreenTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameTeal
primaryColor:self.ows_tealColor
shadeColor:self.ows_tealShadeColor
tintColor:self.ows_tealTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameBlue
primaryColor:self.ows_blueColor
shadeColor:self.ows_blueShadeColor
tintColor:self.ows_blueTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameIndigo
primaryColor:self.ows_indigoColor
shadeColor:self.ows_indigoShadeColor
tintColor:self.ows_indigoTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameViolet
primaryColor:self.ows_violetColor
shadeColor:self.ows_violetShadeColor
tintColor:self.ows_violetTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNamePlum
primaryColor:self.ows_plumColor
shadeColor:self.ows_plumShadeColor
tintColor:self.ows_plumTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameTaupe
primaryColor:self.ows_taupeColor
shadeColor:self.ows_taupeShadeColor
tintColor:self.ows_taupeTintColor],
[OWSConversationColor conversationColorWithName:ConversationColorNameSteel
primaryColor:self.ows_steelColor
shadeColor:self.ows_steelShadeColor
tintColor:self.ows_steelTintColor],
];
});
return allConversationColors;
}
+ (NSDictionary<ConversationColorName, OWSConversationColor *> *)conversationColorMap
{
static NSDictionary<ConversationColorName, OWSConversationColor *> *colorMap;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSMutableDictionary<ConversationColorName, OWSConversationColor *> *mutableColorMap = [NSMutableDictionary new];
for (OWSConversationColor *conversationColor in self.allConversationColors) {
mutableColorMap[conversationColor.name] = conversationColor;
}
colorMap = [mutableColorMap copy];
});
return colorMap;
}
+ (NSArray<ConversationColorName> *)conversationColorNames
{
NSMutableArray<ConversationColorName> *names = [NSMutableArray new];
for (OWSConversationColor *conversationColor in self.allConversationColors) {
[names addObject:conversationColor.name];
}
#ifdef DEBUG
NSSet<ConversationColorName> *colorNameSet = [NSSet setWithArray:names];
// These constants are duplicated in two places. So this canary exists to make sure they stay in sync.
NSSet<ConversationColorName> *threadColorNameSet = [NSSet setWithArray:TSThread.conversationColorNames];
OWSAssertDebug([colorNameSet isEqual:threadColorNameSet]);
#endif
return [names copy];
}
+ (nullable OWSConversationColor *)conversationColorForColorName:(ConversationColorName)conversationColorName
{
OWSConversationColor *_Nullable result = self.conversationColorMap[conversationColorName];
// Any mapping to colorNames should be done in TSThread before this method is called.
OWSAssertDebug(result != nil);
return result;
}
+ (OWSConversationColor *)conversationColorOrDefaultForColorName:(ConversationColorName)conversationColorName
{
OWSConversationColor *_Nullable conversationColor = [self conversationColorForColorName:conversationColorName];
if (conversationColor) {
return conversationColor;
}
return [self defaultConversationColor];
}
+ (OWSConversationColor *)defaultConversationColor
{
return [self conversationColorForColorName:ConversationColorNameDefault];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
#import <SignalServiceKit/Contact.h>
@ -100,8 +100,6 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification;
transaction:(SDSAnyReadTransaction *)transaction;
- (nullable UIImage *)imageForAddressWithSneakyTransaction:(nullable SignalServiceAddress *)address;
- (void)clearColorNameCache;
@end
NS_ASSUME_NONNULL_END

View File

@ -42,7 +42,6 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
@property (nonatomic, readonly) SystemContactsFetcher *systemContactsFetcher;
@property (nonatomic, readonly) NSCache<NSString *, CNContact *> *cnContactCache;
@property (nonatomic, readonly) NSCache<NSString *, UIImage *> *cnContactAvatarCache;
@property (nonatomic, readonly) NSCache<SignalServiceAddress *, NSString *> *colorNameCache;
@property (atomic) BOOL isSetup;
@end
@ -62,7 +61,6 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
// TODO: We need to configure the limits of this cache.
_avatarCachePrivate = [ImageCache new];
_colorNameCache = [NSCache new];
_allContacts = @[];
_allContactsMap = @{};
@ -901,26 +899,6 @@ NSString *const OWSContactsManagerKeyNextFullIntersectionDate = @"OWSContactsMan
return addressLabel.filterStringForDisplay;
}
- (void)clearColorNameCache
{
[self.colorNameCache removeAllObjects];
}
- (ConversationColorName)conversationColorNameForAddress:(SignalServiceAddress *)address
transaction:(SDSAnyReadTransaction *)transaction
{
_Nullable ConversationColorName cachedColorName = [self.colorNameCache objectForKey:address];
if (cachedColorName != nil) {
return cachedColorName;
}
ConversationColorName colorName = [TSContactThread conversationColorNameForContactAddress:address
transaction:transaction];
[self.colorNameCache setObject:colorName forKey:address];
return colorName;
}
- (BOOL)phoneNumber:(PhoneNumber *)phoneNumber1 matchesNumber:(PhoneNumber *)phoneNumber2
{
return [phoneNumber1.toE164 isEqualToString:phoneNumber2.toE164];

View File

@ -140,7 +140,6 @@ public class ConversationStyle: NSObject {
chatColor chatColorValue: ChatColorValue) {
self.type = type
self.conversationColor = ConversationStyle.conversationColor(thread: thread)
self.viewWidth = viewWidth
self.isDarkThemeEnabled = Theme.isDarkThemeEnabled
self.primaryTextColor = Theme.primaryTextColor
@ -203,15 +202,6 @@ public class ConversationStyle: NSObject {
// MARK: Colors
@objc
public let conversationColor: OWSConversationColor
private class func conversationColor(thread: TSThread) -> OWSConversationColor {
let colorName = thread.conversationColorName
return OWSConversationColor.conversationColorOrDefault(colorName: colorName)
}
@objc
public var bubbleColorIncoming: UIColor {
if hasWallpaper {
@ -367,7 +357,6 @@ public class ConversationStyle: NSObject {
(type.isValid == other.type.isValid &&
viewWidth == other.viewWidth &&
dynamicBodyTypePointSize == other.dynamicBodyTypePointSize &&
conversationColor == other.conversationColor &&
isDarkThemeEnabled == other.isDarkThemeEnabled &&
hasWallpaper == other.hasWallpaper &&
maxMessageWidth == other.maxMessageWidth &&
@ -390,7 +379,6 @@ public class ConversationStyle: NSObject {
"type.isValid: \(type.isValid), " +
"viewWidth: \(viewWidth), " +
"dynamicBodyTypePointSize: \(dynamicBodyTypePointSize), " +
"conversationColor: \(conversationColor), " +
"isDarkThemeEnabled: \(isDarkThemeEnabled), " +
"maxMessageWidth: \(maxMessageWidth), " +
"maxMediaMessageWidth: \(maxMediaMessageWidth), " +

View File

@ -48,9 +48,9 @@ typedef void (^OWSAvatarDrawBlock)(CGContextRef context);
OWSAvatarBuilder *avatarBuilder;
if ([thread isKindOfClass:[TSContactThread class]]) {
TSContactThread *contactThread = (TSContactThread *)thread;
ConversationColorName colorName = thread.conversationColorName;
UIColor *avatarColor = [ChatColors avatarColorForThread:thread];
avatarBuilder = [[OWSContactAvatarBuilder alloc] initWithAddress:contactThread.contactAddress
colorName:colorName
avatarColor:avatarColor
diameter:diameter
localUserDisplayMode:localUserDisplayMode
transaction:transaction];

View File

@ -25,11 +25,11 @@ NS_ASSUME_NONNULL_BEGIN
NS_SWIFT_NAME(buildImageForNonLocalAddress(_:diameter:transaction:));
- (instancetype)initWithAddress:(SignalServiceAddress *)address
colorName:(ConversationColorName)colorName
avatarColor:(UIColor *)avatarColor
diameter:(NSUInteger)diameter
localUserDisplayMode:(LocalUserDisplayMode)localUserDisplayMode;
- (instancetype)initWithAddress:(SignalServiceAddress *)address
colorName:(ConversationColorName)colorName
avatarColor:(UIColor *)avatarColor
diameter:(NSUInteger)diameter
localUserDisplayMode:(LocalUserDisplayMode)localUserDisplayMode
transaction:(SDSAnyReadTransaction *)transaction;

View File

@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly, nullable) SignalServiceAddress *address;
@property (nonatomic, readonly, nullable) NSPersonNameComponents *contactNameComponents;
@property (nonatomic, readonly) ConversationColorName colorName;
@property (nonatomic, readonly) UIColor *avatarColor;
@property (nonatomic, readonly) NSUInteger diameter;
@property (nonatomic, readonly) LocalUserDisplayMode localUserDisplayMode;
@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithAddress:(nullable SignalServiceAddress *)address
nameComponents:(nullable NSPersonNameComponents *)nameComponents
colorName:(ConversationColorName)colorName
avatarColor:(UIColor *)avatarColor
diameter:(NSUInteger)diameter
localUserDisplayMode:(LocalUserDisplayMode)localUserDisplayMode
{
@ -38,11 +38,9 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
OWSAssertDebug(colorName.length > 0);
_address = address;
_contactNameComponents = nameComponents;
_colorName = colorName;
_avatarColor = avatarColor;
_diameter = diameter;
_localUserDisplayMode = localUserDisplayMode;
@ -56,7 +54,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (instancetype)initWithAddress:(SignalServiceAddress *)address
colorName:(ConversationColorName)colorName
avatarColor:(UIColor *)avatarColor
diameter:(NSUInteger)diameter
localUserDisplayMode:(LocalUserDisplayMode)localUserDisplayMode
{
@ -67,7 +65,7 @@ NS_ASSUME_NONNULL_BEGIN
}];
return [self initWithAddress:address
nameComponents:nameComponents
colorName:colorName
avatarColor:avatarColor
diameter:diameter
localUserDisplayMode:localUserDisplayMode];
}
@ -80,14 +78,14 @@ NS_ASSUME_NONNULL_BEGIN
}
- (instancetype)initWithAddress:(SignalServiceAddress *)address
colorName:(ConversationColorName)colorName
avatarColor:(UIColor *)avatarColor
diameter:(NSUInteger)diameter
localUserDisplayMode:(LocalUserDisplayMode)localUserDisplayMode
transaction:(SDSAnyReadTransaction *)transaction
{
return [self initWithAddress:address
nameComponents:[OWSContactAvatarBuilder nameComponentsForAddress:address transaction:transaction]
colorName:colorName
avatarColor:avatarColor
diameter:diameter
localUserDisplayMode:localUserDisplayMode];
}
@ -96,10 +94,10 @@ NS_ASSUME_NONNULL_BEGIN
colorSeed:(NSString *)colorSeed
diameter:(NSUInteger)diameter
{
ConversationColorName colorName = [TSThread stableColorNameForNewConversationWithString:colorSeed];
UIColor *avatarColor = [ChatColors avatarColorForSeed:colorSeed];
return [self initWithAddress:nil
nameComponents:nonSignalNameComponents
colorName:colorName
avatarColor:avatarColor
diameter:diameter
localUserDisplayMode:OWSContactAvatarBuilder.defaultLocalUserDisplayMode];
}
@ -116,7 +114,7 @@ NS_ASSUME_NONNULL_BEGIN
instance = [self initWithAddress:address
nameComponents:[OWSContactAvatarBuilder nameComponentsForAddress:address
transaction:transaction]
colorName:ConversationColorNameDefault
avatarColor:ChatColors.defaultAvatarColor
diameter:diameter
localUserDisplayMode:localUserDisplayMode];
}];
@ -133,7 +131,7 @@ NS_ASSUME_NONNULL_BEGIN
SignalServiceAddress *address = TSAccountManager.localAddress;
return [self initWithAddress:address
nameComponents:[OWSContactAvatarBuilder nameComponentsForAddress:address transaction:transaction]
colorName:ConversationColorNameDefault
avatarColor:ChatColors.defaultAvatarColor
diameter:diameter
localUserDisplayMode:localUserDisplayMode];
}
@ -142,12 +140,11 @@ NS_ASSUME_NONNULL_BEGIN
diameter:(NSUInteger)diameter
transaction:(SDSAnyReadTransaction *)transaction
{
ConversationColorName color = [self.contactsManager conversationColorNameForAddress:address
transaction:transaction];
UIColor *avatarColor = [ChatColors avatarColorForAddress:address transaction:transaction];
OWSContactAvatarBuilder *avatarBuilder =
[[self alloc] initWithAddress:address
nameComponents:[OWSContactAvatarBuilder nameComponentsForAddress:address transaction:transaction]
colorName:color
avatarColor:avatarColor
diameter:diameter
localUserDisplayMode:OWSContactAvatarBuilder.defaultLocalUserDisplayMode];
return [avatarBuilder buildWithTransaction:transaction];
@ -195,7 +192,7 @@ NS_ASSUME_NONNULL_BEGIN
return cachedAvatar;
}
UIImage *image = [self noteToSelfImageWithConversationColorName:self.colorName diameter:(CGFloat)self.diameter];
UIImage *image = [self noteToSelfImageWithDiameter:(CGFloat)self.diameter];
if (!image) {
OWSFailDebug(@"Could not generate avatar.");
return nil;
@ -251,9 +248,7 @@ NS_ASSUME_NONNULL_BEGIN
return cachedAvatar;
}
UIColor *color = [OWSConversationColor conversationColorOrDefaultForColorName:self.colorName].themeColor;
OWSAssertDebug(color);
UIColor *color = self.avatarColor;
UIImage *_Nullable image;
if (self.contactInitials.length == 0) {
// We don't have a name for this contact, so we can't make an "initials" image.
@ -292,11 +287,10 @@ NS_ASSUME_NONNULL_BEGIN
return image;
}
- (nullable UIImage *)noteToSelfImageWithConversationColorName:(ConversationColorName)conversationColorName
diameter:(CGFloat)diameter
- (nullable UIImage *)noteToSelfImageWithDiameter:(CGFloat)diameter
{
UIImage *iconImage = [[UIImage imageNamed:@"note-112"] asTintedImageWithColor:UIColor.whiteColor];
UIColor *backgroundColor = [OWSConversationColor conversationColorOrDefaultForColorName:conversationColorName].themeColor;
UIColor *backgroundColor = self.avatarColor;
CGFloat circleWidth = diameter;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(circleWidth, circleWidth), NO, 0.0);

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
#import "OWSAvatarBuilder.h"
@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithThread:(TSGroupThread *)thread diameter:(NSUInteger)diameter;
+ (nullable UIImage *)defaultAvatarForGroupId:(NSData *)groupId
conversationColorName:(NSString *)conversationColorName
avatarColor:(UIColor *)avatarColor
diameter:(NSUInteger)diameter;
@end

View File

@ -47,13 +47,14 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable UIImage *)buildDefaultImage
{
UIColor *avatarColor = [ChatColors avatarColorForThread:self.thread];
return [self.class defaultAvatarForGroupId:self.thread.groupModel.groupId
conversationColorName:self.thread.conversationColorName
avatarColor:avatarColor
diameter:self.diameter];
}
+ (nullable UIImage *)defaultAvatarForGroupId:(NSData *)groupId
conversationColorName:(NSString *)conversationColorName
avatarColor:(UIColor *)avatarColor
diameter:(NSUInteger)diameter
{
NSString *cacheKey = [NSString
@ -65,14 +66,8 @@ NS_ASSUME_NONNULL_BEGIN
return cachedAvatar;
}
#ifdef SHOW_COLOR_PICKER
UIColor *backgroundColor =
[OWSConversationColor conversationColorOrDefaultForColorName:conversationColorName].themeColor;
#else
UIColor *backgroundColor = [OWSConversationColor ows_steelColor];
#endif
UIImage *_Nullable image =
[OWSGroupAvatarBuilder groupAvatarImageWithBackgroundColor:backgroundColor diameter:diameter];
UIImage *_Nullable image = [OWSGroupAvatarBuilder groupAvatarImageWithBackgroundColor:avatarColor
diameter:diameter];
if (!image) {
OWSFailDebug(@"Could not create group avatar.");
return nil;

View File

@ -96,6 +96,7 @@ NS_DESIGNATED_INITIALIZER NS_SWIFT_NAME(init(grdbId:uniqueId:conversationColorNa
// --- CODE GENERATION MARKER
// TODO: Obsolete.
@property (nonatomic) ConversationColorName conversationColorName;
- (void)updateConversationColorName:(ConversationColorName)colorName transaction:(SDSAnyWriteTransaction *)transaction;

View File

@ -80,10 +80,6 @@ NS_DESIGNATED_INITIALIZER NS_SWIFT_NAME(init(grdbId:uniqueId:conversationColorNa
// This method should only be called by GroupManager.
- (void)updateWithGroupModel:(TSGroupModel *)groupModel transaction:(SDSAnyWriteTransaction *)transaction;
#pragma mark -
+ (ConversationColorName)defaultConversationColorNameForGroupId:(NSData *)groupId;
@end
NS_ASSUME_NONNULL_END

View File

@ -187,14 +187,6 @@ lastVisibleSortIdOnScreenPercentageObsolete:lastVisibleSortIdOnScreenPercentageO
userInfo:userInfo];
}
+ (ConversationColorName)defaultConversationColorNameForGroupId:(NSData *)groupId
{
OWSAssertDebug(groupId.length > 0);
NSString *threadUniqueId = [self defaultThreadIdForGroupId:groupId];
return [self.class stableColorNameForNewConversationWithString:threadUniqueId];
}
- (void)anyWillRemoveWithTransaction:(SDSAnyWriteTransaction *)transaction
{
if (self.isGroupV2Thread) {

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2020 Open Whisper Systems. All rights reserved.
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@ -14,8 +14,6 @@ NS_ASSUME_NONNULL_BEGIN
@class TSThread;
@class UIImage;
typedef NSString *ConversationColorName NS_STRING_ENUM;
@protocol ContactsManagerProtocol <NSObject>
/// The name representing this address.
@ -43,9 +41,6 @@ typedef NSString *ConversationColorName NS_STRING_ENUM;
- (NSString *)shortDisplayNameForAddress:(SignalServiceAddress *)address
transaction:(SDSAnyReadTransaction *)transaction;
- (ConversationColorName)conversationColorNameForAddress:(SignalServiceAddress *)address
transaction:(SDSAnyReadTransaction *)transaction;
- (nullable NSPersonNameComponents *)nameComponentsForAddress:(SignalServiceAddress *)address;
- (nullable NSPersonNameComponents *)nameComponentsForAddress:(SignalServiceAddress *)address
transaction:(SDSAnyReadTransaction *)transaction;

View File

@ -424,10 +424,6 @@ public class DebugFlags: BaseFlags {
@objc
public static let fakeLinkedDevices = false
// TODO: Remove
@objc
public static let shouldShowColorPicker = false
@objc
public static let paymentsOnlyInContactThreads = true