@@ -39,61 +39,42 @@ public protocol PaymentMethodsUseCaseDataOutputs {
3939 * `selectedPaymentSource` - The currently selected credit card, or `nil` if no card is selected. Sent at least once after `initialData` is sent.
4040 * `paymentMethodChangedAndValid` - Whether or not the payment method is valid for the current pledge type. Sends an event after `initialData` and potentially more after `creditCardSelected(with:)` has happened.
4141 */
42+
4243public final class PaymentMethodsUseCase : PaymentMethodsUseCaseType , PaymentMethodsUseCaseUIInputs ,
4344 PaymentMethodsUseCaseUIOutputs , PaymentMethodsUseCaseDataOutputs {
44- init ( initialData: Signal < PledgeViewData , Never > , isLoggedIn isLoggedInChanged: Signal < Bool , Never > ) {
45- let project = initialData. map ( \. project)
46- let baseReward = initialData. map ( \. rewards) . map ( \. first) . skipNil ( )
47- let refTag = initialData. map ( \. refTag)
48- let context = initialData. map ( \. context)
49-
50- let initialDataUnpacked = Signal . zip ( project, baseReward, refTag, context)
51- let initialLoggedIn = initialData. map { _ in AppEnvironment . current. currentUser != nil }
52-
53- let isLoggedIn = Signal . merge (
54- initialLoggedIn,
55- isLoggedInChanged
56- ) . skipRepeats ( )
57-
58- let configurePaymentMethodsViewController = Signal . merge (
59- initialDataUnpacked,
60- initialDataUnpacked. takeWhen ( isLoggedIn. filter { $0 == true } )
61- )
45+ private var state : MutableProperty < PaymentMethodsUseCaseState ? >
6246
63- self . configurePaymentMethodsViewControllerWithValue = configurePaymentMethodsViewController
64- . filter { !$3. paymentMethodsViewHidden }
65- . compactMap { project, reward, refTag, context -> PledgePaymentMethodsValue ? in
66- guard let user = AppEnvironment . current. currentUser else { return nil }
67- return ( user, project, " " , reward, context, refTag)
68- }
69-
70- self . paymentMethodsViewHidden = Signal . combineLatest ( isLoggedIn, context)
71- . map { !$0 || $1. paymentMethodsViewHidden }
47+ init ( initialData: Signal < PledgeViewData , Never > , isLoggedIn isLoggedInChanged: Signal < Bool , Never > ) {
48+ self . state = MutableProperty ( nil )
7249
73- self . selectedPaymentSource = Signal . merge (
74- initialData. mapConst ( nil ) ,
75- self . creditCardSelectedSignal. wrapInOptional ( )
50+ self . state <~ Signal . combineLatest (
51+ initialData,
52+ Signal . merge ( initialData. map { _ in AppEnvironment . current. currentUser != nil } , isLoggedInChanged) ,
53+ Signal . merge ( initialData. mapConst ( nil ) , self . creditCardSelectedSignal. wrapInOptional ( ) )
7654 )
55+ . map { data, loggedIn, paymentSource in
56+ PaymentMethodsUseCaseState (
57+ data: data,
58+ isLoggedIn: loggedIn,
59+ paymentSourceSelected: paymentSource
60+ )
61+ }
7762
78- let notChangingPaymentMethod = context . map { context in
79- if context . isUpdating {
80- return context == . updateReward || context == . editPledgeOverTime
81- }
63+ self . paymentMethodsViewHidden = self . state . signal
64+ . skipNil ( )
65+ . map { $0 . isPaymentMethodViewHidden }
66+ . skipRepeats ( )
8267
83- return false
84- }
68+ self . configurePaymentMethodsViewControllerWithValue = self . state. signal
69+ . map { $0? . configurePaymentMethodsViewControllerValue }
70+ . skipNil ( )
8571
86- /// The `paymentMethodChangedAndValid` compares against the existing backing payment source id.
87- self . paymentMethodChangedAndValid = Signal . merge (
88- notChangingPaymentMethod,
89- Signal . combineLatest (
90- project,
91- baseReward,
92- self . creditCardSelectedSignal,
93- context
94- )
95- . map ( paymentMethodValid)
96- )
72+ self . selectedPaymentSource = self . state. signal
73+ . map { $0? . paymentSourceSelected }
74+
75+ self . paymentMethodChangedAndValid = self . state. signal
76+ . map { $0? . paymentMethodChangedAndValid }
77+ . skipNil ( )
9778 }
9879
9980 public let paymentMethodsViewHidden : Signal < Bool , Never >
@@ -112,25 +93,79 @@ public final class PaymentMethodsUseCase: PaymentMethodsUseCaseType, PaymentMeth
11293 public var dataOutputs : PaymentMethodsUseCaseDataOutputs { return self }
11394}
11495
115- private func paymentMethodValid(
116- project: Project ,
117- reward: Reward ,
118- paymentSource: PaymentSourceSelected ,
119- context: PledgeViewContext
120- ) -> Bool {
121- guard
122- let backedPaymentSourceId = project. personalization. backing? . paymentSource? . id,
123- context. isUpdating,
124- userIsBacking ( reward: reward, inProject: project)
125- else {
126- return true
96+ private struct PaymentMethodsUseCaseState {
97+ let data : PledgeViewData
98+ var isLoggedIn : Bool
99+ var paymentSourceSelected : PaymentSourceSelected ?
100+
101+ var isPaymentMethodViewHidden : Bool {
102+ if !self . isLoggedIn {
103+ return true
104+ }
105+
106+ return self . data. context. paymentMethodsViewHidden
107+ }
108+
109+ var baseReward : Reward ? {
110+ return self . data. rewards. first
111+ }
112+
113+ var configurePaymentMethodsViewControllerValue : PledgePaymentMethodsValue ? {
114+ if !self . isLoggedIn || self . isPaymentMethodViewHidden {
115+ return nil
116+ }
117+
118+ guard let user = AppEnvironment . current. currentUser,
119+ let reward = self . baseReward else {
120+ return nil
121+ }
122+
123+ return ( user, self . data. project, " " , reward, self . data. context, self . data. refTag)
127124 }
128125
129- if project. personalization. backing? . status == . errored {
130- return true
131- } else if backedPaymentSourceId != paymentSource. savedCreditCardId {
132- return true
126+ var notChangingPaymentMethod : Bool {
127+ let context = self . data. context
128+
129+ if context. isUpdating {
130+ return context == . updateReward || context == . editPledgeOverTime
131+ }
132+
133+ return false
133134 }
134135
135- return false
136+ /// The `paymentMethodChangedAndValid` compares against the existing backing payment source id.
137+ var paymentMethodChangedAndValid : Bool {
138+ guard let reward = self . baseReward,
139+ let source = self . paymentSourceSelected else { return self . notChangingPaymentMethod }
140+
141+ return self . paymentMethodValid (
142+ project: self . data. project,
143+ reward: reward,
144+ paymentSource: source,
145+ context: self . data. context
146+ )
147+ }
148+
149+ private func paymentMethodValid(
150+ project: Project ,
151+ reward: Reward ,
152+ paymentSource: PaymentSourceSelected ,
153+ context: PledgeViewContext
154+ ) -> Bool {
155+ guard
156+ let backedPaymentSourceId = project. personalization. backing? . paymentSource? . id,
157+ context. isUpdating,
158+ userIsBacking ( reward: reward, inProject: project)
159+ else {
160+ return true
161+ }
162+
163+ if project. personalization. backing? . status == . errored {
164+ return true
165+ } else if backedPaymentSourceId != paymentSource. savedCreditCardId {
166+ return true
167+ }
168+
169+ return false
170+ }
136171}
0 commit comments