Name color improvements

This commit is contained in:
Ilya Laktyushin 2023-10-27 17:31:13 +04:00
parent c4618f19db
commit e6791ac5fd
3 changed files with 55 additions and 24 deletions

View File

@ -63,7 +63,7 @@ private class AvatarNodeParameters: NSObject {
}
}
private func calculateColors(explicitColorIndex: Int?, peerId: EnginePeer.Id?, nameColor: PeerNameColor?, icon: AvatarNodeIcon, theme: PresentationTheme?) -> [UIColor] {
private func calculateColors(context: AccountContext?, explicitColorIndex: Int?, peerId: EnginePeer.Id?, nameColor: PeerNameColor?, icon: AvatarNodeIcon, theme: PresentationTheme?) -> [UIColor] {
let colorIndex: Int
if let explicitColorIndex = explicitColorIndex {
colorIndex = explicitColorIndex
@ -111,7 +111,29 @@ private func calculateColors(explicitColorIndex: Int?, peerId: EnginePeer.Id?, n
}
} else {
if let nameColor {
colors = AvatarNode.gradientColors[Int(nameColor.rawValue) % AvatarNode.gradientColors.count]
if let context, nameColor.rawValue > 13 {
let nameColors = context.peerNameColors.get(nameColor)
let hue = nameColors.main.hsb.h
var index: Int = 0
if hue > 0.9 || hue < 0.02 {
index = 0
} else if hue < 0.1 {
index = 1
} else if hue < 0.4 {
index = 3
} else if hue < 0.5 {
index = 4
} else if hue < 0.6 {
index = 5
} else if hue < 0.75 {
index = 2
} else {
index = 6
}
colors = AvatarNode.gradientColors[index % AvatarNode.gradientColors.count]
} else {
colors = AvatarNode.gradientColors[Int(nameColor.rawValue) % AvatarNode.gradientColors.count]
}
} else {
colors = AvatarNode.gradientColors[colorIndex % AvatarNode.gradientColors.count]
}
@ -489,7 +511,7 @@ public final class AvatarNode: ASDisplayNode {
self.editOverlayNode?.isHidden = true
}
parameters = AvatarNodeParameters(theme: theme, accountPeerId: accountPeerId, peerId: peer.id, colors: calculateColors(explicitColorIndex: nil, peerId: peer.id, nameColor: peer.nameColor, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle)
parameters = AvatarNodeParameters(theme: theme, accountPeerId: accountPeerId, peerId: peer.id, colors: calculateColors(context: nil, explicitColorIndex: nil, peerId: peer.id, nameColor: peer.nameColor, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle)
} else {
self.imageReady.set(.single(true))
self.displaySuspended = false
@ -498,7 +520,7 @@ public final class AvatarNode: ASDisplayNode {
}
self.editOverlayNode?.isHidden = true
let colors = calculateColors(explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), nameColor: peer?.nameColor, icon: icon, theme: theme)
let colors = calculateColors(context: nil, explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), nameColor: peer?.nameColor, icon: icon, theme: theme)
parameters = AvatarNodeParameters(theme: theme, accountPeerId: accountPeerId, peerId: peer?.id ?? EnginePeer.Id(0), colors: colors, letters: peer?.displayLetters ?? [], font: self.font, icon: icon, explicitColorIndex: nil, hasImage: false, clipStyle: clipStyle)
if let badgeView = self.badgeView {
@ -655,7 +677,7 @@ public final class AvatarNode: ASDisplayNode {
self.editOverlayNode?.isHidden = true
}
parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer.id, colors: calculateColors(explicitColorIndex: nil, peerId: peer.id, nameColor: peer.nameColor, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle)
parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer.id, colors: calculateColors(context: genericContext, explicitColorIndex: nil, peerId: peer.id, nameColor: peer.nameColor, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle)
} else {
self.imageReady.set(.single(true))
self.displaySuspended = false
@ -664,7 +686,7 @@ public final class AvatarNode: ASDisplayNode {
}
self.editOverlayNode?.isHidden = true
let colors = calculateColors(explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), nameColor: peer?.nameColor, icon: icon, theme: theme)
let colors = calculateColors(context: genericContext, explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), nameColor: peer?.nameColor, icon: icon, theme: theme)
parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer?.id ?? EnginePeer.Id(0), colors: colors, letters: peer?.displayLetters ?? [], font: self.font, icon: icon, explicitColorIndex: nil, hasImage: false, clipStyle: clipStyle)
if let badgeView = self.badgeView {
@ -701,9 +723,9 @@ public final class AvatarNode: ASDisplayNode {
let parameters: AvatarNodeParameters
if let icon = icon, case .phone = icon {
parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(explicitColorIndex: explicitIndex, peerId: nil, nameColor: nil, icon: .phoneIcon, theme: nil), letters: [], font: self.font, icon: .phoneIcon, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round)
parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(context: nil, explicitColorIndex: explicitIndex, peerId: nil, nameColor: nil, icon: .phoneIcon, theme: nil), letters: [], font: self.font, icon: .phoneIcon, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round)
} else {
parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(explicitColorIndex: explicitIndex, peerId: nil, nameColor: nil, icon: .none, theme: nil), letters: letters, font: self.font, icon: .none, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round)
parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(context: nil, explicitColorIndex: explicitIndex, peerId: nil, nameColor: nil, icon: .none, theme: nil), letters: letters, font: self.font, icon: .none, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round)
}
self.displaySuspended = true

View File

@ -16,19 +16,19 @@ private enum PeerNameColorEntryId: Hashable {
}
private enum PeerNameColorEntry: Comparable, Identifiable {
case color(Int, PeerNameColor, PeerNameColors.Colors, Bool)
case color(Int, PeerNameColor, PeerNameColors.Colors, Bool, Bool)
var stableId: PeerNameColorEntryId {
switch self {
case let .color(_, color, _, _):
case let .color(_, color, _, _, _):
return .color(color.rawValue)
}
}
static func ==(lhs: PeerNameColorEntry, rhs: PeerNameColorEntry) -> Bool {
switch lhs {
case let .color(lhsIndex, lhsColor, lhsAccentColor, lhsSelected):
if case let .color(rhsIndex, rhsColor, rhsAccentColor, rhsSelected) = rhs, lhsIndex == rhsIndex, lhsColor == rhsColor, lhsAccentColor == rhsAccentColor, lhsSelected == rhsSelected {
case let .color(lhsIndex, lhsColor, lhsAccentColor, lhsIsDark, lhsSelected):
if case let .color(rhsIndex, rhsColor, rhsAccentColor, rhsIsDark, rhsSelected) = rhs, lhsIndex == rhsIndex, lhsColor == rhsColor, lhsAccentColor == rhsAccentColor, lhsIsDark == rhsIsDark, lhsSelected == rhsSelected {
return true
} else {
return false
@ -38,9 +38,9 @@ private enum PeerNameColorEntry: Comparable, Identifiable {
static func <(lhs: PeerNameColorEntry, rhs: PeerNameColorEntry) -> Bool {
switch lhs {
case let .color(lhsIndex, _, _, _):
case let .color(lhsIndex, _, _, _, _):
switch rhs {
case let .color(rhsIndex, _, _, _):
case let .color(rhsIndex, _, _, _, _):
return lhsIndex < rhsIndex
}
}
@ -48,8 +48,8 @@ private enum PeerNameColorEntry: Comparable, Identifiable {
func item(action: @escaping (PeerNameColor) -> Void) -> ListViewItem {
switch self {
case let .color(_, index, colors, selected):
return PeerNameColorIconItem(index: index, colors: colors, selected: selected, action: action)
case let .color(_, index, colors, isDark, selected):
return PeerNameColorIconItem(index: index, colors: colors, isDark: isDark, selected: selected, action: action)
}
}
}
@ -58,12 +58,14 @@ private enum PeerNameColorEntry: Comparable, Identifiable {
private class PeerNameColorIconItem: ListViewItem {
let index: PeerNameColor
let colors: PeerNameColors.Colors
let isDark: Bool
let selected: Bool
let action: (PeerNameColor) -> Void
public init(index: PeerNameColor, colors: PeerNameColors.Colors, selected: Bool, action: @escaping (PeerNameColor) -> Void) {
public init(index: PeerNameColor, colors: PeerNameColors.Colors, isDark: Bool, selected: Bool, action: @escaping (PeerNameColor) -> Void) {
self.index = index
self.colors = colors
self.isDark = isDark
self.selected = selected
self.action = action
}
@ -125,7 +127,7 @@ private func generateRingImage(nameColor: PeerNameColors.Colors) -> UIImage? {
})
}
func generatePeerNameColorImage(nameColor: PeerNameColors.Colors, bounds: CGSize = CGSize(width: 40.0, height: 40.0), size: CGSize = CGSize(width: 40.0, height: 40.0)) -> UIImage? {
func generatePeerNameColorImage(nameColor: PeerNameColors.Colors, isDark: Bool, bounds: CGSize = CGSize(width: 40.0, height: 40.0), size: CGSize = CGSize(width: 40.0, height: 40.0)) -> UIImage? {
return generateImage(bounds, rotatedContext: { contextSize, context in
let bounds = CGRect(origin: CGPoint(), size: contextSize)
context.clear(bounds)
@ -135,6 +137,13 @@ func generatePeerNameColorImage(nameColor: PeerNameColors.Colors, bounds: CGSize
context.clip()
if let secondColor = nameColor.secondary {
var firstColor = nameColor.main
var secondColor = secondColor
if isDark, nameColor.tertiary == nil {
firstColor = secondColor
secondColor = nameColor.main
}
context.setFillColor(secondColor.cgColor)
context.fill(circleBounds)
@ -143,7 +152,7 @@ func generatePeerNameColorImage(nameColor: PeerNameColors.Colors, bounds: CGSize
context.addLine(to: CGPoint(x: contextSize.width, y: contextSize.height))
context.addLine(to: CGPoint(x: 0.0, y: contextSize.height))
context.closePath()
context.setFillColor(nameColor.main.cgColor)
context.setFillColor(firstColor.cgColor)
context.fillPath()
context.setFillColor(thirdColor.cgColor)
@ -160,7 +169,7 @@ func generatePeerNameColorImage(nameColor: PeerNameColors.Colors, bounds: CGSize
context.addLine(to: CGPoint(x: contextSize.width, y: 0.0))
context.addLine(to: CGPoint(x: 0.0, y: contextSize.height))
context.closePath()
context.setFillColor(nameColor.main.cgColor)
context.setFillColor(firstColor.cgColor)
context.fillPath()
}
} else {
@ -232,7 +241,7 @@ private final class PeerNameColorIconItemNode : ListViewItemNode {
strongSelf.item = item
if updatedAccentColor {
strongSelf.fillNode.image = generatePeerNameColorImage(nameColor: item.colors)
strongSelf.fillNode.image = generatePeerNameColorImage(nameColor: item.colors, isDark: item.isDark)
strongSelf.ringNode.image = generateRingImage(nameColor: item.colors)
}
@ -526,7 +535,7 @@ final class PeerNameColorItemNode: ListViewItemNode, ItemListItemNode {
for index in item.colors.displayOrder {
let color = PeerNameColor(rawValue: index)
let colors = item.colors.get(color, dark: item.theme.overallDarkAppearance)
entries.append(.color(i, color, colors, color == item.currentColor))
entries.append(.color(i, color, colors, item.theme.overallDarkAppearance, color == item.currentColor))
i += 1
}

View File

@ -599,7 +599,7 @@ public func PeerNameColorScreen(
if let navigationController = controller?.navigationController as? NavigationController {
Queue.mainQueue().after(0.25) {
if let lastController = navigationController.viewControllers.last as? ViewController {
let tipController = UndoOverlayController(presentationData: presentationData, content: .image(image: generatePeerNameColorImage(nameColor: colors, bounds: CGSize(width: 32.0, height: 32.0), size: CGSize(width: 22.0, height: 22.0))!, title: nil, text: presentationData.strings.NameColor_YourColorUpdated, round: false, undoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })
let tipController = UndoOverlayController(presentationData: presentationData, content: .image(image: generatePeerNameColorImage(nameColor: colors, isDark: presentationData.theme.overallDarkAppearance, bounds: CGSize(width: 32.0, height: 32.0), size: CGSize(width: 22.0, height: 22.0))!, title: nil, text: presentationData.strings.NameColor_YourColorUpdated, round: false, undoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })
lastController.present(tipController, in: .window(.root))
}
}
@ -651,7 +651,7 @@ public func PeerNameColorScreen(
if let navigationController = controller?.navigationController as? NavigationController {
Queue.mainQueue().after(0.25) {
if let lastController = navigationController.viewControllers.last as? ViewController {
let tipController = UndoOverlayController(presentationData: presentationData, content: .image(image: generatePeerNameColorImage(nameColor: colors, bounds: CGSize(width: 32.0, height: 32.0), size: CGSize(width: 22.0, height: 22.0))!, title: nil, text: presentationData.strings.NameColor_ChannelColorUpdated, round: false, undoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })
let tipController = UndoOverlayController(presentationData: presentationData, content: .image(image: generatePeerNameColorImage(nameColor: colors, isDark: presentationData.theme.overallDarkAppearance, bounds: CGSize(width: 32.0, height: 32.0), size: CGSize(width: 22.0, height: 22.0))!, title: nil, text: presentationData.strings.NameColor_ChannelColorUpdated, round: false, undoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })
lastController.present(tipController, in: .window(.root))
}
}