FrontPageView.swift 3.1 KB

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