commit 8dc74c94971c319b40dd6a85562e6a865b988611
parent 910e66bc7b6dd11fffcd9434df74320bb9fe09fb
Author: Michael Camilleri <[email protected]>
Date: Wed, 10 Jun 2026 03:02:36 +0900
Remove replay tuning from Settings menu
Diffstat:
2 files changed, 7 insertions(+), 76 deletions(-)
diff --git a/Crossmate/Models/ReplayControls.swift b/Crossmate/Models/ReplayControls.swift
@@ -1,25 +1,16 @@
import Foundation
import Observation
-/// Tunable knobs for the finish-banner replay autoplay, persisted in
-/// `UserDefaults` and editable from the Debugging menu. Reads fall back to the
-/// shipping defaults whenever a key is unset, so an empty store behaves exactly
-/// as it did before these became adjustable.
+/// Step intervals for the finish-banner replay autoplay, one per speed level.
enum ReplayTuning {
- enum Key {
- static let speedMs = ["replay.speed1Ms", "replay.speed2Ms", "replay.speed3Ms"]
- }
-
- /// Default step interval (ms) per speed level, fastest last.
- static let defaultSpeedMs = [350, 160, 70]
+ /// Step interval (ms) per speed level, fastest last.
+ static let speedMs = [350, 160, 70]
- /// Step interval in milliseconds for `speed` (`1...defaultSpeedMs.count`),
- /// from the store or the matching default when unset (stored `0`).
+ /// Step interval in milliseconds for `speed` (`1...speedMs.count`).
static func stepMilliseconds(forSpeed speed: Int) -> Int {
let index = speed - 1
- guard defaultSpeedMs.indices.contains(index) else { return defaultSpeedMs.last ?? 0 }
- let stored = UserDefaults.standard.integer(forKey: Key.speedMs[index])
- return stored > 0 ? stored : defaultSpeedMs[index]
+ guard speedMs.indices.contains(index) else { return speedMs.last ?? 0 }
+ return speedMs[index]
}
}
@@ -83,7 +74,7 @@ final class ReplayControls {
/// Seconds between autoplay steps at the current speed, or `nil` when
/// stopped. Faster speeds step sooner; the per-speed intervals come from
- /// `ReplayTuning` so they can be tuned live from the Debugging menu.
+ /// `ReplayTuning`.
var playbackStepInterval: Duration? {
guard isPlaybackActive else { return nil }
return .milliseconds(ReplayTuning.stepMilliseconds(forSpeed: selectedPlaybackSpeed))
diff --git a/Crossmate/Views/SettingsView.swift b/Crossmate/Views/SettingsView.swift
@@ -50,9 +50,6 @@ struct SettingsView: View {
NavigationLink("Record Editor") {
RecordEditorView()
}
- NavigationLink("Replay Tuning") {
- ReplayTuningView()
- }
Button("Reset Database", role: .destructive) {
showResetConfirmation = true
@@ -165,60 +162,3 @@ struct SettingsView: View {
}
}
-/// Live tuning for the finish-banner replay autoplay, backed by the same
-/// `UserDefaults` keys `ReplayControls` reads. Edits take effect on the next
-/// play, so the knobs can be dialled in without a rebuild.
-private struct ReplayTuningView: View {
- var body: some View {
- Form {
- Section {
- ForEach(Array(ReplayTuning.defaultSpeedMs.enumerated()), id: \.offset) { index, def in
- IntervalSlider(
- title: "Speed \(index + 1) step",
- key: ReplayTuning.Key.speedMs[index],
- defaultMs: def
- )
- }
- } header: {
- Text("Step Interval")
- } footer: {
- Text("Milliseconds between moves at each fast-forward speed. Lower is faster.")
- }
-
- Section {
- Button("Reset to Defaults", role: .destructive) {
- let defaults = UserDefaults.standard
- for key in ReplayTuning.Key.speedMs { defaults.removeObject(forKey: key) }
- }
- }
- }
- .navigationTitle("Replay Tuning")
- .navigationBarTitleDisplayMode(.inline)
- }
-
- private struct IntervalSlider: View {
- let title: String
- @AppStorage private var milliseconds: Int
-
- init(title: String, key: String, defaultMs: Int) {
- self.title = title
- _milliseconds = AppStorage(wrappedValue: defaultMs, key)
- }
-
- var body: some View {
- VStack(alignment: .leading, spacing: 4) {
- LabeledContent(title) {
- Text("\(milliseconds) ms").monospacedDigit()
- }
- Slider(
- value: Binding(
- get: { Double(milliseconds) },
- set: { milliseconds = Int($0) }
- ),
- in: 20...600,
- step: 5
- )
- }
- }
- }
-}