FrontPageView.swift 3.7 KB

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