@fto-consult/expo-ui 3.2.0 → 3.3.1
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/bin/index.js +15 -8
- package/electron/exec.js +4 -2
- package/electron/index.js +35 -12
- package/electron/src/preload.js +3 -63
- package/package.json +2 -2
- package/src/auth/Login.js +19 -4
- package/src/components/Avatar/AutoHeightImage/index.js +11 -8
- package/src/components/Image/index.js +1 -1
package/bin/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
//#!/usr/bin/env node
|
|
2
2
|
/**@see : https://blog.shahednasser.com/how-to-create-a-npx-tool/ */
|
|
3
3
|
'use strict';
|
|
4
4
|
process.on('unhandledRejection', err => {
|
|
@@ -25,6 +25,7 @@ if(!parsedArgs.script || !(parsedArgs.script in supportedScript)){
|
|
|
25
25
|
const {script} = parsedArgs;
|
|
26
26
|
let cmd = null;
|
|
27
27
|
/****
|
|
28
|
+
* 1. installer electron globallement : npm i -g electron@latest
|
|
28
29
|
* cmde : [cmd] start electron config=[path-to-config-relative-to-project-dir]
|
|
29
30
|
* splash=[path-to-splashcreen-relative-to-project-root]
|
|
30
31
|
* output-dir|out = [path-to-output-dir-relative-to-root-project]
|
|
@@ -64,10 +65,9 @@ if(parsedArgs.electron){
|
|
|
64
65
|
if(parsedArgs.compile || !fs.existsSync(path.resolve(webBuildDir,"index.html"))){
|
|
65
66
|
cmd = "npx expo export:web";
|
|
66
67
|
console.log("******************** exporting app : "+cmd);
|
|
67
|
-
return exec({cmd
|
|
68
|
-
} else {
|
|
69
|
-
next();
|
|
68
|
+
return exec({cmd,projectRoot}).then(next).catch(reject);
|
|
70
69
|
}
|
|
70
|
+
next();
|
|
71
71
|
});
|
|
72
72
|
return promise.then(()=>{
|
|
73
73
|
if(!fs.existsSync(buildOutDir) || !fs.existsSync(indexFile)){
|
|
@@ -75,15 +75,22 @@ if(parsedArgs.electron){
|
|
|
75
75
|
}
|
|
76
76
|
switch(script){
|
|
77
77
|
case "start":
|
|
78
|
-
cmd = "
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
cmd = "electron "+electronDir;
|
|
79
|
+
return new Promise((resolve,reject)=>{
|
|
80
|
+
exec({
|
|
81
|
+
cmd,
|
|
82
|
+
projectRoot : electronDir,
|
|
83
|
+
}).finally(()=>{
|
|
84
|
+
console.log("ant to exit");
|
|
85
|
+
})
|
|
86
|
+
setTimeout(resolve,1000)
|
|
82
87
|
})
|
|
83
88
|
break;
|
|
84
89
|
case "build":
|
|
85
90
|
break;
|
|
86
91
|
}
|
|
92
|
+
}).catch((e)=>{
|
|
93
|
+
console.log(e," is cathing ggg");
|
|
87
94
|
}).finally(()=>{
|
|
88
95
|
process.exit();
|
|
89
96
|
});
|
package/electron/exec.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const exec = require('child_process').exec;
|
|
2
2
|
const fs = require("fs");
|
|
3
3
|
const _exec = (cmd,cmdOpts,logMessages)=>{
|
|
4
|
+
cmdOpts = typeof cmdOpts =='object' && cmdOpts || {};
|
|
4
5
|
return new Promise((resolve,reject)=>{
|
|
5
|
-
const timer = loaderTimer();
|
|
6
|
+
const timer = cmdOpts.loader !==false ? loaderTimer(cmd) : null;
|
|
6
7
|
exec(cmd,cmdOpts, (error, stdout, stderr) => {
|
|
7
8
|
if (error) {
|
|
8
9
|
logMessages !== false && console.log(`error: ${error.message}`);;
|
|
@@ -25,11 +26,12 @@ const _exec = (cmd,cmdOpts,logMessages)=>{
|
|
|
25
26
|
})
|
|
26
27
|
}
|
|
27
28
|
const loaderTimer = function(timout) {
|
|
29
|
+
const text = typeof timout =='string' && timout ||'';
|
|
28
30
|
timout = typeof timout =='number'? timout : 250;
|
|
29
31
|
var P = ["\\", "|", "/", "-"];
|
|
30
32
|
var x = 0;
|
|
31
33
|
return setInterval(function() {
|
|
32
|
-
process.stdout.write("\r" +
|
|
34
|
+
process.stdout.write("\r"+text+" "+P[x++]);
|
|
33
35
|
x &= 3;
|
|
34
36
|
}, timout);
|
|
35
37
|
};
|
package/electron/index.js
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
1
|
const {app, BrowserWindow,Tray,Menu,MenuItem,systemPreferences,powerMonitor,dialog, nativeTheme} = require('electron')
|
|
2
2
|
const appConfig = {}//require("../src/app/config");
|
|
3
|
-
const session = require("./session");
|
|
3
|
+
const session = require("./src/session");
|
|
4
4
|
const path = require("path");
|
|
5
|
+
const paths = require("./paths.json");
|
|
6
|
+
const images = paths.$images, assets = paths.$assets, logo = paths.logo;
|
|
5
7
|
// Gardez une reference globale de l'objet window, si vous ne le faites pas, la fenetre sera
|
|
6
8
|
// fermee automatiquement quand l'objet JavaScript sera garbage collected.
|
|
7
9
|
let win = undefined;
|
|
8
10
|
let fs = require("fs");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
const isWindow = process.platform =="win32",
|
|
12
|
+
isMac = process.platform =='darwin',
|
|
13
|
+
isLinux = process.platform =="linux";
|
|
14
|
+
const getIcon = (p)=>{
|
|
15
|
+
if(Array.isArray(p)){
|
|
16
|
+
for(let i in p){
|
|
17
|
+
const r = getIcon(p[i]);
|
|
18
|
+
if(r) return r;
|
|
19
|
+
}
|
|
20
|
+
} else if(typeof p =='string' && p && fs.existsSync(p)){
|
|
21
|
+
const ext = isWindow ? ".ico" : isMac ? ".incs" : ".png";
|
|
22
|
+
const possibles = ["icon","logo","favicon"];
|
|
23
|
+
for(let i in possibles){
|
|
24
|
+
const icon = path.join(p,possibles[i]+ext);
|
|
25
|
+
if(fs.existsSync(icon)){
|
|
26
|
+
return icon;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
17
31
|
}
|
|
18
|
-
|
|
32
|
+
const icon = isLinux && logo && fs.existsSync(logo) && logo || getIcon(
|
|
33
|
+
logo && fs.existsSync(logo) && path.dirname(logo),
|
|
34
|
+
images,
|
|
35
|
+
assets,
|
|
36
|
+
)
|
|
37
|
+
/*console.log(icon," is iccccccc");
|
|
38
|
+
console.log(logo," is logo ",images,assets);
|
|
39
|
+
throw {
|
|
40
|
+
message : "icon is "+icon+" logo is "+logo+" image is "+images+" assets is "+assets
|
|
41
|
+
}*/
|
|
19
42
|
Menu.setApplicationMenu(null);
|
|
20
43
|
let clipboadContextMenu = (_, props) => {
|
|
21
44
|
if (props.isEditable || props.selectionText) {
|
|
@@ -248,7 +271,7 @@ app.whenReady().then(() => {
|
|
|
248
271
|
});
|
|
249
272
|
})
|
|
250
273
|
|
|
251
|
-
|
|
274
|
+
const {ipcMain} = require("electron");
|
|
252
275
|
|
|
253
276
|
ipcMain.on("electron-restart-app",x =>{
|
|
254
277
|
app.relaunch();
|
|
@@ -291,7 +314,7 @@ ipcMain.on("update-system-tray",(event,opts)=>{
|
|
|
291
314
|
tray.setContextMenu(contextMenu)
|
|
292
315
|
})
|
|
293
316
|
ipcMain.on("electron-get-path",(event,pathName)=>{
|
|
294
|
-
|
|
317
|
+
const p = app.getPath(pathName);
|
|
295
318
|
event.returnValue = p;
|
|
296
319
|
return p;
|
|
297
320
|
});
|
package/electron/src/preload.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
(function(window) {
|
|
2
2
|
let showingExitApp = undefined;
|
|
3
|
-
|
|
4
|
-
const { exec } = require('child_process');
|
|
3
|
+
const exec = require("../exec");
|
|
5
4
|
if(typeof window.isElectron != 'function'){
|
|
6
5
|
Object.defineProperties(window,{
|
|
7
6
|
ELECTRON : {
|
|
@@ -23,8 +22,7 @@
|
|
|
23
22
|
},
|
|
24
23
|
})
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
let fs = require("fs");
|
|
25
|
+
const fs = require("fs");
|
|
28
26
|
let _app = require("./app.config");
|
|
29
27
|
require("./pload")(ELECTRON);
|
|
30
28
|
const {ipcRenderer} = require('electron')
|
|
@@ -286,65 +284,7 @@
|
|
|
286
284
|
value : getPath, override:false,writable:false
|
|
287
285
|
},
|
|
288
286
|
exec : {
|
|
289
|
-
value :
|
|
290
|
-
if(isNonNullString(opts)){
|
|
291
|
-
opts = {cmd:opts};
|
|
292
|
-
}
|
|
293
|
-
let {cmd} = opts;
|
|
294
|
-
opts = defaultObj(opts);
|
|
295
|
-
successCB = defaultFunc(successCB,opts.onSuccess)
|
|
296
|
-
errorCB = defaultFunc(errorCB,opts.onError);
|
|
297
|
-
return new Promise((resolve,reject)=>{
|
|
298
|
-
let handle = function(error, stdout, stderr) {
|
|
299
|
-
if(error){
|
|
300
|
-
errorCB({error,stderr})
|
|
301
|
-
return reject({error,stderr})
|
|
302
|
-
}
|
|
303
|
-
successCB(stdout);
|
|
304
|
-
resolve(stdout);
|
|
305
|
-
}
|
|
306
|
-
if(opts.sudo || opts.runAsAdmin){
|
|
307
|
-
sudo.exec(cmd, opts,handle)
|
|
308
|
-
} else {
|
|
309
|
-
exec(cmd,handle);
|
|
310
|
-
}
|
|
311
|
-
})
|
|
312
|
-
}
|
|
313
|
-
},
|
|
314
|
-
installNewAppVersion : {
|
|
315
|
-
value : (conf,successCB,errorCB)=>{
|
|
316
|
-
if(isNonNullString(conf)){
|
|
317
|
-
conf = {filePath:conf}
|
|
318
|
-
}
|
|
319
|
-
conf = defaultObj(conf);
|
|
320
|
-
let {notify} = APP.require("$dialog");
|
|
321
|
-
|
|
322
|
-
if(isNonNullString(conf.filePath) && fs.existsSync(conf.filePath)){
|
|
323
|
-
let cmd = conf.filePath;
|
|
324
|
-
if(ELECTRON.DEVICE.isLinux){
|
|
325
|
-
cmd = "dpkg -i "+cmd;
|
|
326
|
-
}
|
|
327
|
-
let rootPath = path.join(__dirname,'..')
|
|
328
|
-
let incs = path.join(rootPath, ELECTRON.DEVICE.isWindows?'icon.ico':ELECTRON.DEVICE.isLinux?'icon.png':'incs');
|
|
329
|
-
const options = {
|
|
330
|
-
title : "Authorisez "+APP.getName()+"",
|
|
331
|
-
name: APP.getName(),
|
|
332
|
-
incs,
|
|
333
|
-
icon : incs,
|
|
334
|
-
cmd,
|
|
335
|
-
sudo:true,
|
|
336
|
-
onSoucces : (stdout)=>{
|
|
337
|
-
let message = "Le processus d'installation de la mise à jour de l'application a été exécutée evec succès. Veuillez relancer l'application";
|
|
338
|
-
notify.success(message);
|
|
339
|
-
},
|
|
340
|
-
onError: ({error})=>{
|
|
341
|
-
notify.error("Erreur lors de l'exécution du fichier d'installation : "+defaultStr(error.message));
|
|
342
|
-
}
|
|
343
|
-
//icns: '/Applications/Electron.app/Contents/Resources/Electron.icns'
|
|
344
|
-
};
|
|
345
|
-
return ELECTRON.exec(options,successCB,errorCB)
|
|
346
|
-
}
|
|
347
|
-
}, override : false, writable : false
|
|
287
|
+
value : exec,
|
|
348
288
|
},
|
|
349
289
|
updateSystemTheme : {
|
|
350
290
|
value : (theme)=>{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"delete-node-modules": "rimraf ./**/node_modules",
|
|
43
43
|
"modifier-url-remote-git": "git remote set-url origin 'https://borispipo@github.com/borispipo/smart-eneo.git'"
|
|
44
44
|
},
|
|
45
|
-
"bin": "bin/index.js",
|
|
45
|
+
"bin": "./bin/index.js",
|
|
46
46
|
"repository": {
|
|
47
47
|
"type": "git",
|
|
48
48
|
"url": "git+https://github.com/borispipo/expo-ui.git"
|
package/src/auth/Login.js
CHANGED
|
@@ -86,7 +86,11 @@ export default function LoginComponent(props){
|
|
|
86
86
|
},1000)
|
|
87
87
|
}
|
|
88
88
|
},[withPortal])
|
|
89
|
-
const {header,
|
|
89
|
+
const {header,
|
|
90
|
+
headerTopContent:HeaderTopContent,
|
|
91
|
+
containerProps : customContainerProps,
|
|
92
|
+
contentProp,
|
|
93
|
+
withScrollView:customWithScrollView,children,initialize,contentTop,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,mutateData,beforeSubmit:beforeSubmitForm,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
|
|
90
94
|
...state,
|
|
91
95
|
setState,
|
|
92
96
|
state,
|
|
@@ -101,6 +105,8 @@ export default function LoginComponent(props){
|
|
|
101
105
|
ProviderSelector,
|
|
102
106
|
previousButtonRef,
|
|
103
107
|
}));
|
|
108
|
+
const containerProps = defaultObj(customContainerProps);
|
|
109
|
+
|
|
104
110
|
React.useEffect(()=>{
|
|
105
111
|
Preloader.closeAll();
|
|
106
112
|
/*** pour initializer les cordonnées du composant login */
|
|
@@ -191,13 +197,22 @@ export default function LoginComponent(props){
|
|
|
191
197
|
});
|
|
192
198
|
const withScrollView = typeof customWithScrollView =='boolean'? customWithScrollView : true;
|
|
193
199
|
const Wrapper = withPortal ? ScreenWithoutAuthContainer : withScrollView ? ScrollView: View;
|
|
200
|
+
const mQueryUpdateProps = (a)=>{
|
|
201
|
+
const style = StyleSheet.flatten([updateMediaQueryStyle(),containerProps.style]);
|
|
202
|
+
if(typeof containerProps.updateMediaQueryStyle =='function'){
|
|
203
|
+
return containerProps.updateMediaQueryStyle({style})
|
|
204
|
+
}
|
|
205
|
+
return {style};
|
|
206
|
+
};
|
|
194
207
|
const wrapperProps = withPortal ? {appBarProps,authRequired:false,title:loginTitle,withScrollView} : { style:styles.wrapper};
|
|
208
|
+
const sH = React.isComponent(HeaderTopContent)? <HeaderTopContent
|
|
209
|
+
mediaQueryUpdateNativeProps = {mQueryUpdateProps}
|
|
210
|
+
/> : React.isValidElement(HeaderTopContent)? HeaderTopContent : null;
|
|
195
211
|
return <Wrapper testID = {testID+"_Wrapper" }{...wrapperProps}>
|
|
196
212
|
<DialogProvider ref={dialogProviderRef}/>
|
|
213
|
+
{sH}
|
|
197
214
|
<Surface style={[styles.container,{backgroundColor}]} testID={testID}>
|
|
198
|
-
<Surface elevation = {0} mediaQueryUpdateNativeProps = {(
|
|
199
|
-
return {style:updateMediaQueryStyle()}
|
|
200
|
-
}} testID={testID+"_Content"} style={[styles.content,updateMediaQueryStyle(),{backgroundColor}]}>
|
|
215
|
+
<Surface elevation = {0} {...containerProps} mediaQueryUpdateNativeProps = {mQueryUpdateProps} {...containerProps} testID={testID+"_Content"} style={[styles.content,updateMediaQueryStyle(),{backgroundColor},containerProps.style]}>
|
|
201
216
|
<FormData
|
|
202
217
|
formName = {formName}
|
|
203
218
|
testID = {testID+"_FormData"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
///@see : https://github.com/vivaxy/react-native-auto-height-image
|
|
2
|
-
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
+
import React, { useEffect, useState, useRef } from '$react';
|
|
3
3
|
import ImagePolyfill from './ImagePolyfill';
|
|
4
4
|
import AnimatableImage from './AnimatableImage';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
@@ -22,6 +22,7 @@ function AutoHeightImage(props) {
|
|
|
22
22
|
maxHeight,
|
|
23
23
|
onError,
|
|
24
24
|
testID:cTestID,
|
|
25
|
+
preloader,
|
|
25
26
|
...rest
|
|
26
27
|
} = props;
|
|
27
28
|
const [height, setHeight] = useState(
|
|
@@ -29,14 +30,14 @@ function AutoHeightImage(props) {
|
|
|
29
30
|
DEFAULT_HEIGHT
|
|
30
31
|
);
|
|
31
32
|
const mountedRef = useRef(false);
|
|
32
|
-
|
|
33
|
-
useEffect(function () {
|
|
33
|
+
const toolgeMounted = function () {
|
|
34
34
|
mountedRef.current = true;
|
|
35
35
|
return function () {
|
|
36
36
|
mountedRef.current = false;
|
|
37
37
|
};
|
|
38
|
-
}
|
|
39
|
-
|
|
38
|
+
}
|
|
39
|
+
useEffect(toolgeMounted,[])
|
|
40
|
+
React.useOnRender(toolgeMounted,0);
|
|
40
41
|
useEffect(
|
|
41
42
|
function () {
|
|
42
43
|
(async function () {
|
|
@@ -75,7 +76,7 @@ function AutoHeightImage(props) {
|
|
|
75
76
|
onError={onError}
|
|
76
77
|
{...rest}
|
|
77
78
|
/>
|
|
78
|
-
{!mountedRef.current ? <ActivityIndicator testID={testID+"_ActivityIndicator"} color={theme.colors.primary}/> : null}
|
|
79
|
+
{!mountedRef.current && preloader !== false && (!width || !height) ? <ActivityIndicator testID={testID+"_ActivityIndicator"} color={theme.colors.primary}/> : null}
|
|
79
80
|
</View>
|
|
80
81
|
);
|
|
81
82
|
}
|
|
@@ -85,13 +86,15 @@ AutoHeightImage.propTypes = {
|
|
|
85
86
|
width: PropTypes.number.isRequired,
|
|
86
87
|
maxHeight: PropTypes.number,
|
|
87
88
|
onHeightChange: PropTypes.func,
|
|
88
|
-
animated: PropTypes.bool
|
|
89
|
+
animated: PropTypes.bool,
|
|
90
|
+
preloader : PropTypes.bool,//si l'on affichera le preloader
|
|
89
91
|
};
|
|
90
92
|
|
|
91
93
|
AutoHeightImage.defaultProps = {
|
|
92
94
|
maxHeight: Infinity,
|
|
93
95
|
onHeightChange: NOOP,
|
|
94
|
-
animated: false
|
|
96
|
+
animated: false,
|
|
97
|
+
preloader : true,
|
|
95
98
|
};
|
|
96
99
|
|
|
97
100
|
export default AutoHeightImage;
|
|
@@ -72,7 +72,7 @@ export default function ImageComponent(props){
|
|
|
72
72
|
drawProps = defaultObj(drawProps);
|
|
73
73
|
const flattenStyle = StyleSheet.flatten(props.style) || {};
|
|
74
74
|
defaultSrc = defaultVal(defaultSrc);
|
|
75
|
-
editable = defaultBool(editable,
|
|
75
|
+
editable = defaultBool(editable,false);
|
|
76
76
|
if(disabled){
|
|
77
77
|
editable = false;
|
|
78
78
|
}
|