mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
purchaseSectionSize + feature selection
This commit is contained in:
parent
2b7357d1fe
commit
7ca339ce73
@ -104,10 +104,13 @@ struct SGPayWallFeatureDetails: View {
|
|||||||
let contentHeight: CGFloat = 650.0
|
let contentHeight: CGFloat = 650.0
|
||||||
let features: [SGProFeature]
|
let features: [SGProFeature]
|
||||||
|
|
||||||
// Add animation states
|
@State var shownFeature: SGProFeatureId?
|
||||||
|
// Add animation states
|
||||||
@State private var showBackground = false
|
@State private var showBackground = false
|
||||||
@State private var showContent = false
|
@State private var showContent = false
|
||||||
|
|
||||||
|
@State private var dragOffset: CGFloat = 0
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack(alignment: .bottom) {
|
ZStack(alignment: .bottom) {
|
||||||
// Background overlay
|
// Background overlay
|
||||||
@ -125,14 +128,14 @@ struct SGPayWallFeatureDetails: View {
|
|||||||
if showContent {
|
if showContent {
|
||||||
VStack {
|
VStack {
|
||||||
if #available(iOS 14.0, *) {
|
if #available(iOS 14.0, *) {
|
||||||
TabView {
|
TabView(selection: $shownFeature) {
|
||||||
ForEach(features) { feature in
|
ForEach(features) { feature in
|
||||||
ScrollView(showsIndicators: false) {
|
ScrollView(showsIndicators: false) {
|
||||||
SGProFeatureView(
|
SGProFeatureView(
|
||||||
feature: feature
|
feature: feature
|
||||||
)
|
)
|
||||||
// .padding(.bottom, bottomOffset)
|
|
||||||
}
|
}
|
||||||
|
.tag(feature.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.tabViewStyle(.page)
|
.tabViewStyle(.page)
|
||||||
@ -162,7 +165,7 @@ struct SGPayWallFeatureDetails: View {
|
|||||||
showBackground = true
|
showBackground = true
|
||||||
}
|
}
|
||||||
|
|
||||||
withAnimation(.spring()/*.delay(0.1)*/) {
|
withAnimation(.spring(duration: 0.3)/*.delay(0.1)*/) {
|
||||||
showContent = true
|
showContent = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,6 +317,7 @@ struct SGPayWallView: View {
|
|||||||
@State private var showErrorAlert: Bool = false
|
@State private var showErrorAlert: Bool = false
|
||||||
@State private var showConfetti: Bool = false
|
@State private var showConfetti: Bool = false
|
||||||
@State private var showDetails: Bool = false
|
@State private var showDetails: Bool = false
|
||||||
|
@State private var shownFeature: SGProFeatureId? = nil
|
||||||
|
|
||||||
private let productsPub = NotificationCenter.default.publisher(for: .SGIAPHelperProductsUpdatedNotification, object: nil)
|
private let productsPub = NotificationCenter.default.publisher(for: .SGIAPHelperProductsUpdatedNotification, object: nil)
|
||||||
private let buyOrRestoreSuccessPub = NotificationCenter.default.publisher(for: .SGIAPHelperPurchaseNotification, object: nil)
|
private let buyOrRestoreSuccessPub = NotificationCenter.default.publisher(for: .SGIAPHelperPurchaseNotification, object: nil)
|
||||||
@ -325,12 +329,7 @@ struct SGPayWallView: View {
|
|||||||
@State private var hapticFeedback: HapticFeedback?
|
@State private var hapticFeedback: HapticFeedback?
|
||||||
private let confettiDuration: Double = 5.0
|
private let confettiDuration: Double = 5.0
|
||||||
|
|
||||||
@Environment(\.sizeCategory) var sizeCategory: ContentSizeCategory
|
@State private var purchaseSectionSize: CGSize = .zero
|
||||||
private var purchaseButtonBottomOffset: CGFloat {
|
|
||||||
let baseOffset: CGFloat = 50.0
|
|
||||||
let sizeMultiplier = UIFontMetrics.default.scaledValue(for: 1.0)
|
|
||||||
return baseOffset * sizeMultiplier
|
|
||||||
}
|
|
||||||
|
|
||||||
private var features: [SGProFeature] {
|
private var features: [SGProFeature] {
|
||||||
return [
|
return [
|
||||||
@ -386,22 +385,24 @@ struct SGPayWallView: View {
|
|||||||
|
|
||||||
|
|
||||||
// Spacer for purchase buttons
|
// Spacer for purchase buttons
|
||||||
Color.clear.frame(height: purchaseButtonBottomOffset)
|
Color.clear.frame(height: (purchaseSectionSize.height / 2.0))
|
||||||
}
|
}
|
||||||
.padding(.vertical, purchaseButtonBottomOffset)
|
.padding(.vertical, (purchaseSectionSize.height / 2.0))
|
||||||
}
|
}
|
||||||
.padding(.leading, max(innerShadowWidth + 8.0, sgLeftSafeAreaInset(containerViewLayout)))
|
.padding(.leading, max(innerShadowWidth + 8.0, sgLeftSafeAreaInset(containerViewLayout)))
|
||||||
.padding(.trailing, max(innerShadowWidth + 8.0, sgRightSafeAreaInset(containerViewLayout)))
|
.padding(.trailing, max(innerShadowWidth + 8.0, sgRightSafeAreaInset(containerViewLayout)))
|
||||||
|
|
||||||
if showDetails {
|
if showDetails {
|
||||||
SGPayWallFeatureDetails(
|
SGPayWallFeatureDetails(
|
||||||
dismissAction: { showDetails = false },
|
dismissAction: dismissDetails,
|
||||||
bottomOffset: purchaseButtonBottomOffset * 0.9, // reduced offset for paginator
|
bottomOffset: (purchaseSectionSize.height / 2.0) * 0.9, // reduced offset for paginator
|
||||||
features: features)
|
features: features,
|
||||||
|
shownFeature: shownFeature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixed purchase button at bottom
|
// Fixed purchase button at bottom
|
||||||
purchaseSection
|
purchaseSection
|
||||||
|
.trackSize($purchaseSectionSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.confetti(isActive: $showConfetti, duration: confettiDuration)
|
.confetti(isActive: $showConfetti, duration: confettiDuration)
|
||||||
@ -624,10 +625,16 @@ struct SGPayWallView: View {
|
|||||||
|
|
||||||
private func showDetailsForFeature(_ featureId: SGProFeatureId) {
|
private func showDetailsForFeature(_ featureId: SGProFeatureId) {
|
||||||
if #available(iOS 14.0, *) {
|
if #available(iOS 14.0, *) {
|
||||||
|
shownFeature = featureId
|
||||||
showDetails = true
|
showDetails = true
|
||||||
} // pagination is not available on iOS 13
|
} // pagination is not available on iOS 13
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func dismissDetails() {
|
||||||
|
// shownFeature = nil
|
||||||
|
showDetails = false
|
||||||
|
}
|
||||||
|
|
||||||
private func updateSelectedProduct() {
|
private func updateSelectedProduct() {
|
||||||
product = SGIAP.availableProducts.first { $0.id == SG_CONFIG.iaps.first ?? "" }
|
product = SGIAP.availableProducts.first { $0.id == SG_CONFIG.iaps.first ?? "" }
|
||||||
}
|
}
|
||||||
|
@ -413,6 +413,21 @@ public enum BackgroundMaterial {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum BounceBehavior {
|
||||||
|
case automatic
|
||||||
|
case always
|
||||||
|
case basedOnSize
|
||||||
|
|
||||||
|
@available(iOS 16.4, *)
|
||||||
|
var behavior: ScrollBounceBehavior {
|
||||||
|
switch self {
|
||||||
|
case .automatic: return .automatic
|
||||||
|
case .always: return .always
|
||||||
|
case .basedOnSize: return .basedOnSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
@available(iOS 13.0, *)
|
||||||
public extension View {
|
public extension View {
|
||||||
@ -438,6 +453,17 @@ public extension View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, *)
|
||||||
|
public extension View {
|
||||||
|
func scrollBounceBehaviorIfAvailable(_ behavior: BounceBehavior) -> some View {
|
||||||
|
if #available(iOS 16.4, *) {
|
||||||
|
return self.scrollBounceBehavior(behavior.behavior)
|
||||||
|
} else {
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
@available(iOS 13.0, *)
|
||||||
public extension View {
|
public extension View {
|
||||||
func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
|
func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
|
||||||
@ -459,3 +485,29 @@ public struct RoundedCorner: Shape {
|
|||||||
return Path(path.cgPath)
|
return Path(path.cgPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, *)
|
||||||
|
public struct ContentSizeModifier: ViewModifier {
|
||||||
|
@Binding var size: CGSize
|
||||||
|
|
||||||
|
public func body(content: Content) -> some View {
|
||||||
|
content
|
||||||
|
.background(
|
||||||
|
GeometryReader { geometry -> Color in
|
||||||
|
if geometry.size != size {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.size = geometry.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Color.clear
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, *)
|
||||||
|
public extension View {
|
||||||
|
func trackSize(_ size: Binding<CGSize>) -> some View {
|
||||||
|
self.modifier(ContentSizeModifier(size: size))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user