react-native-glance-chat 0.1.9 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +3 -1
- package/android/src/main/java/com/glancechat/GlanceChatModuleImpl.kt +72 -0
- package/android/src/main/java/com/glancechat/GlanceMixAndMatchWidgetViewManager.kt +85 -5
- package/android/src/newarch/java/com/glancechat/GlanceChatModule.kt +2 -0
- package/android/src/oldarch/java/com/glancechat/GlanceChatModule.kt +3 -0
- package/lib/module/GlanceMixAndMatchWidgetNativeComponent.ts +33 -1
- package/lib/module/NativeGlanceChat.js +8 -0
- package/lib/module/NativeGlanceChat.js.map +1 -1
- package/lib/module/index.js +9 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/GlanceMixAndMatchWidgetNativeComponent.d.ts +29 -1
- package/lib/typescript/src/GlanceMixAndMatchWidgetNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/NativeGlanceChat.d.ts +52 -0
- package/lib/typescript/src/NativeGlanceChat.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +5 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/GlanceMixAndMatchWidgetNativeComponent.ts +33 -1
- package/src/NativeGlanceChat.ts +56 -0
- package/src/index.tsx +16 -1
package/android/build.gradle
CHANGED
|
@@ -9,7 +9,9 @@ buildscript {
|
|
|
9
9
|
// example/android/settings.gradle and the README integration section. During local
|
|
10
10
|
// development, publish with `./gradlew publishToMavenLocal -Psdk.version=1.0.0`
|
|
11
11
|
// (produces 1.0.0-local) and set sdkVersion to "1.0.0-local" to resolve from mavenLocal().
|
|
12
|
-
|
|
12
|
+
// 1.0.16 is the first SDK release with `GlanceChatSDK.setUser`; it must be published
|
|
13
|
+
// before this wrapper version can build or ship.
|
|
14
|
+
sdkVersion: "1.0.18"
|
|
13
15
|
]
|
|
14
16
|
|
|
15
17
|
ext.getExtOrDefault = { prop ->
|
|
@@ -11,6 +11,7 @@ import com.facebook.react.bridge.ReadableMap
|
|
|
11
11
|
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
12
12
|
import com.glance.chat.GlanceChatSDK
|
|
13
13
|
import com.glance.chat.core.config.GlanceChatConfig
|
|
14
|
+
import com.glance.chat.core.config.GlanceTheme
|
|
14
15
|
import kotlinx.coroutines.CoroutineScope
|
|
15
16
|
import kotlinx.coroutines.Dispatchers
|
|
16
17
|
import kotlinx.coroutines.SupervisorJob
|
|
@@ -54,11 +55,37 @@ class GlanceChatModuleImpl(private val reactContext: ReactApplicationContext) {
|
|
|
54
55
|
Arguments.createMap().apply {
|
|
55
56
|
putString("productId", product.id)
|
|
56
57
|
putString("name", product.name)
|
|
58
|
+
// The host may navigate from the click alone: the deeplink is blank for some
|
|
59
|
+
// catalogue entries, and the merchant variant id is what the host's product
|
|
60
|
+
// page needs when there is no URL to parse.
|
|
61
|
+
putString("deeplinkUrl", product.deeplinkUrl)
|
|
62
|
+
putString("merchantVariantId", product.merchantVariantId)
|
|
57
63
|
}
|
|
58
64
|
)
|
|
59
65
|
product.deeplinkUrl.takeIf { it.isNotBlank() }?.let { emit(EVENT_DEEPLINK_CLICK, it) }
|
|
60
66
|
}
|
|
61
67
|
|
|
68
|
+
// The host owns the cart. The shopper's confirmed size selection arrives here and JS
|
|
69
|
+
// adds it through the host's own cart action (Appmaker's ADD_TO_CART_V2).
|
|
70
|
+
GlanceChatSDK.addToCartHandler = { item ->
|
|
71
|
+
emit(
|
|
72
|
+
EVENT_ADD_TO_CART,
|
|
73
|
+
Arguments.createMap().apply {
|
|
74
|
+
putString("productId", item.productId)
|
|
75
|
+
putString("productName", item.productName)
|
|
76
|
+
putString("productImageUrl", item.productImageUrl)
|
|
77
|
+
putString("productPrice", item.productPrice)
|
|
78
|
+
putString("deeplinkUrl", item.deeplinkUrl)
|
|
79
|
+
putString("merchantVariantId", item.merchantVariantId)
|
|
80
|
+
putString("sizeId", item.sizeId)
|
|
81
|
+
putString("sizeLabel", item.sizeLabel)
|
|
82
|
+
putInt("quantity", item.quantity)
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
GlanceChatSDK.viewCartHandler = { emit(EVENT_VIEW_CART, Arguments.createMap()) }
|
|
88
|
+
|
|
62
89
|
// Auth token cannot be fetched/refreshed — host should re-authenticate.
|
|
63
90
|
GlanceChatSDK.onSessionExpired = {
|
|
64
91
|
emit(EVENT_SESSION_EXPIRED, Arguments.createMap())
|
|
@@ -68,11 +95,30 @@ class GlanceChatModuleImpl(private val reactContext: ReactApplicationContext) {
|
|
|
68
95
|
}
|
|
69
96
|
}
|
|
70
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Follows the host's login/logout without tearing the SDK down. Requires a Glance SDK
|
|
100
|
+
* that exposes `setUser`; against an older AAR this is a logged no-op so the host keeps
|
|
101
|
+
* the identity it initialized with instead of crashing.
|
|
102
|
+
*/
|
|
103
|
+
fun setUser(userId: String) {
|
|
104
|
+
runOnMain {
|
|
105
|
+
try {
|
|
106
|
+
GlanceChatSDK.setUser(userId)
|
|
107
|
+
} catch (error: NoSuchMethodError) {
|
|
108
|
+
Log.w(TAG, "Glance SDK ${BuildConfig.SDK_VERSION} has no setUser(); identity unchanged", error)
|
|
109
|
+
} catch (error: NoClassDefFoundError) {
|
|
110
|
+
Log.w(TAG, "Glance SDK ${BuildConfig.SDK_VERSION} has no setUser(); identity unchanged", error)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
71
115
|
fun destroy() {
|
|
72
116
|
runOnMain {
|
|
73
117
|
scope?.cancel()
|
|
74
118
|
scope = null
|
|
75
119
|
GlanceChatSDK.productNavigationHandler = null
|
|
120
|
+
GlanceChatSDK.addToCartHandler = null
|
|
121
|
+
GlanceChatSDK.viewCartHandler = null
|
|
76
122
|
GlanceChatSDK.onSessionExpired = null
|
|
77
123
|
GlanceChatSDK.destroy()
|
|
78
124
|
}
|
|
@@ -113,12 +159,36 @@ class GlanceChatModuleImpl(private val reactContext: ReactApplicationContext) {
|
|
|
113
159
|
.userId(resolvedUserId)
|
|
114
160
|
.environment(parseEnvironment(config.getString("environment")))
|
|
115
161
|
.storeHandle(config.getString("storeHandle") ?: "")
|
|
162
|
+
// The catalogue tenant id differs from the Shopify handle when the merchant sells on a
|
|
163
|
+
// custom domain; mix-and-match and similar-products resolve by this id.
|
|
164
|
+
.catalogId(config.getString("catalogId") ?: "")
|
|
165
|
+
.storefrontBaseUrl(config.getString("storefrontBaseUrl") ?: "")
|
|
166
|
+
// X-Store-Region: the backend filters mix-and-match recommendations by it.
|
|
167
|
+
.countryCode(config.getString("countryCode") ?: "")
|
|
116
168
|
.showTryOnProgressPill(
|
|
117
169
|
if (config.hasKey("showTryOnProgressPill")) config.getBoolean("showTryOnProgressPill") else true
|
|
118
170
|
)
|
|
171
|
+
// Appearance settings for the SDK's own composables. Each is optional: GlanceTheme's
|
|
172
|
+
// defaults reproduce the hardcoded values the SDK shipped with, so an older host config
|
|
173
|
+
// (or a field the merchant never set) renders exactly as before.
|
|
174
|
+
.theme(
|
|
175
|
+
GlanceTheme(
|
|
176
|
+
brandAccentColor = config.optString("brandAccentColor", ""),
|
|
177
|
+
mnmStyleOnMeRadius = config.optString("mnmStyleOnMeRadius", ""),
|
|
178
|
+
mnmAddToCartRadius = config.optString("mnmAddToCartRadius", ""),
|
|
179
|
+
mnmCartIconRadius = config.optString("mnmCartIconRadius", ""),
|
|
180
|
+
onboardingContinueRadius = config.optString("onboardingContinueRadius", ""),
|
|
181
|
+
onboardingGenderRadius = config.optString("onboardingGenderRadius", "")
|
|
182
|
+
)
|
|
183
|
+
)
|
|
119
184
|
.build()
|
|
120
185
|
}
|
|
121
186
|
|
|
187
|
+
// ReadableMap has no generic "string or default" helper across the old/new arch impls, and
|
|
188
|
+
// a missing key must not throw — a blank string lets GlanceTheme apply its own default.
|
|
189
|
+
private fun ReadableMap.optString(key: String, fallback: String): String =
|
|
190
|
+
if (hasKey(key) && !isNull(key)) getString(key) ?: fallback else fallback
|
|
191
|
+
|
|
122
192
|
@Suppress("HardwareIds")
|
|
123
193
|
private fun androidId(): String =
|
|
124
194
|
Settings.Secure.getString(reactContext.contentResolver, Settings.Secure.ANDROID_ID) ?: "anonymous"
|
|
@@ -162,6 +232,8 @@ class GlanceChatModuleImpl(private val reactContext: ReactApplicationContext) {
|
|
|
162
232
|
private const val EVENT_TRY_ON_STATES = "onTryOnStatesChanged"
|
|
163
233
|
private const val EVENT_PRODUCT_CLICK = "onProductClick"
|
|
164
234
|
private const val EVENT_DEEPLINK_CLICK = "onDeeplinkClick"
|
|
235
|
+
private const val EVENT_ADD_TO_CART = "onAddToCart"
|
|
236
|
+
private const val EVENT_VIEW_CART = "onViewCart"
|
|
165
237
|
private const val EVENT_SESSION_EXPIRED = "onSessionExpired"
|
|
166
238
|
}
|
|
167
239
|
}
|
|
@@ -53,6 +53,12 @@ class GlanceMixAndMatchWidgetViewManager :
|
|
|
53
53
|
"bubbled" to "onAddToCartClick",
|
|
54
54
|
"captured" to "onAddToCartClickCapture"
|
|
55
55
|
)
|
|
56
|
+
),
|
|
57
|
+
"onContentStateChange" to mapOf(
|
|
58
|
+
"phasedRegistrationNames" to mapOf(
|
|
59
|
+
"bubbled" to "onContentStateChange",
|
|
60
|
+
"captured" to "onContentStateChangeCapture"
|
|
61
|
+
)
|
|
56
62
|
)
|
|
57
63
|
)
|
|
58
64
|
}
|
|
@@ -61,26 +67,59 @@ class GlanceMixAndMatchWidgetViewManager :
|
|
|
61
67
|
surfaceId: Int,
|
|
62
68
|
viewId: Int,
|
|
63
69
|
private val productId: String,
|
|
64
|
-
private val
|
|
70
|
+
private val productTitle: String,
|
|
71
|
+
private val productImageUrl: String,
|
|
72
|
+
private val productPrice: String?,
|
|
73
|
+
private val productDeeplinkUrl: String?,
|
|
74
|
+
private val merchantVariantId: String?,
|
|
75
|
+
private val sizeId: String,
|
|
76
|
+
private val sizeLabel: String
|
|
65
77
|
) : Event<AddToCartEvent>(surfaceId, viewId) {
|
|
66
78
|
override fun getEventName() = "onAddToCartClick"
|
|
67
79
|
override fun getEventData() = Arguments.createMap().apply {
|
|
68
80
|
putString("productId", productId)
|
|
69
|
-
putString("
|
|
81
|
+
putString("productTitle", productTitle)
|
|
82
|
+
putString("productImageUrl", productImageUrl)
|
|
83
|
+
putString("productPrice", productPrice)
|
|
84
|
+
putString("productDeeplinkUrl", productDeeplinkUrl)
|
|
85
|
+
putString("merchantVariantId", merchantVariantId)
|
|
86
|
+
// `sizeId` is the purchasable merchant variant id; `sizeLabel` is the
|
|
87
|
+
// display label ("M"). `size` is kept for older extension builds only.
|
|
88
|
+
putString("sizeId", sizeId)
|
|
89
|
+
putString("sizeLabel", sizeLabel)
|
|
90
|
+
putString("size", sizeLabel)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private class ContentStateEvent(
|
|
95
|
+
surfaceId: Int,
|
|
96
|
+
viewId: Int,
|
|
97
|
+
private val status: String,
|
|
98
|
+
private val itemCount: Int
|
|
99
|
+
) : Event<ContentStateEvent>(surfaceId, viewId) {
|
|
100
|
+
override fun getEventName() = "onContentStateChange"
|
|
101
|
+
override fun getEventData() = Arguments.createMap().apply {
|
|
102
|
+
putString("status", status)
|
|
103
|
+
putInt("itemCount", itemCount)
|
|
70
104
|
}
|
|
71
105
|
}
|
|
72
106
|
|
|
73
107
|
private class WidgetHostLayout(context: ThemedReactContext) : FrameLayout(context) {
|
|
74
108
|
private var composeView: ComposeView? = null
|
|
75
109
|
|
|
110
|
+
// Fabric commits every prop on each React render, changed or not. Without these guards
|
|
111
|
+
// each commit called renderContent() → setContent{}, which restarted the widget's
|
|
112
|
+
// fetch effect — one recommendations request per parent re-render.
|
|
76
113
|
var variantId: String = ""
|
|
77
114
|
set(value) {
|
|
115
|
+
if (field == value) return
|
|
78
116
|
field = value
|
|
79
117
|
if (isAttachedToWindow) renderContent()
|
|
80
118
|
}
|
|
81
119
|
|
|
82
120
|
var widgetEnabled: Boolean = true
|
|
83
121
|
set(value) {
|
|
122
|
+
if (field == value) return
|
|
84
123
|
field = value
|
|
85
124
|
if (isAttachedToWindow) renderContent()
|
|
86
125
|
}
|
|
@@ -111,7 +150,19 @@ class GlanceMixAndMatchWidgetViewManager :
|
|
|
111
150
|
MixAndMatchWidget(
|
|
112
151
|
merchantVariantId = currentVariantId,
|
|
113
152
|
onAddToCartClick = { product, size ->
|
|
114
|
-
emitAddToCart(
|
|
153
|
+
emitAddToCart(
|
|
154
|
+
productId = product.id,
|
|
155
|
+
productTitle = product.name,
|
|
156
|
+
productImageUrl = product.imageUrl,
|
|
157
|
+
productPrice = product.price,
|
|
158
|
+
productDeeplinkUrl = product.deeplinkUrl,
|
|
159
|
+
merchantVariantId = product.merchantVariantId,
|
|
160
|
+
sizeId = size.id,
|
|
161
|
+
sizeLabel = size.value
|
|
162
|
+
)
|
|
163
|
+
},
|
|
164
|
+
onContentStateChange = { status, itemCount ->
|
|
165
|
+
emitContentState(status?.name ?: "", itemCount)
|
|
115
166
|
}
|
|
116
167
|
)
|
|
117
168
|
}
|
|
@@ -128,11 +179,40 @@ class GlanceMixAndMatchWidgetViewManager :
|
|
|
128
179
|
child.layout(0, 0, width, height)
|
|
129
180
|
}
|
|
130
181
|
|
|
131
|
-
private fun emitAddToCart(
|
|
182
|
+
private fun emitAddToCart(
|
|
183
|
+
productId: String,
|
|
184
|
+
productTitle: String,
|
|
185
|
+
productImageUrl: String,
|
|
186
|
+
productPrice: String?,
|
|
187
|
+
productDeeplinkUrl: String?,
|
|
188
|
+
merchantVariantId: String?,
|
|
189
|
+
sizeId: String,
|
|
190
|
+
sizeLabel: String
|
|
191
|
+
) {
|
|
192
|
+
val reactContext = context as? ThemedReactContext ?: return
|
|
193
|
+
val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
|
|
194
|
+
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
|
|
195
|
+
dispatcher?.dispatchEvent(
|
|
196
|
+
AddToCartEvent(
|
|
197
|
+
surfaceId,
|
|
198
|
+
id,
|
|
199
|
+
productId,
|
|
200
|
+
productTitle,
|
|
201
|
+
productImageUrl,
|
|
202
|
+
productPrice,
|
|
203
|
+
productDeeplinkUrl,
|
|
204
|
+
merchantVariantId,
|
|
205
|
+
sizeId,
|
|
206
|
+
sizeLabel
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private fun emitContentState(status: String, itemCount: Int) {
|
|
132
212
|
val reactContext = context as? ThemedReactContext ?: return
|
|
133
213
|
val surfaceId = UIManagerHelper.getSurfaceId(reactContext)
|
|
134
214
|
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
|
|
135
|
-
dispatcher?.dispatchEvent(
|
|
215
|
+
dispatcher?.dispatchEvent(ContentStateEvent(surfaceId, id, status, itemCount))
|
|
136
216
|
}
|
|
137
217
|
}
|
|
138
218
|
|
|
@@ -18,6 +18,8 @@ class GlanceChatModule(reactContext: ReactApplicationContext) :
|
|
|
18
18
|
override fun initialize(partnerId: String, config: ReadableMap, userId: String?) =
|
|
19
19
|
impl.initialize(partnerId, config, userId)
|
|
20
20
|
|
|
21
|
+
override fun setUser(userId: String) = impl.setUser(userId)
|
|
22
|
+
|
|
21
23
|
override fun destroy() = impl.destroy()
|
|
22
24
|
|
|
23
25
|
override fun isInitialized() = impl.isInitialized()
|
|
@@ -21,6 +21,9 @@ class GlanceChatModule(reactContext: ReactApplicationContext) :
|
|
|
21
21
|
fun initialize(partnerId: String, config: ReadableMap, userId: String?) =
|
|
22
22
|
impl.initialize(partnerId, config, userId)
|
|
23
23
|
|
|
24
|
+
@ReactMethod
|
|
25
|
+
fun setUser(userId: String) = impl.setUser(userId)
|
|
26
|
+
|
|
24
27
|
@ReactMethod
|
|
25
28
|
fun destroy() = impl.destroy()
|
|
26
29
|
|
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
import type { ViewProps, HostComponent } from 'react-native';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
BubblingEventHandler,
|
|
4
|
+
Int32,
|
|
5
|
+
} from 'react-native/Libraries/Types/CodegenTypesNamespace';
|
|
3
6
|
import { codegenNativeComponent } from 'react-native';
|
|
4
7
|
|
|
5
8
|
export type AddToCartEvent = Readonly<{
|
|
6
9
|
productId: string;
|
|
10
|
+
productTitle: string;
|
|
11
|
+
productImageUrl: string;
|
|
12
|
+
productPrice: string | null;
|
|
13
|
+
productDeeplinkUrl: string | null;
|
|
14
|
+
/** Product-level merchant variant id the catalogue was keyed by. */
|
|
15
|
+
merchantVariantId: string | null;
|
|
16
|
+
/** Purchasable size-specific merchant variant id (what goes in the cart). */
|
|
17
|
+
sizeId: string;
|
|
18
|
+
/** Display label, e.g. "M". */
|
|
19
|
+
sizeLabel: string;
|
|
20
|
+
/** Same as sizeLabel — kept for older consumers. */
|
|
7
21
|
size: string;
|
|
8
22
|
}>;
|
|
9
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Payload for {@link NativeProps.onContentStateChange}: how much the widget will render.
|
|
26
|
+
*
|
|
27
|
+
* `status` is the recommendation fetch status ('NONE' | 'LOADING' | 'LOADED' | 'FAILED'), or
|
|
28
|
+
* an empty string when the widget is not rendering at all (feature disabled, module absent).
|
|
29
|
+
* `itemCount` is the number of look groups the tray will actually show — a group needs at
|
|
30
|
+
* least two products to render.
|
|
31
|
+
*/
|
|
32
|
+
export type ContentStateEvent = Readonly<{
|
|
33
|
+
status: string;
|
|
34
|
+
itemCount: Int32;
|
|
35
|
+
}>;
|
|
36
|
+
|
|
10
37
|
export interface NativeProps extends ViewProps {
|
|
11
38
|
/** Merchant variant id of the anchor product the tray recommends for. */
|
|
12
39
|
variantId: string;
|
|
@@ -14,6 +41,11 @@ export interface NativeProps extends ViewProps {
|
|
|
14
41
|
enabled?: boolean;
|
|
15
42
|
/** Fired when a size is confirmed in the add-to-cart sheet. */
|
|
16
43
|
onAddToCartClick?: BubblingEventHandler<AddToCartEvent> | null;
|
|
44
|
+
/**
|
|
45
|
+
* Fired whenever the rendered amount changes, so a host that sizes this widget from its own
|
|
46
|
+
* layout box can collapse to nothing instead of leaving a blank band when the tray is empty.
|
|
47
|
+
*/
|
|
48
|
+
onContentStateChange?: BubblingEventHandler<ContentStateEvent> | null;
|
|
17
49
|
}
|
|
18
50
|
|
|
19
51
|
export default codegenNativeComponent<NativeProps>(
|
|
@@ -10,6 +10,14 @@ import { TurboModuleRegistry } from 'react-native';
|
|
|
10
10
|
|
|
11
11
|
/** Payload for the {@link Spec.onProductClick} event. */
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Payload for {@link Spec.onAddToCart}: one shopper-confirmed size selection from an
|
|
15
|
+
* SDK surface. The SDK owns no cart — the host adds this through its own cart action.
|
|
16
|
+
*
|
|
17
|
+
* `sizeId` is the purchasable merchant variant id; `sizeLabel` is display text only and
|
|
18
|
+
* must never be sent as a variant id.
|
|
19
|
+
*/
|
|
20
|
+
|
|
13
21
|
/**
|
|
14
22
|
* Payload for {@link Spec.onTryOnStatesChanged}: a map of variantId -> status
|
|
15
23
|
* string (e.g. 'IDLE' | 'GENERATING' | 'READY' | 'FAILED'). Codegen does not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeGlanceChat.ts"],"mappings":";;AAEA,SAASA,mBAAmB,QAAQ,cAAc;;AAElD;AACA;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeGlanceChat.ts"],"mappings":";;AAEA,SAASA,mBAAmB,QAAQ,cAAc;;AAElD;AACA;AACA;AACA;AACA;;AA2BA;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;;AAaA;AACA;AACA;AACA;AACA;;AAqFA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,YAAY,CAAC","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -21,6 +21,9 @@ export const Glance = {
|
|
|
21
21
|
initialize(partnerId, config, userId) {
|
|
22
22
|
GlanceChat.initialize(partnerId, config, userId ?? null);
|
|
23
23
|
},
|
|
24
|
+
setUser(userId) {
|
|
25
|
+
GlanceChat.setUser(userId);
|
|
26
|
+
},
|
|
24
27
|
destroy() {
|
|
25
28
|
GlanceChat.destroy();
|
|
26
29
|
},
|
|
@@ -55,6 +58,12 @@ export const Glance = {
|
|
|
55
58
|
onDeeplinkClick(listener) {
|
|
56
59
|
return GlanceChat.onDeeplinkClick(listener);
|
|
57
60
|
},
|
|
61
|
+
onAddToCart(listener) {
|
|
62
|
+
return GlanceChat.onAddToCart(listener);
|
|
63
|
+
},
|
|
64
|
+
onViewCart(listener) {
|
|
65
|
+
return GlanceChat.onViewCart(listener);
|
|
66
|
+
},
|
|
58
67
|
onTryOnStatesChanged(listener) {
|
|
59
68
|
return GlanceChat.onTryOnStatesChanged(listener);
|
|
60
69
|
},
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["GlanceChat","default","GlanceChatOverlay","GlanceProductTryOnWidget","GlanceMixAndMatchWidget","GlancePdpSuggestions","GlanceEnvironment","DEVELOPMENT","UAT","PRODUCTION","Glance","initialize","partnerId","config","userId","destroy","isInitialized","isLoggedIn","setPageContext","context","metadata","clearPageContext","closeChat","openChatWithSuggestion","suggestion","handleDeepLink","uri","startOnboarding","variantId","onProductClick","listener","onDeeplinkClick","onTryOnStatesChanged","onSessionExpired"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,uBAAoB;
|
|
1
|
+
{"version":3,"names":["GlanceChat","default","GlanceChatOverlay","GlanceProductTryOnWidget","GlanceMixAndMatchWidget","GlancePdpSuggestions","GlanceEnvironment","DEVELOPMENT","UAT","PRODUCTION","Glance","initialize","partnerId","config","userId","setUser","destroy","isInitialized","isLoggedIn","setPageContext","context","metadata","clearPageContext","closeChat","openChatWithSuggestion","suggestion","handleDeepLink","uri","startOnboarding","variantId","onProductClick","listener","onDeeplinkClick","onAddToCart","onViewCart","onTryOnStatesChanged","onSessionExpired"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,UAAU,MAAM,uBAAoB;AAe3C;AACA,SAASC,OAAO,IAAIC,iBAAiB,QAAQ,oCAAoC;AACjF,SAASD,OAAO,IAAIE,wBAAwB,QAAQ,2CAA2C;AAC/F,SAASF,OAAO,IAAIG,uBAAuB,QAAQ,0CAA0C;AAC7F,SAASH,OAAO,IAAII,oBAAoB,QAAQ,uCAAuC;;AAEvF;AACA,OAAO,MAAMC,iBAAiB,GAAG;EAC/BC,WAAW,EAAE,aAAa;EAC1BC,GAAG,EAAE,KAAK;EACVC,UAAU,EAAE;AACd,CAAU;AAIV;AACA;AACA;AACA;AACA,OAAO,MAAMC,MAAM,GAAG;EACpBC,UAAUA,CACRC,SAAiB,EACjBC,MAAwB,EACxBC,MAAsB,EAChB;IACNd,UAAU,CAACW,UAAU,CAACC,SAAS,EAAEC,MAAM,EAAEC,MAAM,IAAI,IAAI,CAAC;EAC1D,CAAC;EACDC,OAAOA,CAACD,MAAc,EAAQ;IAC5Bd,UAAU,CAACe,OAAO,CAACD,MAAM,CAAC;EAC5B,CAAC;EACDE,OAAOA,CAAA,EAAS;IACdhB,UAAU,CAACgB,OAAO,CAAC,CAAC;EACtB,CAAC;EACDC,aAAaA,CAAA,EAAY;IACvB,OAAOjB,UAAU,CAACiB,aAAa,CAAC,CAAC;EACnC,CAAC;EACDC,UAAUA,CAAA,EAAY;IACpB,OAAOlB,UAAU,CAACkB,UAAU,CAAC,CAAC;EAChC,CAAC;EACDC,cAAcA,CAACC,OAAe,EAAEC,QAAgC,GAAG,CAAC,CAAC,EAAQ;IAC3ErB,UAAU,CAACmB,cAAc,CAACC,OAAO,EAAEC,QAAQ,CAAC;EAC9C,CAAC;EACDC,gBAAgBA,CAAA,EAAS;IACvBtB,UAAU,CAACsB,gBAAgB,CAAC,CAAC;EAC/B,CAAC;EACDC,SAASA,CAAA,EAAS;IAChBvB,UAAU,CAACuB,SAAS,CAAC,CAAC;EACxB,CAAC;EACDC,sBAAsBA,CAACC,UAAkB,EAAQ;IAC/CzB,UAAU,CAACwB,sBAAsB,CAACC,UAAU,CAAC;EAC/C,CAAC;EACDC,cAAcA,CAACC,GAAW,EAAW;IACnC,OAAO3B,UAAU,CAAC0B,cAAc,CAACC,GAAG,CAAC;EACvC,CAAC;EACDC,eAAeA,CAACC,SAAkB,EAAQ;IACxC7B,UAAU,CAAC4B,eAAe,CAACC,SAAS,CAAC;EACvC,CAAC;EAED;EACAC,cAAcA,CAACC,QAA4C,EAAE;IAC3D,OAAO/B,UAAU,CAAC8B,cAAc,CAACC,QAAQ,CAAC;EAC5C,CAAC;EACDC,eAAeA,CAACD,QAA+B,EAAE;IAC/C,OAAO/B,UAAU,CAACgC,eAAe,CAACD,QAAQ,CAAC;EAC7C,CAAC;EACDE,WAAWA,CAACF,QAAyC,EAAE;IACrD,OAAO/B,UAAU,CAACiC,WAAW,CAACF,QAAQ,CAAC;EACzC,CAAC;EACDG,UAAUA,CAACH,QAAoB,EAAE;IAC/B,OAAO/B,UAAU,CAACkC,UAAU,CAACH,QAAQ,CAAC;EACxC,CAAC;EACDI,oBAAoBA,CAACJ,QAA2C,EAAE;IAChE,OAAO/B,UAAU,CAACmC,oBAAoB,CAACJ,QAAQ,CAAC;EAClD,CAAC;EACDK,gBAAgBA,CAACL,QAAoB,EAAE;IACrC,OAAO/B,UAAU,CAACoC,gBAAgB,CAACL,QAAQ,CAAC;EAC9C;AACF,CAAC","ignoreList":[]}
|
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
import type { ViewProps, HostComponent } from 'react-native';
|
|
2
|
-
import type { BubblingEventHandler } from 'react-native/Libraries/Types/CodegenTypesNamespace';
|
|
2
|
+
import type { BubblingEventHandler, Int32 } from 'react-native/Libraries/Types/CodegenTypesNamespace';
|
|
3
3
|
export type AddToCartEvent = Readonly<{
|
|
4
4
|
productId: string;
|
|
5
|
+
productTitle: string;
|
|
6
|
+
productImageUrl: string;
|
|
7
|
+
productPrice: string | null;
|
|
8
|
+
productDeeplinkUrl: string | null;
|
|
9
|
+
/** Product-level merchant variant id the catalogue was keyed by. */
|
|
10
|
+
merchantVariantId: string | null;
|
|
11
|
+
/** Purchasable size-specific merchant variant id (what goes in the cart). */
|
|
12
|
+
sizeId: string;
|
|
13
|
+
/** Display label, e.g. "M". */
|
|
14
|
+
sizeLabel: string;
|
|
15
|
+
/** Same as sizeLabel — kept for older consumers. */
|
|
5
16
|
size: string;
|
|
6
17
|
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Payload for {@link NativeProps.onContentStateChange}: how much the widget will render.
|
|
20
|
+
*
|
|
21
|
+
* `status` is the recommendation fetch status ('NONE' | 'LOADING' | 'LOADED' | 'FAILED'), or
|
|
22
|
+
* an empty string when the widget is not rendering at all (feature disabled, module absent).
|
|
23
|
+
* `itemCount` is the number of look groups the tray will actually show — a group needs at
|
|
24
|
+
* least two products to render.
|
|
25
|
+
*/
|
|
26
|
+
export type ContentStateEvent = Readonly<{
|
|
27
|
+
status: string;
|
|
28
|
+
itemCount: Int32;
|
|
29
|
+
}>;
|
|
7
30
|
export interface NativeProps extends ViewProps {
|
|
8
31
|
/** Merchant variant id of the anchor product the tray recommends for. */
|
|
9
32
|
variantId: string;
|
|
@@ -11,6 +34,11 @@ export interface NativeProps extends ViewProps {
|
|
|
11
34
|
enabled?: boolean;
|
|
12
35
|
/** Fired when a size is confirmed in the add-to-cart sheet. */
|
|
13
36
|
onAddToCartClick?: BubblingEventHandler<AddToCartEvent> | null;
|
|
37
|
+
/**
|
|
38
|
+
* Fired whenever the rendered amount changes, so a host that sizes this widget from its own
|
|
39
|
+
* layout box can collapse to nothing instead of leaving a blank band when the tray is empty.
|
|
40
|
+
*/
|
|
41
|
+
onContentStateChange?: BubblingEventHandler<ContentStateEvent> | null;
|
|
14
42
|
}
|
|
15
43
|
declare const _default: HostComponent<NativeProps>;
|
|
16
44
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GlanceMixAndMatchWidgetNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/GlanceMixAndMatchWidgetNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"GlanceMixAndMatchWidgetNativeComponent.d.ts","sourceRoot":"","sources":["../../../src/GlanceMixAndMatchWidgetNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,EACV,oBAAoB,EACpB,KAAK,EACN,MAAM,oDAAoD,CAAC;AAG5D,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,KAAK,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IAC/D;;;OAGG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC;CACvE;wBAII,aAAa,CAAC,WAAW,CAAC;AAF/B,wBAEgC"}
|
|
@@ -8,16 +8,54 @@ import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypesName
|
|
|
8
8
|
export type GlanceChatConfig = {
|
|
9
9
|
environment: string;
|
|
10
10
|
storeHandle: string;
|
|
11
|
+
/** Catalogue tenant id Glance indexes products under; falls back to storeHandle. */
|
|
12
|
+
catalogId?: string;
|
|
13
|
+
/** Public storefront origin, e.g. "https://thebearhouse.com", for absolute product URLs. */
|
|
14
|
+
storefrontBaseUrl?: string;
|
|
15
|
+
/** ISO 3166-1 alpha-2 store region (e.g. "IN", "US"), sent as X-Store-Region. */
|
|
16
|
+
countryCode?: string;
|
|
11
17
|
brandName?: string;
|
|
12
18
|
brandLogoUrl?: string;
|
|
13
19
|
productDeeplinkBaseUrl?: string;
|
|
14
20
|
/** Host-configurable floating "Generating…" pill during try-on; default true. */
|
|
15
21
|
showTryOnProgressPill?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Appearance for the SDK's own composables. Each value falls back to the SDK's
|
|
24
|
+
* original hardcoded look when omitted or unrecognised.
|
|
25
|
+
*/
|
|
26
|
+
brandAccentColor?: string;
|
|
27
|
+
mnmStyleOnMeRadius?: string;
|
|
28
|
+
mnmAddToCartRadius?: string;
|
|
29
|
+
mnmCartIconRadius?: string;
|
|
30
|
+
onboardingContinueRadius?: string;
|
|
31
|
+
onboardingGenderRadius?: string;
|
|
16
32
|
};
|
|
17
33
|
/** Payload for the {@link Spec.onProductClick} event. */
|
|
18
34
|
export type ProductClickEvent = {
|
|
19
35
|
productId: string;
|
|
20
36
|
name: string;
|
|
37
|
+
/** Empty when the catalogue entry has no merchant URL. */
|
|
38
|
+
deeplinkUrl: string;
|
|
39
|
+
/** The purchasable merchant variant id, when the SDK has one. */
|
|
40
|
+
merchantVariantId: string | null;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Payload for {@link Spec.onAddToCart}: one shopper-confirmed size selection from an
|
|
44
|
+
* SDK surface. The SDK owns no cart — the host adds this through its own cart action.
|
|
45
|
+
*
|
|
46
|
+
* `sizeId` is the purchasable merchant variant id; `sizeLabel` is display text only and
|
|
47
|
+
* must never be sent as a variant id.
|
|
48
|
+
*/
|
|
49
|
+
export type AddToCartEvent = {
|
|
50
|
+
productId: string;
|
|
51
|
+
productName: string;
|
|
52
|
+
productImageUrl: string;
|
|
53
|
+
productPrice: string | null;
|
|
54
|
+
deeplinkUrl: string | null;
|
|
55
|
+
merchantVariantId: string | null;
|
|
56
|
+
sizeId: string;
|
|
57
|
+
sizeLabel: string;
|
|
58
|
+
quantity: number;
|
|
21
59
|
};
|
|
22
60
|
/**
|
|
23
61
|
* Payload for {@link Spec.onTryOnStatesChanged}: a map of variantId -> status
|
|
@@ -41,6 +79,13 @@ export interface Spec extends TurboModule {
|
|
|
41
79
|
* When omitted, the SDK falls back to the device id.
|
|
42
80
|
*/
|
|
43
81
|
initialize(partnerId: string, config: GlanceChatConfig, userId?: string | null): void;
|
|
82
|
+
/**
|
|
83
|
+
* Switch the shopper the SDK acts as, without re-initializing it — call on host
|
|
84
|
+
* login/logout. The bearer token is re-minted for the new id and identity-scoped
|
|
85
|
+
* state (avatar, profile, trial quota, conversation) is cleared. Re-sending the
|
|
86
|
+
* current id is a no-op.
|
|
87
|
+
*/
|
|
88
|
+
setUser(userId: string): void;
|
|
44
89
|
/** Tear down the SDK and release resources. */
|
|
45
90
|
destroy(): void;
|
|
46
91
|
/** Whether {@link initialize} has completed. */
|
|
@@ -71,6 +116,13 @@ export interface Spec extends TurboModule {
|
|
|
71
116
|
readonly onProductClick: EventEmitter<ProductClickEvent>;
|
|
72
117
|
/** Emitted when the SDK requests the host to open a deeplink URL. */
|
|
73
118
|
readonly onDeeplinkClick: EventEmitter<string>;
|
|
119
|
+
/**
|
|
120
|
+
* Emitted when the shopper confirms a size in an SDK add-to-cart sheet. The host
|
|
121
|
+
* adds the item to its own cart; the SDK's surfaces assume no cart.
|
|
122
|
+
*/
|
|
123
|
+
readonly onAddToCart: EventEmitter<AddToCartEvent>;
|
|
124
|
+
/** Emitted when the shopper taps "View Cart" inside an SDK surface. */
|
|
125
|
+
readonly onViewCart: EventEmitter<void>;
|
|
74
126
|
/** Emitted whenever the try-on state map changes. */
|
|
75
127
|
readonly onTryOnStatesChanged: EventEmitter<TryOnStatesEvent>;
|
|
76
128
|
/** Emitted when the auth session expires and the host should re-authenticate. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeGlanceChat.d.ts","sourceRoot":"","sources":["../../../src/NativeGlanceChat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oDAAoD,CAAC;AAGvF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iFAAiF;IACjF,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,yDAAyD;AACzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"NativeGlanceChat.d.ts","sourceRoot":"","sources":["../../../src/NativeGlanceChat.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { GlanceChatConfig, ProductClickEvent, TryOnStatesEvent } from './NativeGlanceChat';
|
|
2
|
-
export type { GlanceChatConfig, ProductClickEvent, TryOnStatesEvent };
|
|
1
|
+
import type { AddToCartEvent, GlanceChatConfig, ProductClickEvent, TryOnStatesEvent } from './NativeGlanceChat';
|
|
2
|
+
export type { AddToCartEvent, GlanceChatConfig, ProductClickEvent, TryOnStatesEvent, };
|
|
3
3
|
export { default as GlanceChatOverlay } from './GlanceChatOverlayNativeComponent';
|
|
4
4
|
export { default as GlanceProductTryOnWidget } from './GlanceProductTryOnWidgetNativeComponent';
|
|
5
5
|
export { default as GlanceMixAndMatchWidget } from './GlanceMixAndMatchWidgetNativeComponent';
|
|
@@ -17,6 +17,7 @@ export type GlanceEnvironment = (typeof GlanceEnvironment)[keyof typeof GlanceEn
|
|
|
17
17
|
*/
|
|
18
18
|
export declare const Glance: {
|
|
19
19
|
initialize(partnerId: string, config: GlanceChatConfig, userId?: string | null): void;
|
|
20
|
+
setUser(userId: string): void;
|
|
20
21
|
destroy(): void;
|
|
21
22
|
isInitialized(): boolean;
|
|
22
23
|
isLoggedIn(): boolean;
|
|
@@ -28,6 +29,8 @@ export declare const Glance: {
|
|
|
28
29
|
startOnboarding(variantId?: string): void;
|
|
29
30
|
onProductClick(listener: (event: ProductClickEvent) => void): import("react-native").EventSubscription;
|
|
30
31
|
onDeeplinkClick(listener: (uri: string) => void): import("react-native").EventSubscription;
|
|
32
|
+
onAddToCart(listener: (event: AddToCartEvent) => void): import("react-native").EventSubscription;
|
|
33
|
+
onViewCart(listener: () => void): import("react-native").EventSubscription;
|
|
31
34
|
onTryOnStatesChanged(listener: (event: TryOnStatesEvent) => void): import("react-native").EventSubscription;
|
|
32
35
|
onSessionExpired(listener: () => void): import("react-native").EventSubscription;
|
|
33
36
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,CAAC;AAGF,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAChG,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAExF,qCAAqC;AACrC,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAC3B,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,MAAM;0BAEJ,MAAM,UACT,gBAAgB,WACf,MAAM,GAAG,IAAI,GACrB,IAAI;oBAGS,MAAM,GAAG,IAAI;eAGlB,IAAI;qBAGE,OAAO;kBAGV,OAAO;4BAGG,MAAM,aAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAQ,IAAI;wBAGxD,IAAI;iBAGX,IAAI;uCAGkB,MAAM,GAAG,IAAI;wBAG5B,MAAM,GAAG,OAAO;gCAGR,MAAM,GAAG,IAAI;6BAKhB,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI;8BAGjC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;0BAGzB,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI;yBAGhC,MAAM,IAAI;mCAGA,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI;+BAGrC,MAAM,IAAI;CAGtC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-glance-chat",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "React Native wrapper for the Glance Chat SDK (Android + iOS)",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -125,4 +125,4 @@
|
|
|
125
125
|
],
|
|
126
126
|
"version": "0.63.0"
|
|
127
127
|
}
|
|
128
|
-
}
|
|
128
|
+
}
|
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
import type { ViewProps, HostComponent } from 'react-native';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
BubblingEventHandler,
|
|
4
|
+
Int32,
|
|
5
|
+
} from 'react-native/Libraries/Types/CodegenTypesNamespace';
|
|
3
6
|
import { codegenNativeComponent } from 'react-native';
|
|
4
7
|
|
|
5
8
|
export type AddToCartEvent = Readonly<{
|
|
6
9
|
productId: string;
|
|
10
|
+
productTitle: string;
|
|
11
|
+
productImageUrl: string;
|
|
12
|
+
productPrice: string | null;
|
|
13
|
+
productDeeplinkUrl: string | null;
|
|
14
|
+
/** Product-level merchant variant id the catalogue was keyed by. */
|
|
15
|
+
merchantVariantId: string | null;
|
|
16
|
+
/** Purchasable size-specific merchant variant id (what goes in the cart). */
|
|
17
|
+
sizeId: string;
|
|
18
|
+
/** Display label, e.g. "M". */
|
|
19
|
+
sizeLabel: string;
|
|
20
|
+
/** Same as sizeLabel — kept for older consumers. */
|
|
7
21
|
size: string;
|
|
8
22
|
}>;
|
|
9
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Payload for {@link NativeProps.onContentStateChange}: how much the widget will render.
|
|
26
|
+
*
|
|
27
|
+
* `status` is the recommendation fetch status ('NONE' | 'LOADING' | 'LOADED' | 'FAILED'), or
|
|
28
|
+
* an empty string when the widget is not rendering at all (feature disabled, module absent).
|
|
29
|
+
* `itemCount` is the number of look groups the tray will actually show — a group needs at
|
|
30
|
+
* least two products to render.
|
|
31
|
+
*/
|
|
32
|
+
export type ContentStateEvent = Readonly<{
|
|
33
|
+
status: string;
|
|
34
|
+
itemCount: Int32;
|
|
35
|
+
}>;
|
|
36
|
+
|
|
10
37
|
export interface NativeProps extends ViewProps {
|
|
11
38
|
/** Merchant variant id of the anchor product the tray recommends for. */
|
|
12
39
|
variantId: string;
|
|
@@ -14,6 +41,11 @@ export interface NativeProps extends ViewProps {
|
|
|
14
41
|
enabled?: boolean;
|
|
15
42
|
/** Fired when a size is confirmed in the add-to-cart sheet. */
|
|
16
43
|
onAddToCartClick?: BubblingEventHandler<AddToCartEvent> | null;
|
|
44
|
+
/**
|
|
45
|
+
* Fired whenever the rendered amount changes, so a host that sizes this widget from its own
|
|
46
|
+
* layout box can collapse to nothing instead of leaving a blank band when the tray is empty.
|
|
47
|
+
*/
|
|
48
|
+
onContentStateChange?: BubblingEventHandler<ContentStateEvent> | null;
|
|
17
49
|
}
|
|
18
50
|
|
|
19
51
|
export default codegenNativeComponent<NativeProps>(
|
package/src/NativeGlanceChat.ts
CHANGED
|
@@ -10,17 +10,56 @@ import { TurboModuleRegistry } from 'react-native';
|
|
|
10
10
|
export type GlanceChatConfig = {
|
|
11
11
|
environment: string; // 'DEVELOPMENT' | 'UAT' | 'PRODUCTION'
|
|
12
12
|
storeHandle: string;
|
|
13
|
+
/** Catalogue tenant id Glance indexes products under; falls back to storeHandle. */
|
|
14
|
+
catalogId?: string;
|
|
15
|
+
/** Public storefront origin, e.g. "https://thebearhouse.com", for absolute product URLs. */
|
|
16
|
+
storefrontBaseUrl?: string;
|
|
17
|
+
/** ISO 3166-1 alpha-2 store region (e.g. "IN", "US"), sent as X-Store-Region. */
|
|
18
|
+
countryCode?: string;
|
|
13
19
|
brandName?: string;
|
|
14
20
|
brandLogoUrl?: string;
|
|
15
21
|
productDeeplinkBaseUrl?: string;
|
|
16
22
|
/** Host-configurable floating "Generating…" pill during try-on; default true. */
|
|
17
23
|
showTryOnProgressPill?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Appearance for the SDK's own composables. Each value falls back to the SDK's
|
|
26
|
+
* original hardcoded look when omitted or unrecognised.
|
|
27
|
+
*/
|
|
28
|
+
brandAccentColor?: string; // '#RRGGBB'
|
|
29
|
+
mnmStyleOnMeRadius?: string; // '0' | '4' | '8' | '12' | 'pill'
|
|
30
|
+
mnmAddToCartRadius?: string;
|
|
31
|
+
mnmCartIconRadius?: string;
|
|
32
|
+
onboardingContinueRadius?: string;
|
|
33
|
+
onboardingGenderRadius?: string;
|
|
18
34
|
};
|
|
19
35
|
|
|
20
36
|
/** Payload for the {@link Spec.onProductClick} event. */
|
|
21
37
|
export type ProductClickEvent = {
|
|
22
38
|
productId: string;
|
|
23
39
|
name: string;
|
|
40
|
+
/** Empty when the catalogue entry has no merchant URL. */
|
|
41
|
+
deeplinkUrl: string;
|
|
42
|
+
/** The purchasable merchant variant id, when the SDK has one. */
|
|
43
|
+
merchantVariantId: string | null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Payload for {@link Spec.onAddToCart}: one shopper-confirmed size selection from an
|
|
48
|
+
* SDK surface. The SDK owns no cart — the host adds this through its own cart action.
|
|
49
|
+
*
|
|
50
|
+
* `sizeId` is the purchasable merchant variant id; `sizeLabel` is display text only and
|
|
51
|
+
* must never be sent as a variant id.
|
|
52
|
+
*/
|
|
53
|
+
export type AddToCartEvent = {
|
|
54
|
+
productId: string;
|
|
55
|
+
productName: string;
|
|
56
|
+
productImageUrl: string;
|
|
57
|
+
productPrice: string | null;
|
|
58
|
+
deeplinkUrl: string | null;
|
|
59
|
+
merchantVariantId: string | null;
|
|
60
|
+
sizeId: string;
|
|
61
|
+
sizeLabel: string;
|
|
62
|
+
quantity: number;
|
|
24
63
|
};
|
|
25
64
|
|
|
26
65
|
/**
|
|
@@ -49,6 +88,14 @@ export interface Spec extends TurboModule {
|
|
|
49
88
|
userId?: string | null
|
|
50
89
|
): void;
|
|
51
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Switch the shopper the SDK acts as, without re-initializing it — call on host
|
|
93
|
+
* login/logout. The bearer token is re-minted for the new id and identity-scoped
|
|
94
|
+
* state (avatar, profile, trial quota, conversation) is cleared. Re-sending the
|
|
95
|
+
* current id is a no-op.
|
|
96
|
+
*/
|
|
97
|
+
setUser(userId: string): void;
|
|
98
|
+
|
|
52
99
|
/** Tear down the SDK and release resources. */
|
|
53
100
|
destroy(): void;
|
|
54
101
|
|
|
@@ -88,6 +135,15 @@ export interface Spec extends TurboModule {
|
|
|
88
135
|
/** Emitted when the SDK requests the host to open a deeplink URL. */
|
|
89
136
|
readonly onDeeplinkClick: EventEmitter<string>;
|
|
90
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Emitted when the shopper confirms a size in an SDK add-to-cart sheet. The host
|
|
140
|
+
* adds the item to its own cart; the SDK's surfaces assume no cart.
|
|
141
|
+
*/
|
|
142
|
+
readonly onAddToCart: EventEmitter<AddToCartEvent>;
|
|
143
|
+
|
|
144
|
+
/** Emitted when the shopper taps "View Cart" inside an SDK surface. */
|
|
145
|
+
readonly onViewCart: EventEmitter<void>;
|
|
146
|
+
|
|
91
147
|
/** Emitted whenever the try-on state map changes. */
|
|
92
148
|
readonly onTryOnStatesChanged: EventEmitter<TryOnStatesEvent>;
|
|
93
149
|
|
package/src/index.tsx
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import GlanceChat from './NativeGlanceChat';
|
|
2
2
|
import type {
|
|
3
|
+
AddToCartEvent,
|
|
3
4
|
GlanceChatConfig,
|
|
4
5
|
ProductClickEvent,
|
|
5
6
|
TryOnStatesEvent,
|
|
6
7
|
} from './NativeGlanceChat';
|
|
7
8
|
|
|
8
|
-
export type {
|
|
9
|
+
export type {
|
|
10
|
+
AddToCartEvent,
|
|
11
|
+
GlanceChatConfig,
|
|
12
|
+
ProductClickEvent,
|
|
13
|
+
TryOnStatesEvent,
|
|
14
|
+
};
|
|
9
15
|
|
|
10
16
|
// Native UI components (Fabric). Each hosts the corresponding SDK Composable.
|
|
11
17
|
export { default as GlanceChatOverlay } from './GlanceChatOverlayNativeComponent';
|
|
@@ -34,6 +40,9 @@ export const Glance = {
|
|
|
34
40
|
): void {
|
|
35
41
|
GlanceChat.initialize(partnerId, config, userId ?? null);
|
|
36
42
|
},
|
|
43
|
+
setUser(userId: string): void {
|
|
44
|
+
GlanceChat.setUser(userId);
|
|
45
|
+
},
|
|
37
46
|
destroy(): void {
|
|
38
47
|
GlanceChat.destroy();
|
|
39
48
|
},
|
|
@@ -69,6 +78,12 @@ export const Glance = {
|
|
|
69
78
|
onDeeplinkClick(listener: (uri: string) => void) {
|
|
70
79
|
return GlanceChat.onDeeplinkClick(listener);
|
|
71
80
|
},
|
|
81
|
+
onAddToCart(listener: (event: AddToCartEvent) => void) {
|
|
82
|
+
return GlanceChat.onAddToCart(listener);
|
|
83
|
+
},
|
|
84
|
+
onViewCart(listener: () => void) {
|
|
85
|
+
return GlanceChat.onViewCart(listener);
|
|
86
|
+
},
|
|
72
87
|
onTryOnStatesChanged(listener: (event: TryOnStatesEvent) => void) {
|
|
73
88
|
return GlanceChat.onTryOnStatesChanged(listener);
|
|
74
89
|
},
|