Fix HAProgressView animation positioning (#4403)

<!-- 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 -->
- HAProgressView had a glitch when positioned inside a NavigationView,
where it would animate incorrectly, this PR fixes it

## 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. -->
This commit is contained in:
Bruno Pantaleão Gonçalves
2026-03-03 14:34:35 +01:00
committed by GitHub
parent b9806be40b
commit 6cdba80ca1

View File

@@ -2,6 +2,7 @@ import SwiftUI
final class HAProgressViewModel: ObservableObject {
@Published var isAnimating = false
@Published var rotationDegrees: CGFloat = 0
@Published var trimEnd: CGFloat = 0.1
}
@@ -61,22 +62,23 @@ public struct HAProgressView: View {
style: StrokeStyle(lineWidth: style.lineWidth, lineCap: .round)
)
.frame(width: style.size.width, height: style.size.height)
.rotationEffect(Angle(degrees: viewModel.isAnimating ? 360 : 0))
.animation(
Animation.linear(duration: 1).repeatForever(autoreverses: false),
value: viewModel.isAnimating
)
.rotationEffect(Angle(degrees: viewModel.rotationDegrees))
.onAppear {
guard !viewModel.isAnimating else { return }
viewModel.isAnimating = true
withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
viewModel.rotationDegrees = 360
}
withAnimation(.easeInOut(duration: 1.75).repeatForever(autoreverses: true)) {
viewModel.trimEnd = 0.7
}
}
}
.frame(width: style.size.width, height: style.size.height, alignment: .center)
}
}
#Preview {
#Preview("In HStack") {
HStack(spacing: DesignSystem.Spaces.two) {
HAProgressView(style: .small)
HAProgressView(style: .medium)
@@ -84,3 +86,45 @@ public struct HAProgressView: View {
HAProgressView(style: .extraLarge)
}
}
#Preview("In List") {
List {
HAProgressView(style: .small)
HAProgressView(style: .medium)
HAProgressView(style: .large)
HAProgressView(style: .extraLarge)
}
}
#Preview("In VStack") {
VStack {
HAProgressView(style: .small)
HAProgressView(style: .medium)
HAProgressView(style: .large)
HAProgressView(style: .extraLarge)
}
}
#Preview("In Navigation view small") {
NavigationView {
HAProgressView(style: .small)
}
}
#Preview("In Navigation view medium") {
NavigationView {
HAProgressView(style: .medium)
}
}
#Preview("In Navigation view large") {
NavigationView {
HAProgressView(style: .large)
}
}
#Preview("In Navigation view extra lar") {
NavigationView {
HAProgressView(style: .extraLarge)
}
}