mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
remove welcome view model
This commit is contained in:
parent
f97c196f3e
commit
aa355088d2
7 changed files with 174 additions and 199 deletions
|
|
@ -170,7 +170,7 @@ public struct RootView: View {
|
|||
#endif
|
||||
|
||||
} else {
|
||||
WelcomeView(viewModel: WelcomeViewModel.make(services: viewModel.services))
|
||||
WelcomeView(services: viewModel.services)
|
||||
.accessibilityElement()
|
||||
.accessibilityIdentifier("welcomeView")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
import Services
|
||||
import SwiftUI
|
||||
import Utils
|
||||
import Views
|
||||
|
||||
extension WelcomeViewModel {
|
||||
static func make(services: Services) -> WelcomeViewModel {
|
||||
let registrationViewModel = RegistrationViewModel.make(services: services)
|
||||
let viewModel = WelcomeViewModel(registrationViewModel: registrationViewModel)
|
||||
viewModel.bind(services: services)
|
||||
return viewModel
|
||||
}
|
||||
|
||||
func bind(services: Services) {
|
||||
performActionSubject.sink { [weak self] action in
|
||||
switch action {
|
||||
case .hiddenGesturePerformed:
|
||||
if !Bundle.main.isAppStoreBuild {
|
||||
self?.debugMenuViewModel = DebugMenuViewModel.make(services: services)
|
||||
self?.showDebugModal = true
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &subscriptions)
|
||||
}
|
||||
}
|
||||
83
apple/OmnivoreKit/Sources/Binders/Views/WelcomeView.swift
Normal file
83
apple/OmnivoreKit/Sources/Binders/Views/WelcomeView.swift
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import Combine
|
||||
import Services
|
||||
import SwiftUI
|
||||
import Utils
|
||||
import Views
|
||||
|
||||
struct WelcomeView: View {
|
||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
||||
let services: Services
|
||||
@State private var showRegistrationView = false
|
||||
@State private var isKeyboardOnScreen = false
|
||||
@State private var showDebugModal = false
|
||||
|
||||
func handleHiddenGestureAction() {
|
||||
if !Bundle.main.isAppStoreBuild {
|
||||
showDebugModal = true
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func userInteractiveView(width: CGFloat) -> some View {
|
||||
Group {
|
||||
if showRegistrationView {
|
||||
RegistrationView(viewModel: RegistrationViewModel.make(services: services))
|
||||
} else {
|
||||
GetStartedView(showRegistrationView: $showRegistrationView)
|
||||
}
|
||||
}
|
||||
.frame(width: width)
|
||||
.zIndex(2)
|
||||
}
|
||||
|
||||
@ViewBuilder func primaryContent() -> some View {
|
||||
if horizontalSizeClass == .compact {
|
||||
GeometryReader { geometry in
|
||||
ZStack(alignment: .leading) {
|
||||
Color.systemBackground
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
|
||||
if geometry.size.width < geometry.size.height, !isKeyboardOnScreen {
|
||||
VStack {
|
||||
Color.appDeepBackground.frame(height: 100)
|
||||
Spacer()
|
||||
}
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
|
||||
VStack {
|
||||
if geometry.size.width < geometry.size.height, !isKeyboardOnScreen {
|
||||
RegistrationHeroImageView(tapGestureHandler: handleHiddenGestureAction)
|
||||
}
|
||||
userInteractiveView(width: geometry.size.width)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GeometryReader { geometry in
|
||||
ZStack(alignment: .leading) {
|
||||
SplitColorBackground(width: geometry.size.width)
|
||||
|
||||
VStack {
|
||||
TitleLogoView(handleHiddenGestureAction: handleHiddenGestureAction)
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
|
||||
HStack(spacing: 0) {
|
||||
userInteractiveView(width: geometry.size.width * 0.5)
|
||||
ReadingIllustrationXXLView(width: geometry.size.width * 0.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
primaryContent()
|
||||
.sheet(isPresented: $showDebugModal) {
|
||||
DebugMenuView(viewModel: DebugMenuViewModel.make(services: services))
|
||||
}
|
||||
.onReceive(Publishers.keyboardHeight) { isKeyboardOnScreen = $0 > 1 }
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import SwiftUI
|
|||
import UIKit
|
||||
#endif
|
||||
|
||||
extension Publishers {
|
||||
public extension Publishers {
|
||||
static var keyboardHeight: AnyPublisher<CGFloat, Never> {
|
||||
#if os(iOS)
|
||||
let willShow = NotificationCenter.default
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import SwiftUI
|
||||
|
||||
struct RegistrationHeroImageView: View {
|
||||
public struct RegistrationHeroImageView: View {
|
||||
let tapGestureHandler: () -> Void
|
||||
|
||||
var body: some View {
|
||||
public init(tapGestureHandler: @escaping () -> Void) {
|
||||
self.tapGestureHandler = tapGestureHandler
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
ZStack(alignment: .topLeading) {
|
||||
Image.readingIllustration
|
||||
.resizable()
|
||||
|
|
|
|||
|
|
@ -1,169 +0,0 @@
|
|||
import Combine
|
||||
import Models
|
||||
import SwiftUI
|
||||
|
||||
public final class WelcomeViewModel: ObservableObject {
|
||||
@Published public var showDebugModal: Bool = false
|
||||
@Published public var showRegistrationModal: Bool = false
|
||||
|
||||
public let registrationViewModel: RegistrationViewModel
|
||||
public var debugMenuViewModel: DebugMenuViewModel?
|
||||
|
||||
public enum Action {
|
||||
case hiddenGesturePerformed
|
||||
}
|
||||
|
||||
public var subscriptions = Set<AnyCancellable>()
|
||||
public let performActionSubject = PassthroughSubject<Action, Never>()
|
||||
|
||||
public init(registrationViewModel: RegistrationViewModel) {
|
||||
self.registrationViewModel = registrationViewModel
|
||||
}
|
||||
}
|
||||
|
||||
public struct WelcomeView: View {
|
||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
||||
@ObservedObject private var viewModel: WelcomeViewModel
|
||||
@State private var showRegistrationView = false
|
||||
@State private var isKeyboardOnScreen = false
|
||||
|
||||
public init(viewModel: WelcomeViewModel) {
|
||||
self.viewModel = viewModel
|
||||
}
|
||||
|
||||
@ViewBuilder func userInteractiveView(width: CGFloat) -> some View {
|
||||
Group {
|
||||
if showRegistrationView {
|
||||
RegistrationView(viewModel: viewModel.registrationViewModel)
|
||||
} else {
|
||||
GetStartedView(showRegistrationView: $showRegistrationView)
|
||||
}
|
||||
}
|
||||
.frame(width: width)
|
||||
.zIndex(2)
|
||||
}
|
||||
|
||||
@ViewBuilder func primaryContent() -> some View {
|
||||
if horizontalSizeClass == .compact {
|
||||
GeometryReader { geometry in
|
||||
ZStack(alignment: .leading) {
|
||||
Color.systemBackground
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
|
||||
if geometry.size.width < geometry.size.height, !isKeyboardOnScreen {
|
||||
VStack {
|
||||
Color.appDeepBackground.frame(height: 100)
|
||||
Spacer()
|
||||
}
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
|
||||
VStack {
|
||||
if geometry.size.width < geometry.size.height, !isKeyboardOnScreen {
|
||||
RegistrationHeroImageView(
|
||||
tapGestureHandler: { viewModel.performActionSubject.send(.hiddenGesturePerformed) }
|
||||
)
|
||||
}
|
||||
userInteractiveView(width: geometry.size.width)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GeometryReader { geometry in
|
||||
ZStack(alignment: .leading) {
|
||||
SplitColorBackground(width: geometry.size.width)
|
||||
|
||||
VStack {
|
||||
TitleLogoView {
|
||||
viewModel.performActionSubject.send(.hiddenGesturePerformed)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
|
||||
HStack(spacing: 0) {
|
||||
userInteractiveView(width: geometry.size.width * 0.5)
|
||||
ReadingIllustrationXXLView(width: geometry.size.width * 0.5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
primaryContent()
|
||||
.sheet(isPresented: $viewModel.showDebugModal) {
|
||||
if let debugMenuViewModel = viewModel.debugMenuViewModel {
|
||||
DebugMenuView(viewModel: debugMenuViewModel)
|
||||
}
|
||||
}
|
||||
.onReceive(Publishers.keyboardHeight) { isKeyboardOnScreen = $0 > 1 }
|
||||
}
|
||||
}
|
||||
|
||||
public struct ReadingIllustrationXXLView: View {
|
||||
let width: CGFloat
|
||||
|
||||
public var body: some View {
|
||||
Image.readingIllustrationXXL
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: width)
|
||||
.clipped()
|
||||
.edgesIgnoringSafeArea([.vertical, .trailing])
|
||||
}
|
||||
}
|
||||
|
||||
public struct TitleLogoView: View {
|
||||
let handleHiddenGestureAction: () -> Void
|
||||
|
||||
public var body: some View {
|
||||
Image.omnivoreTitleLogo
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(.appGrayTextContrast)
|
||||
.frame(height: 40)
|
||||
.gesture(
|
||||
TapGesture(count: 2)
|
||||
.onEnded {
|
||||
handleHiddenGestureAction()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct GetStartedView: View {
|
||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
||||
@Binding var showRegistrationView: Bool
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 32) {
|
||||
Text("A better social\nreading experience\nstarts with Omnivore.")
|
||||
.font(.appTitle)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
BorderedButton(color: .appGrayTextContrast, text: "Get Started") {
|
||||
showRegistrationView = true
|
||||
}
|
||||
.frame(width: 220)
|
||||
}
|
||||
.padding(.leading, horizontalSizeClass == .compact ? 16 : 80)
|
||||
.padding(.top, horizontalSizeClass == .compact ? 16 : 0)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SplitColorBackground: View {
|
||||
let width: CGFloat
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 0) {
|
||||
Color.systemBackground.frame(width: width * 0.5)
|
||||
Color.appBackground.frame(width: width * 0.5)
|
||||
}
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import SwiftUI
|
||||
|
||||
public struct ReadingIllustrationXXLView: View {
|
||||
let width: CGFloat
|
||||
|
||||
public init(width: CGFloat) {
|
||||
self.width = width
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
Image.readingIllustrationXXL
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: width)
|
||||
.clipped()
|
||||
.edgesIgnoringSafeArea([.vertical, .trailing])
|
||||
}
|
||||
}
|
||||
|
||||
public struct TitleLogoView: View {
|
||||
let handleHiddenGestureAction: () -> Void
|
||||
|
||||
public init(handleHiddenGestureAction: @escaping () -> Void) {
|
||||
self.handleHiddenGestureAction = handleHiddenGestureAction
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
Image.omnivoreTitleLogo
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(.appGrayTextContrast)
|
||||
.frame(height: 40)
|
||||
.gesture(
|
||||
TapGesture(count: 2)
|
||||
.onEnded {
|
||||
handleHiddenGestureAction()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
public struct GetStartedView: View {
|
||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
||||
@Binding var showRegistrationView: Bool
|
||||
|
||||
public init(showRegistrationView: Binding<Bool>) {
|
||||
self._showRegistrationView = showRegistrationView
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 32) {
|
||||
Text("A better social\nreading experience\nstarts with Omnivore.")
|
||||
.font(.appTitle)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
BorderedButton(color: .appGrayTextContrast, text: "Get Started") {
|
||||
showRegistrationView = true
|
||||
}
|
||||
.frame(width: 220)
|
||||
}
|
||||
.padding(.leading, horizontalSizeClass == .compact ? 16 : 80)
|
||||
.padding(.top, horizontalSizeClass == .compact ? 16 : 0)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct SplitColorBackground: View {
|
||||
let width: CGFloat
|
||||
|
||||
public init(width: CGFloat) {
|
||||
self.width = width
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
HStack(spacing: 0) {
|
||||
Color.systemBackground.frame(width: width * 0.5)
|
||||
Color.appBackground.frame(width: width * 0.5)
|
||||
}
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue