add switch theme

This commit is contained in:
cheykrym 2025-10-06 23:06:23 +03:00
parent dee0e7444d
commit d502a059b9
5 changed files with 126 additions and 10 deletions

View File

@ -577,7 +577,7 @@
"Спасибо!" : { "Спасибо!" : {
}, },
"Тёмная тема" : { "Темы" : {
}, },
"Уведомления" : { "Уведомления" : {

View File

@ -4,7 +4,8 @@ import SwiftUI
enum Theme: String, CaseIterable { enum Theme: String, CaseIterable {
case system = "System" case system = "System"
case light = "Light" case light = "Light"
case dark = "Dark" case oledDark = "Oled"
// case dark = "Dark" // TODO
var colorScheme: ColorScheme? { var colorScheme: ColorScheme? {
switch self { switch self {
@ -12,7 +13,7 @@ enum Theme: String, CaseIterable {
return nil return nil
case .light: case .light:
return .light return .light
case .dark: case .oledDark:
return .dark return .dark
} }
} }
@ -42,10 +43,10 @@ class ThemeManager: ObservableObject {
switch theme { switch theme {
case .system: case .system:
// If system is active, toggle to the opposite of the current system theme // If system is active, toggle to the opposite of the current system theme
newTheme = currentSystemScheme == .dark ? .light : .dark newTheme = currentSystemScheme == .dark ? .light : .oledDark
case .light: case .light:
newTheme = .dark newTheme = .oledDark
case .dark: case .oledDark:
newTheme = .light newTheme = .light
} }
setTheme(newTheme) setTheme(newTheme)

View File

@ -163,7 +163,7 @@ struct LoginView: View {
return colorScheme == .dark ? "moon.fill" : "sun.max.fill" return colorScheme == .dark ? "moon.fill" : "sun.max.fill"
case .light: case .light:
return "sun.max.fill" return "sun.max.fill"
case .dark: case .oledDark:
return "moon.fill" return "moon.fill"
} }
} }

View File

@ -2,7 +2,79 @@ import SwiftUI
struct SettingsView: View { struct SettingsView: View {
@ObservedObject var viewModel: LoginViewModel @ObservedObject var viewModel: LoginViewModel
@EnvironmentObject private var themeManager: ThemeManager
@AppStorage("isDarkMode") private var isDarkMode: Bool = true @AppStorage("isDarkMode") private var isDarkMode: Bool = true
@State private var isThemeExpanded = false
private let themeOptions: [ThemeOption] = [.system, .dark, .oledDark, .lightTest, .custom]
private enum ThemeOption: String, CaseIterable, Identifiable {
case system
case dark
case oledDark
case lightTest
case custom
var id: String { rawValue }
var title: String {
switch self {
case .system:
return "Системная"
case .oledDark:
return "OLED тёмная"
case .lightTest:
return "Светлая"
case .custom:
return "Кастомная"
case .dark:
return "Тёмная"
}
}
var note: String? {
switch self {
case .lightTest:
return "Тестовая версия"
case .custom, .dark:
return "Недоступна"
default:
return nil
}
}
var isEnabled: Bool {
switch self {
case .custom, .dark:
return false
default:
return true
}
}
var mappedTheme: Theme? {
switch self {
case .system:
return .system
case .lightTest:
return .light
case .oledDark:
return .oledDark
case .custom, .dark:
return nil
}
}
}
private var selectedThemeOption: ThemeOption {
switch themeManager.theme {
case .system:
return .system
case .light:
return .lightTest
case .oledDark:
return .oledDark
}
}
var body: some View { var body: some View {
Form { Form {
@ -32,8 +104,18 @@ struct SettingsView: View {
Label("Язык", systemImage: "globe") Label("Язык", systemImage: "globe")
} }
Toggle(isOn: $isDarkMode) { DisclosureGroup(isExpanded: $isThemeExpanded) {
Label("Тёмная тема", systemImage: "moon.fill") VStack(alignment: .leading, spacing: 12) {
ForEach(Array(themeOptions.enumerated()), id: \.element.id) { index, option in
themeRow(for: option)
if index < themeOptions.count - 1 {
Divider()
}
}
}
.padding(.vertical, 4)
} label: {
Label("Темы", systemImage: "moon.fill")
} }
NavigationLink(destination: Text("Заглушка: Хранилище данных")) { NavigationLink(destination: Text("Заглушка: Хранилище данных")) {
@ -95,4 +177,37 @@ struct SettingsView: View {
UIApplication.shared.open(url) UIApplication.shared.open(url)
} }
private func themeRow(for option: ThemeOption) -> some View {
let isSelected = option == selectedThemeOption
return Button(action: {
selectTheme(option)
}) {
HStack(spacing: 12) {
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.foregroundColor(isSelected ? .accentColor : .secondary)
VStack(alignment: .leading, spacing: 2) {
Text(option.title)
.foregroundColor(.primary)
if let note = option.note {
Text(note)
.font(.caption)
.foregroundColor(.secondary)
}
}
Spacer()
}
.contentShape(Rectangle())
}
.disabled(!option.isEnabled)
.opacity(option.isEnabled ? 1.0 : 0.5)
.buttonStyle(.plain)
}
private func selectTheme(_ option: ThemeOption) {
guard let mappedTheme = option.mappedTheme else { return }
themeManager.setTheme(mappedTheme)
isDarkMode = mappedTheme == .oledDark
}
} }

View File

@ -93,7 +93,7 @@ struct SideMenuView: View {
effectiveScheme = colorScheme effectiveScheme = colorScheme
case .light: case .light:
effectiveScheme = .light effectiveScheme = .light
case .dark: case .oledDark:
effectiveScheme = .dark effectiveScheme = .dark
} }