Files
Reflect/Shared/Models/Theme.swift
Trey t c4e013763a Fix theme selection bug and update onboarding with AppTheme picker
- Change Theme enum from Int to String raw values to fix theme selection bug
- Replace OnboardingStyle icon/color pickers with unified AppTheme grid
- Remove visible text labels from voting layouts while keeping accessibility labels (WCAG 2.1 AA compliant)
- Update widget voting views to use icons only with proper accessibility support
- Consolidate app icons to single unified icon set

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 00:03:34 -06:00

215 lines
5.3 KiB
Swift

//
// theme.currentTheme.swift
// Feels (iOS)
//
// Created by Trey Tartt on 2/4/22.
//
import SwiftUI
struct ThemeConstants {
static let iconSize: CGFloat = 50
}
enum Theme: String, CaseIterable {
case system = "system"
case iFeel = "iFeel"
case dark = "dark"
case light = "light"
// Legacy Int-based init for backwards compatibility with existing UserDefaults data
init?(legacyIntValue: Int) {
switch legacyIntValue {
case 0: self = .system
case 1: self = .iFeel
case 2: self = .dark
case 3: self = .light
default: return nil
}
}
var title: String {
switch self {
case .system:
return SystemTheme.title
case .iFeel:
return IFeelTheme.title
case .dark:
return AlwaysDark.title
case .light:
return AlwaysLight.title
}
}
var currentTheme: Themeable {
switch self {
case .system:
return SystemTheme()
case .iFeel:
return IFeelTheme()
case .dark:
return AlwaysDark()
case .light:
return AlwaysLight()
}
}
}
protocol Themeable {
static var title: String { get }
var secondaryBGColor: Color { get }
var bgColor: Color { get }
var bg: AnyView { get }
var preview: AnyView { get }
var labelColor: Color { get }
}
struct IFeelTheme: Themeable {
var bgColor: Color {
return Color(uiColor: UIColor.systemBackground)
}
var labelColor: Color {
return Color(uiColor: UIColor.label)
}
static var title: String {
return "iFeel"
}
var secondaryBGColor: Color {
return Color(uiColor: UIColor.secondarySystemBackground)
}
var bg: AnyView {
return AnyView(
BGView().equatable()
)
}
var preview: AnyView {
return AnyView(
ZStack {
BGView().equatable()
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
)
}
}
struct SystemTheme: Themeable {
var bgColor: Color {
return Color(uiColor: UIColor.systemBackground)
}
var labelColor: Color {
return Color(uiColor: UIColor.label)
}
static var title: String {
return "System"
}
var secondaryBGColor: Color {
return Color(uiColor: UIColor.secondarySystemBackground)
}
var bg: AnyView {
return AnyView(
ZStack {
Rectangle()
.fill(Color(UIColor.systemBackground))
}
)
}
var preview: AnyView {
return AnyView(
ZStack {
Rectangle()
.fill(Color(UIColor.secondarySystemBackground))
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
)
}
}
struct AlwaysDark: Themeable {
var bgColor: Color {
return Color(uiColor: UIColor.systemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark)))
}
var labelColor: Color {
return .white
}
static var title: String {
return "Dark"
}
var secondaryBGColor: Color {
return Color(uiColor: UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark)))
}
var bg: AnyView {
return AnyView(
ZStack {
Rectangle()
.fill(Color(UIColor.systemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark))))
}
)
}
var preview: AnyView {
return AnyView(
ZStack {
Rectangle()
.fill(Color(UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .dark))))
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
)
}
}
struct AlwaysLight: Themeable {
var bgColor: Color {
return Color(uiColor: UIColor.systemBackground)
}
var labelColor: Color {
return .black
}
static var title: String {
return "Light"
}
var secondaryBGColor: Color {
return Color(uiColor: UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .light)))
}
var bg: AnyView {
return AnyView(
ZStack {
Rectangle()
.fill(Color(UIColor.systemBackground.resolvedColor(with: .init(userInterfaceStyle: .light))))
}
)
}
var preview: AnyView {
return AnyView(
ZStack {
Rectangle()
.fill(Color(UIColor.secondarySystemBackground.resolvedColor(with: .init(userInterfaceStyle: .light))))
.frame(width: ThemeConstants.iconSize, height: ThemeConstants.iconSize)
.clipShape(RoundedRectangle(cornerRadius: 25, style: .continuous))
}
)
}
}