Files
Reflect/Shared/Models/MoodTintable.swift
Trey t 0442eab1f8 Rebrand entire project from Feels to Reflect
Complete rename across all bundle IDs, App Groups, CloudKit containers,
StoreKit product IDs, data store filenames, URL schemes, logger subsystems,
Swift identifiers, user-facing strings (7 languages), file names, directory
names, Xcode project, schemes, assets, and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 11:47:16 -06:00

354 lines
11 KiB
Swift

//
// 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)
}
}
}