Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2025-09-10 12:51:13 -05:00
parent 05cd4f10e6
commit 7f6f5817e1

View File

@ -16,6 +16,7 @@ struct ClockSettingsView: View {
@State private var digitColor: Color = .white
@State private var backgroundColor: Color = .black
@State private var showAdvancedSettings = false
// MARK: - Init
init(style: ClockStyle, onCommit: @escaping (ClockStyle) -> Void) {
@ -27,17 +28,38 @@ struct ClockSettingsView: View {
var body: some View {
NavigationView {
Form {
TimeFormatSection(style: $style)
FontSection(style: $style)
AppearanceSection(
// BASIC SETTINGS - Most commonly used
BasicAppearanceSection(
style: $style,
digitColor: $digitColor,
backgroundColor: $backgroundColor,
onCommit: onCommit
)
BasicDisplaySection(style: $style)
// ADVANCED SETTINGS - Toggle to show/hide
if showAdvancedSettings {
AdvancedAppearanceSection(
style: $style,
digitColor: $digitColor,
backgroundColor: $backgroundColor,
onCommit: onCommit
)
FontSection(style: $style)
NightModeSection(style: $style)
DisplaySection(style: $style)
OverlaySection(style: $style)
AdvancedDisplaySection(style: $style)
}
// TOGGLE FOR ADVANCED SETTINGS
Section {
Toggle("Show Advanced Settings", isOn: $showAdvancedSettings)
}
}
.navigationTitle("Clock Settings")
.navigationBarTitleDisplayMode(.inline)
@ -53,6 +75,156 @@ struct ClockSettingsView: View {
}
// MARK: - Supporting Views
// MARK: - Basic Settings Sections
private struct BasicAppearanceSection: View {
@Binding var style: ClockStyle
@Binding var digitColor: Color
@Binding var backgroundColor: Color
let onCommit: (ClockStyle) -> Void
var body: some View {
Section(header: Text("Colors"), footer: Text("Choose your favorite color theme or create a custom look.")) {
// Color Theme Picker
Picker("Color Theme", selection: $style.selectedColorTheme) {
ForEach(ClockStyle.availableColorThemes(), id: \.0) { theme in
HStack {
Circle()
.fill(themeColor(for: theme.0))
.frame(width: 20, height: 20)
Text(theme.1)
}
.tag(theme.0)
}
}
.pickerStyle(.menu)
.onChange(of: style.selectedColorTheme) { _, newTheme in
if newTheme != "Custom" {
style.applyColorTheme(newTheme)
digitColor = Color(hex: style.digitColorHex) ?? .white
backgroundColor = Color(hex: style.backgroundHex) ?? .black
}
}
// Custom color pickers (only show if Custom is selected)
if style.selectedColorTheme == "Custom" {
ColorPicker("Digit Color", selection: $digitColor, supportsOpacity: false)
ColorPicker("Background Color", selection: $backgroundColor, supportsOpacity: true)
}
}
.onChange(of: backgroundColor) { _, newValue in
style.backgroundHex = newValue.toHex() ?? AppConstants.Defaults.backgroundColorHex
style.selectedColorTheme = "Custom"
style.clearColorCache()
}
.onChange(of: digitColor) { _, newValue in
style.digitColorHex = newValue.toHex() ?? AppConstants.Defaults.digitColorHex
style.selectedColorTheme = "Custom"
style.clearColorCache()
}
}
/// Get the color for a theme
private func themeColor(for theme: String) -> Color {
switch theme {
case "Custom":
return .gray
case "Red":
return .red
case "Orange":
return .orange
case "Yellow":
return .yellow
case "Green":
return .green
case "Blue":
return .blue
case "Purple":
return .purple
case "Pink":
return .pink
case "White":
return .white
default:
return .gray
}
}
}
private struct BasicDisplaySection: View {
@Binding var style: ClockStyle
var body: some View {
Section(header: Text("Display"), footer: Text("Basic display settings for your clock.")) {
Toggle("24Hour Format", isOn: $style.use24Hour)
Toggle("Show Seconds", isOn: $style.showSeconds)
Toggle("Auto Brightness", isOn: $style.autoBrightness)
}
}
}
// MARK: - Advanced Settings Sections
private struct AdvancedAppearanceSection: View {
@Binding var style: ClockStyle
@Binding var digitColor: Color
@Binding var backgroundColor: Color
let onCommit: (ClockStyle) -> Void
var body: some View {
Section(header: Text("Advanced Appearance"), footer: Text("Fine-tune the visual appearance of your clock.")) {
Toggle("Randomize Color (every minute)", isOn: $style.randomizeColor)
Toggle("Stretched (auto-fit)", isOn: $style.stretched)
if !style.stretched {
HStack {
Text("Size")
Slider(value: $style.digitScale, in: 0.0...1.0)
Text("\(Int((min(max(style.digitScale, 0.0), 1.0)) * 100))%")
.frame(width: 50, alignment: .trailing)
}
}
HStack {
Text("Glow")
Slider(value: $style.glowIntensity, in: 0...1)
Text("\(Int(style.glowIntensity * 100))%")
.frame(width: 50, alignment: .trailing)
}
HStack {
Text("Clock Opacity")
Slider(value: $style.clockOpacity, in: 0.0...1.0)
Text("\(Int(style.clockOpacity * 100))%")
.frame(width: 50, alignment: .trailing)
}
}
}
}
private struct AdvancedDisplaySection: View {
@Binding var style: ClockStyle
var body: some View {
Section(header: Text("Advanced Display"), footer: Text("Advanced display and system integration settings.")) {
Toggle("Keep Awake in Display Mode", isOn: $style.keepAwake)
if style.autoBrightness {
HStack {
Text("Current Brightness")
Spacer()
Text("\(Int(style.effectiveBrightness * 100))%")
.foregroundColor(.secondary)
}
}
}
Section(header: Text("Focus Modes"), footer: Text("Control how the app behaves when Focus modes (Do Not Disturb) are active.")) {
Toggle("Respect Focus Modes", isOn: $style.respectFocusModes)
}
}
}
private struct FontSection: View {
@Binding var style: ClockStyle
@ -104,113 +276,6 @@ private struct FontSection: View {
}
}
private struct TimeFormatSection: View {
@Binding var style: ClockStyle
var body: some View {
Section(header: Text("Time")) {
Toggle("24Hour", isOn: $style.use24Hour)
Toggle("Show Seconds", isOn: $style.showSeconds)
}
}
}
private struct AppearanceSection: View {
@Binding var style: ClockStyle
@Binding var digitColor: Color
@Binding var backgroundColor: Color
let onCommit: (ClockStyle) -> Void
var body: some View {
Section(header: Text("Appearance")) {
// Color Theme Picker
Picker("Color Theme", selection: $style.selectedColorTheme) {
ForEach(ClockStyle.availableColorThemes(), id: \.0) { theme in
HStack {
Circle()
.fill(themeColor(for: theme.0))
.frame(width: 20, height: 20)
Text(theme.1)
}
.tag(theme.0)
}
}
.pickerStyle(.menu)
.onChange(of: style.selectedColorTheme) { _, newTheme in
if newTheme != "Custom" {
style.applyColorTheme(newTheme)
digitColor = Color(hex: style.digitColorHex) ?? .white
backgroundColor = Color(hex: style.backgroundHex) ?? .black
}
}
ColorPicker("Background Color", selection: $backgroundColor, supportsOpacity: true)
ColorPicker("Digit Color", selection: $digitColor, supportsOpacity: false)
Toggle("Randomize Color (every minute)", isOn: $style.randomizeColor)
Toggle("Stretched (auto-fit)", isOn: $style.stretched)
if !style.stretched {
HStack {
Text("Size")
Slider(value: $style.digitScale, in: 0.0...1.0)
Text("\(Int((min(max(style.digitScale, 0.0), 1.0)) * 100))%")
.frame(width: 50, alignment: .trailing)
}
}
HStack {
Text("Glow")
Slider(value: $style.glowIntensity, in: 0...1)
Text("\(Int(style.glowIntensity * 100))%")
.frame(width: 50, alignment: .trailing)
}
HStack {
Text("Clock Opacity")
Slider(value: $style.clockOpacity, in: 0.0...1.0)
Text("\(Int(style.clockOpacity * 100))%")
.frame(width: 50, alignment: .trailing)
}
}
.onChange(of: backgroundColor) { _, newValue in
style.backgroundHex = newValue.toHex() ?? AppConstants.Defaults.backgroundColorHex
style.selectedColorTheme = "Custom"
style.clearColorCache()
}
.onChange(of: digitColor) { _, newValue in
style.digitColorHex = newValue.toHex() ?? AppConstants.Defaults.digitColorHex
style.selectedColorTheme = "Custom"
style.clearColorCache()
}
}
/// Get the color for a theme
private func themeColor(for theme: String) -> Color {
switch theme {
case "Custom":
return .gray
case "Red":
return .red
case "Orange":
return .orange
case "Yellow":
return .yellow
case "Green":
return .green
case "Blue":
return .blue
case "Purple":
return .purple
case "Pink":
return .pink
case "White":
return .white
default:
return .gray
}
}
}
private struct NightModeSection: View {
@Binding var style: ClockStyle
@ -289,32 +354,6 @@ private struct OverlaySection: View {
}
}
private struct DisplaySection: View {
@Binding var style: ClockStyle
var body: some View {
Section(header: Text("Display"), footer: Text("Keep the screen awake when in full-screen display mode. This prevents the device from sleeping while viewing the clock.")) {
Toggle("Keep Awake in Display Mode", isOn: $style.keepAwake)
}
Section(header: Text("Auto Brightness"), footer: Text("Automatically adjust display brightness based on color theme and ambient light. Works with all color themes and night mode.")) {
Toggle("Auto Brightness", isOn: $style.autoBrightness)
if style.autoBrightness {
HStack {
Text("Current Brightness")
Spacer()
Text("\(Int(style.effectiveBrightness * 100))%")
.foregroundColor(.secondary)
}
}
}
Section(header: Text("Focus Modes"), footer: Text("Control how the app behaves when Focus modes (Do Not Disturb) are active. When enabled, audio may be paused during Focus mode.")) {
Toggle("Respect Focus Modes", isOn: $style.respectFocusModes)
}
}
}
private struct TimePickerView: View {
@Binding var timeString: String