// // MoodTintable.swift // Reflect (iOS) // // Created by Trey Tartt on 2/19/22. // import SwiftUI protocol MoodTintable { static func color(forMood mood: Mood) -> Color static func secondary(forMood mood: Mood) -> Color } enum MoodTints: Int, CaseIterable { case Default case Neon case Pastel case Custom static var defaultOptions: [MoodTints] { return [Default, Neon, Pastel] } func color(forMood mood: Mood) -> Color { switch self { case .Default: return DefaultMoodTint.color(forMood: mood) case .Custom: return CustomMoodTint.color(forMood: mood) case .Neon: return NeonMoodTint.color(forMood: mood) case .Pastel: return PastelTint.color(forMood: mood) } } func secondary(forMood mood: Mood) -> Color { switch self { case .Default: return DefaultMoodTint.secondary(forMood: mood) case .Custom: return CustomMoodTint.secondary(forMood: mood) case .Neon: return NeonMoodTint.secondary(forMood: mood) case .Pastel: return PastelTint.secondary(forMood: mood) } } /// Returns black or white text color based on the mood's background luminance func contrastingTextColor(forMood mood: Mood) -> Color { color(forMood: mood).contrastingTextColor } var moodTints: MoodTintable.Type { switch self { case .Default: return DefaultMoodTint.self case .Custom: return CustomMoodTint.self case .Neon: return NeonMoodTint.self case .Pastel: return PastelTint.self } } } final class SavedMoodTint: NSObject, ObservableObject, Codable { @Published var colorOne: Color @Published var colorTwo: Color @Published var colorThree: Color @Published var colorFour: Color @Published var colorFive: Color override init() { colorOne = Color(hex: "a92b26") colorTwo = Color(hex: "a92b26") colorThree = Color(hex: "a92b26") colorFour = Color(hex: "a92b26") colorFive = Color(hex: "a92b26") } enum CodingKeys: CodingKey { case colorOne, colorTwo, colorThree, colorFour, colorFive } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) colorOne = try container.decode(Color.self, forKey: .colorOne) colorTwo = try container.decode(Color.self, forKey: .colorTwo) colorThree = try container.decode(Color.self, forKey: .colorThree) colorFour = try container.decode(Color.self, forKey: .colorFour) colorFive = try container.decode(Color.self, forKey: .colorFive) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(colorOne, forKey: .colorOne) try container.encode(colorTwo, forKey: .colorTwo) try container.encode(colorThree, forKey: .colorThree) try container.encode(colorFour, forKey: .colorFour) try container.encode(colorFive, forKey: .colorFive) } } final class CustomMoodTint: MoodTintable { static func color(forMood mood: Mood) -> Color { switch mood { case .horrible: return UserDefaultsStore.getCustomMoodTint().colorFive case .bad: return UserDefaultsStore.getCustomMoodTint().colorFour case .average: return UserDefaultsStore.getCustomMoodTint().colorThree case .good: return UserDefaultsStore.getCustomMoodTint().colorTwo case .great: return UserDefaultsStore.getCustomMoodTint().colorOne case .missing: return Color(uiColor: UIColor.lightGray) case .placeholder: return Color(uiColor: UIColor.lightGray) } } static func secondary(forMood mood: Mood) -> Color { switch mood { case .horrible: return UserDefaultsStore.getCustomMoodTint().colorFive.darker(by: 40) case .bad: return UserDefaultsStore.getCustomMoodTint().colorFour.darker(by: 40) case .average: return UserDefaultsStore.getCustomMoodTint().colorThree.darker(by: 40) case .good: return UserDefaultsStore.getCustomMoodTint().colorTwo.darker(by: 40) case .great: return UserDefaultsStore.getCustomMoodTint().colorOne.darker(by: 40) case .missing: return Color(uiColor: UIColor.lightGray).darker(by: 40) case .placeholder: return Color(uiColor: UIColor.lightGray).darker(by: 40) } } } final class DefaultMoodTint: MoodTintable { static func color(forMood mood: Mood) -> Color { switch mood { case .horrible: return Color(hex: "ff453a") case .bad: return Color(hex: "ff9e0b") case .average: return Color(hex: "0b84ff") case .good: return Color(hex: "ffd709") case .great: return Color(hex: "31d158") case .missing: return Color(uiColor: UIColor.systemGray2) case .placeholder: return Color(uiColor: UIColor.systemGray2) } } static func secondary(forMood mood: Mood) -> Color { switch mood { case .horrible: return Color(hex: "a92b26") case .bad: return Color(hex: "a06407") case .average: return Color(hex: "074f9a") case .good: return Color(hex: "9d8405") case .great: return Color(hex: "208939") case .missing: return Color(uiColor: UIColor.label) case .placeholder: return Color(uiColor: UIColor.label) } } } final class AllRedMoodTint: MoodTintable { static func color(forMood mood: Mood) -> Color { switch mood { case .horrible: return .red case .bad: return .red case .average: return .red case .good: return .red case .great: return .red case .missing: return Color(uiColor: UIColor.systemGray2) case .placeholder: return Color(uiColor: UIColor.systemGray2) } } static func secondary(forMood mood: Mood) -> Color { switch mood { case .horrible: return .red case .bad: return .red case .average: return .red case .good: return .red case .great: return .red case .missing: return Color(uiColor: UIColor.label) case .placeholder: return Color(uiColor: UIColor.label) } } } final class NeonMoodTint: MoodTintable { // Synthwave color palette matching the Neon voting style private static let neonCyan = Color(red: 0.0, green: 1.0, blue: 0.82) private static let neonLime = Color(red: 0.2, green: 1.0, blue: 0.6) private static let neonYellow = Color(red: 1.0, green: 0.9, blue: 0.0) private static let neonOrange = Color(red: 1.0, green: 0.5, blue: 0.0) private static let neonMagenta = Color(red: 1.0, green: 0.0, blue: 0.8) static func color(forMood mood: Mood) -> Color { switch mood { case .horrible: return neonMagenta case .bad: return neonOrange case .average: return neonYellow case .good: return neonLime case .great: return neonCyan case .missing: return Color(uiColor: UIColor.systemGray2) case .placeholder: return Color(uiColor: UIColor.systemGray2) } } static func secondary(forMood mood: Mood) -> Color { switch mood { case .horrible: return neonMagenta.opacity(0.6) case .bad: return neonOrange.opacity(0.6) case .average: return neonYellow.opacity(0.6) case .good: return neonLime.opacity(0.6) case .great: return neonCyan.opacity(0.6) case .missing: return Color(uiColor: UIColor.label) case .placeholder: return Color(uiColor: UIColor.label) } } } final class MonoChromeTint: MoodTintable { static func color(forMood mood: Mood) -> Color { switch mood { case .horrible: return Color(hex: "#000000") case .bad: return Color(hex: "#47474a") case .average: return Color(hex: "#7b7b81") case .good: return Color(hex: "#a3a3ab") case .great: return Color(hex: "#c2c1cb") case .missing: return Color(hex: "#ff0000") case .placeholder: return Color(hex: "#efeffb") } } static func secondary(forMood mood: Mood) -> Color { switch mood { case .horrible: return .black case .bad: return Color(uiColor: UIColor.systemGray) case .average: return Color(uiColor: UIColor.systemGray) case .good: return Color(uiColor: UIColor.systemGray2) case .great: return Color(uiColor: UIColor.systemGray3) case .missing: return Color(uiColor: UIColor.systemGray2) case .placeholder: return Color(uiColor: UIColor.systemGray4) } } } final class PastelTint: MoodTintable { static func color(forMood mood: Mood) -> Color { switch mood { case .horrible: return Color(hex: "#FF6961") case .bad: return Color(hex: "#ffb347") case .average: return Color(hex: "#A7C7E7") case .good: return Color(hex: "#fdfd96") case .great: return Color(hex: "#C1E1C1") case .missing: return Color(uiColor: UIColor.systemGray2) case .placeholder: return Color(uiColor: UIColor.systemGray2) } } static func secondary(forMood mood: Mood) -> Color { switch mood { case .horrible: return Color(hex: "#893734") case .bad: return Color(hex: "#855d28") case .average: return Color(hex: "#5d6e83") case .good: return Color(hex: "#7f804f") case .great: return Color(hex: "#6b7e6d") case .missing: return Color(uiColor: UIColor.label) case .placeholder: return Color(uiColor: UIColor.label) } } }