add switch theme
This commit is contained in:
parent
dee0e7444d
commit
d502a059b9
@ -577,7 +577,7 @@
|
||||
"Спасибо!" : {
|
||||
|
||||
},
|
||||
"Тёмная тема" : {
|
||||
"Темы" : {
|
||||
|
||||
},
|
||||
"Уведомления" : {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ struct SideMenuView: View {
|
||||
effectiveScheme = colorScheme
|
||||
case .light:
|
||||
effectiveScheme = .light
|
||||
case .dark:
|
||||
case .oledDark:
|
||||
effectiveScheme = .dark
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user