fix: render 3-digit shorthand label colors instead of falling back to gray

This commit is contained in:
systemblue 2026-06-11 21:47:08 +02:00 committed by secana
parent f8a050e484
commit 6c053741c5
2 changed files with 58 additions and 8 deletions

View file

@ -19,10 +19,7 @@ struct IssueLabelView: View {
}
private var textColor: Color {
let hex = label.color.trimmingCharacters(in: CharacterSet(charactersIn: "#"))
guard hex.count == 6,
let rgb = UInt64(hex, radix: 16)
else {
guard let rgb = Color.rgbValue(hex: label.color) else {
return .white
}
let red = Double((rgb >> 16) & 0xFF) / 255.0
@ -35,10 +32,7 @@ struct IssueLabelView: View {
extension Color {
init?(hex: String) {
let hex = hex.trimmingCharacters(in: CharacterSet(charactersIn: "#"))
guard hex.count == 6,
let rgb = UInt64(hex, radix: 16)
else {
guard let rgb = Color.rgbValue(hex: hex) else {
return nil
}
self.init(
@ -47,6 +41,21 @@ extension Color {
blue: Double(rgb & 0xFF) / 255.0,
)
}
/// Parses a 6-digit or 3-digit shorthand hex color into its RGB value,
/// expanding the shorthand the same way Forgejo normalizes label colors
/// (#f00 -> #ff0000). Labels created before Forgejo normalized colors on
/// write can still carry the shorthand form.
static func rgbValue(hex: String) -> UInt64? {
var hex = hex.trimmingCharacters(in: CharacterSet(charactersIn: "#"))
if hex.count == 3 {
hex = hex.map { "\($0)\($0)" }.joined()
}
guard hex.count == 6 else {
return nil
}
return UInt64(hex, radix: 16)
}
}
#if DEBUG

View file

@ -0,0 +1,41 @@
@testable import Forji
import SwiftUI
import Testing
struct LabelColorHexTests {
// MARK: - Six-digit colors
@Test("six digit hex parses") func sixDigitHexParses() {
#expect(Color(hex: "#ff0000") != nil)
#expect(Color(hex: "00ff00") != nil)
}
@Test("six digit value matches") func sixDigitValueMatches() throws {
let rgb = try #require(Color.rgbValue(hex: "#3366cc"))
#expect(rgb == 0x3366CC)
}
// MARK: - Three-digit shorthand
@Test("three digit shorthand parses") func threeDigitShorthandParses() {
#expect(Color(hex: "#f00") != nil)
#expect(Color(hex: "abc") != nil)
}
@Test("three digit shorthand expands like six digit") func threeDigitShorthandExpandsLikeSixDigit() throws {
#expect(Color(hex: "#f00") == Color(hex: "#ff0000"))
#expect(Color(hex: "abc") == Color(hex: "aabbcc"))
let rgb = try #require(Color.rgbValue(hex: "#f00"))
#expect(rgb == 0xFF0000)
}
// MARK: - Invalid input
@Test("invalid hex returns nil") func invalidHexReturnsNil() {
#expect(Color(hex: "") == nil)
#expect(Color(hex: "#ff00") == nil)
#expect(Color(hex: "12345") == nil)
#expect(Color(hex: "xyzxyz") == nil)
#expect(Color(hex: "#xyz") == nil)
}
}