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 {
case system = "System"
case light = "Light"
case dark = "Dark"
case oledDark = "Oled"
// case dark = "Dark" // TODO
var colorScheme: ColorScheme? {
switch self {
@ -12,7 +13,7 @@ enum Theme: String, CaseIterable {
return nil
case .light:
return .light
case .dark:
case .oledDark:
return .dark
}
}
@ -42,10 +43,10 @@ class ThemeManager: ObservableObject {
switch theme {
case .system:
// 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:
newTheme = .dark
case .dark:
newTheme = .oledDark
case .oledDark:
newTheme = .light
}
setTheme(newTheme)

View File

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

View File

@ -2,7 +2,79 @@ import SwiftUI
struct SettingsView: View {
@ObservedObject var viewModel: LoginViewModel
@EnvironmentObject private var themeManager: ThemeManager
@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 {
Form {
@ -32,8 +104,18 @@ struct SettingsView: View {
Label("Язык", systemImage: "globe")
}
Toggle(isOn: $isDarkMode) {
Label("Тёмная тема", systemImage: "moon.fill")
DisclosureGroup(isExpanded: $isThemeExpanded) {
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("Заглушка: Хранилище данных")) {
@ -95,4 +177,37 @@ struct SettingsView: View {
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
case .light:
effectiveScheme = .light
case .dark:
case .oledDark:
effectiveScheme = .dark
}