Compare commits
2 Commits
a92cf8c812
...
f5e9f66f76
Author | SHA1 | Date |
---|---|---|
Shadowfacts | f5e9f66f76 | |
Shadowfacts | ee5f9a62ff |
|
@ -74,4 +74,9 @@ extension PreferenceStore {
|
||||||
public func hasFeatureFlag(_ flag: FeatureFlag) -> Bool {
|
public func hasFeatureFlag(_ flag: FeatureFlag) -> Bool {
|
||||||
enabledFeatureFlags.contains(flag)
|
enabledFeatureFlags.contains(flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public func getValue<Key: PreferenceKey>(preferenceKeyPath: KeyPath<PreferenceStore, PreferencePublisher<Key>>) -> Key.Value {
|
||||||
|
self[keyPath: preferenceKeyPath].preference.wrappedValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,26 +8,11 @@
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
import TuskerPreferences
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
@MainActor
|
func appGroupedListBackground(container: UIAppearanceContainer.Type) -> some View {
|
||||||
@ViewBuilder
|
self.modifier(AppGroupedListBackground(container: container))
|
||||||
func appGroupedListBackground(container: UIAppearanceContainer.Type, applyBackground: Bool = true) -> some View {
|
|
||||||
if #available(iOS 16.0, *) {
|
|
||||||
if applyBackground {
|
|
||||||
self
|
|
||||||
.scrollContentBackground(.hidden)
|
|
||||||
.background(Color.appGroupedBackground.edgesIgnoringSafeArea(.all))
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
.scrollContentBackground(.hidden)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
.onAppear {
|
|
||||||
UITableView.appearance(whenContainedInInstancesOf: [container]).backgroundColor = .appGroupedBackground
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func appGroupedListRowBackground() -> some View {
|
func appGroupedListRowBackground() -> some View {
|
||||||
|
@ -35,11 +20,45 @@ extension View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct AppGroupedListRowBackground: ViewModifier {
|
private struct AppGroupedListBackground: ViewModifier {
|
||||||
|
let container: any UIAppearanceContainer.Type
|
||||||
@Environment(\.colorScheme) private var colorScheme
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
@Environment(\.pureBlackDarkMode) private var environmentPureBlackDarkMode
|
||||||
|
|
||||||
|
private var pureBlackDarkMode: Bool {
|
||||||
|
// using @PreferenceObserving just does not work for this, so try the environment key when available
|
||||||
|
// if it's not available, the color won't update automatically, but it will be correct when the view is created
|
||||||
|
if #available(iOS 17.0, *) {
|
||||||
|
environmentPureBlackDarkMode
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
if colorScheme == .dark, !Preferences.shared.pureBlackDarkMode {
|
if #available(iOS 16.0, *) {
|
||||||
|
if colorScheme == .dark, !pureBlackDarkMode {
|
||||||
|
content
|
||||||
|
.scrollContentBackground(.hidden)
|
||||||
|
.background(Color.appGroupedBackground.edgesIgnoringSafeArea(.all))
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
.onAppear {
|
||||||
|
UITableView.appearance(whenContainedInInstancesOf: [container]).backgroundColor = .appGroupedBackground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct AppGroupedListRowBackground: ViewModifier {
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
@PreferenceObserving(\.$pureBlackDarkMode) private var pureBlackDarkMode
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
if colorScheme == .dark, !pureBlackDarkMode {
|
||||||
content
|
content
|
||||||
.listRowBackground(Color.appGroupedCellBackground)
|
.listRowBackground(Color.appGroupedCellBackground)
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,3 +66,31 @@ private struct AppGroupedListRowBackground: ViewModifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@propertyWrapper
|
||||||
|
private struct PreferenceObserving<Key: TuskerPreferences.PreferenceKey>: DynamicProperty {
|
||||||
|
typealias PrefKeyPath = KeyPath<PreferenceStore, PreferencePublisher<Key>>
|
||||||
|
|
||||||
|
let keyPath: PrefKeyPath
|
||||||
|
@StateObject private var observer: Observer
|
||||||
|
|
||||||
|
init(_ keyPath: PrefKeyPath) {
|
||||||
|
self.keyPath = keyPath
|
||||||
|
self._observer = StateObject(wrappedValue: Observer(keyPath: keyPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrappedValue: Key.Value {
|
||||||
|
Preferences.shared.getValue(preferenceKeyPath: keyPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
private class Observer: ObservableObject {
|
||||||
|
private var cancellable: AnyCancellable?
|
||||||
|
|
||||||
|
init(keyPath: PrefKeyPath) {
|
||||||
|
cancellable = Preferences.shared[keyPath: keyPath].sink { [unowned self] _ in
|
||||||
|
self.objectWillChange.send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -143,3 +143,33 @@ extension UIMutableTraits {
|
||||||
set { self[PureBlackDarkModeTrait.self] = newValue }
|
set { self[PureBlackDarkModeTrait.self] = newValue }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 17.0, *)
|
||||||
|
private struct PureBlackDarkModeKey: UITraitBridgedEnvironmentKey {
|
||||||
|
static let defaultValue: Bool = false
|
||||||
|
|
||||||
|
static func read(from traitCollection: UITraitCollection) -> Bool {
|
||||||
|
traitCollection[PureBlackDarkModeTrait.self]
|
||||||
|
}
|
||||||
|
|
||||||
|
static func write(to mutableTraits: inout any UIMutableTraits, value: Bool) {
|
||||||
|
mutableTraits[PureBlackDarkModeTrait.self] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnvironmentValues {
|
||||||
|
var pureBlackDarkMode: Bool {
|
||||||
|
get {
|
||||||
|
if #available(iOS 17.0, *) {
|
||||||
|
self[PureBlackDarkModeKey.self]
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if #available(iOS 17.0, *) {
|
||||||
|
self[PureBlackDarkModeKey.self] = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ private struct PushSubscriptionSettingsView: View {
|
||||||
// status notifications not supported until we can enable/disable them in the app
|
// status notifications not supported until we can enable/disable them in the app
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.groupBoxStyle(AppBackgroundGroupBoxStyle())
|
||||||
}
|
}
|
||||||
|
|
||||||
private var allSupportedAlertTypes: PushSubscription.Alerts {
|
private var allSupportedAlertTypes: PushSubscription.Alerts {
|
||||||
|
@ -125,6 +126,19 @@ private extension PushSubscription.Policy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct AppBackgroundGroupBoxStyle: GroupBoxStyle {
|
||||||
|
func makeBody(configuration: Configuration) -> some View {
|
||||||
|
VStack(alignment: .leading, spacing: 16) {
|
||||||
|
configuration.label
|
||||||
|
.font(.headline)
|
||||||
|
|
||||||
|
configuration.content
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.background(Color.appGroupedBackground, in: RoundedRectangle(cornerRadius: 8))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//#Preview {
|
//#Preview {
|
||||||
// PushSubscriptionView()
|
// PushSubscriptionView()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -157,7 +157,7 @@ struct ReportView: View {
|
||||||
.appGroupedListRowBackground()
|
.appGroupedListRowBackground()
|
||||||
}
|
}
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
.appGroupedListBackground(container: UIHostingController<ReportView>.self, applyBackground: true)
|
.appGroupedListBackground(container: UIHostingController<ReportView>.self)
|
||||||
.alertWithData("Error Reporting", data: $error, actions: { error in
|
.alertWithData("Error Reporting", data: $error, actions: { error in
|
||||||
Button("OK") {}
|
Button("OK") {}
|
||||||
}, message: { error in
|
}, message: { error in
|
||||||
|
|
Loading…
Reference in New Issue