-
Notifications
You must be signed in to change notification settings - Fork 629
/
AddressLauncher.kt
185 lines (161 loc) · 6.01 KB
/
AddressLauncher.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package com.stripe.android.paymentsheet.addresselement
import android.os.Parcelable
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.Fragment
import com.stripe.android.core.injection.InjectorKey
import com.stripe.android.core.injection.WeakMapInjectorRegistry
import com.stripe.android.paymentsheet.PaymentSheet
import kotlinx.parcelize.Parcelize
/**
* A drop-in class that presents a bottom sheet to collect a customer's address.
*/
internal class AddressLauncher internal constructor(
private val activityResultLauncher: ActivityResultLauncher<AddressElementActivityContract.Args>
) {
@InjectorKey
private val injectorKey: String =
WeakMapInjectorRegistry.nextKey(requireNotNull(AddressLauncher::class.simpleName))
/**
* Constructor to be used when launching the address element from an Activity.
*
* @param activity the Activity that is presenting the address element.
* @param callback called with the result after the address element is dismissed.
*/
constructor(
activity: ComponentActivity,
callback: AddressLauncherResultCallback
) : this(
activity.registerForActivityResult(
AddressElementActivityContract()
) {
callback.onAddressLauncherResult(it)
}
)
/**
* Constructor to be used when launching the address element from a Fragment.
*
* @param fragment the Fragment that is presenting the payment sheet.
* @param callback called with the result after the address element is dismissed.
*/
constructor(
fragment: Fragment,
callback: AddressLauncherResultCallback
) : this(
fragment.registerForActivityResult(
AddressElementActivityContract()
) {
callback.onAddressLauncherResult(it)
}
)
@JvmOverloads
fun present(
publishableKey: String,
configuration: Configuration = Configuration()
) {
activityResultLauncher.launch(
AddressElementActivityContract.Args(
publishableKey,
configuration,
injectorKey
)
)
}
/** Configuration for [AddressLauncher] **/
@Parcelize
internal data class Configuration @JvmOverloads constructor(
/**
* Configuration for the look and feel of the UI
*/
val appearance: PaymentSheet.Appearance = PaymentSheet.Appearance(),
/**
* The values to pre-populate shipping address fields with.
*/
val defaultValues: AddressDetails? = null,
/**
* A list of two-letter country codes representing countries the customers can select.
* If the list is empty (the default), we display all countries.
*/
val allowedCountries: Set<String> = emptySet(),
/**
* The title of the primary button displayed at the bottom of the screen.
* Defaults to "Save address".
*/
val buttonTitle: String? = null,
/**
* Configuration for the field that collects a phone number.
* Defaults to HIDDEN
*/
val phone: AdditionalFieldsConfiguration = AdditionalFieldsConfiguration.OPTIONAL,
/**
* Configuration for a "Remember this shipping destination" checkbox.
* Defaults to false
*/
val shouldShowCheckBox: Boolean = false,
/**
* Configuration for the title displayed at the top of the screen.
* Defaults to "Address"
*/
val title: String? = null,
/**
* Google Places api key used to provide autocomplete suggestions
* When null, autocomplete is disabled.
*/
val googlePlacesApiKey: String? = ""
) : Parcelable {
/**
* [Configuration] builder for cleaner object creation from Java.
*/
class Builder {
var appearance: PaymentSheet.Appearance = PaymentSheet.Appearance()
var defaultValues: AddressDetails? = null
var allowedCountries: Set<String> = emptySet()
var buttonTitle: String? = null
var phone: AdditionalFieldsConfiguration = AdditionalFieldsConfiguration.OPTIONAL
var shouldShowCheckBox: Boolean = false
var title: String? = null
var googlePlacesApiKey: String? = null
fun appearance(appearance: PaymentSheet.Appearance) =
apply { this.appearance = appearance }
fun defaultValues(defaultValues: AddressDetails?) =
apply { this.defaultValues = defaultValues }
fun allowedCountries(allowedCountries: Set<String>) =
apply { this.allowedCountries = allowedCountries }
fun buttonTitle(buttonTitle: String?) =
apply { this.buttonTitle = buttonTitle }
fun phone(phone: AdditionalFieldsConfiguration) =
apply { this.phone = phone }
fun shouldShowCheckBox(shouldShowCheckBox: Boolean) =
apply { this.shouldShowCheckBox = shouldShowCheckBox }
fun title(title: String?) =
apply { this.title = title }
fun googlePlacesApiKey(googlePlacesApiKey: String?) =
apply { this.googlePlacesApiKey = googlePlacesApiKey }
fun build() = Configuration(
appearance,
defaultValues,
allowedCountries,
buttonTitle,
phone,
shouldShowCheckBox,
title,
googlePlacesApiKey
)
}
}
@Parcelize
enum class AdditionalFieldsConfiguration : Parcelable {
/**
* The field is not displayed.
*/
HIDDEN,
/**
* The field is displayed but the customer can leave it blank.
*/
OPTIONAL,
/**
* The field is displayed and the customer is required to fill it in.
*/
REQUIRED
}
}