iOS/Sources/Extensions/Widgets/Custom/AppIntents/CustomWidgetToggleAppIntent.swift
Bruno Pantaleão Gonçalves cac8f15627
Add debug notifications option (#3674)
<!-- Thank you for submitting a Pull Request and helping to improve Home
Assistant. Please complete the following sections to help the processing
and review of your changes. Please do not delete anything from this
template. -->

## Summary
<!-- Provide a brief summary of the changes you have made and most
importantly what they aim to achieve -->
This PR adds option in the debug section to receive debug notifications,
this is a debugging tool only and it is not visible to the user unless
it open the debugging tool hidden panel.

First use case: Receive notification when location fails to update ein
brackground.

## Screenshots
<!-- If this is a user-facing change not in the frontend, please include
screenshots in light and dark mode. -->

## Link to pull request in Documentation repository
<!-- Pull requests that add, change or remove functionality must have a
corresponding pull request in the Companion App Documentation repository
(https://github.com/home-assistant/companion.home-assistant). Please add
the number of this pull request after the "#" -->
Documentation: home-assistant/companion.home-assistant#

## Any other notes
<!-- If there is any other information of note, like if this Pull
Request is part of a bigger change, please include it here. -->
2025-06-25 17:05:43 +02:00

63 lines
2.5 KiB
Swift

import AppIntents
import Foundation
import Shared
import SwiftUI
import WidgetKit
@available(iOS 16.4, *)
struct CustomWidgetToggleAppIntent: AppIntent {
static var title: LocalizedStringResource = "Toggle"
static var isDiscoverable: Bool = false
// No translation needed below, this is not a discoverable intent
@Parameter(title: "Server")
var serverId: String?
@Parameter(title: "Domain")
var domain: String?
@Parameter(title: "Entity ID")
var entityId: String?
@Parameter(title: "Is widget showing states?")
var widgetShowingStates: Bool?
func perform() async throws -> some IntentResult {
guard let serverId,
let domainString = domain,
let domain = Domain(rawValue: domainString),
let entityId,
let widgetShowingStates,
let server = Current.servers.all.first(where: { server in
server.identifier.rawValue == serverId
}), let connection = Current.api(for: server)?.connection else {
return .result()
}
AppIntentHaptics.notify()
await withCheckedContinuation { continuation in
connection.send(.toggleDomain(domain: domain, entityId: entityId)).promise.pipe { result in
switch result {
case .fulfilled:
continuation.resume()
case let .rejected(error):
Current.Log
.error(
"Failed to execute ToggleAppIntent, serverId: \(serverId), domain: \(domain), entityId: \(entityId), error: \(error)"
)
Current.notificationDispatcher.send(.init(
id: .intentToggleFailed,
title: L10n.Widgets.Custom.IntentToggleFailed.title,
body: L10n.Widgets.Custom.IntentToggleFailed.body
))
continuation.resume()
}
}
}
_ = try await ResetAllCustomWidgetConfirmationAppIntent().perform()
if widgetShowingStates {
/* Since when you toggle an entity not always it reflects the new state right away
and at the same time push notifications to update widgets are currently not working reliably
in iOS, this delay is out best effort for the user to see the correct state after finishing the interaction */
try await Task.sleep(nanoseconds: 1_000_000_000)
}
return .result()
}
}