Add Live Activity for level sensor (surfaces on CarPlay automatically)
Replaces the ActivityKit boilerplate with a real lock screen/Dynamic Island UI driven by live pitch/roll readings, toggled from the leveling device's detail screen. Since iOS 17 shows any running Live Activity on CarPlay's dashboard without a dedicated CarPlay app entitlement, this covers the requested CarPlay use case without one. Also fixes the widget extension never being embedded into the app (missing Embed Foundation Extensions build phase and target dependency), which meant no widget or Live Activity could ever have rendered regardless of code changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
da64b1b6bd
commit
bfe2b00a5c
@@ -107,6 +107,7 @@ struct LevelControls: View {
|
||||
|
||||
@Environment(BluetoothManager.self) private var bluetooth
|
||||
@Environment(DeviceStore.self) private var store
|
||||
@Environment(LevelActivityManager.self) private var levelActivity
|
||||
@State private var showAssistant = false
|
||||
@AppStorage("levelDisplayStyle") private var displayStyle: LevelDisplayStyle = .bubble
|
||||
|
||||
@@ -177,6 +178,29 @@ struct LevelControls: View {
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
Toggle(isOn: liveActivityBinding) {
|
||||
Label {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("Live Activity")
|
||||
Text("Sperrbildschirm, Dynamic Island und CarPlay")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
} icon: {
|
||||
Image(systemName: "widget.small")
|
||||
}
|
||||
}
|
||||
// Ohne laufende Messwerte gäbe es nichts anzuzeigen – und beim
|
||||
// Umschalten hätte die Activity sofort einen veralteten Stand.
|
||||
.disabled(!isLive || !state.hasReading)
|
||||
} footer: {
|
||||
Text(!isLive
|
||||
? "Braucht laufende Messwerte. Der Neigungsmesser ist gerade nicht verbunden."
|
||||
: "Zeigt die Neigung, solange sie läuft – auch bei gesperrtem Bildschirm. "
|
||||
+ "Ist das iPhone mit CarPlay verbunden, erscheint sie automatisch auch dort.")
|
||||
}
|
||||
|
||||
// Einbaulage und Nullpunkt liegen auf einer eigenen Seite. Direkt unter
|
||||
// der Libelle verstellte ein Fehlgriff beim Ablesen den Nullpunkt.
|
||||
Section {
|
||||
@@ -196,6 +220,19 @@ struct LevelControls: View {
|
||||
|
||||
private var isLive: Bool { bluetooth.linkStates[device.id] == .live }
|
||||
|
||||
private var liveActivityBinding: Binding<Bool> {
|
||||
Binding(
|
||||
get: { levelActivity.isActive(for: device.id) },
|
||||
set: { isOn in
|
||||
if isOn {
|
||||
levelActivity.start(deviceID: device.id, deviceName: device.name, state: state)
|
||||
} else {
|
||||
levelActivity.end()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Was auf der Einrichtungsseite zu holen ist – der Nullpunkt zuerst, denn
|
||||
/// ohne ihn stimmt die Anzeige nicht.
|
||||
private var setupSummary: String {
|
||||
|
||||
Reference in New Issue
Block a user