feat: added background and foreground customization
05460409
4 file(s) · +50 −4
| 24 | 24 | /// The color used for toolbar buttons (navigation, menu, etc.) |
|
| 25 | 25 | @Published var toolbarButtonColor: Color = .blue |
|
| 26 | 26 | ||
| 27 | + | /// The background color for the main content area |
|
| 28 | + | @Published var backgroundColor: Color = Color(UIColor.systemBackground) |
|
| 29 | + | ||
| 30 | + | /// The text color for content |
|
| 31 | + | @Published var textColor: Color = Color(UIColor.label) |
|
| 32 | + | ||
| 27 | 33 | /// The home page URL that the browser navigates to on launch and when pressing Home |
|
| 28 | 34 | @AppStorage("homePage") var homePage: String = "gemini://geminiprotocol.net/" |
|
| 29 | 35 | ||
| 30 | 36 | /// Key for persisting accent color hex value |
|
| 31 | 37 | private static let accentColorKey = "accentColorHex" |
|
| 38 | + | private static let backgroundColorKey = "backgroundColorHex" |
|
| 39 | + | private static let textColorKey = "textColorHex" |
|
| 32 | 40 | ||
| 33 | 41 | init() { |
|
| 34 | 42 | if let hex = UserDefaults.standard.string(forKey: Self.accentColorKey), |
|
| 35 | 43 | let color = Color(hex: hex) { |
|
| 36 | - | setAllColors(color) |
|
| 44 | + | setAllAccentColors(color) |
|
| 45 | + | } |
|
| 46 | + | if let hex = UserDefaults.standard.string(forKey: Self.backgroundColorKey), |
|
| 47 | + | let color = Color(hex: hex) { |
|
| 48 | + | backgroundColor = color |
|
| 49 | + | } |
|
| 50 | + | if let hex = UserDefaults.standard.string(forKey: Self.textColorKey), |
|
| 51 | + | let color = Color(hex: hex) { |
|
| 52 | + | textColor = color |
|
| 37 | 53 | } |
|
| 38 | 54 | } |
|
| 39 | 55 | ||
| 40 | 56 | /// Sets all accent colors to the given color and persists the choice |
|
| 41 | - | func setAllColors(_ color: Color) { |
|
| 57 | + | func setAllAccentColors(_ color: Color) { |
|
| 42 | 58 | accentColor = color |
|
| 43 | 59 | progressBarColor = color |
|
| 44 | 60 | linkColor = color |
|
| 47 | 63 | ||
| 48 | 64 | if let hex = color.toHex() { |
|
| 49 | 65 | UserDefaults.standard.set(hex, forKey: Self.accentColorKey) |
|
| 66 | + | } |
|
| 67 | + | } |
|
| 68 | + | ||
| 69 | + | /// Sets the background color and persists the choice |
|
| 70 | + | func setBackgroundColor(_ color: Color) { |
|
| 71 | + | backgroundColor = color |
|
| 72 | + | if let hex = color.toHex() { |
|
| 73 | + | UserDefaults.standard.set(hex, forKey: Self.backgroundColorKey) |
|
| 74 | + | } |
|
| 75 | + | } |
|
| 76 | + | ||
| 77 | + | /// Sets the text color and persists the choice |
|
| 78 | + | func setTextColor(_ color: Color) { |
|
| 79 | + | textColor = color |
|
| 80 | + | if let hex = color.toHex() { |
|
| 81 | + | UserDefaults.standard.set(hex, forKey: Self.textColorKey) |
|
| 50 | 82 | } |
|
| 51 | 83 | } |
|
| 52 | 84 | } |
|
| 65 | 65 | } |
|
| 66 | 66 | } |
|
| 67 | 67 | .contentMargins(.top, 20, for: .scrollContent) |
|
| 68 | + | .background(themeSettings.backgroundColor) |
|
| 68 | 69 | .safeAreaInset(edge: .bottom) { |
|
| 69 | 70 | BrowserToolbar( |
|
| 70 | 71 | urlText: $urlText, |
| 11 | 11 | ||
| 12 | 12 | @State private var homePageText: String = "" |
|
| 13 | 13 | @State private var selectedAccentColor: Color = .blue |
|
| 14 | + | @State private var selectedBackgroundColor: Color = Color(UIColor.systemBackground) |
|
| 15 | + | @State private var selectedTextColor: Color = Color(UIColor.label) |
|
| 14 | 16 | ||
| 15 | 17 | var body: some View { |
|
| 16 | 18 | NavigationStack { |
|
| 28 | 30 | ||
| 29 | 31 | Section { |
|
| 30 | 32 | ColorPicker("Accent Color", selection: $selectedAccentColor, supportsOpacity: false) |
|
| 33 | + | ColorPicker("Background Color", selection: $selectedBackgroundColor, supportsOpacity: false) |
|
| 34 | + | ColorPicker("Text Color", selection: $selectedTextColor, supportsOpacity: false) |
|
| 31 | 35 | } header: { |
|
| 32 | 36 | Text("Appearance") |
|
| 33 | 37 | } footer: { |
|
| 34 | - | Text("Changes the color of links, buttons, and other interactive elements.") |
|
| 38 | + | Text("Customize the colors of your browser interface.") |
|
| 35 | 39 | } |
|
| 36 | 40 | } |
|
| 37 | 41 | .navigationTitle("Settings") |
|
| 45 | 49 | ToolbarItem(placement: .confirmationAction) { |
|
| 46 | 50 | Button("Save") { |
|
| 47 | 51 | themeSettings.homePage = homePageText |
|
| 48 | - | themeSettings.setAllColors(selectedAccentColor) |
|
| 52 | + | themeSettings.setAllAccentColors(selectedAccentColor) |
|
| 53 | + | themeSettings.setBackgroundColor(selectedBackgroundColor) |
|
| 54 | + | themeSettings.setTextColor(selectedTextColor) |
|
| 49 | 55 | dismiss() |
|
| 50 | 56 | } |
|
| 51 | 57 | } |
|
| 53 | 59 | .onAppear { |
|
| 54 | 60 | homePageText = themeSettings.homePage |
|
| 55 | 61 | selectedAccentColor = themeSettings.accentColor |
|
| 62 | + | selectedBackgroundColor = themeSettings.backgroundColor |
|
| 63 | + | selectedTextColor = themeSettings.textColor |
|
| 56 | 64 | } |
|
| 57 | 65 | } |
|
| 58 | 66 | } |
|
| 77 | 77 | case .text(let text): |
|
| 78 | 78 | Text(text) |
|
| 79 | 79 | .font(.system(.body, design: .monospaced)) |
|
| 80 | + | .foregroundColor(themeSettings.textColor) |
|
| 80 | 81 | ||
| 81 | 82 | case .link(let url, let label): |
|
| 82 | 83 | Button(action: { onLinkTap(url) }) { |
|
| 93 | 94 | Text(text) |
|
| 94 | 95 | .font(.system(.title, design: .monospaced)) |
|
| 95 | 96 | .fontWeight(.bold) |
|
| 97 | + | .foregroundColor(themeSettings.textColor) |
|
| 96 | 98 | .padding(.top, 8) |
|
| 97 | 99 | ||
| 98 | 100 | case .heading2(let text): |
|
| 99 | 101 | Text(text) |
|
| 100 | 102 | .font(.system(.title2, design: .monospaced)) |
|
| 101 | 103 | .fontWeight(.semibold) |
|
| 104 | + | .foregroundColor(themeSettings.textColor) |
|
| 102 | 105 | .padding(.top, 6) |
|
| 103 | 106 | ||
| 104 | 107 | case .heading3(let text): |
|
| 105 | 108 | Text(text) |
|
| 106 | 109 | .font(.system(.title3, design: .monospaced)) |
|
| 107 | 110 | .fontWeight(.medium) |
|
| 111 | + | .foregroundColor(themeSettings.textColor) |
|
| 108 | 112 | .padding(.top, 4) |
|
| 109 | 113 | ||
| 110 | 114 | case .listItem(let text): |
|
| 113 | 117 | Text(text) |
|
| 114 | 118 | } |
|
| 115 | 119 | .font(.system(.body, design: .monospaced)) |
|
| 120 | + | .foregroundColor(themeSettings.textColor) |
|
| 116 | 121 | ||
| 117 | 122 | case .quote(let text): |
|
| 118 | 123 | Text(text) |
|