Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
05cd4f10e6
commit
7f6f5817e1
@ -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
|
||||
)
|
||||
NightModeSection(style: $style)
|
||||
DisplaySection(style: $style)
|
||||
OverlaySection(style: $style)
|
||||
|
||||
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)
|
||||
|
||||
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("24‑Hour 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("24‑Hour", 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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user