react-native-timacare 3.3.44 → 3.3.46
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/lib/commonjs/navigation/navigationRef.js +1 -1
- package/lib/commonjs/navigation/navigationRef.js.flow +73 -15
- package/lib/commonjs/navigation/navigationRef.js.map +1 -1
- package/lib/commonjs/navigation/primary-navigator.js +1 -1
- package/lib/commonjs/navigation/primary-navigator.js.flow +53 -6
- package/lib/commonjs/navigation/primary-navigator.js.map +1 -1
- package/lib/commonjs/screens/home/index.js +1 -1
- package/lib/commonjs/screens/home/index.js.flow +1 -0
- package/lib/commonjs/screens/home/index.js.map +1 -1
- package/lib/module/navigation/navigationRef.js +1 -1
- package/lib/module/navigation/navigationRef.js.map +1 -1
- package/lib/module/navigation/primary-navigator.js +1 -1
- package/lib/module/navigation/primary-navigator.js.map +1 -1
- package/lib/module/screens/home/index.js +1 -1
- package/lib/module/screens/home/index.js.map +1 -1
- package/lib/typescript/navigation/navigationRef.d.ts +49 -4
- package/lib/typescript/navigation/navigationRef.d.ts.map +1 -1
- package/lib/typescript/navigation/primary-navigator.d.ts +9 -2
- package/lib/typescript/navigation/primary-navigator.d.ts.map +1 -1
- package/lib/typescript/screens/home/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/navigation/navigationRef.ts +73 -15
- package/src/navigation/primary-navigator.tsx +53 -6
- package/src/screens/home/index.tsx +1 -0
|
@@ -2,30 +2,79 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Navigation bridge for the Timacare SDK.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* right after the container mounts). The SDK then uses it to drive navigation
|
|
8
|
-
* imperatively from outside React — e.g. deep-linking into a loan detail via
|
|
9
|
-
* `goDetail()`.
|
|
5
|
+
* SDK screens (DetailLoan, DetailLoanTima, ...) live ONLY inside the SDK's
|
|
6
|
+
* PrimaryNavigator. There are two situations the SDK has to drive navigation in:
|
|
10
7
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
8
|
+
* 1. The SDK navigator is currently mounted (the user is somewhere inside the
|
|
9
|
+
* SDK). We then navigate using the navigator's OWN navigation object — see
|
|
10
|
+
* `sdkNavigation`, captured from inside PrimaryNavigator. React Navigation's
|
|
11
|
+
* `navigate()` only bubbles UP to parents, never DOWN into descendants, so
|
|
12
|
+
* the host's root container ref cannot reach a nested SDK screen — but the
|
|
13
|
+
* SDK navigator's own object can.
|
|
14
|
+
*
|
|
15
|
+
* 2. The SDK navigator is NOT mounted (e.g. the host shows its own home with a
|
|
16
|
+
* loan list and only mounts <RNTimacare/> under a dedicated route). Here we
|
|
17
|
+
* need the host's NavigationContainer ref AND the name of the host route that
|
|
18
|
+
* mounts the SDK, so we can mount it and deep-link in one nested navigate.
|
|
19
|
+
*
|
|
20
|
+
* The host registers both via `setNavigationRef(ref, hostRoute)`.
|
|
16
21
|
*/
|
|
22
|
+
|
|
23
|
+
// Host's NavigationContainer ref (or a plain useRef passed to the container).
|
|
17
24
|
let externalNavigationRef = null;
|
|
18
25
|
|
|
19
|
-
|
|
26
|
+
// Name of the host route whose screen renders <RNTimacare/> (PrimaryNavigator).
|
|
27
|
+
// Required to deep-link into the SDK when the SDK navigator isn't mounted yet.
|
|
28
|
+
let hostRoute = null;
|
|
29
|
+
|
|
30
|
+
// Navigation object scoped to the SDK navigator, captured from inside its tree.
|
|
31
|
+
let sdkNavigation = null;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Register the host's NavigationContainer ref, and optionally the host route
|
|
35
|
+
* name under which <RNTimacare/> is mounted.
|
|
36
|
+
*
|
|
37
|
+
* Accepts either ref form:
|
|
38
|
+
* - the object from `createNavigationContainerRef()` / `useNavigationContainerRef()`
|
|
39
|
+
* (methods live directly on it), or
|
|
40
|
+
* - a plain `useRef()` passed to <NavigationContainer ref={ref}> (methods on `.current`).
|
|
41
|
+
*/
|
|
42
|
+
export const setNavigationRef = (ref, route = null) => {
|
|
20
43
|
externalNavigationRef = ref;
|
|
44
|
+
if (route != null) {
|
|
45
|
+
hostRoute = route;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** Set/override the host route that mounts the SDK navigator. */
|
|
50
|
+
export const setHostRoute = (route) => {
|
|
51
|
+
hostRoute = route;
|
|
21
52
|
};
|
|
22
53
|
|
|
54
|
+
export const getHostRoute = () => hostRoute;
|
|
55
|
+
|
|
23
56
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* registered yet or the container isn't ready.
|
|
57
|
+
* Registered from inside PrimaryNavigator while it is mounted (and cleared on
|
|
58
|
+
* unmount, so we never hand out a stale/detached handle).
|
|
27
59
|
*/
|
|
28
|
-
export const
|
|
60
|
+
export const setSdkNavigation = (nav) => {
|
|
61
|
+
sdkNavigation = nav;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** The SDK navigator's own navigation object, if currently mounted. */
|
|
65
|
+
export const getSdkNavigation = () => {
|
|
66
|
+
if (sdkNavigation && typeof sdkNavigation.navigate === 'function') {
|
|
67
|
+
return sdkNavigation;
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Resolves the host ref down to the actual NavigationContainerRef, regardless of
|
|
74
|
+
* which ref form the host provided. Returns null when nothing is registered yet
|
|
75
|
+
* or the container isn't ready.
|
|
76
|
+
*/
|
|
77
|
+
export const getHostNavigation = () => {
|
|
29
78
|
const ref = externalNavigationRef;
|
|
30
79
|
if (!ref) {
|
|
31
80
|
return null;
|
|
@@ -38,3 +87,12 @@ export const getNavigation = () => {
|
|
|
38
87
|
|
|
39
88
|
return nav;
|
|
40
89
|
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Backwards-compatible resolver: prefers the SDK navigator's own object, falling
|
|
93
|
+
* back to the host ref (which only reaches SDK screens when the host mounts
|
|
94
|
+
* PrimaryNavigator as its root). Prefer `goDetail()` for deep-linking.
|
|
95
|
+
*/
|
|
96
|
+
export const getNavigation = () => {
|
|
97
|
+
return getSdkNavigation() || getHostNavigation();
|
|
98
|
+
};
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
import React, { useEffect } from 'react';
|
|
9
9
|
|
|
10
10
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
getSdkNavigation,
|
|
13
|
+
getHostNavigation,
|
|
14
|
+
getHostRoute,
|
|
15
|
+
setSdkNavigation,
|
|
16
|
+
} from './navigationRef';
|
|
12
17
|
import { OTP } from '../screens/otp';
|
|
13
18
|
import { NationalID } from '../screens/nationalID';
|
|
14
19
|
import { Selfie } from '../screens/selfie';
|
|
@@ -157,12 +162,27 @@ export const ScreenNames = {
|
|
|
157
162
|
const Stack = createNativeStackNavigator();
|
|
158
163
|
|
|
159
164
|
export function PrimaryNavigator(props) {
|
|
165
|
+
// When this navigator unmounts, drop the captured navigation so getNavigation()
|
|
166
|
+
// doesn't hand goDetail() a stale (detached) handle — it should cleanly fall
|
|
167
|
+
// back to the host ref / return null instead.
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
return () => setSdkNavigation(null);
|
|
170
|
+
}, []);
|
|
171
|
+
|
|
160
172
|
return (
|
|
161
173
|
<Stack.Navigator
|
|
162
174
|
initialRouteName={ScreenNames.Main}
|
|
163
175
|
screenOptions={{
|
|
164
176
|
headerShown: false,
|
|
165
177
|
}}
|
|
178
|
+
// Capture this navigator's own navigation object so goDetail() (and any
|
|
179
|
+
// other imperative SDK navigation) can reach SDK screens even when the host
|
|
180
|
+
// mounts this navigator nested inside its tree. The screen `navigation`
|
|
181
|
+
// prop is scoped to THIS stack, so navigate() resolves SDK screens directly.
|
|
182
|
+
screenListeners={({ navigation }) => {
|
|
183
|
+
setSdkNavigation(navigation);
|
|
184
|
+
return {};
|
|
185
|
+
}}
|
|
166
186
|
>
|
|
167
187
|
<Stack.Screen name={ScreenNames.Main} component={Home} />
|
|
168
188
|
<Stack.Screen name={ScreenNames.NationalID} component={NationalID} />
|
|
@@ -323,20 +343,26 @@ export const canExit = (routeName: string) => exitRoutes.includes(routeName);
|
|
|
323
343
|
* Imperatively navigate into a loan detail screen from outside React.
|
|
324
344
|
*
|
|
325
345
|
* Intended for the host app to deep-link the user straight into a loan detail
|
|
326
|
-
* (e.g. from a push notification or a list rendered outside the SDK).
|
|
327
|
-
* the host to register its NavigationContainer ref once via `setNavigationRef()`.
|
|
346
|
+
* (e.g. from a push notification or a list rendered outside the SDK).
|
|
328
347
|
*
|
|
329
348
|
* Accepts either a loan id or a partial loan object. The detail screen only
|
|
330
349
|
* needs `id` to fetch its data; `disbursementPartner` (when provided) selects
|
|
331
350
|
* the matching screen — 'CIMB' -> DetailLoan, otherwise -> DetailLoanTima.
|
|
351
|
+
*
|
|
352
|
+
* Resolution order:
|
|
353
|
+
* 1. SDK navigator already mounted -> navigate within it directly.
|
|
354
|
+
* 2. SDK not mounted, but the host registered its ref + the route that mounts
|
|
355
|
+
* <RNTimacare/> (via `setNavigationRef(ref, hostRoute)`) -> mount the SDK and
|
|
356
|
+
* deep-link in one nested navigate.
|
|
357
|
+
* 3. Fallback: dispatch on the host ref directly (only reaches SDK screens when
|
|
358
|
+
* the host mounts PrimaryNavigator as its root navigator).
|
|
332
359
|
*/
|
|
333
360
|
export function goDetail(
|
|
334
361
|
loan: number | { id: number; disbursementPartner?: string }
|
|
335
362
|
) {
|
|
336
363
|
const loanObj = typeof loan === 'number' ? { id: loan } : loan;
|
|
337
|
-
const navigation = getNavigation();
|
|
338
364
|
|
|
339
|
-
if (!loanObj?.id
|
|
365
|
+
if (!loanObj?.id) {
|
|
340
366
|
return;
|
|
341
367
|
}
|
|
342
368
|
|
|
@@ -345,5 +371,26 @@ export function goDetail(
|
|
|
345
371
|
? ScreenNames.DetailLoan
|
|
346
372
|
: ScreenNames.DetailLoanTima;
|
|
347
373
|
|
|
348
|
-
|
|
374
|
+
// 1) SDK navigator is mounted: navigate within the navigator that owns the screen.
|
|
375
|
+
const sdkNavigation = getSdkNavigation();
|
|
376
|
+
if (sdkNavigation) {
|
|
377
|
+
sdkNavigation.navigate(screen, { loan: loanObj });
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// 2) SDK not mounted: mount it via the host route and deep-link in one go.
|
|
382
|
+
const hostNavigation = getHostNavigation();
|
|
383
|
+
const hostRoute = getHostRoute();
|
|
384
|
+
if (hostNavigation && hostRoute) {
|
|
385
|
+
hostNavigation.navigate(hostRoute, {
|
|
386
|
+
screen,
|
|
387
|
+
params: { loan: loanObj },
|
|
388
|
+
});
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// 3) Last resort: host ref dispatch (works only if the SDK is the host root).
|
|
393
|
+
if (hostNavigation) {
|
|
394
|
+
hostNavigation.navigate(screen, { loan: loanObj });
|
|
395
|
+
}
|
|
349
396
|
}
|