This commit is contained in:
Daniel Arantes Loverde
2026-07-07 15:11:31 -03:00
parent 8b9ebdcb44
commit e51c99973f
293 changed files with 457 additions and 4919 deletions

View File

@@ -0,0 +1,76 @@
import SwiftUI
struct CategoryHeaderOffsetPreferenceKey: PreferenceKey {
static let defaultValue: [String: CGFloat] = [:]
static func reduce(value: inout [String: CGFloat], nextValue: () -> [String: CGFloat]) {
value.merge(nextValue(), uniquingKeysWith: { _, new in new })
}
}
enum StoreDetailScrollCoordinateSpace {
static let name = "store-detail-scroll"
}
struct ScrollOffsetPreferenceKey: PreferenceKey {
static let defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
struct ScrollOffsetReader: View {
@Binding var offsetY: CGFloat
@State private var baseline: CGFloat? = nil
var body: some View {
Color.clear
.frame(height: 0)
.background(
GeometryReader { geometry in
Color.clear.preference(
key: ScrollOffsetPreferenceKey.self,
value: geometry.frame(in: .named(StoreDetailScrollCoordinateSpace.name)).minY
)
}
)
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { minY in
if baseline == nil { baseline = minY }
let offset = (baseline ?? 0) - minY
if abs(offsetY - offset) > 0.5 {
offsetY = offset
}
}
}
}
struct AsyncStoreImage: View {
let imageURL: String?
var fallbackImageName: String = "placeholder-product"
var fitMode: ImageFitMode = .fill
var body: some View {
GeometryReader { geometry in
CachedRemoteImage(imageURL: imageURL, fitMode: fitMode) {
fallback
}
// Lock the scaledToFill image to the actually proposed box.
// Without this, a wide/landscape source image's fill-scaled
// ideal width can exceed the box and balloon the parent
// ZStack's ideal width, pushing sibling content off-screen.
.frame(width: geometry.size.width, height: geometry.size.height)
.clipped()
}
.background(AppColors.brandSoft)
}
private var fallback: some View {
Image(fallbackImageName)
.resizable()
.scaledToFill()
}
}