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 digitColor: Color = .white
|
||||||
@State private var backgroundColor: Color = .black
|
@State private var backgroundColor: Color = .black
|
||||||
|
@State private var showAdvancedSettings = false
|
||||||
|
|
||||||
// MARK: - Init
|
// MARK: - Init
|
||||||
init(style: ClockStyle, onCommit: @escaping (ClockStyle) -> Void) {
|
init(style: ClockStyle, onCommit: @escaping (ClockStyle) -> Void) {
|
||||||
@ -27,17 +28,38 @@ struct ClockSettingsView: View {
|
|||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
Form {
|
Form {
|
||||||
TimeFormatSection(style: $style)
|
// BASIC SETTINGS - Most commonly used
|
||||||
FontSection(style: $style)
|
BasicAppearanceSection(
|
||||||
AppearanceSection(
|
|
||||||
style: $style,
|
style: $style,
|
||||||
digitColor: $digitColor,
|
digitColor: $digitColor,
|
||||||
backgroundColor: $backgroundColor,
|
backgroundColor: $backgroundColor,
|
||||||
onCommit: onCommit
|
onCommit: onCommit
|
||||||
)
|
)
|
||||||
NightModeSection(style: $style)
|
|
||||||
DisplaySection(style: $style)
|
BasicDisplaySection(style: $style)
|
||||||
OverlaySection(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")
|
.navigationTitle("Clock Settings")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
@ -53,6 +75,156 @@ struct ClockSettingsView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Supporting Views
|
// 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 {
|
private struct FontSection: View {
|
||||||
@Binding var style: ClockStyle
|
@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 {
|
private struct NightModeSection: View {
|
||||||
@Binding var style: ClockStyle
|
@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 {
|
private struct TimePickerView: View {
|
||||||
@Binding var timeString: String
|
@Binding var timeString: String
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user