- Fix LargeVotingView mood icons getting clipped at edges by using flexible HStack spacing with maxWidth: .infinity - Fix VotingView medium layout with smaller icons and even distribution - Add comprehensive #Preview macros for all widget states: - Vote widget: small/medium, voted/not voted, all mood states - Timeline widget: small/medium/large with various data states - Reduce icon sizes and padding to fit within widget bounds - Update accessibility labels and hints across views 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
99 lines
3.1 KiB
Swift
99 lines
3.1 KiB
Swift
//
|
|
// FeelsSubscriptionStoreView.swift
|
|
// Feels
|
|
//
|
|
// Native StoreKit 2 subscription purchase view.
|
|
//
|
|
|
|
import SwiftUI
|
|
import StoreKit
|
|
|
|
struct FeelsSubscriptionStoreView: View {
|
|
@Environment(\.dismiss) private var dismiss
|
|
@EnvironmentObject var iapManager: IAPManager
|
|
|
|
var body: some View {
|
|
SubscriptionStoreView(groupID: IAPManager.subscriptionGroupID) {
|
|
VStack(spacing: 20) {
|
|
// App icon or logo
|
|
ZStack {
|
|
Circle()
|
|
.fill(
|
|
LinearGradient(
|
|
colors: [.pink.opacity(0.3), .orange.opacity(0.2)],
|
|
startPoint: .topLeading,
|
|
endPoint: .bottomTrailing
|
|
)
|
|
)
|
|
.frame(width: 100, height: 100)
|
|
|
|
Image(systemName: "heart.fill")
|
|
.font(.largeTitle)
|
|
.foregroundStyle(
|
|
LinearGradient(
|
|
colors: [.pink, .red],
|
|
startPoint: .top,
|
|
endPoint: .bottom
|
|
)
|
|
)
|
|
}
|
|
|
|
VStack(spacing: 8) {
|
|
Text("Unlock Premium")
|
|
.font(.title.weight(.bold))
|
|
|
|
Text("Get unlimited access to all features")
|
|
.font(.body)
|
|
.foregroundStyle(.secondary)
|
|
.multilineTextAlignment(.center)
|
|
}
|
|
|
|
// Feature highlights
|
|
VStack(alignment: .leading, spacing: 12) {
|
|
FeatureHighlight(icon: "calendar", text: "Month & Year Views")
|
|
FeatureHighlight(icon: "lightbulb.fill", text: "AI-Powered Insights")
|
|
FeatureHighlight(icon: "heart.text.square.fill", text: "Health Data Correlation")
|
|
FeatureHighlight(icon: "square.grid.2x2.fill", text: "Interactive Widgets")
|
|
}
|
|
.padding(.top, 8)
|
|
}
|
|
.padding(.horizontal, 20)
|
|
.padding(.vertical, 10)
|
|
}
|
|
.subscriptionStoreControlStyle(.prominentPicker)
|
|
.storeButton(.visible, for: .restorePurchases)
|
|
.subscriptionStoreButtonLabel(.multiline)
|
|
.tint(.pink)
|
|
.onInAppPurchaseCompletion { _, result in
|
|
if case .success(.success(_)) = result {
|
|
dismiss()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Feature Highlight Row
|
|
struct FeatureHighlight: View {
|
|
let icon: String
|
|
let text: String
|
|
|
|
var body: some View {
|
|
HStack(spacing: 12) {
|
|
Image(systemName: "checkmark.circle.fill")
|
|
.font(.headline)
|
|
.foregroundColor(.green)
|
|
|
|
Text(text)
|
|
.font(.subheadline.weight(.medium))
|
|
.foregroundColor(.primary)
|
|
|
|
Spacer()
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
FeelsSubscriptionStoreView()
|
|
.environmentObject(IAPManager())
|
|
}
|