mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
Merged via /review-pr -> /prepare-pr -> /merge-pr.
Prepared head SHA: f60cd10f6d
Co-authored-by: ngutman <1540134+ngutman@users.noreply.github.com>
Co-authored-by: ngutman <1540134+ngutman@users.noreply.github.com>
Reviewed-by: @ngutman
72 lines
2.8 KiB
Swift
72 lines
2.8 KiB
Swift
import SwiftUI
|
|
|
|
enum StatusActivityBuilder {
|
|
@MainActor
|
|
static func build(
|
|
appModel: NodeAppModel,
|
|
voiceWakeEnabled: Bool,
|
|
cameraHUDText: String?,
|
|
cameraHUDKind: NodeAppModel.CameraHUDKind?
|
|
) -> StatusPill.Activity? {
|
|
// Keep the top pill consistent across tabs (camera + voice wake + pairing states).
|
|
if appModel.isBackgrounded {
|
|
return StatusPill.Activity(
|
|
title: "Foreground required",
|
|
systemImage: "exclamationmark.triangle.fill",
|
|
tint: .orange)
|
|
}
|
|
|
|
let gatewayStatus = appModel.gatewayStatusText.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
let gatewayLower = gatewayStatus.lowercased()
|
|
if gatewayLower.contains("repair") {
|
|
return StatusPill.Activity(title: "Repairing…", systemImage: "wrench.and.screwdriver", tint: .orange)
|
|
}
|
|
if gatewayLower.contains("approval") || gatewayLower.contains("pairing") {
|
|
return StatusPill.Activity(title: "Approval pending", systemImage: "person.crop.circle.badge.clock")
|
|
}
|
|
// Avoid duplicating the primary gateway status ("Connecting…") in the activity slot.
|
|
|
|
if appModel.screenRecordActive {
|
|
return StatusPill.Activity(title: "Recording screen…", systemImage: "record.circle.fill", tint: .red)
|
|
}
|
|
|
|
if let cameraHUDText, !cameraHUDText.isEmpty, let cameraHUDKind {
|
|
let systemImage: String
|
|
let tint: Color?
|
|
switch cameraHUDKind {
|
|
case .photo:
|
|
systemImage = "camera.fill"
|
|
tint = nil
|
|
case .recording:
|
|
systemImage = "video.fill"
|
|
tint = .red
|
|
case .success:
|
|
systemImage = "checkmark.circle.fill"
|
|
tint = .green
|
|
case .error:
|
|
systemImage = "exclamationmark.triangle.fill"
|
|
tint = .red
|
|
}
|
|
return StatusPill.Activity(title: cameraHUDText, systemImage: systemImage, tint: tint)
|
|
}
|
|
|
|
if voiceWakeEnabled {
|
|
let voiceStatus = appModel.voiceWake.statusText
|
|
if voiceStatus.localizedCaseInsensitiveContains("microphone permission") {
|
|
return StatusPill.Activity(title: "Mic permission", systemImage: "mic.slash", tint: .orange)
|
|
}
|
|
if voiceStatus == "Paused" {
|
|
// Talk mode intentionally pauses voice wake to release the mic. Don't spam the HUD for that case.
|
|
if appModel.talkMode.isEnabled {
|
|
return nil
|
|
}
|
|
let suffix = appModel.isBackgrounded ? " (background)" : ""
|
|
return StatusPill.Activity(title: "Voice Wake paused\(suffix)", systemImage: "pause.circle.fill")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|