Tusker/Tusker/Screens/Preferences/Notifications/TriStateToggle.swift

71 lines
1.6 KiB
Swift

//
// TriStateToggle.swift
// Tusker
//
// Created by Shadowfacts on 4/7/24.
// Copyright © 2024 Shadowfacts. All rights reserved.
//
import SwiftUI
struct TriStateToggle: View {
let titleKey: LocalizedStringKey
@Binding var mode: Mode
let onChange: (Bool) async -> Void
@State private var isOn: Bool
init(titleKey: LocalizedStringKey, mode: Binding<Mode>, onChange: @escaping (Bool) async -> Void) {
self.titleKey = titleKey
self._mode = mode
self.onChange = onChange
self.isOn = mode.wrappedValue == .on
}
var body: some View {
toggleOrSpinner
.onChange(of: mode) { newValue in
switch newValue {
case .off:
isOn = false
case .loading:
break
case .on:
isOn = true
}
}
}
@ViewBuilder
private var toggleOrSpinner: some View {
if mode == .loading {
ProgressView()
} else {
Toggle(titleKey, isOn: Binding {
isOn
} set: { newValue in
isOn = newValue
mode = .loading
Task {
await onChange(newValue)
mode = newValue ? .on : .off
}
})
.labelsHidden()
}
}
enum Mode {
case off
case loading
case on
}
}
#Preview {
@State var mode = TriStateToggle.Mode.on
return TriStateToggle(titleKey: "", mode: $mode) { _ in
try! await Task.sleep(nanoseconds: NSEC_PER_SEC)
}
}