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