Skip to content

Commit

Permalink
FTU
Browse files Browse the repository at this point in the history
  • Loading branch information
ruixhuang committed Jan 25, 2025
1 parent 071c355 commit e7b012f
Show file tree
Hide file tree
Showing 23 changed files with 390 additions and 106 deletions.
58 changes: 46 additions & 12 deletions PlatformUI/PlatformUI/DesignSystem/Theme/ThemeViewModifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -715,21 +715,21 @@ public extension View {
// MARK: ScrollView

public extension View {
func disableBounces() -> some View {
modifier(DisableBouncesModifier())
}
func disableBounces() -> some View {
modifier(DisableBouncesModifier())
}
}

struct DisableBouncesModifier: ViewModifier {
func body(content: Content) -> some View {
content
.onAppear {
UIScrollView.appearance().bounces = false
}
.onDisappear {
UIScrollView.appearance().bounces = true
}
}
func body(content: Content) -> some View {
content
.onAppear {
UIScrollView.appearance().bounces = false
}
.onDisappear {
UIScrollView.appearance().bounces = true
}
}
}

// MARK: Conditional
Expand All @@ -745,3 +745,37 @@ public extension View {
}
}
}

// MARK: GradientShade

public extension View {
func gradientShade(backgroundColor: ThemeColor.SemanticColor = .layer2, height: CGFloat = 42) -> some View {
modifier(GradientShadeModifier(layerColor: backgroundColor, height: height))
}
}

private struct GradientShadeModifier: ViewModifier {
let layerColor: ThemeColor.SemanticColor
let height: CGFloat

private var gradient: LinearGradient { LinearGradient(
gradient: Gradient(colors: [
layerColor.color,
Color.clear]),
startPoint: .bottom, endPoint: .top)
}

func body(content: Content) -> some View {
ZStack {
content
VStack {
Spacer()
VStack {
}
.frame(height: height)
.frame(maxWidth: .infinity)
.background(gradient)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ extension UIViewController: PanModalPresentable {
@objc open var showDragIndicator: Bool {
return false
}

@objc open func panModalDidDismiss() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public enum dydxBoolFeatureFlag: String, CaseIterable {
case .metadata_service:
return true
case .simple_ui:
return false
return true
}
}

Expand Down
12 changes: 12 additions & 0 deletions dydx/dydxPresenters/dydxPresenters.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
020492532D3EDA3100394CBE /* dydxSimpleUITradeStatusViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 020492522D3EDA3000394CBE /* dydxSimpleUITradeStatusViewBuilder.swift */; };
020494362D42D1DC00394CBE /* dydxSimpleUITradeInputPositionViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 020494282D42D1DB00394CBE /* dydxSimpleUITradeInputPositionViewPresenter.swift */; };
0204946D2D43F6D500394CBE /* dydxProfileHelpViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0204945F2D43F6CC00394CBE /* dydxProfileHelpViewPresenter.swift */; };
020494732D4433CE00394CBE /* dydxFirstTimeViewBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 020494722D4433CD00394CBE /* dydxFirstTimeViewBuilder.swift */; };
0207FC9D2D269C00004C2C9F /* dydxSimpleUITradeInputValidationViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0207FC8F2D269BFF004C2C9F /* dydxSimpleUITradeInputValidationViewPresenter.swift */; };
0207FC9F2D27BA6B004C2C9F /* dydxSimpleUITradeInputCtaButtonViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0207FC9E2D27BA62004C2C9F /* dydxSimpleUITradeInputCtaButtonViewPresenter.swift */; };
0207FCA32D2A181D004C2C9F /* dydxSimpleUIMarketsHeaderViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0207FCA22D2A181C004C2C9F /* dydxSimpleUIMarketsHeaderViewPresenter.swift */; };
Expand Down Expand Up @@ -448,6 +449,7 @@
020492522D3EDA3000394CBE /* dydxSimpleUITradeStatusViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUITradeStatusViewBuilder.swift; sourceTree = "<group>"; };
020494282D42D1DB00394CBE /* dydxSimpleUITradeInputPositionViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUITradeInputPositionViewPresenter.swift; sourceTree = "<group>"; };
0204945F2D43F6CC00394CBE /* dydxProfileHelpViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxProfileHelpViewPresenter.swift; sourceTree = "<group>"; };
020494722D4433CD00394CBE /* dydxFirstTimeViewBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxFirstTimeViewBuilder.swift; sourceTree = "<group>"; };
0207FC8F2D269BFF004C2C9F /* dydxSimpleUITradeInputValidationViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUITradeInputValidationViewPresenter.swift; sourceTree = "<group>"; };
0207FC9E2D27BA62004C2C9F /* dydxSimpleUITradeInputCtaButtonViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUITradeInputCtaButtonViewPresenter.swift; sourceTree = "<group>"; };
0207FCA22D2A181C004C2C9F /* dydxSimpleUIMarketsHeaderViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dydxSimpleUIMarketsHeaderViewPresenter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -737,6 +739,14 @@
path = TradeStatus;
sourceTree = "<group>";
};
020494712D4433C300394CBE /* FirstTime */ = {
isa = PBXGroup;
children = (
020494722D4433CD00394CBE /* dydxFirstTimeViewBuilder.swift */,
);
path = FirstTime;
sourceTree = "<group>";
};
02084B1B297FC2B400CF9522 /* Components */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1411,6 +1421,7 @@
02D6DAEA2D1234A3008AAEA1 /* SimpleUI */ = {
isa = PBXGroup;
children = (
020494712D4433C300394CBE /* FirstTime */,
02048BC12D382B8A00394CBE /* Search */,
027886012D1F4BC300366321 /* Trade */,
027885E22D1DD62600366321 /* MarketInfo */,
Expand Down Expand Up @@ -2199,6 +2210,7 @@
0273A1472ACCC4C4001B89F5 /* dydxHistoryViewBuilder.swift in Sources */,
020494362D42D1DC00394CBE /* dydxSimpleUITradeInputPositionViewPresenter.swift in Sources */,
02F958232A1BDEFA00828F9A /* dydxKeyExportViewBuilder.swift in Sources */,
020494732D4433CE00394CBE /* dydxFirstTimeViewBuilder.swift in Sources */,
02D6DB272D124AAF008AAEA1 /* dydxAppModeViewBuilder.swift in Sources */,
025D22D628F65E1B00C4ADAE /* dydxMarketStatsViewPresenter.swift in Sources */,
6453AB2B299EA4380041A0C4 /* dydxClosePositionInputCtaButtonViewPresenter.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PlatformUI
import Abacus
import dydxStateManager
import dydxAnalytics
import PanModal

public class dydxOnboardWelcomeViewBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
Expand All @@ -26,6 +27,12 @@ public class dydxOnboardWelcomeViewBuilder: NSObject, ObjectBuilderProtocol {
private class dydxOnboardWelcomeViewController: HostingViewController<PlatformView, dydxOnboardWelcomeViewModel> {
override public func arrive(to request: RoutingRequest?, animated: Bool) -> Bool {
if request?.path == "/onboard" {
if let mode = request?.params?["mode"] as? String,
let presenter = presenter as? dydxOnboardWelcomeViewPresenter {
if mode == "welcome" {
presenter.mode = .simpleUIWelcome
}
}
return true
} else {
return false
Expand All @@ -38,6 +45,13 @@ private protocol dydxOnboardWelcomeViewPresenterProtocol: HostedViewPresenterPro
}

private class dydxOnboardWelcomeViewPresenter: HostedViewPresenter<dydxOnboardWelcomeViewModel>, dydxOnboardWelcomeViewPresenterProtocol {
enum Mode {
case simpleUIWelcome
case walletOnboard
}

var mode: Mode = .walletOnboard

private let onboardingAnalytics: OnboardingAnalytics

init(onboardingAnalytics: OnboardingAnalytics = OnboardingAnalytics()) {
Expand All @@ -46,10 +60,30 @@ private class dydxOnboardWelcomeViewPresenter: HostedViewPresenter<dydxOnboardWe

viewModel = dydxOnboardWelcomeViewModel()
viewModel?.ctaAction = { [weak self] in
self?.onboardingAnalytics.log(step: .chooseWallet)
Router.shared?.navigate(to: RoutingRequest(path: "/onboard/wallets"), animated: true, completion: nil)
guard let self else { return }
switch self.mode {
case .simpleUIWelcome:
Router.shared?.navigate(to: RoutingRequest(path: "/action/dismiss"), animated: true) { _, _ in
Router.shared?.navigate(to: RoutingRequest(path: "/settings/app_mode"), animated: true, completion: nil)
}
case .walletOnboard:
self.onboardingAnalytics.log(step: .chooseWallet)
Router.shared?.navigate(to: RoutingRequest(path: "/onboard/wallets"), animated: true, completion: nil)
}
}
viewModel?.tosUrl = AbacusStateManager.shared.environment?.links?.tos
viewModel?.privacyPolicyUrl = AbacusStateManager.shared.environment?.links?.privacy
}

override func onHalfSheetDismissal() {
super.onHalfSheetDismissal()

switch mode {
case .simpleUIWelcome:
Router.shared?.navigate(to: RoutingRequest(path: "/settings/app_mode"), animated: true, completion: nil)
case .walletOnboard:
// no-op
break
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class dydxAppModeViewBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
let presenter = dydxAppModeViewPresenter()
let view = presenter.viewModel?.createView() ?? PlatformViewModel().createView()
return dydxAppModeViewController(presenter: presenter, view: view, configuration: .ignoreSafeArea) as? T
return dydxAppModeViewController(presenter: presenter, view: view, configuration: .fullScreenSheet) as? T
}
}

Expand Down Expand Up @@ -52,16 +52,30 @@ private class dydxAppModeViewPresenter: HostedViewPresenter<dydxAppModeViewModel
self?.viewModel?.appMode = mode
AppMode.current = mode

Router.shared?.navigate(to: RoutingRequest(path: "/loading"), animated: true, completion: { _, _ in
Router.shared?.navigate(to: RoutingRequest(path: "/"), animated: true, completion: { _, _ in
})
})
self?.loadRoot()
}
}
viewModel?.onCancel = {
Router.shared?.navigate(to: RoutingRequest(path: "/action/dismiss"), animated: true, completion: nil)
}
}

override func onHalfSheetDismissal() {
super.onHalfSheetDismissal()

if AppMode.current == nil {
// Defaulting to Simple
AppMode.current = .simple
loadRoot()
}
}

private func loadRoot() {
Router.shared?.navigate(to: RoutingRequest(path: "/loading"), animated: true, completion: { _, _ in
Router.shared?.navigate(to: RoutingRequest(path: "/"), animated: true, completion: { _, _ in
})
})
}
}

public extension AppMode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,49 @@ import PlatformUI
import ParticlesKit
import dydxFormatter
import dydxViews
import dydxStateManager
import Combine

public class dydxRootBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
if dydxBoolFeatureFlag.simple_ui.isEnabled, AppMode.current == .simple {
let presenter = dydxSimpleUIMarketsViewPresenter()
let view = presenter.viewModel?.createView() ?? PlatformViewModel().createView()
let viewController = dydxSimpleUIMarketsViewController(presenter: presenter, view: view, configuration: .default)
return UINavigationController(rootViewController: viewController) as? T
} else {
return dydxProUITabBarController() as? T
}
nil
}

private var subscriptions = [AnyCancellable]()

public func buildAsync<T>(completion: @escaping ((T?) -> Void)) {
AbacusStateManager.shared.state.onboarded
.prefix(1)
.sink { onboarded in
if dydxBoolFeatureFlag.simple_ui.isEnabled {
if AppMode.current == nil {
if onboarded {
let viewController = dydxProUITabBarController() as? T
completion(viewController)
} else {
// first time user
let presenter = dydxFirstTimeViewPresenter()
let view = presenter.viewModel?.createView() ?? PlatformViewModel().createView()
let viewController = dydxFirstTimeViewController(presenter: presenter, view: view, configuration: .default) as? T
completion(viewController)
}
} else {
if AppMode.current == .simple {
let presenter = dydxSimpleUIMarketsViewPresenter()
let view = presenter.viewModel?.createView() ?? PlatformViewModel().createView()
let viewController = dydxSimpleUIMarketsViewController(presenter: presenter, view: view, configuration: .default)
let navController = UINavigationController(rootViewController: viewController) as? T
completion(navController)
} else {
let viewController = dydxProUITabBarController() as? T
completion(viewController)
}
}
} else {
let viewController = dydxProUITabBarController() as? T
completion(viewController)
}
}
.store(in: &subscriptions)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// dydxFirstTimeViewBuilder.swift
// dydxPresenters
//
// Created by Rui Huang on 24/01/2025.
//

import Utilities
import dydxViews
import PlatformParticles
import RoutingKit
import ParticlesKit
import PlatformUI

public class dydxFirstTimeViewBuilder: NSObject, ObjectBuilderProtocol {
public func build<T>() -> T? {
let presenter = dydxFirstTimeViewPresenter()
let view = presenter.viewModel?.createView() ?? PlatformViewModel().createView()
return dydxFirstTimeViewController(presenter: presenter, view: view, configuration: .default) as? T
}
}

class dydxFirstTimeViewController: HostingViewController<PlatformView, dydxFirstTimeViewModel> {
override public func arrive(to request: RoutingRequest?, animated: Bool) -> Bool {
if request?.path == "<Replace>" {
return true
}
return false
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

guard let presenter = presenter as? dydxFirstTimeViewPresenter else {
return
}

presenter.showWelecomScreen()
}
}

protocol dydxFirstTimeViewPresenterProtocol: HostedViewPresenterProtocol {
var viewModel: dydxFirstTimeViewModel? { get }
}

class dydxFirstTimeViewPresenter: HostedViewPresenter<dydxFirstTimeViewModel>, dydxFirstTimeViewPresenterProtocol {

private var started = false

override init() {
super.init()

viewModel = dydxFirstTimeViewModel()
}

func showWelecomScreen() {
if !started {
started = true
let params = ["mode": "welcome"]
Router.shared?.navigate(to: RoutingRequest(path: "/onboard", params: params), animated: true, completion: nil)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ public class dydxSimpleUIMarketsViewPresenter: HostedViewPresenter<dydxSimpleUIM
}

attachChildren(workers: childPresenters)

AbacusStateManager.shared.state.onboarded
.prefix(1)
.sink { onboarded in
print(onboarded)
}
.store(in: &subscriptions)
}

public override func start() {
Expand Down
Loading

0 comments on commit e7b012f

Please sign in to comment.