diff --git a/CamperMonitor/Views/AlignmentAssistantView.swift b/CamperMonitor/Views/AlignmentAssistantView.swift index 168792f..871f477 100644 --- a/CamperMonitor/Views/AlignmentAssistantView.swift +++ b/CamperMonitor/Views/AlignmentAssistantView.swift @@ -38,6 +38,8 @@ struct AlignmentAssistantView: View { VehicleTiltView(pitch: state.pitch, roll: state.roll) } + if !isLive { disconnectedBanner } + adviceBanner readings @@ -95,6 +97,29 @@ struct AlignmentAssistantView: View { // MARK: - Bausteine + private var isLive: Bool { bluetooth.linkStates[device.id] == .live } + + /// Reisst die Verbindung beim Rangieren ab, stehen die Zahlen still. Ohne + /// Hinweis sähe das aus, als hinge die App – man rangiert dann nach einem + /// Wert, der längst nicht mehr gilt. + private var disconnectedBanner: some View { + Label { + VStack(alignment: .leading, spacing: 2) { + Text("Nicht verbunden").font(.headline) + Text("Die Anzeige steht still, bis der Neigungsmesser wieder da ist.") + .font(.callout) + .foregroundStyle(.secondary) + } + } icon: { + Image(systemName: "antenna.radiowaves.left.and.right.slash") + .font(.title) + .foregroundStyle(.orange) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding() + .background(Color.orange.opacity(0.15), in: .rect(cornerRadius: 16)) + } + private var adviceBanner: some View { HStack(spacing: 12) { Image(systemName: assistant.hasReachedTarget diff --git a/CamperMonitor/Views/LevelView.swift b/CamperMonitor/Views/LevelView.swift index 5151f71..e427162 100644 --- a/CamperMonitor/Views/LevelView.swift +++ b/CamperMonitor/Views/LevelView.swift @@ -160,7 +160,21 @@ struct LevelControls: View { Image(systemName: "car.side.arrowtriangle.up.arrowtriangle.down") } } - .disabled(!state.hasReading) + // Der Assistent lebt von laufenden Messwerten. Ein einmal + // empfangener Wert genügt nicht: nach einem Verbindungsabbruch + // bliebe er stehen und die Ansicht sähe eingefroren aus. + .disabled(!isLive || !state.hasReading) + // Der Vollbildschirm gehört an den Knopf, nicht an den Abschnitt. + // SwiftUI zeigt Blätter und Vollbildschirme an einer `Section` + // nicht zuverlässig an – dasselbe hatte die Kühlbox schon. + .fullScreenCover(isPresented: $showAssistant) { + AlignmentAssistantView(device: device, profile: store.activeProfile) + } + } footer: { + if !isLive { + Text("Der Assistent braucht laufende Messwerte. Der Neigungsmesser " + + "ist gerade nicht verbunden.") + } } // Einbaulage und Nullpunkt liegen auf einer eigenen Seite. Direkt unter @@ -178,11 +192,10 @@ struct LevelControls: View { } footer: { Text("Einbaulage des Sensors und Nullpunkt der Anzeige.") } - .fullScreenCover(isPresented: $showAssistant) { - AlignmentAssistantView(device: device, profile: store.activeProfile) - } } + private var isLive: Bool { bluetooth.linkStates[device.id] == .live } + /// Was auf der Einrichtungsseite zu holen ist – der Nullpunkt zuerst, denn /// ohne ihn stimmt die Anzeige nicht. private var setupSummary: String {