Files
damus/damus/Components/Shimmer.swift
Sam DuBois 549cbb9bce Fix issue with loading view using the redacted modifier
Also tried to make some adjusmtents to the refresh subscribtion to see
if this fixes bugs people were having

Closes: #119

Changelog-Fixed: Fixed issues when refreshing global view
2022-12-22 18:10:42 -08:00

84 lines
2.6 KiB
Swift

//
// Shimmer.swift
//
//
// Created by Joshua Homann on 2/20/21.
//
import SwiftUI
public struct ShimmerConfiguration {
@Environment(\.colorScheme) var colorScheme
public let gradient: Gradient
public let initialLocation: (start: UnitPoint, end: UnitPoint)
public let finalLocation: (start: UnitPoint, end: UnitPoint)
public let duration: TimeInterval
public let opacity: Double
public static let `default` = ShimmerConfiguration(
gradient: Gradient(stops: [
.init(color: .clear, location: 0),
.init(color: .black, location: 0.3),
.init(color: .black, location: 0.7),
.init(color: .clear, location: 1),
]),
initialLocation: (start: UnitPoint(x: -1, y: 0.5), end: .leading),
finalLocation: (start: .trailing, end: UnitPoint(x: 2, y: 0.5)),
duration: 2,
opacity: 0.6
)
}
struct ShimmeringView<Content: View>: View {
private let content: () -> Content
private let configuration: ShimmerConfiguration
@State private var startPoint: UnitPoint
@State private var endPoint: UnitPoint
init(configuration: ShimmerConfiguration, @ViewBuilder content: @escaping () -> Content) {
self.configuration = configuration
self.content = content
_startPoint = .init(wrappedValue: configuration.initialLocation.start)
_endPoint = .init(wrappedValue: configuration.initialLocation.end)
}
var body: some View {
ZStack {
content()
LinearGradient(
gradient: configuration.gradient,
startPoint: startPoint,
endPoint: endPoint
)
.opacity(configuration.opacity)
.blendMode(.overlay)
.onAppear {
withAnimation(Animation.linear(duration: configuration.duration).repeatForever(autoreverses: false)) {
startPoint = configuration.finalLocation.start
endPoint = configuration.finalLocation.end
}
}
}
.edgesIgnoringSafeArea(.all)
}
}
public struct ShimmerModifier: ViewModifier {
let configuration: ShimmerConfiguration
public func body(content: Content) -> some View {
ShimmeringView(configuration: configuration) { content }
}
}
public extension View {
@ViewBuilder func shimmer(configuration: ShimmerConfiguration = .default, _ loading: Bool) -> some View {
if loading {
modifier(ShimmerModifier(configuration: configuration))
} else {
self
}
}
}