FrontPageView.swift 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import SwiftUI
  2. struct FrontPageView: View {
  3. @EnvironmentObject private var subscriptions: SubscriptionManager
  4. @State private var viewModel = FrontPageViewModel()
  5. @State private var paywallViewModel = PaywallViewModel()
  6. @State private var postGeneratorViewModel = PostGeneratorViewModel()
  7. @State private var titleOptimizerViewModel = TitleOptimizerViewModel()
  8. @State private var commentWriterViewModel = CommentWriterViewModel()
  9. var body: some View {
  10. ZStack {
  11. HStack(spacing: 0) {
  12. SidebarView(
  13. viewModel: viewModel,
  14. isPremium: subscriptions.hasPremiumAccess
  15. )
  16. mainContent
  17. .frame(maxWidth: .infinity, maxHeight: .infinity)
  18. .environment(\.requirePremiumAccess, {
  19. if subscriptions.hasPremiumAccess { return true }
  20. viewModel.showPaywall()
  21. return false
  22. })
  23. }
  24. if viewModel.isPaywallPresented {
  25. PaywallView(viewModel: paywallViewModel) {
  26. viewModel.dismissPaywall()
  27. }
  28. .frame(maxWidth: .infinity, maxHeight: .infinity)
  29. .ignoresSafeArea()
  30. .zIndex(1)
  31. .transition(.opacity)
  32. }
  33. }
  34. .animation(.easeInOut(duration: 0.2), value: viewModel.isPaywallPresented)
  35. .onChange(of: subscriptions.hasPremiumAccess) { hasPremium in
  36. if hasPremium {
  37. viewModel.dismissPaywall()
  38. }
  39. }
  40. .frame(minWidth: AppWindow.minWidth, minHeight: AppWindow.minHeight)
  41. .background(AppTheme.background)
  42. }
  43. @ViewBuilder
  44. private var mainContent: some View {
  45. ZStack {
  46. RedditWebView(
  47. url: viewModel.redditLoadURL,
  48. reloadTrigger: viewModel.redditReloadTrigger
  49. )
  50. .id("reddit-webview")
  51. .frame(maxWidth: .infinity, maxHeight: .infinity)
  52. .allowsHitTesting(viewModel.isRedditActive)
  53. .accessibilityHidden(!viewModel.isRedditActive)
  54. if viewModel.isSettingsActive {
  55. SettingsView()
  56. } else if !viewModel.isRedditActive, let item = viewModel.selectedNavItem {
  57. toolContent(for: item)
  58. }
  59. }
  60. .background(AppTheme.background)
  61. }
  62. @ViewBuilder
  63. private func toolContent(for item: SidebarNavItem) -> some View {
  64. switch item.iconKind {
  65. case .postGenerator:
  66. PostGeneratorView(viewModel: postGeneratorViewModel)
  67. case .titleOptimizer:
  68. TitleOptimizerView(viewModel: titleOptimizerViewModel)
  69. case .commentWriter:
  70. CommentWriterView(viewModel: commentWriterViewModel)
  71. default:
  72. ToolPlaceholderView(item: item)
  73. }
  74. }
  75. }
  76. private struct ToolPlaceholderView: View {
  77. let item: SidebarNavItem
  78. var body: some View {
  79. VStack(spacing: 12) {
  80. ModernSidebarIconView(kind: item.iconKind, size: 56)
  81. Text(item.title)
  82. .font(.system(size: 20, weight: .semibold))
  83. .foregroundStyle(AppTheme.textPrimary)
  84. Text(item.subtitle)
  85. .font(.system(size: 13))
  86. .foregroundStyle(AppTheme.textSecondary)
  87. }
  88. .frame(maxWidth: .infinity, maxHeight: .infinity)
  89. .background(AppTheme.background)
  90. }
  91. }
  92. #Preview {
  93. FrontPageView()
  94. .environmentObject(SubscriptionManager())
  95. .frame(width: AppWindow.width, height: AppWindow.height)
  96. }