Files
Reflect/Shared/Models/Theme.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

226 lines
5.5 KiB
Swift

//
// theme.currentTheme.swift
// Reflect (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()
}
}
var preferredColorScheme: ColorScheme? {
switch self {
case .system, .iFeel:
return nil // Follow system
case .dark:
return .dark
case .light:
return .light
}
}
}
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))
}
)
}
}