mirror of
https://github.com/home-assistant/iOS.git
synced 2026-02-04 11:42:39 -06:00
<!-- 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 --> ## 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. --> https://github.com/user-attachments/assets/e79c6e4d-13ff-405a-9463-02e597ce4996
135 lines
4.0 KiB
Swift
135 lines
4.0 KiB
Swift
import SwiftUI
|
|
|
|
/// View used to display and highlight privacy related information
|
|
public struct PrivacyNoteView: View {
|
|
@State private var startPoint: UnitPoint = .topLeading
|
|
@State private var endPoint: UnitPoint = .bottomTrailing
|
|
@State private var timer: Timer?
|
|
@State private var background: AnyView = .init(
|
|
LinearGradient(
|
|
colors: [.purple, .blue],
|
|
startPoint: .topLeading,
|
|
endPoint: .bottomTrailing
|
|
)
|
|
.overlay(content: {
|
|
ThickMaterialOverlay()
|
|
})
|
|
.clipShape(RoundedRectangle(cornerRadius: CornerRadiusSizes.oneAndMicro))
|
|
)
|
|
|
|
private let content: String
|
|
private let animating: Bool
|
|
|
|
public init(content: String, animating: Bool = true) {
|
|
self.content = content
|
|
self.animating = animating
|
|
}
|
|
|
|
public var body: some View {
|
|
VStack(spacing: Spaces.one) {
|
|
Text(L10n.privacyLabel)
|
|
.font(.caption.bold())
|
|
.padding(.horizontal, Spaces.one)
|
|
.padding(.vertical, Spaces.half)
|
|
.background(.thickMaterial)
|
|
.foregroundStyle(.gray)
|
|
.clipShape(Capsule())
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
Text(verbatim: content)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.font(.caption)
|
|
.multilineTextAlignment(.leading)
|
|
.fixedSize(horizontal: false, vertical: true)
|
|
.foregroundStyle(.gray)
|
|
}
|
|
.padding(Spaces.one)
|
|
.background(background)
|
|
.clipShape(RoundedRectangle(cornerRadius: CornerRadiusSizes.oneAndMicro))
|
|
.shadow(color: Color(uiColor: .label).opacity(0.2), radius: 5)
|
|
.padding(.top)
|
|
.onAppear {
|
|
if animating {
|
|
rotareLinearBackgroundPointsForBackgroundAnimation()
|
|
startTimer()
|
|
}
|
|
}
|
|
.onDisappear {
|
|
stopTimer()
|
|
}
|
|
}
|
|
|
|
private func startTimer() {
|
|
timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { _ in
|
|
rotareLinearBackgroundPointsForBackgroundAnimation()
|
|
}
|
|
}
|
|
|
|
private func stopTimer() {
|
|
timer?.invalidate()
|
|
timer = nil
|
|
}
|
|
|
|
private func rotareLinearBackgroundPointsForBackgroundAnimation() {
|
|
startPoint = rotatePoint(startPoint)
|
|
endPoint = rotatePoint(endPoint)
|
|
withAnimation(.easeIn(duration: 2)) {
|
|
background = AnyView(
|
|
LinearGradient(
|
|
colors: [.purple, .blue],
|
|
startPoint: startPoint,
|
|
endPoint: endPoint
|
|
)
|
|
.overlay(content: {
|
|
ThickMaterialOverlay()
|
|
})
|
|
.clipShape(RoundedRectangle(cornerRadius: CornerRadiusSizes.oneAndMicro))
|
|
)
|
|
}
|
|
}
|
|
|
|
private func rotatePoint(_ point: UnitPoint) -> UnitPoint {
|
|
switch point {
|
|
case .topLeading:
|
|
return .top
|
|
case .top:
|
|
return .topTrailing
|
|
case .topTrailing:
|
|
return .trailing
|
|
case .trailing:
|
|
return .bottomTrailing
|
|
case .bottomTrailing:
|
|
return .bottom
|
|
case .bottom:
|
|
return .bottomLeading
|
|
case .bottomLeading:
|
|
return .leading
|
|
case .leading:
|
|
return .topLeading
|
|
default:
|
|
return .topLeading
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ThickMaterialOverlay: View {
|
|
var body: some View {
|
|
VStack {}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.background(.thickMaterial)
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
VStack {
|
|
PrivacyNoteView(
|
|
content: "This is a privacy note. It contains important information about your data and how it is used."
|
|
)
|
|
.padding()
|
|
PrivacyNoteView(
|
|
content: "This is a privacy note. It contains important information about your data and how it is used.",
|
|
animating: false
|
|
)
|
|
.padding()
|
|
}
|
|
}
|