Fix the lag of the display setting sliders (#1342) close #1341

* Fix the lag of the display setting sliders

The sliders in the display settings were laggy because changing the value in the
theme class needs comparatively much time. This writing to the class is now
only done when the user lets go of the slider, so sliding it is responsive. I
was unable to make writing to the class more responsive, the example post needs
therefore a short time before it accepts the new values. Furthermore, all
AppStorage keys are now realized with a ThemeKey to clean the class up.
Fixes #1341

Signed-off-by: Paul Schuetz <pa.schuetz@web.de>

* Remove unnecessary changes to theme

The changing of theme keys is unnecessary for the fix oft the lag, so it's
removed.

Signed-off-by: Paul Schuetz <pa.schuetz@web.de>

* Rework fix to be more similar to other lag fixes

The fix now uses the ...LocalValues class, which published updates only every
half a second.

Signed-off-by: Paul Schuetz <pa.schuetz@web.de>

---------

Signed-off-by: Paul Schuetz <pa.schuetz@web.de>
This commit is contained in:
Paul Schuetz 2023-03-31 15:34:24 +02:00 committed by GitHub
parent d3e71cea74
commit 59b16d86a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -6,11 +6,13 @@ import Network
import Status import Status
import SwiftUI import SwiftUI
class DisplaySettingsLocalColors: ObservableObject { class DisplaySettingsLocalValues: ObservableObject {
@Published var tintColor = Theme.shared.tintColor @Published var tintColor = Theme.shared.tintColor
@Published var primaryBackgroundColor = Theme.shared.primaryBackgroundColor @Published var primaryBackgroundColor = Theme.shared.primaryBackgroundColor
@Published var secondaryBackgroundColor = Theme.shared.secondaryBackgroundColor @Published var secondaryBackgroundColor = Theme.shared.secondaryBackgroundColor
@Published var labelColor = Theme.shared.labelColor @Published var labelColor = Theme.shared.labelColor
@Published var lineSpacing = Theme.shared.lineSpacing
@Published var fontSizeScale = Theme.shared.fontSizeScale
private var subscriptions = Set<AnyCancellable>() private var subscriptions = Set<AnyCancellable>()
@ -31,6 +33,14 @@ class DisplaySettingsLocalColors: ObservableObject {
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main) .debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.sink(receiveValue: { newColor in Theme.shared.labelColor = newColor }) .sink(receiveValue: { newColor in Theme.shared.labelColor = newColor })
.store(in: &subscriptions) .store(in: &subscriptions)
$lineSpacing
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.sink(receiveValue: { newSpacing in Theme.shared.lineSpacing = newSpacing })
.store(in: &subscriptions)
$fontSizeScale
.debounce(for: .seconds(0.5), scheduler: DispatchQueue.main)
.sink(receiveValue: { newScale in Theme.shared.fontSizeScale = newScale })
.store(in: &subscriptions)
} }
} }
@ -41,7 +51,7 @@ struct DisplaySettingsView: View {
@EnvironmentObject private var theme: Theme @EnvironmentObject private var theme: Theme
@EnvironmentObject private var userPreferences: UserPreferences @EnvironmentObject private var userPreferences: UserPreferences
@StateObject private var localColors = DisplaySettingsLocalColors() @StateObject private var localValues = DisplaySettingsLocalValues()
@State private var isFontSelectorPresented = false @State private var isFontSelectorPresented = false
@ -92,18 +102,18 @@ struct DisplaySettingsView: View {
Toggle("settings.display.theme.systemColor", isOn: $theme.followSystemColorScheme) Toggle("settings.display.theme.systemColor", isOn: $theme.followSystemColorScheme)
themeSelectorButton themeSelectorButton
Group { Group {
ColorPicker("settings.display.theme.tint", selection: $localColors.tintColor) ColorPicker("settings.display.theme.tint", selection: $localValues.tintColor)
ColorPicker("settings.display.theme.background", selection: $localColors.primaryBackgroundColor) ColorPicker("settings.display.theme.background", selection: $localValues.primaryBackgroundColor)
ColorPicker("settings.display.theme.secondary-background", selection: $localColors.secondaryBackgroundColor) ColorPicker("settings.display.theme.secondary-background", selection: $localValues.secondaryBackgroundColor)
ColorPicker("settings.display.theme.text-color", selection: $localColors.labelColor) ColorPicker("settings.display.theme.text-color", selection: $localValues.labelColor)
} }
.disabled(theme.followSystemColorScheme) .disabled(theme.followSystemColorScheme)
.opacity(theme.followSystemColorScheme ? 0.5 : 1.0) .opacity(theme.followSystemColorScheme ? 0.5 : 1.0)
.onChange(of: theme.selectedSet) { _ in .onChange(of: theme.selectedSet) { _ in
localColors.tintColor = theme.tintColor localValues.tintColor = theme.tintColor
localColors.primaryBackgroundColor = theme.primaryBackgroundColor localValues.primaryBackgroundColor = theme.primaryBackgroundColor
localColors.secondaryBackgroundColor = theme.secondaryBackgroundColor localValues.secondaryBackgroundColor = theme.secondaryBackgroundColor
localColors.labelColor = theme.labelColor localValues.labelColor = theme.labelColor
} }
} header: { } header: {
Text("settings.display.section.theme") Text("settings.display.section.theme")
@ -147,17 +157,17 @@ struct DisplaySettingsView: View {
.navigationDestination(isPresented: $isFontSelectorPresented, destination: { FontPicker() }) .navigationDestination(isPresented: $isFontSelectorPresented, destination: { FontPicker() })
VStack { VStack {
Slider(value: $theme.fontSizeScale, in: 0.5 ... 1.5, step: 0.1) Slider(value: $localValues.fontSizeScale, in: 0.5 ... 1.5, step: 0.1)
Text("settings.display.font.scaling-\(String(format: "%.1f", theme.fontSizeScale))") Text("settings.display.font.scaling-\(String(format: "%.1f", localValues.fontSizeScale))")
.font(.scaledBody) .font(.scaledBody)
} }
.alignmentGuide(.listRowSeparatorLeading) { d in .alignmentGuide(.listRowSeparatorLeading) { d in
d[.leading] d[.leading]
} }
VStack { VStack {
Slider(value: $theme.lineSpacing, in: 0.4 ... 10.0, step: 0.2) Slider(value: $localValues.lineSpacing, in: 0.4 ... 10.0, step: 0.2)
Text("settings.display.font.line-spacing-\(String(format: "%.1f", theme.lineSpacing))") Text("settings.display.font.line-spacing-\(String(format: "%.1f", localValues.lineSpacing))")
.font(.scaledBody) .font(.scaledBody)
} }
.alignmentGuide(.listRowSeparatorLeading) { d in .alignmentGuide(.listRowSeparatorLeading) { d in
@ -222,10 +232,10 @@ struct DisplaySettingsView: View {
theme.avatarPosition = .top theme.avatarPosition = .top
theme.statusActionsDisplay = .full theme.statusActionsDisplay = .full
localColors.tintColor = theme.tintColor localValues.tintColor = theme.tintColor
localColors.primaryBackgroundColor = theme.primaryBackgroundColor localValues.primaryBackgroundColor = theme.primaryBackgroundColor
localColors.secondaryBackgroundColor = theme.secondaryBackgroundColor localValues.secondaryBackgroundColor = theme.secondaryBackgroundColor
localColors.labelColor = theme.labelColor localValues.labelColor = theme.labelColor
} label: { } label: {
Text("settings.display.restore") Text("settings.display.restore")