@fto-consult/expo-ui 5.3.0 → 5.5.0
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/index.js +13 -0
- package/package.json +4 -4
- package/src/App.js +3 -1
- package/src/components/AppBar/index.js +0 -2
- package/src/components/BottomSheet/Menu.js +10 -9
- package/src/components/Datagrid/SWRDatagrid.js +3 -0
- package/src/components/Menu/Menu.js +17 -34
- package/src/components/Menu/index.js +12 -3
- package/src/components/Menu/utils.js +1 -1
- package/src/index.js +14 -7
- package/src/navigation/index.js +13 -5
- package/src/screens/Auth/Profile.js +1 -1
- package/src/screens/Help/PrivacyPolicy/content.js +1 -1
- package/src/screens/index.js +13 -12
package/index.js
CHANGED
|
@@ -2,6 +2,19 @@ import { registerRootComponent } from "expo";
|
|
|
2
2
|
import {Platform } from 'react-native';
|
|
3
3
|
import App from "./src/App";
|
|
4
4
|
const isWeb = Platform.OS === "web";
|
|
5
|
+
|
|
6
|
+
/****
|
|
7
|
+
* les options sont de la forme :
|
|
8
|
+
* {
|
|
9
|
+
* @param init {function} ()=>Promise<{}>, initialise l'application, lorsque la promèsse n'est pas résolue, alors l'application considère qu'il s'agit d'une étape pour l'écran de GetStarted dans ce cas,
|
|
10
|
+
* l'option la route getStartedRouteName est utilisée comme route par défaut de l'application
|
|
11
|
+
* @param initialRouteName {string} la route initiale, par d'afaut Home, valide lorsque la promèsse résultat de la fonction init est résolue
|
|
12
|
+
* @param getStartedRouteName {string} la route de l'écran de GetStarted, valide lorsque la promèsse résultat de la fonction init n'est pas résolue
|
|
13
|
+
* L'écran de route getStartedRouteName prend en paramètre onGetStarted {function}, qui est appelée lorsque le contenu de l'écran GetStarted est affiché à l'utilisateur
|
|
14
|
+
* @maram {swrConfig}, les options supplémentaires à passer au gestinnaire swr
|
|
15
|
+
* les écrans d'initialisation doivent garder la propriété Start à true ou doivent avoir le groupe INTALL, pour spécifier que ce sont es écrans qui apparaissent lorsque l'application n'est pas initialisée
|
|
16
|
+
* }
|
|
17
|
+
*/
|
|
5
18
|
export default function registerApp (options){
|
|
6
19
|
options = options && typeof options =='object' && !Array.isArray(options)? options : {};
|
|
7
20
|
registerRootComponent(function(props){
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@emotion/native": "^11.10.0",
|
|
62
62
|
"@expo/html-elements": "^0.2.0",
|
|
63
63
|
"@expo/vector-icons": "^13.0.0",
|
|
64
|
-
"@fto-consult/common": "^3.3.
|
|
64
|
+
"@fto-consult/common": "^3.3.6",
|
|
65
65
|
"@gorhom/portal": "^1.0.14",
|
|
66
66
|
"@react-native-async-storage/async-storage": "^1.17.11",
|
|
67
67
|
"@react-native-community/datetimepicker": "^6.7.3",
|
|
@@ -96,8 +96,8 @@
|
|
|
96
96
|
"react-native-blob-util": "^0.17.0",
|
|
97
97
|
"react-native-gesture-handler": "~2.9.0",
|
|
98
98
|
"react-native-mime-types": "^2.3.0",
|
|
99
|
-
"react-native-paper": "^4.
|
|
100
|
-
"react-native-paper-dates": "^0.
|
|
99
|
+
"react-native-paper": "^5.4.1",
|
|
100
|
+
"react-native-paper-dates": "^0.15.1",
|
|
101
101
|
"react-native-reanimated": "~2.14.4",
|
|
102
102
|
"react-native-safe-area-context": "^4.5.0",
|
|
103
103
|
"react-native-screens": "~3.20.0",
|
package/src/App.js
CHANGED
|
@@ -40,7 +40,7 @@ Object.map(Utils,(v,i)=>{
|
|
|
40
40
|
window[i] = v;
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
|
-
export default function getIndex({onMount,onUnmount,onRender,preferences:appPreferences,...rest}){
|
|
43
|
+
export default function getIndex({onMount,onUnmount,swrConfig,onRender,preferences:appPreferences,...rest}){
|
|
44
44
|
const isScreenFocusedRef = React.useRef(true);
|
|
45
45
|
///garde pour chaque écran sa date de dernière activité
|
|
46
46
|
const screensRef = React.useRef({});//la liste des écrans actifs
|
|
@@ -49,6 +49,7 @@ export default function getIndex({onMount,onUnmount,onRender,preferences:appPref
|
|
|
49
49
|
const appStateRef = React.useRef({});
|
|
50
50
|
const isKeyboardOpenRef = React.useRef(false);
|
|
51
51
|
React.useOnRender(onRender);
|
|
52
|
+
swrConfig = defaultObj(swrConfig);
|
|
52
53
|
React.useEffect(()=>{
|
|
53
54
|
///la fonction de rappel lorsque le composant est monté
|
|
54
55
|
let cb = typeof onMount =='function'? onMount() : null;
|
|
@@ -120,6 +121,7 @@ export default function getIndex({onMount,onUnmount,onRender,preferences:appPref
|
|
|
120
121
|
return (
|
|
121
122
|
<SWRConfig
|
|
122
123
|
value={{
|
|
124
|
+
...swrConfig,
|
|
123
125
|
provider: () => new Map(),
|
|
124
126
|
isOnline() {
|
|
125
127
|
/* Customize the network state detector */
|
|
@@ -27,7 +27,6 @@ export const GO_BACK_EVENT = "STACK_NAVIGATOR_GO_BACK";
|
|
|
27
27
|
* @param menuProps : les props à passer au menu au cas où les actions de l'appBar son segmentés avec certaines qui sont découpées dans un menu more
|
|
28
28
|
|
|
29
29
|
*/
|
|
30
|
-
const isNullOrE = x => x === null || x === false;
|
|
31
30
|
|
|
32
31
|
const AppBarComponent = React.forwardRef((props,ref)=> {
|
|
33
32
|
let { bindResizeEvent,elevation,isMainDrawer,
|
|
@@ -91,7 +90,6 @@ const AppBarComponent = React.forwardRef((props,ref)=> {
|
|
|
91
90
|
children = {backAction}
|
|
92
91
|
/>
|
|
93
92
|
}
|
|
94
|
-
console.log(backAction," is back actions");
|
|
95
93
|
const [context] = React.useState({});
|
|
96
94
|
actions = typeof actions =='function'? actions(getCallAgs()) : actions;
|
|
97
95
|
const dimensions = Dimensions.get("window");
|
|
@@ -11,17 +11,15 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
11
11
|
let {anchor,anchorProps,screenIndent,height:customHeight,bindResizeEvent,onDismiss,testID,visible:customVisible,controlled,mobile,animateOnClose,renderMenuContent,sheet,children,...rest} = props;
|
|
12
12
|
rest = defaultObj(rest);
|
|
13
13
|
const isControlled = controlled ? true : false;
|
|
14
|
-
const visibleRef = React.useRef(null);
|
|
15
14
|
const [state,setState] = React.useState({
|
|
16
15
|
visible : false,
|
|
17
16
|
height : undefined,
|
|
18
17
|
});
|
|
19
|
-
const visible =
|
|
20
|
-
visibleRef.current = null;
|
|
18
|
+
const visible = isControlled ? customVisible : state.visible;
|
|
21
19
|
let height = state.height;
|
|
22
20
|
const isMounted = React.useIsMounted();
|
|
23
21
|
const anchorRef = React.useRef(null);
|
|
24
|
-
const isMobile = x=> mobile || sheet === true || renderMenuContent === false ||
|
|
22
|
+
const isMobile = x=> mobile || sheet === true || renderMenuContent === false || isMob ? true : false;
|
|
25
23
|
let isMob = isMobile();
|
|
26
24
|
testID = defaultStr(testID,'RN_BottomSheetMenuComponent');
|
|
27
25
|
const innerRef = React.useRef(null);
|
|
@@ -32,9 +30,9 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
32
30
|
getContentHeight(anchorRef,({height})=>{
|
|
33
31
|
setState({...state,visible:true,height});
|
|
34
32
|
},screenIndent);
|
|
35
|
-
}, close = ()=>{
|
|
36
|
-
if(!isMobile()) return;
|
|
37
|
-
if(!isMounted() || !visible) return;
|
|
33
|
+
}, close = (force)=>{
|
|
34
|
+
if(force !== true && !isMobile()) return;
|
|
35
|
+
if(!isMounted() || (force !== true && !visible)) return;
|
|
38
36
|
if(isControlled){
|
|
39
37
|
if(onDismiss){
|
|
40
38
|
onDismiss({});
|
|
@@ -43,6 +41,7 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
43
41
|
}
|
|
44
42
|
setState({...state,visible:false})
|
|
45
43
|
}
|
|
44
|
+
const prevIsMob = React.usePrevious(isMob);
|
|
46
45
|
const Component = isMob ? BottomSheet : Menu;
|
|
47
46
|
anchorProps = defaultObj(anchorProps);
|
|
48
47
|
if(isMob){
|
|
@@ -67,6 +66,9 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
67
66
|
delete rest.visible;
|
|
68
67
|
height = undefined;
|
|
69
68
|
}
|
|
69
|
+
if(prevIsMob !== isMob){
|
|
70
|
+
rest.visible = visible;
|
|
71
|
+
}
|
|
70
72
|
if(!isControlled){
|
|
71
73
|
rest.onAnchorPress = ()=>{
|
|
72
74
|
open();
|
|
@@ -77,8 +79,7 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
77
79
|
React.useEffect(()=>{
|
|
78
80
|
const closeModal = ()=>{
|
|
79
81
|
if(!isMounted()) return;
|
|
80
|
-
|
|
81
|
-
setState({...state});
|
|
82
|
+
close(true);
|
|
82
83
|
}
|
|
83
84
|
if(bindResizeEvent !== false){
|
|
84
85
|
APP.on(APP.EVENTS.RESIZE_PAGE,closeModal);
|
|
@@ -177,6 +177,9 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
|
|
|
177
177
|
opts = defaultObj(opts);
|
|
178
178
|
opts.fetchOptions = isObj(opts.fetchOptions)? Object.clone(opts.fetchOptions) : {};
|
|
179
179
|
extendObj(true,opts.fetchOptions,fetchOptionsRef.current?.fetchOptions);
|
|
180
|
+
if(props.convertFiltersToSQL === false){
|
|
181
|
+
opts.fetchOptions.selector = extendObj(true,{},opts.fetchOptions.selector,fetchOptionsRef.current?.selector);
|
|
182
|
+
}
|
|
180
183
|
opts.fetchOptions.sort = sortRef.current;
|
|
181
184
|
if(canHandleLimit){
|
|
182
185
|
opts.fetchOptions.limit = limitRef.current;
|
|
@@ -47,18 +47,9 @@ class _Menu extends AppComponent {
|
|
|
47
47
|
statusBarHeight: APPROX_STATUSBAR_HEIGHT,
|
|
48
48
|
overlayAccessibilityLabel: 'Close menu',
|
|
49
49
|
};
|
|
50
|
-
|
|
51
|
-
static getDerivedStateFromProps1(nextProps, prevState) {
|
|
52
|
-
if (nextProps.visible && !prevState.rendered) {
|
|
53
|
-
return { rendered: true };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
50
|
constructor(props){
|
|
59
51
|
super(props);
|
|
60
52
|
extendObj(this.state,{
|
|
61
|
-
rendered: this.props.visible,
|
|
62
53
|
top: 0,
|
|
63
54
|
left: 0,
|
|
64
55
|
menuLayout: { width: 0, height: 0 },
|
|
@@ -78,17 +69,13 @@ class _Menu extends AppComponent {
|
|
|
78
69
|
componentWillUnmount() {
|
|
79
70
|
super.componentWillUnmount();
|
|
80
71
|
this.removeListeners();
|
|
72
|
+
this.menu = null;
|
|
73
|
+
this.anchor = null;
|
|
81
74
|
}
|
|
82
75
|
|
|
83
76
|
anchor = null;
|
|
84
|
-
menu = null;
|
|
85
77
|
backHandlerSubscription;
|
|
86
78
|
|
|
87
|
-
isCoordinate = (anchor) =>
|
|
88
|
-
!React.isValidElement(anchor) &&
|
|
89
|
-
typeof anchor?.x === 'number' &&
|
|
90
|
-
typeof anchor?.y === 'number';
|
|
91
|
-
|
|
92
79
|
measureMenuLayout = () =>
|
|
93
80
|
new Promise((resolve) => {
|
|
94
81
|
if (this.menu) {
|
|
@@ -100,12 +87,6 @@ class _Menu extends AppComponent {
|
|
|
100
87
|
|
|
101
88
|
measureAnchorLayout = () =>
|
|
102
89
|
new Promise((resolve) => {
|
|
103
|
-
const { anchor } = this.props;
|
|
104
|
-
if (this.isCoordinate(anchor)) {
|
|
105
|
-
resolve({ x: anchor.x, y: anchor.y, width: 0, height: 0 });
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
90
|
if (this.anchor) {
|
|
110
91
|
this.anchor.measureInWindow((x, y, width, height) => {
|
|
111
92
|
resolve({ x, y, width, height });
|
|
@@ -198,8 +179,8 @@ class _Menu extends AppComponent {
|
|
|
198
179
|
!windowLayout.height ||
|
|
199
180
|
!menuLayout.width ||
|
|
200
181
|
!menuLayout.height ||
|
|
201
|
-
(!anchorLayout.width
|
|
202
|
-
(!anchorLayout.height
|
|
182
|
+
(!anchorLayout.width) ||
|
|
183
|
+
(!anchorLayout.height)
|
|
203
184
|
) {
|
|
204
185
|
requestAnimationFrame(this.show);
|
|
205
186
|
return;
|
|
@@ -255,7 +236,7 @@ class _Menu extends AppComponent {
|
|
|
255
236
|
useNativeDriver: true,
|
|
256
237
|
}).start(({ finished }) => {
|
|
257
238
|
if (finished) {
|
|
258
|
-
this.setState({ menuLayout: { width: 0, height: 0 }
|
|
239
|
+
this.setState({ menuLayout: { width: 0, height: 0 }});
|
|
259
240
|
this.state.scaleAnimation.setValue({ x: 0, y: 0 });
|
|
260
241
|
this.focusFirstDOMNode(this.anchor);
|
|
261
242
|
}
|
|
@@ -283,8 +264,8 @@ class _Menu extends AppComponent {
|
|
|
283
264
|
opacityAnimation,
|
|
284
265
|
scaleAnimation,
|
|
285
266
|
} = this.state;
|
|
286
|
-
const rendered = visible;
|
|
287
267
|
const minWidth = defaultDecimal(customMinWidth);
|
|
268
|
+
const rendered = this.props.visible;
|
|
288
269
|
let { left, top } = this.state;
|
|
289
270
|
|
|
290
271
|
// I don't know why but on Android measure function is wrong by 24
|
|
@@ -458,7 +439,7 @@ class _Menu extends AppComponent {
|
|
|
458
439
|
|
|
459
440
|
//- (sameWidth ? anchorLayout.height : 0)
|
|
460
441
|
const positionStyle = {
|
|
461
|
-
top:
|
|
442
|
+
top: top + additionalVerticalValue,
|
|
462
443
|
...(I18nManager.isRTL ? { right: left } : { left }),
|
|
463
444
|
};
|
|
464
445
|
if(sameWidth){
|
|
@@ -474,8 +455,9 @@ class _Menu extends AppComponent {
|
|
|
474
455
|
positionStyle.top = SCREEN_INDENT;
|
|
475
456
|
}
|
|
476
457
|
const maxMenuHeight = windowLayout.height - top - SCREEN_INDENT;
|
|
477
|
-
const maxHeight = maxMenuHeight >=0 ? Math.max(Math.
|
|
458
|
+
const maxHeight = maxMenuHeight >=0 ? Math.max(Math.max(maxMenuHeight,menuLayout.height),150) : windowLayout.height - SCREEN_INDENT*2;
|
|
478
459
|
const contentContainerStyle = maxMenuHeight > SCREEN_INDENT ? {maxHeight} : undefined;
|
|
460
|
+
const hiddenStyle = !rendered ? {display:'none',width:0,opacity:0} : null;
|
|
479
461
|
return (
|
|
480
462
|
<View
|
|
481
463
|
testID = {testID}
|
|
@@ -485,17 +467,18 @@ class _Menu extends AppComponent {
|
|
|
485
467
|
collapsable={false}
|
|
486
468
|
style = {{backgroundColor:'transparent'}}
|
|
487
469
|
>
|
|
488
|
-
{
|
|
489
|
-
{
|
|
470
|
+
{anchor}
|
|
471
|
+
{true ? (
|
|
490
472
|
<Portal>
|
|
491
|
-
<TouchableWithoutFeedback
|
|
473
|
+
{rendered ? <TouchableWithoutFeedback
|
|
492
474
|
testID={testID+"_TouchableWithoutFeedBack"}
|
|
493
475
|
accessibilityLabel={overlayAccessibilityLabel}
|
|
494
476
|
accessibilityRole="button"
|
|
495
477
|
onPress={onDismiss}
|
|
478
|
+
style = {[hiddenStyle]}
|
|
496
479
|
>
|
|
497
480
|
<View style={[StyleSheet.absoluteFill,{flex:1,backgroundColor:'transparent'}]} testID={testID+"_Backdrop"} />
|
|
498
|
-
</TouchableWithoutFeedback
|
|
481
|
+
</TouchableWithoutFeedback>:null}
|
|
499
482
|
<View
|
|
500
483
|
testID = {testID+"_ContentContainer"}
|
|
501
484
|
ref={(ref) => {
|
|
@@ -503,11 +486,11 @@ class _Menu extends AppComponent {
|
|
|
503
486
|
}}
|
|
504
487
|
collapsable={false}
|
|
505
488
|
accessibilityViewIsModal={visible}
|
|
506
|
-
style={[styles.wrapper, positionStyle, style]}
|
|
489
|
+
style={[styles.wrapper, positionStyle, style,hiddenStyle]}
|
|
507
490
|
pointerEvents={visible ? 'box-none' : 'none'}
|
|
508
491
|
onAccessibilityEscape={onDismiss}
|
|
509
492
|
>
|
|
510
|
-
|
|
493
|
+
{rendered?<Animated.View style={{ transform: positionTransforms }} testID={testID+"_Animated"}>
|
|
511
494
|
<Surface
|
|
512
495
|
elevation = {5}
|
|
513
496
|
testID= {testID+"_Content"}
|
|
@@ -525,7 +508,7 @@ class _Menu extends AppComponent {
|
|
|
525
508
|
{((scrollableMenuHeight|| contentContainerStyle) && (<ScrollView contentContainerStyle={contentContainerStyle} testID={testID+"_ScrollView"}>{children}</ScrollView>
|
|
526
509
|
)) || children}
|
|
527
510
|
</Surface>
|
|
528
|
-
</Animated.View>
|
|
511
|
+
</Animated.View> : null}
|
|
529
512
|
</View>
|
|
530
513
|
</Portal>
|
|
531
514
|
) : null}
|
|
@@ -73,7 +73,7 @@ const MenuComponent = React.forwardRef((props,ref)=>{
|
|
|
73
73
|
console.error("unable to render menu, anchor not spécified for props",props);
|
|
74
74
|
}
|
|
75
75
|
const context = {openMenu,closeMenu,open:openMenu,close:closeMenu};
|
|
76
|
-
React.setRef(ref,context);
|
|
76
|
+
//React.setRef(ref,context);
|
|
77
77
|
if(typeof children =='function'){
|
|
78
78
|
children = children({openMenu,closeMenu,context});
|
|
79
79
|
}
|
|
@@ -81,8 +81,17 @@ const MenuComponent = React.forwardRef((props,ref)=>{
|
|
|
81
81
|
return ()=>{
|
|
82
82
|
React.setRef(ref,null);
|
|
83
83
|
}
|
|
84
|
-
},[])
|
|
85
|
-
return <Menu {...menuProps}
|
|
84
|
+
},[]);
|
|
85
|
+
return <Menu {...menuProps} ref={(el)=>{
|
|
86
|
+
if(el){
|
|
87
|
+
for(let i in context){
|
|
88
|
+
if(!(i in el)){
|
|
89
|
+
el[i] = context[i];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
React.setRef(ref,el);
|
|
94
|
+
}} testID={testID} visible={visible} onDismiss={closeMenu} anchor={anchor}>
|
|
86
95
|
{renderItems({...props,onPressItem,renderItem,openMenu,closeMenu})}
|
|
87
96
|
{React.isValidElement(children)? children: null}
|
|
88
97
|
</Menu>
|
package/src/index.js
CHANGED
|
@@ -33,7 +33,12 @@ const resetExitCounter = ()=>{
|
|
|
33
33
|
|
|
34
34
|
const NAVIGATION_PERSISTENCE_KEY = 'NAVIGATION_STATE';
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
/****
|
|
37
|
+
* init {function}: ()=>Promise<{}> est la fonction d'initialisation de l'application
|
|
38
|
+
* initialRouteName : la route initiale par défaut
|
|
39
|
+
* getStartedRouteName : la route par défaut de getStarted lorsque l'application est en mode getStarted, c'est à dire lorsque la fonction init renvoie une erreur (reject)
|
|
40
|
+
*/
|
|
41
|
+
function App({init:initApp,initialRouteName:appInitialRouteName,getStartedRouteName}) {
|
|
37
42
|
AppStateService.init();
|
|
38
43
|
const [initialState, setInitialState] = React.useState(undefined);
|
|
39
44
|
const appReadyRef = React.useRef(true);
|
|
@@ -156,16 +161,16 @@ function App({init:initApp}) {
|
|
|
156
161
|
console.log(e," is net info heinn")
|
|
157
162
|
});
|
|
158
163
|
loadResources().finally(()=>{
|
|
159
|
-
(typeof initApp =='function'?initApp : init)().then(()=>{
|
|
164
|
+
(typeof initApp =='function'?initApp : init)().then((args)=>{
|
|
160
165
|
if(Auth.isLoggedIn()){
|
|
161
166
|
Auth.loginUser(false);
|
|
162
167
|
}
|
|
163
168
|
setState({
|
|
164
|
-
...state,isInitialized:true,isLoading : false,
|
|
169
|
+
...state,hasGetStarted:true,...defaultObj(args && args?.state),isInitialized:true,isLoading : false,
|
|
165
170
|
});
|
|
166
171
|
}).catch((e)=>{
|
|
167
172
|
console.error(e," initializing app")
|
|
168
|
-
setState({...state,isInitialized:true,isLoading : false});
|
|
173
|
+
setState({...state,isInitialized:true,isLoading : false,hasGetStarted:false});
|
|
169
174
|
})
|
|
170
175
|
});
|
|
171
176
|
|
|
@@ -197,7 +202,6 @@ function App({init:initApp}) {
|
|
|
197
202
|
}
|
|
198
203
|
}, []);
|
|
199
204
|
const {isInitialized} = state;
|
|
200
|
-
const hasGetStarted = true;
|
|
201
205
|
const isLoading = state.isLoading || !isInitialized || !appReadyRef.current? true : false;
|
|
202
206
|
React.useEffect(()=>{
|
|
203
207
|
if(isInitialized){
|
|
@@ -205,7 +209,7 @@ function App({init:initApp}) {
|
|
|
205
209
|
trackIDLE(true);
|
|
206
210
|
}
|
|
207
211
|
},[isInitialized]);
|
|
208
|
-
const
|
|
212
|
+
const hasGetStarted = state.hasGetStarted !== false? true : false;
|
|
209
213
|
return (<SplashScreen isLoaded={!isLoading}>
|
|
210
214
|
<NavigationContainer
|
|
211
215
|
ref={navigationRef}
|
|
@@ -216,9 +220,12 @@ function App({init:initApp}) {
|
|
|
216
220
|
}
|
|
217
221
|
>
|
|
218
222
|
<Navigation
|
|
219
|
-
initialRouteName = {
|
|
223
|
+
initialRouteName = {defaultStr(hasGetStarted ? appInitialRouteName : getStartedRouteName,"Home")}
|
|
220
224
|
state = {state}
|
|
221
225
|
hasGetStarted = {hasGetStarted}
|
|
226
|
+
onGetStart = {(e)=>{
|
|
227
|
+
setState({...state,hasGetStarted:true})
|
|
228
|
+
}}
|
|
222
229
|
/>
|
|
223
230
|
</NavigationContainer>
|
|
224
231
|
</SplashScreen>);
|
package/src/navigation/index.js
CHANGED
|
@@ -6,15 +6,23 @@ import DrawerNavigator from "./Drawer";
|
|
|
6
6
|
|
|
7
7
|
export * from "./utils";
|
|
8
8
|
|
|
9
|
+
/**** la fonction onGetStart doit normalement être appélée lorsque l'application
|
|
10
|
+
* lorsque hasGetStarted est à false, celle-ci rend l'écran Start permettant de rendre le contenu GetStarted
|
|
11
|
+
*/
|
|
9
12
|
export default function NavigationComponent (props){
|
|
10
|
-
let {state,hasGetStarted,initialRouteName,extra} = props;
|
|
13
|
+
let {state,hasGetStarted,onGetStart,initialRouteName,extra} = props;
|
|
11
14
|
const allScreens = initScreens({Factory:Stack,ModalFactory:Stack,filter:({name,Screen})=>{
|
|
12
|
-
|
|
15
|
+
if(name === initialRouteName){
|
|
16
|
+
extra = defaultObj(extra);
|
|
17
|
+
extra.onGetStart = onGetStart;
|
|
18
|
+
extra.state = state;
|
|
19
|
+
return extra;
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
13
22
|
}});
|
|
14
|
-
|
|
15
23
|
initialRouteName = sanitizeName(initialRouteName);
|
|
16
|
-
const drawerScreens = handleContent({screens:allScreens,hasGetStarted,initialRouteName,state,Factory:Stack});
|
|
17
|
-
const stackScreens = handleContent({screens:allScreens.modals,hasGetStarted,initialRouteName,state,Factory:Stack});
|
|
24
|
+
const drawerScreens = handleContent({screens:allScreens,onGetStart,hasGetStarted,initialRouteName,state,Factory:Stack});
|
|
25
|
+
const stackScreens = handleContent({screens:allScreens.modals,onGetStart,hasGetStarted,initialRouteName,state,Factory:Stack});
|
|
18
26
|
if(!drawerScreens.length && !stackScreens.length){
|
|
19
27
|
console.error("apps will stuck on splash screen because any valid screen has been found on screens ",allScreens);
|
|
20
28
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import FormDataScreen from "$elayouts/Screen/FormData";
|
|
2
2
|
import {defaultStr,defaultObj,isObjOrArray,isObj} from "$utils";
|
|
3
|
-
import Auth from "$
|
|
3
|
+
import Auth from "$cauth";
|
|
4
4
|
import {navigate} from "$cnavigation";
|
|
5
5
|
import SelectTheme from "$themeSelectorComponent";
|
|
6
6
|
import Preloader from "$epreloader";
|
|
@@ -6,7 +6,7 @@ import Label from "$components/Label";
|
|
|
6
6
|
|
|
7
7
|
export default function ContentPrivacy (){
|
|
8
8
|
return <Label primary style={{fontSize:15,fontWeight:'bold',padding:10}}>
|
|
9
|
-
Pour modifier le contenu de la
|
|
9
|
+
Pour modifier le contenu de la politique de confidentialité, il suffit de déclarer dans les alias, l'alias
|
|
10
10
|
$PrivacyPolicy prointant vers un fichier javascript dans lequel on exporte par défaut, soit un composant React
|
|
11
11
|
où encore un élément react valide dont le rendu remplacera ledit contenu.
|
|
12
12
|
</Label>
|
package/src/screens/index.js
CHANGED
|
@@ -7,8 +7,7 @@ import { SCREEN_OPTIONS } from "./utils";
|
|
|
7
7
|
|
|
8
8
|
export * from "./utils";
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
export const handleScreen = ({Screen,Factory,ModalFactory,result,useTheme,filter,index})=>{
|
|
10
|
+
export const handleScreen = ({Screen,Factory,ModalFactory,result,filter,index})=>{
|
|
12
11
|
result = defaultObj(result);
|
|
13
12
|
result.screens = defaultObj(result.screens);
|
|
14
13
|
result.groups = defaultObj(result.groups);
|
|
@@ -18,7 +17,7 @@ export const handleScreen = ({Screen,Factory,ModalFactory,result,useTheme,filter
|
|
|
18
17
|
let screenOptions = undefined;
|
|
19
18
|
if(Array.isArray(Screen)){
|
|
20
19
|
Screen.map((S,i)=>{
|
|
21
|
-
return handleScreen({Screen:S,Factory,ModalFactory,result,groups,
|
|
20
|
+
return handleScreen({Screen:S,Factory,ModalFactory,result,groups,filter,index:i});
|
|
22
21
|
})
|
|
23
22
|
} else if(typeof Screen ==='object' && React.isComponent(Screen.Component) && isNonNullString(Screen.screenName)){
|
|
24
23
|
screenName = Screen.screenName;
|
|
@@ -40,11 +39,15 @@ export const handleScreen = ({Screen,Factory,ModalFactory,result,useTheme,filter
|
|
|
40
39
|
if(!GROUP_NAMES[groupName]){
|
|
41
40
|
groupName = GROUP_NAMES.PRIVATE;
|
|
42
41
|
}
|
|
43
|
-
if(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
if( groupName !== GROUP_NAMES.INSTALL){
|
|
43
|
+
if(!authRequired){
|
|
44
|
+
groupName = groupName || GROUP_NAMES.PUBLIC;
|
|
45
|
+
} else{
|
|
46
|
+
groupName = GROUP_NAMES.PRIVATE;
|
|
47
|
+
authRequired = true;
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
authRequired = false;
|
|
48
51
|
}
|
|
49
52
|
groups[groupName] = defaultObj(groups[groupName]);
|
|
50
53
|
groups[groupName][sanitizeName] = name;
|
|
@@ -84,7 +87,6 @@ export const handleScreen = ({Screen,Factory,ModalFactory,result,useTheme,filter
|
|
|
84
87
|
* @param Factory {typeof Factory : voir @https://reactnavigation.org/}
|
|
85
88
|
* @param screens {Object {screns:{screens:{},groups:{}}}} l'objet dans lequel le screensat sera retourné
|
|
86
89
|
* @param screens {array} la liste des écrans à rendre dynamiquement dans le FactoryContainer
|
|
87
|
-
* @param useTheme {boolean} si le composant sera wrapper par le hook withTheme de react-native-paper
|
|
88
90
|
* @return {object} : objet comportant deux propriétés :
|
|
89
91
|
* screens : {} : liste des écrans de l'application initialisés. il est à noter que, tous les écrans sont dans les sous répertoire du dossier courant
|
|
90
92
|
screens screens est de la forme : {group1:[],group2:[], ...groupN:[]}:
|
|
@@ -92,7 +94,7 @@ export const handleScreen = ({Screen,Factory,ModalFactory,result,useTheme,filter
|
|
|
92
94
|
|
|
93
95
|
groups : {} : la liste des différents groupes d'écrans rendus par la méthode
|
|
94
96
|
*/
|
|
95
|
-
export default function initScreens ({Factory,ModalFactory,
|
|
97
|
+
export default function initScreens ({Factory,ModalFactory,screens,result,filter}){
|
|
96
98
|
if(!isArray(screens) || !screens.length){
|
|
97
99
|
screens = mainScreens;
|
|
98
100
|
}
|
|
@@ -100,7 +102,6 @@ export default function initScreens ({Factory,ModalFactory,useTheme,screens,resu
|
|
|
100
102
|
result.screens = defaultObj(result.screens);
|
|
101
103
|
result.groups = defaultObj(result.groups);
|
|
102
104
|
///lorsque les écrans sont passés enparamètres, par défaut, le wrapper withTheme n'est pas utilisé
|
|
103
|
-
useTheme = defaultBool(useTheme,false);
|
|
104
105
|
filter = typeof filter =="function" ? filter : x=> true;
|
|
105
106
|
defaultArray(screens).map((Screen,index)=>{
|
|
106
107
|
handleScreen({Screen,result,Factory,ModalFactory,filter,index})
|
|
@@ -108,7 +109,7 @@ export default function initScreens ({Factory,ModalFactory,useTheme,screens,resu
|
|
|
108
109
|
return result;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
export const handleContent = ({screens,hasGetStarted,state,Factory})=>{
|
|
112
|
+
export const handleContent = ({screens,hasGetStarted,onGetStart,state,Factory})=>{
|
|
112
113
|
const content = [];
|
|
113
114
|
state = defaultObj(state);
|
|
114
115
|
screens = defaultObj(screens);
|