@fto-consult/expo-ui 7.5.16 → 7.5.18
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 +2 -2
- package/electron/create-index-file.js +5 -2
- package/electron/index.js +34 -545
- package/electron/main-app/index.js +567 -0
- package/electron/pload.js +2 -2
- package/electron/preload.js +4 -4
- package/package.json +1 -1
- package/electron/init/index.js +0 -0
package/bin/index.js
CHANGED
@@ -102,7 +102,6 @@ program.command('electron')
|
|
102
102
|
pathsJSON
|
103
103
|
});
|
104
104
|
}
|
105
|
-
require("../electron/create-index-file")(electronProjectRoot);
|
106
105
|
const outDir = out && path.dirname(out) && path.resolve(path.dirname(out),"electron") || path.resolve(electronProjectRoot,"bin")
|
107
106
|
if(!createDir(outDir)){
|
108
107
|
throwError("Impossible de créer le répertoire <<"+outDir+">> du fichier binaire!!");
|
@@ -123,9 +122,10 @@ program.command('electron')
|
|
123
122
|
const packageObj = require(`${packagePath}`);
|
124
123
|
const homepage = packageObj.homepage;
|
125
124
|
let cmd = undefined;
|
125
|
+
require("../electron/create-index-file")({electronProjectRoot,appName:packageObj.name});
|
126
126
|
const start = x=>{
|
127
127
|
return new Promise((resolve,reject)=>{
|
128
|
-
cmd = `electron "${electronProjectRoot}" --root ${
|
128
|
+
cmd = `electron "${electronProjectRoot}" --root ${electronProjectRoot} ${isValidUrl(url)? ` --url ${url}`:''}`;
|
129
129
|
exec({
|
130
130
|
cmd,
|
131
131
|
projectRoot : electronProjectRoot,
|
@@ -7,7 +7,10 @@ module.exports = (electronProjectRoot)=>{
|
|
7
7
|
if(!electronProjectRoot || typeof electronProjectRoot !='string' || !fs.existsSync(electronProjectRoot)){
|
8
8
|
return null;
|
9
9
|
}
|
10
|
-
const indexPath = path.resolve(electronProjectRoot,"index.js");
|
11
|
-
writeFile(indexPath,`module.exports = require("${packageJSON.name}/electron/index.js")
|
10
|
+
const indexPath = path.resolve({electronProjectRoot,packageJSON,appName},"index.js");
|
11
|
+
writeFile(indexPath,`module.exports = require("${packageJSON.name}/electron/index.js")({
|
12
|
+
projectRoot : "${electronProjectRoot}",
|
13
|
+
appName : "${appName}"
|
14
|
+
})`);
|
12
15
|
return indexPath;
|
13
16
|
}
|
package/electron/index.js
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
const {app, BrowserWindow,Tray,Menu,MenuItem,globalShortcut,systemPreferences,powerMonitor,ipcMain,dialog, nativeTheme} = require('electron')
|
2
|
-
const session = require("./utils/session");
|
3
|
-
const path = require("path");
|
4
|
-
const fs = require("fs");
|
5
1
|
const { program } = require('commander');
|
2
|
+
const mainApp = require("./main-app");
|
6
3
|
|
7
4
|
program
|
8
5
|
.option('-u, --url <url>', 'L\'adresse url à ouvrir au lancement de l\'application')
|
@@ -11,559 +8,51 @@ program
|
|
11
8
|
.parse();
|
12
9
|
|
13
10
|
const programOptions = program.opts();
|
14
|
-
const {url:pUrl,root:mainProjectRoot} = programOptions
|
11
|
+
const {url:pUrl,root:mainProjectRoot} = programOptions;
|
15
12
|
|
16
13
|
const isAsar = (typeof require.main =="string" && require.main ||"").indexOf('app.asar') !== -1;
|
17
|
-
const
|
18
|
-
const
|
19
|
-
const
|
20
|
-
const isValidUrl = require("./utils/isValidUrl");
|
21
|
-
const packageJSON = fs.existsSync(packageJSONPath) ? require(`${packageJSONPath}`) : {};
|
22
|
-
const indexFilePath = path.resolve(path.join(electronProjectRoot,"dist",'index.html'));
|
23
|
-
const mainProcessPath = path.resolve('processes',"main","index.js");
|
24
|
-
const mainProcessIndex = electronProjectRoot && fs.existsSync(path.resolve(electronProjectRoot,mainProcessPath)) && path.resolve(electronProjectRoot,mainProcessPath);
|
25
|
-
const mainProcessRequired = mainProcessIndex && require(`${mainProcessIndex}`);
|
26
|
-
//pour étendre les fonctionnalités au niveau du main proceess, bien vouloir écrire dans le fichier projectRoot/electron/main/index.js
|
27
|
-
const mainProcess = mainProcessRequired && typeof mainProcessRequired =='object'? mainProcessRequired : {};
|
28
|
-
// Gardez une reference globale de l'objet window, si vous ne le faites pas, la fenetre sera
|
29
|
-
// fermee automatiquement quand l'objet JavaScript sera garbage collected.
|
30
|
-
let win = undefined;
|
31
|
-
Menu.setApplicationMenu(null);
|
14
|
+
const path = require("path");
|
15
|
+
const fs = require("fs");
|
16
|
+
const isValidUrl = require("../utils/isValidUrl");
|
32
17
|
|
33
|
-
|
34
|
-
|
35
|
-
|
18
|
+
const distPath = path.join("dist",'index.html');
|
19
|
+
const processCWD = process.cwd();
|
20
|
+
const electronProjectRoot = mainProjectRoot && fs.existsSync(mainProjectRoot) && fs.existsSync(path.resolve(mainProjectRoot,distPath)) ? mainProjectRoot : null;
|
21
|
+
const projectRoot = electronProjectRoot || fs.existsSync(path.resolve(processCWD,"electron")) && fs.existsSync(path.resolve(processCWD,"electron",distPath)) ? fs.existsSync(path.resolve(processCWD,"electron")) : undefined;
|
22
|
+
const packageJSONPath = fs.existsSync(processCWD,"package.json")? path.resolve(processCWD,"package.json") : path.resolve(projectRoot,"package.json");
|
23
|
+
const packageJSON = fs.existsSync(packageJSONPath) ? require(`${packageJSONPath}`) : {};
|
36
24
|
|
37
|
-
const
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
menu.append(new MenuItem({ label: 'Copier', role: 'copy' }));
|
42
|
-
if(props.isEditable){
|
43
|
-
menu.append(new MenuItem({ label: 'Couper', role: 'cut' }));
|
44
|
-
}
|
45
|
-
}
|
46
|
-
if(props.isEditable){
|
47
|
-
menu.append(new MenuItem({ label: 'Coller', role: 'paste' }));
|
25
|
+
const ObjectSize = (object)=>{
|
26
|
+
if(!object || typeof object !=='object' || Array.isArray(object)) return false;
|
27
|
+
for(let i in object){
|
28
|
+
if(object?.hasOwnProperty(i)) return true;
|
48
29
|
}
|
49
|
-
|
50
|
-
}
|
51
|
-
};
|
52
|
-
const log = (message)=>{
|
53
|
-
return win != null && win && win.webContents.send("console.log",message);
|
30
|
+
return false;
|
54
31
|
}
|
55
32
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
let menu = options.menu;
|
63
|
-
options.webPreferences = isObj(options.webPreferences)? options.webPreferences : {};
|
64
|
-
options.webPreferences = {
|
65
|
-
sandbox: false,
|
66
|
-
webSecurity : true,
|
67
|
-
plugin:false,
|
68
|
-
autoHideMenuBar: true,
|
69
|
-
contextIsolation: true,
|
70
|
-
contentSecurityPolicy: `
|
71
|
-
default-src 'none';
|
72
|
-
script-src 'self';
|
73
|
-
img-src 'self' data:;
|
74
|
-
style-src 'self';
|
75
|
-
font-src 'self';
|
76
|
-
`,
|
77
|
-
...options.webPreferences,
|
78
|
-
devTools: typeof options.webPreferences.devTools === 'boolean'? options.webPreferences.devTools : false,
|
79
|
-
allowRunningInsecureContent: false,
|
80
|
-
nodeIntegration: false,
|
81
|
-
preload: options.preload ? options.preload : null,
|
82
|
-
}
|
83
|
-
if(options.modal && !options.parent && win){
|
84
|
-
options.parent = win;
|
85
|
-
}
|
86
|
-
if(typeof options.show ==='undefined'){
|
87
|
-
options.show = false;
|
88
|
-
}
|
89
|
-
let showOnLoad = options.showOnLoad ===true ? true : undefined;
|
90
|
-
if(showOnLoad){
|
91
|
-
options.show = false;
|
92
|
-
}
|
93
|
-
if(typeof mainProcess.beforeCreateWindow =='function'){
|
94
|
-
const opts = Object.assign({},mainProcess.beforeCreateWindow(options));
|
95
|
-
options = {...options,...opts};
|
96
|
-
}
|
97
|
-
let _win = new BrowserWindow(options);
|
98
|
-
if(!menu){
|
99
|
-
_win.setMenu(null);
|
100
|
-
_win.removeMenu();
|
101
|
-
_win.setMenuBarVisibility(false)
|
102
|
-
_win.setAutoHideMenuBar(true)
|
103
|
-
}
|
104
|
-
const url = isValidUrl(options.loadURL) || typeof options.loadURL ==='string' && options.loadURL.trim().startsWith("file://") ? options.loadURL : undefined;
|
105
|
-
if(url){
|
106
|
-
_win.loadURL(url);
|
107
|
-
} else if(options.file && fs.existsSync(options.file)){
|
108
|
-
_win.loadFile(options.file);
|
109
|
-
}
|
110
|
-
if(showOnLoad){
|
111
|
-
_win.once('ready-to-show', () => {
|
112
|
-
_win.show();
|
113
|
-
_win.webContents.send("window-ready-to-show",JSON.stringify(options.readyToShowOptions));
|
114
|
-
});
|
115
|
-
}
|
116
|
-
_win.on('closed', function() {
|
117
|
-
if(isMainWindow && typeof mainProcess.onMainWindowClosed == "function"){
|
118
|
-
mainProcess.onMainWindowClosed(_win);
|
119
|
-
}
|
120
|
-
_win = null;
|
121
|
-
});
|
122
|
-
return _win;
|
123
|
-
}
|
124
|
-
function createWindow () {
|
125
|
-
// Créer le browser window
|
126
|
-
win = createBrowserWindow({
|
127
|
-
showOnLoad : false,
|
128
|
-
loadURL : undefined,
|
129
|
-
isMainWindow : true,
|
130
|
-
registerDevToolsCommand : false,
|
131
|
-
preload : path.resolve(__dirname,'preload.js'),
|
132
|
-
webPreferences : {
|
133
|
-
devTools : true,
|
134
|
-
}
|
135
|
-
});
|
136
|
-
|
137
|
-
const sOptions = {width: 500, height: 400, transparent: true, frame: false, alwaysOnTop: true};
|
138
|
-
const splash = typeof mainProcess.splashScreen ==='function'&& mainProcess.splashScreen(sOptions)
|
139
|
-
|| typeof mainProcess.splash ==='function' && mainProcess.splash(sOptions)
|
140
|
-
|| (mainProcess.splash instanceof BrowserWindow) && mainProcess.splash
|
141
|
-
|| (mainProcess.splashScreen instanceof BrowserWindow) && mainProcess.splashScreen;
|
142
|
-
null;
|
143
|
-
let hasInitWindows = false;
|
144
|
-
win.on('show', () => {
|
145
|
-
//win.blur();
|
146
|
-
setTimeout(() => {
|
147
|
-
win.focus();
|
148
|
-
win.moveTop();
|
149
|
-
win.webContents.focus();
|
150
|
-
if(!hasInitWindows){
|
151
|
-
hasInitWindows = true;
|
152
|
-
win.webContents.send('appReady');
|
153
|
-
}
|
154
|
-
}, 200);
|
155
|
-
});
|
156
|
-
|
157
|
-
win.on("focus",()=>{
|
158
|
-
if(win && hasInitWindows){
|
159
|
-
win.webContents.send("main-window-focus");
|
160
|
-
}
|
161
|
-
});
|
162
|
-
win.on("blur",()=>{
|
163
|
-
if(win && hasInitWindows){
|
164
|
-
win.webContents.send("main-window-blur");
|
33
|
+
function mainExportedApp (options){
|
34
|
+
options = Object.assign({},options);
|
35
|
+
options.isAsar = isAsar;
|
36
|
+
options.url = isValidUrl(options.url)? options.url : isValidUrl(pUrl)? pUrl : undefined;
|
37
|
+
if(!options.projectRoot || typeof options.projectRoot !=='string' || !fs.existsSync(options.projectRoot) || !fs.existsSync(path.resolve(options.projectRoot,distPath))){
|
38
|
+
options.projectRoot = projectRoot;
|
165
39
|
}
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
mainProcess.onMainWindowReadyToShow(win);
|
171
|
-
}
|
172
|
-
win.minimize()
|
173
|
-
try {
|
174
|
-
if(splash && splash instanceof BrowserWindow){
|
175
|
-
splash.destroy();
|
40
|
+
options.packageJSON = ObjectSize(options.packageJSON) && options.packageJSON || packageJSON;
|
41
|
+
if(!ObjectSize(options.packageJSON)){
|
42
|
+
if(options.projectRoot && fs.existsSync(path.resolve(options.projectRoot,"package.json"))){
|
43
|
+
options.packageJSON = require(path.resolve(options.projectRoot,"package.json"));
|
176
44
|
}
|
177
|
-
} catch{ }
|
178
|
-
win.restore();
|
179
|
-
win.show();
|
180
|
-
//log(icon," is consooleeeee")
|
181
|
-
})
|
182
|
-
|
183
|
-
win.on('close', (e) => {
|
184
|
-
if (win) {
|
185
|
-
if(typeof mainProcess.onMainWindowClose == "function"){
|
186
|
-
mainProcess.onMainWindowClose(win);
|
187
|
-
}
|
188
|
-
e.preventDefault();
|
189
|
-
win.webContents.send('before-app-exit');
|
190
|
-
}
|
191
|
-
});
|
192
|
-
if(isValidUrl(pUrl)){
|
193
|
-
win.loadURL(pUrl);
|
194
|
-
} else {
|
195
|
-
win.loadFile(indexFilePath)
|
196
|
-
}
|
197
|
-
|
198
|
-
win.on('unresponsive', async () => {
|
199
|
-
const { response } = await dialog.showMessageBox({
|
200
|
-
title: "L'application a cessé de répondre",
|
201
|
-
message : 'Voulez vous relancer l\'application?',
|
202
|
-
buttons: ['Relancer', 'Arrêter'],
|
203
|
-
cancelId: 1
|
204
|
-
})
|
205
|
-
if (response === 0) {
|
206
|
-
win.forcefullyCrashRenderer()
|
207
|
-
win.reload()
|
208
|
-
} else {
|
209
|
-
win.forcefullyCrashRenderer()
|
210
|
-
app.exit();
|
211
|
-
}
|
212
|
-
})
|
213
|
-
|
214
|
-
// Ouvre les DevTools.
|
215
|
-
//win.webContents.openDevTools()
|
216
|
-
|
217
|
-
// Émit lorsque la fenêtre est fermée.
|
218
|
-
win.on('closed', () => {
|
219
|
-
win = null
|
220
|
-
})
|
221
|
-
win.webContents.on('context-menu',clipboadContextMenu);
|
222
|
-
win.setMenu(null);
|
223
|
-
|
224
|
-
/*** les dimenssions de la fenêtre principale */
|
225
|
-
let mWindowSessinName = "mainWindowSizes";
|
226
|
-
let mWindowPositionSName = mWindowSessinName+"-positions";
|
227
|
-
let sizeW = session.get(mWindowSessinName);
|
228
|
-
if(!sizeW || typeof sizeW !== 'object'){
|
229
|
-
sizeW = {};
|
230
|
-
}
|
231
|
-
let sPositions = session.get(mWindowPositionSName);
|
232
|
-
if(!sPositions || typeof sPositions !=='object'){
|
233
|
-
sPositions = {};
|
234
|
-
}
|
235
|
-
let isNumber = x => typeof x =="number";
|
236
|
-
if(isNumber(sizeW.width) && isNumber(sizeW.height)){
|
237
|
-
win.setSize(sizeW.width,sizeW.height);
|
238
|
-
if(isNumber(sPositions.x) && isNumber(sPositions.y)){
|
239
|
-
win.setPosition(sPositions.x,sPositions.y);
|
240
|
-
}
|
241
|
-
}
|
242
|
-
let onWinResizeEv = debounce(function () {
|
243
|
-
if(win){
|
244
|
-
let wSize = win.getSize();
|
245
|
-
if(Array.isArray(wSize) && wSize.length == 2){
|
246
|
-
let [width,height] = wSize;
|
247
|
-
if(width && height){
|
248
|
-
session.set(mWindowSessinName,{width,height});
|
249
|
-
}
|
250
|
-
let [x,y] = win.getPosition();
|
251
|
-
session.set(mWindowPositionSName,{x,y});
|
252
|
-
}
|
253
|
-
}
|
254
|
-
}, 100);
|
255
|
-
win.off('resize',onWinResizeEv);
|
256
|
-
win.on('resize',onWinResizeEv);
|
257
|
-
win.off('move',onWinResizeEv);
|
258
|
-
win.on('move',onWinResizeEv);
|
259
|
-
if(typeof mainProcess.onCreateMainWindow =='function'){
|
260
|
-
mainProcess.onCreateMainWindow(win);
|
261
|
-
}
|
262
|
-
return win;
|
263
|
-
}
|
264
|
-
|
265
|
-
const quit = ()=>{
|
266
|
-
try {
|
267
|
-
app.quit();
|
268
|
-
} catch(e){
|
269
|
-
console.log(e," triing kit app")
|
270
|
-
}
|
271
|
-
}
|
272
|
-
// Quitte l'application quand toutes les fenêtres sont fermées.
|
273
|
-
app.on('window-all-closed', () => {
|
274
|
-
// Sur macOS, il est commun pour une application et leur barre de menu
|
275
|
-
// de rester active tant que l'utilisateur ne quitte pas explicitement avec Cmd + Q
|
276
|
-
if (process.platform !== 'darwin') {
|
277
|
-
quit();
|
278
|
-
}
|
279
|
-
})
|
280
|
-
|
281
|
-
const toggleDevTools = (value,window)=>{
|
282
|
-
window = window instanceof BrowserWindow ? window : win;
|
283
|
-
if(window !==null && window.webContents){
|
284
|
-
const isOpen= window.webContents.isDevToolsOpened();
|
285
|
-
value = value === undefined ? !isOpen : value;
|
286
|
-
if(value && !isOpen){
|
287
|
-
window.webContents.openDevTools();
|
288
|
-
return window.webContents.isDevToolsOpened();
|
289
|
-
} else {
|
290
|
-
if(isOpen) window.webContents.closeDevTools();
|
291
45
|
}
|
292
|
-
|
293
|
-
|
294
|
-
|
46
|
+
options.appName = typeof options.appName =="string" && options.appName ||
|
47
|
+
typeof options.packageJSON?.realAppName =='string' && options?.packageJSON?.realAppName || typeof packageJSON?.realAppName =="string" && packageJSON?.realAppName ||
|
48
|
+
typeof option?.packageJSON?.name =="string" && options?.packageJSON?.name || typeof packageJSON.name =="string" && packageJSON.name || undefined;
|
49
|
+
return mainApp(options);
|
295
50
|
}
|
296
|
-
ipcMain.on("toggle-dev-tools",function(event,value) {
|
297
|
-
return toggleDevTools(value);
|
298
|
-
});
|
299
51
|
|
52
|
+
module.exports = mainExportedApp;
|
300
53
|
|
301
|
-
|
302
|
-
|
303
|
-
if(typeof mainProcess.whenAppReady =='function'){
|
304
|
-
mainProcess.whenAppReady(readOpts);
|
305
|
-
}
|
306
|
-
globalShortcut.register('CommandOrControl+F12', () => {
|
307
|
-
toggleDevTools();
|
308
|
-
});
|
309
|
-
}).then(()=>{
|
310
|
-
createWindow();
|
311
|
-
app.on('activate', function () {
|
312
|
-
if (win == null || (BrowserWindow.getAllWindows().length === 0)) createWindow()
|
313
|
-
});
|
314
|
-
})
|
315
|
-
|
316
|
-
ipcMain.on("restart-app",x =>{app.relaunch();})
|
317
|
-
let tray = null;
|
318
|
-
let isJSON = function (json_string){
|
319
|
-
if(!json_string || typeof json_string != 'string') return false;
|
320
|
-
var text = json_string;
|
321
|
-
return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g, '')));
|
54
|
+
if(isValidUrl(pUrl) || electronProjectRoot){
|
55
|
+
mainExportedApp({url:pUrl,projectRoot,packageJSON});
|
322
56
|
}
|
323
|
-
ipcMain.on("update-system-tray",(event,opts)=>{
|
324
|
-
opts = opts && typeof opts == 'object'? opts : {};
|
325
|
-
let {contextMenu,tooltip} = opts;
|
326
|
-
if(tray){
|
327
|
-
} else {
|
328
|
-
tray = new Tray();
|
329
|
-
}
|
330
|
-
if(!tooltip || typeof tooltip !=="string"){
|
331
|
-
tooltip = ""
|
332
|
-
}
|
333
|
-
tray.setToolTip(tooltip);
|
334
|
-
if(isJSON(contextMenu)){
|
335
|
-
contextMenu = JSON.parse(contextMenu);
|
336
|
-
}
|
337
|
-
if(Array.isArray(contextMenu) && contextMenu.length) {
|
338
|
-
let tpl = []
|
339
|
-
contextMenu.map((m,index)=>{
|
340
|
-
if(!m || typeof m !=='object') return;
|
341
|
-
m.click = (e)=>{
|
342
|
-
if(win && win.webContents) win.webContents.send("click-on-system-tray-menu-item",{
|
343
|
-
action : m.action && typeof m.action =='string'? m.action : undefined,
|
344
|
-
index,
|
345
|
-
menuItem : JSON.stringify(m),
|
346
|
-
})
|
347
|
-
}
|
348
|
-
tpl.push(m);
|
349
|
-
})
|
350
|
-
contextMenu = Menu.buildFromTemplate(tpl);
|
351
|
-
} else contextMenu = null;
|
352
|
-
tray.setContextMenu(contextMenu)
|
353
|
-
})
|
354
|
-
ipcMain.on("get-path",(event,pathName)=>{
|
355
|
-
const p = app.getPath(pathName);
|
356
|
-
event.returnValue = p;
|
357
|
-
return p;
|
358
|
-
});
|
359
|
-
|
360
|
-
ipcMain.on("get-project-root",(event)=>{
|
361
|
-
event.returnValue = projectRoot;
|
362
|
-
return projectRoot;
|
363
|
-
});
|
364
|
-
ipcMain.on("get-electron-project-root",(event)=>{
|
365
|
-
event.returnValue = electronProjectRoot;
|
366
|
-
return event.returnValue ;
|
367
|
-
});
|
368
|
-
|
369
|
-
ipcMain.on("get-package.json",(event)=>{
|
370
|
-
event.returnValue = JSON.stringify(packageJSON);
|
371
|
-
return event.returnValue ;
|
372
|
-
});
|
373
|
-
|
374
|
-
ipcMain.on("get-app-name",(event)=>{
|
375
|
-
event.returnValue = packageJSON.realAppName || packageJSON.name;
|
376
|
-
return event.returnValue ;
|
377
|
-
});
|
378
|
-
|
379
|
-
ipcMain.on("get-media-access-status",(event,mediaType)=>{
|
380
|
-
let p = systemPreferences.getMediaAccessStatus(mediaType);
|
381
|
-
event.returnValue = p;
|
382
|
-
return p;
|
383
|
-
});
|
384
|
-
|
385
|
-
ipcMain.on("ask-for-media-access",(event,mediaType)=>{
|
386
|
-
systemPreferences.askForMediaAccess(mediaType);
|
387
|
-
});
|
388
|
-
|
389
|
-
ipcMain.on("get-app-icon",(event)=>{
|
390
|
-
event.returnValue = win != win && win.getIcon && win.getIcon();
|
391
|
-
});
|
392
|
-
ipcMain.on("set-app-icon",(event,iconPath)=>{
|
393
|
-
if(iconPath && win != null){
|
394
|
-
win.setIcon(iconPath);
|
395
|
-
event.returnValue = iconPath;
|
396
|
-
} else {
|
397
|
-
event.returnValue = null;
|
398
|
-
}
|
399
|
-
});
|
400
|
-
|
401
|
-
ipcMain.on('minimize-main-window', () => {
|
402
|
-
if(win !== null && win){
|
403
|
-
win.blur();
|
404
|
-
win.minimize();
|
405
|
-
}
|
406
|
-
})
|
407
|
-
ipcMain.on('restore-main-window', () => {
|
408
|
-
if(win && win !== null){
|
409
|
-
win.restore()
|
410
|
-
win.blur();
|
411
|
-
setTimeout(() => {
|
412
|
-
win.focus();
|
413
|
-
win.moveTop();
|
414
|
-
win.webContents.focus();
|
415
|
-
}, 200);
|
416
|
-
}
|
417
|
-
})
|
418
|
-
ipcMain.on('close-main-render-process', _ => {
|
419
|
-
if(win){
|
420
|
-
win.destroy();
|
421
|
-
}
|
422
|
-
win = null;
|
423
|
-
if(typeof gc =="function"){
|
424
|
-
gc();
|
425
|
-
}
|
426
|
-
quit();
|
427
|
-
});
|
428
|
-
|
429
|
-
|
430
|
-
function debounce(func, wait, immediate) {
|
431
|
-
var timeout;
|
432
|
-
|
433
|
-
return function executedFunction(...args) {
|
434
|
-
var context = this;
|
435
|
-
|
436
|
-
var later = function() {
|
437
|
-
timeout = null;
|
438
|
-
if (!immediate) func.apply(context, args);
|
439
|
-
};
|
440
|
-
|
441
|
-
var callNow = immediate && !timeout;
|
442
|
-
|
443
|
-
clearTimeout(timeout);
|
444
|
-
|
445
|
-
timeout = setTimeout(later, wait);
|
446
|
-
|
447
|
-
if (callNow) func.apply(context, args);
|
448
|
-
};
|
449
|
-
};
|
450
|
-
//app.disableHardwareAcceleration();
|
451
|
-
|
452
|
-
|
453
|
-
const gotTheLock = app.requestSingleInstanceLock()
|
454
|
-
|
455
|
-
if (!gotTheLock) {
|
456
|
-
quit()
|
457
|
-
} else {
|
458
|
-
app.on('second-instance', (event, commandLine, workingDirectory) => {
|
459
|
-
// Someone tried to run a second instance, we should focus our window.
|
460
|
-
//pour plus tard il sera possible d'afficher la gestion multi fenêtre en environnement electron
|
461
|
-
if (win) {
|
462
|
-
if (win.isMinimized()) win.restore()
|
463
|
-
win.focus()
|
464
|
-
}
|
465
|
-
})
|
466
|
-
}
|
467
|
-
|
468
|
-
const powerMonitorCallbackEvent = (action)=>{
|
469
|
-
if(!win || !win.webContents) return;
|
470
|
-
if(action =="suspend" || action =="lock-screen"){
|
471
|
-
win.webContents.send("main-app-suspended",action);
|
472
|
-
return;
|
473
|
-
}
|
474
|
-
win.webContents.send("main-app-restaured",action);
|
475
|
-
win.webContents.focus();
|
476
|
-
return null;
|
477
|
-
}
|
478
|
-
if(powerMonitor){
|
479
|
-
["suspend","resume","lock-screen","unlock-screen"].map((action)=>{
|
480
|
-
powerMonitor.on(action,(event)=>{
|
481
|
-
powerMonitorCallbackEvent(action,event);
|
482
|
-
})
|
483
|
-
})
|
484
|
-
}
|
485
|
-
ipcMain.on("set-main-window-title",(event,title)=>{
|
486
|
-
if(win !== null){
|
487
|
-
win.setTitle(title);
|
488
|
-
}
|
489
|
-
})
|
490
|
-
|
491
|
-
|
492
|
-
ipcMain.handle("create-browser-windows",function(event,options){
|
493
|
-
if(typeof options =='string'){
|
494
|
-
try {
|
495
|
-
const t = JSON.parse(options);
|
496
|
-
options = t;
|
497
|
-
} catch{}
|
498
|
-
}
|
499
|
-
options = Object.assign({},options);
|
500
|
-
createBrowserWindow(options);
|
501
|
-
})
|
502
|
-
|
503
|
-
ipcMain.handle("show-open-dialog",function(event,options){
|
504
|
-
if(!isObj(options)){
|
505
|
-
options = {};
|
506
|
-
}
|
507
|
-
return dialog.showOpenDialog(win,options)
|
508
|
-
})
|
509
|
-
|
510
|
-
ipcMain.handle("show-save-dialog",function(event,options){
|
511
|
-
if(!isObj(options)){
|
512
|
-
options = {};
|
513
|
-
}
|
514
|
-
return dialog.showSaveDialog(win,options)
|
515
|
-
})
|
516
|
-
ipcMain.on("is-dev-tools-open",function(event,value) {
|
517
|
-
if(win !==null && win.webContents){
|
518
|
-
return win.webContents.isDevToolsOpened();
|
519
|
-
}
|
520
|
-
return false;
|
521
|
-
});
|
522
|
-
|
523
|
-
|
524
|
-
ipcMain.on("window-set-progressbar",(event,interval)=>{
|
525
|
-
if(typeof interval !="number" || interval <0) interval = 0;
|
526
|
-
interval = Math.floor(interval);
|
527
|
-
if(win){
|
528
|
-
win.setProgressBar(interval);
|
529
|
-
}
|
530
|
-
})
|
531
|
-
|
532
|
-
const setOSTheme = (theme) => {
|
533
|
-
theme = theme && typeof theme == "string"? theme : "light";
|
534
|
-
theme = theme.toLowerCase().trim();
|
535
|
-
if(theme !== 'system' && theme !=='dark'){
|
536
|
-
theme = "light";
|
537
|
-
}
|
538
|
-
nativeTheme.themeSource = theme;
|
539
|
-
session.set("os-theme",theme);
|
540
|
-
return nativeTheme.shouldUseDarkColors
|
541
|
-
}
|
542
|
-
|
543
|
-
/**** customisation des thèmes de l'application */
|
544
|
-
ipcMain.handle('set-system-theme:toggle', (event,theme) => {
|
545
|
-
return setOSTheme(theme);
|
546
|
-
});
|
547
|
-
|
548
|
-
ipcMain.handle('set-system-theme:dark-mode', (event) => {
|
549
|
-
nativeTheme.themeSource = 'dark';
|
550
|
-
return nativeTheme.shouldUseDarkColors;
|
551
|
-
});
|
552
|
-
ipcMain.handle('set-system-theme:light-mode', (event) => {
|
553
|
-
nativeTheme.themeSource = 'light';
|
554
|
-
return nativeTheme.shouldUseDarkColors;
|
555
|
-
});
|
556
|
-
|
557
|
-
|
558
|
-
ipcMain.handle('dark-mode:toggle', () => {
|
559
|
-
if (nativeTheme.shouldUseDarkColors) {
|
560
|
-
nativeTheme.themeSource = 'light'
|
561
|
-
} else {
|
562
|
-
nativeTheme.themeSource = 'dark'
|
563
|
-
}
|
564
|
-
return nativeTheme.shouldUseDarkColors
|
565
|
-
})
|
566
57
|
|
567
|
-
|
568
|
-
nativeTheme.themeSource = 'system'
|
569
|
-
});
|
58
|
+
module.exports.createBrowserWindow = mainApp.createBrowserWindow;
|
@@ -0,0 +1,567 @@
|
|
1
|
+
const {app, BrowserWindow,Tray,Menu,MenuItem,globalShortcut,systemPreferences,powerMonitor,ipcMain,dialog, nativeTheme} = require('electron')
|
2
|
+
const session = require("../utils/session");
|
3
|
+
const path = require("path");
|
4
|
+
const fs = require("fs");
|
5
|
+
const isValidUrl = require("../utils/isValidUrl");
|
6
|
+
|
7
|
+
const log = (message)=>{
|
8
|
+
return win != null && win && win.webContents.send("console.log",message);
|
9
|
+
}
|
10
|
+
|
11
|
+
const isObj = x => x && typeof x =='object';
|
12
|
+
|
13
|
+
const mainProcessRef = {current:{}};
|
14
|
+
|
15
|
+
module.exports = function(mainOptions){
|
16
|
+
mainOptions = Object.assign({},mainOptions);
|
17
|
+
let {packageJSON,projectRoot,appName,url:pUrl} = mainOptions;
|
18
|
+
packageJSON = Object.assign({},packageJSON);
|
19
|
+
// fermee automatiquement quand l'objet JavaScript sera garbage collected.
|
20
|
+
let win = undefined;
|
21
|
+
Menu.setApplicationMenu(null);
|
22
|
+
|
23
|
+
appName = typeof appName == "string" && appName || typeof packageJSON.realAppName =="string" && packageJSON.realAppName || typeof packageJSON.name =="string" && packageJSON.name || "";
|
24
|
+
const indexFilePath = path.resolve(path.join(projectRoot,"dist",'index.html'));
|
25
|
+
const mainProcessPath = path.resolve('processes',"main","index.js");
|
26
|
+
const mainProcessIndex = projectRoot && fs.existsSync(path.resolve(projectRoot,mainProcessPath)) && path.resolve(projectRoot,mainProcessPath);
|
27
|
+
const mainProcessRequired = mainProcessIndex && require(`${mainProcessIndex}`);
|
28
|
+
//pour étendre les fonctionnalités au niveau du main proceess, bien vouloir écrire dans le fichier projectRoot/electron/main/index.js
|
29
|
+
const mainProcess = mainProcessRequired && typeof mainProcessRequired =='object'? mainProcessRequired : {};
|
30
|
+
mainProcessRef.current = mainProcess;
|
31
|
+
// Gardez une reference globale de l'objet window, si vous ne le faites pas, la fenetre sera
|
32
|
+
|
33
|
+
if(!isValidUrl(pUrl) && !fs.existsSync(indexFilePath)){
|
34
|
+
throw `Unable to start the application: index file located at [${indexFilePath}] does not exists : projectRoot = [${projectRoot}], isAsar:[${require.main}]`
|
35
|
+
}
|
36
|
+
|
37
|
+
const clipboadContextMenu = (_, props) => {
|
38
|
+
if (props.isEditable || props.selectionText) {
|
39
|
+
const menu = new Menu();
|
40
|
+
if(props.selectionText){
|
41
|
+
menu.append(new MenuItem({ label: 'Copier', role: 'copy' }));
|
42
|
+
if(props.isEditable){
|
43
|
+
menu.append(new MenuItem({ label: 'Couper', role: 'cut' }));
|
44
|
+
}
|
45
|
+
}
|
46
|
+
if(props.isEditable){
|
47
|
+
menu.append(new MenuItem({ label: 'Coller', role: 'paste' }));
|
48
|
+
}
|
49
|
+
menu.popup();
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
const quit = ()=>{
|
54
|
+
try {
|
55
|
+
app.quit();
|
56
|
+
} catch(e){
|
57
|
+
console.log(e," triing kit app")
|
58
|
+
}
|
59
|
+
}
|
60
|
+
// Quitte l'application quand toutes les fenêtres sont fermées.
|
61
|
+
app.on('window-all-closed', () => {
|
62
|
+
// Sur macOS, il est commun pour une application et leur barre de menu
|
63
|
+
// de rester active tant que l'utilisateur ne quitte pas explicitement avec Cmd + Q
|
64
|
+
if (process.platform !== 'darwin') {
|
65
|
+
quit();
|
66
|
+
}
|
67
|
+
})
|
68
|
+
|
69
|
+
const toggleDevTools = (value,window)=>{
|
70
|
+
window = window instanceof BrowserWindow ? window : win;
|
71
|
+
if(window !==null && window.webContents){
|
72
|
+
const isOpen= window.webContents.isDevToolsOpened();
|
73
|
+
value = value === undefined ? !isOpen : value;
|
74
|
+
if(value && !isOpen){
|
75
|
+
window.webContents.openDevTools();
|
76
|
+
return window.webContents.isDevToolsOpened();
|
77
|
+
} else {
|
78
|
+
if(isOpen) window.webContents.closeDevTools();
|
79
|
+
}
|
80
|
+
return window.webContents.isDevToolsOpened();
|
81
|
+
}
|
82
|
+
return false;
|
83
|
+
}
|
84
|
+
ipcMain.on("toggle-dev-tools",function(event,value) {
|
85
|
+
return toggleDevTools(value);
|
86
|
+
});
|
87
|
+
|
88
|
+
|
89
|
+
app.whenReady().then(() => {
|
90
|
+
const readOpts = {toggleDevTools,browserWindow:win,mainWindow:win};
|
91
|
+
if(typeof mainProcess.whenAppReady =='function'){
|
92
|
+
mainProcess.whenAppReady(readOpts);
|
93
|
+
}
|
94
|
+
globalShortcut.register('CommandOrControl+F12', () => {
|
95
|
+
toggleDevTools();
|
96
|
+
});
|
97
|
+
}).then(()=>{
|
98
|
+
createWindow();
|
99
|
+
app.on('activate', function () {
|
100
|
+
if (win == null || (BrowserWindow.getAllWindows().length === 0)) createWindow()
|
101
|
+
});
|
102
|
+
})
|
103
|
+
|
104
|
+
ipcMain.on("restart-app",x =>{app.relaunch();})
|
105
|
+
let tray = null;
|
106
|
+
let isJSON = function (json_string){
|
107
|
+
if(!json_string || typeof json_string != 'string') return false;
|
108
|
+
var text = json_string;
|
109
|
+
return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(text.replace(/"(\\.|[^"\\])*"/g, '')));
|
110
|
+
}
|
111
|
+
ipcMain.on("update-system-tray",(event,opts)=>{
|
112
|
+
opts = opts && typeof opts == 'object'? opts : {};
|
113
|
+
let {contextMenu,tooltip} = opts;
|
114
|
+
if(tray){
|
115
|
+
} else {
|
116
|
+
tray = new Tray();
|
117
|
+
}
|
118
|
+
if(!tooltip || typeof tooltip !=="string"){
|
119
|
+
tooltip = ""
|
120
|
+
}
|
121
|
+
tray.setToolTip(tooltip);
|
122
|
+
if(isJSON(contextMenu)){
|
123
|
+
contextMenu = JSON.parse(contextMenu);
|
124
|
+
}
|
125
|
+
if(Array.isArray(contextMenu) && contextMenu.length) {
|
126
|
+
let tpl = []
|
127
|
+
contextMenu.map((m,index)=>{
|
128
|
+
if(!m || typeof m !=='object') return;
|
129
|
+
m.click = (e)=>{
|
130
|
+
if(win && win.webContents) win.webContents.send("click-on-system-tray-menu-item",{
|
131
|
+
action : m.action && typeof m.action =='string'? m.action : undefined,
|
132
|
+
index,
|
133
|
+
menuItem : JSON.stringify(m),
|
134
|
+
})
|
135
|
+
}
|
136
|
+
tpl.push(m);
|
137
|
+
})
|
138
|
+
contextMenu = Menu.buildFromTemplate(tpl);
|
139
|
+
} else contextMenu = null;
|
140
|
+
tray.setContextMenu(contextMenu)
|
141
|
+
})
|
142
|
+
ipcMain.on("get-path",(event,pathName)=>{
|
143
|
+
const p = app.getPath(pathName);
|
144
|
+
event.returnValue = p;
|
145
|
+
return p;
|
146
|
+
});
|
147
|
+
|
148
|
+
ipcMain.on("get-project-root",(event)=>{
|
149
|
+
event.returnValue = projectRoot;
|
150
|
+
return event.returnValue;
|
151
|
+
});
|
152
|
+
ipcMain.on("get-electron-project-root",(event)=>{
|
153
|
+
event.returnValue = projectRoot;
|
154
|
+
return event.returnValue ;
|
155
|
+
});
|
156
|
+
|
157
|
+
ipcMain.on("get-package.json",(event)=>{
|
158
|
+
event.returnValue = JSON.stringify(packageJSON);
|
159
|
+
return event.returnValue ;
|
160
|
+
});
|
161
|
+
|
162
|
+
ipcMain.on("get-app-name",(event)=>{
|
163
|
+
event.returnValue = appName;
|
164
|
+
return event.returnValue ;
|
165
|
+
});
|
166
|
+
|
167
|
+
ipcMain.on("get-media-access-status",(event,mediaType)=>{
|
168
|
+
let p = systemPreferences.getMediaAccessStatus(mediaType);
|
169
|
+
event.returnValue = p;
|
170
|
+
return p;
|
171
|
+
});
|
172
|
+
|
173
|
+
ipcMain.on("ask-for-media-access",(event,mediaType)=>{
|
174
|
+
systemPreferences.askForMediaAccess(mediaType);
|
175
|
+
});
|
176
|
+
|
177
|
+
ipcMain.on("get-app-icon",(event)=>{
|
178
|
+
event.returnValue = win != win && win.getIcon && win.getIcon();
|
179
|
+
});
|
180
|
+
ipcMain.on("set-app-icon",(event,iconPath)=>{
|
181
|
+
if(iconPath && win != null){
|
182
|
+
win.setIcon(iconPath);
|
183
|
+
event.returnValue = iconPath;
|
184
|
+
} else {
|
185
|
+
event.returnValue = null;
|
186
|
+
}
|
187
|
+
});
|
188
|
+
|
189
|
+
ipcMain.on('minimize-main-window', () => {
|
190
|
+
if(win !== null && win){
|
191
|
+
win.blur();
|
192
|
+
win.minimize();
|
193
|
+
}
|
194
|
+
})
|
195
|
+
ipcMain.on('restore-main-window', () => {
|
196
|
+
if(win && win !== null){
|
197
|
+
win.restore()
|
198
|
+
win.blur();
|
199
|
+
setTimeout(() => {
|
200
|
+
win.focus();
|
201
|
+
win.moveTop();
|
202
|
+
win.webContents.focus();
|
203
|
+
}, 200);
|
204
|
+
}
|
205
|
+
})
|
206
|
+
ipcMain.on('close-main-render-process', _ => {
|
207
|
+
if(win){
|
208
|
+
win.destroy();
|
209
|
+
}
|
210
|
+
win = null;
|
211
|
+
if(typeof gc =="function"){
|
212
|
+
gc();
|
213
|
+
}
|
214
|
+
quit();
|
215
|
+
});
|
216
|
+
|
217
|
+
|
218
|
+
function debounce(func, wait, immediate) {
|
219
|
+
var timeout;
|
220
|
+
|
221
|
+
return function executedFunction(...args) {
|
222
|
+
var context = this;
|
223
|
+
|
224
|
+
var later = function() {
|
225
|
+
timeout = null;
|
226
|
+
if (!immediate) func.apply(context, args);
|
227
|
+
};
|
228
|
+
|
229
|
+
var callNow = immediate && !timeout;
|
230
|
+
|
231
|
+
clearTimeout(timeout);
|
232
|
+
|
233
|
+
timeout = setTimeout(later, wait);
|
234
|
+
|
235
|
+
if (callNow) func.apply(context, args);
|
236
|
+
};
|
237
|
+
};
|
238
|
+
//app.disableHardwareAcceleration();
|
239
|
+
|
240
|
+
|
241
|
+
const gotTheLock = app.requestSingleInstanceLock()
|
242
|
+
|
243
|
+
if (!gotTheLock) {
|
244
|
+
quit()
|
245
|
+
} else {
|
246
|
+
app.on('second-instance', (event, commandLine, workingDirectory) => {
|
247
|
+
// Someone tried to run a second instance, we should focus our window.
|
248
|
+
//pour plus tard il sera possible d'afficher la gestion multi fenêtre en environnement electron
|
249
|
+
if (win) {
|
250
|
+
if (win.isMinimized()) win.restore()
|
251
|
+
win.focus()
|
252
|
+
}
|
253
|
+
})
|
254
|
+
}
|
255
|
+
|
256
|
+
const powerMonitorCallbackEvent = (action)=>{
|
257
|
+
if(!win || !win.webContents) return;
|
258
|
+
if(action =="suspend" || action =="lock-screen"){
|
259
|
+
win.webContents.send("main-app-suspended",action);
|
260
|
+
return;
|
261
|
+
}
|
262
|
+
win.webContents.send("main-app-restaured",action);
|
263
|
+
win.webContents.focus();
|
264
|
+
return null;
|
265
|
+
}
|
266
|
+
if(powerMonitor){
|
267
|
+
["suspend","resume","lock-screen","unlock-screen"].map((action)=>{
|
268
|
+
powerMonitor.on(action,(event)=>{
|
269
|
+
powerMonitorCallbackEvent(action,event);
|
270
|
+
})
|
271
|
+
})
|
272
|
+
}
|
273
|
+
ipcMain.on("set-main-window-title",(event,title)=>{
|
274
|
+
if(win !== null){
|
275
|
+
win.setTitle(title);
|
276
|
+
}
|
277
|
+
})
|
278
|
+
|
279
|
+
|
280
|
+
ipcMain.handle("create-browser-windows",function(event,options){
|
281
|
+
if(typeof options =='string'){
|
282
|
+
try {
|
283
|
+
const t = JSON.parse(options);
|
284
|
+
options = t;
|
285
|
+
} catch{}
|
286
|
+
}
|
287
|
+
options = Object.assign({},options);
|
288
|
+
createBrowserWindow(options);
|
289
|
+
})
|
290
|
+
|
291
|
+
ipcMain.handle("show-open-dialog",function(event,options){
|
292
|
+
if(!isObj(options)){
|
293
|
+
options = {};
|
294
|
+
}
|
295
|
+
return dialog.showOpenDialog(win,options)
|
296
|
+
})
|
297
|
+
|
298
|
+
ipcMain.handle("show-save-dialog",function(event,options){
|
299
|
+
if(!isObj(options)){
|
300
|
+
options = {};
|
301
|
+
}
|
302
|
+
return dialog.showSaveDialog(win,options)
|
303
|
+
})
|
304
|
+
ipcMain.on("is-dev-tools-open",function(event,value) {
|
305
|
+
if(win !==null && win.webContents){
|
306
|
+
return win.webContents.isDevToolsOpened();
|
307
|
+
}
|
308
|
+
return false;
|
309
|
+
});
|
310
|
+
|
311
|
+
|
312
|
+
ipcMain.on("window-set-progressbar",(event,interval)=>{
|
313
|
+
if(typeof interval !="number" || interval <0) interval = 0;
|
314
|
+
interval = Math.floor(interval);
|
315
|
+
if(win){
|
316
|
+
win.setProgressBar(interval);
|
317
|
+
}
|
318
|
+
})
|
319
|
+
|
320
|
+
const setOSTheme = (theme) => {
|
321
|
+
theme = theme && typeof theme == "string"? theme : "light";
|
322
|
+
theme = theme.toLowerCase().trim();
|
323
|
+
if(theme !== 'system' && theme !=='dark'){
|
324
|
+
theme = "light";
|
325
|
+
}
|
326
|
+
nativeTheme.themeSource = theme;
|
327
|
+
session.set("os-theme",theme);
|
328
|
+
return nativeTheme.shouldUseDarkColors
|
329
|
+
}
|
330
|
+
|
331
|
+
/**** customisation des thèmes de l'application */
|
332
|
+
ipcMain.handle('set-system-theme:toggle', (event,theme) => {
|
333
|
+
return setOSTheme(theme);
|
334
|
+
});
|
335
|
+
|
336
|
+
ipcMain.handle('set-system-theme:dark-mode', (event) => {
|
337
|
+
nativeTheme.themeSource = 'dark';
|
338
|
+
return nativeTheme.shouldUseDarkColors;
|
339
|
+
});
|
340
|
+
ipcMain.handle('set-system-theme:light-mode', (event) => {
|
341
|
+
nativeTheme.themeSource = 'light';
|
342
|
+
return nativeTheme.shouldUseDarkColors;
|
343
|
+
});
|
344
|
+
|
345
|
+
|
346
|
+
ipcMain.handle('dark-mode:toggle', () => {
|
347
|
+
if (nativeTheme.shouldUseDarkColors) {
|
348
|
+
nativeTheme.themeSource = 'light'
|
349
|
+
} else {
|
350
|
+
nativeTheme.themeSource = 'dark'
|
351
|
+
}
|
352
|
+
return nativeTheme.shouldUseDarkColors
|
353
|
+
})
|
354
|
+
|
355
|
+
ipcMain.handle('dark-mode:system', () => {
|
356
|
+
nativeTheme.themeSource = 'system'
|
357
|
+
});
|
358
|
+
function createWindow () {
|
359
|
+
// Créer le browser window
|
360
|
+
win = createBrowserWindow({
|
361
|
+
showOnLoad : false,
|
362
|
+
loadURL : undefined,
|
363
|
+
isMainWindow : true,
|
364
|
+
registerDevToolsCommand : false,
|
365
|
+
preload : path.resolve(__dirname,'preload.js'),
|
366
|
+
webPreferences : {
|
367
|
+
devTools : true,
|
368
|
+
}
|
369
|
+
});
|
370
|
+
|
371
|
+
const sOptions = {width: 500, height: 400, transparent: true, frame: false, alwaysOnTop: true};
|
372
|
+
const splash = typeof mainProcess.splashScreen ==='function'&& mainProcess.splashScreen(sOptions)
|
373
|
+
|| typeof mainProcess.splash ==='function' && mainProcess.splash(sOptions)
|
374
|
+
|| (mainProcess.splash instanceof BrowserWindow) && mainProcess.splash
|
375
|
+
|| (mainProcess.splashScreen instanceof BrowserWindow) && mainProcess.splashScreen;
|
376
|
+
null;
|
377
|
+
let hasInitWindows = false;
|
378
|
+
win.on('show', () => {
|
379
|
+
//win.blur();
|
380
|
+
setTimeout(() => {
|
381
|
+
win.focus();
|
382
|
+
win.moveTop();
|
383
|
+
win.webContents.focus();
|
384
|
+
if(!hasInitWindows){
|
385
|
+
hasInitWindows = true;
|
386
|
+
win.webContents.send('appReady');
|
387
|
+
}
|
388
|
+
}, 200);
|
389
|
+
});
|
390
|
+
|
391
|
+
win.on("focus",()=>{
|
392
|
+
if(win && hasInitWindows){
|
393
|
+
win.webContents.send("main-window-focus");
|
394
|
+
}
|
395
|
+
});
|
396
|
+
win.on("blur",()=>{
|
397
|
+
if(win && hasInitWindows){
|
398
|
+
win.webContents.send("main-window-blur");
|
399
|
+
}
|
400
|
+
});
|
401
|
+
|
402
|
+
win.once("ready-to-show",function(){
|
403
|
+
if(typeof mainProcess.onMainWindowReadyToShow ==='function'){
|
404
|
+
mainProcess.onMainWindowReadyToShow(win);
|
405
|
+
}
|
406
|
+
win.minimize()
|
407
|
+
try {
|
408
|
+
if(splash && splash instanceof BrowserWindow){
|
409
|
+
splash.destroy();
|
410
|
+
}
|
411
|
+
} catch{ }
|
412
|
+
win.restore();
|
413
|
+
win.show();
|
414
|
+
//log(icon," is consooleeeee")
|
415
|
+
})
|
416
|
+
|
417
|
+
win.on('close', (e) => {
|
418
|
+
if (win) {
|
419
|
+
if(typeof mainProcess.onMainWindowClose == "function"){
|
420
|
+
mainProcess.onMainWindowClose(win);
|
421
|
+
}
|
422
|
+
e.preventDefault();
|
423
|
+
win.webContents.send('before-app-exit');
|
424
|
+
}
|
425
|
+
});
|
426
|
+
if(isValidUrl(pUrl)){
|
427
|
+
win.loadURL(pUrl);
|
428
|
+
} else {
|
429
|
+
win.loadFile(indexFilePath)
|
430
|
+
}
|
431
|
+
|
432
|
+
win.on('unresponsive', async () => {
|
433
|
+
const { response } = await dialog.showMessageBox({
|
434
|
+
title: "L'application a cessé de répondre",
|
435
|
+
message : 'Voulez vous relancer l\'application?',
|
436
|
+
buttons: ['Relancer', 'Arrêter'],
|
437
|
+
cancelId: 1
|
438
|
+
})
|
439
|
+
if (response === 0) {
|
440
|
+
win.forcefullyCrashRenderer()
|
441
|
+
win.reload()
|
442
|
+
} else {
|
443
|
+
win.forcefullyCrashRenderer()
|
444
|
+
app.exit();
|
445
|
+
}
|
446
|
+
})
|
447
|
+
|
448
|
+
// Ouvre les DevTools.
|
449
|
+
//win.webContents.openDevTools()
|
450
|
+
|
451
|
+
// Émit lorsque la fenêtre est fermée.
|
452
|
+
win.on('closed', () => {
|
453
|
+
win = null
|
454
|
+
})
|
455
|
+
win.webContents.on('context-menu',clipboadContextMenu);
|
456
|
+
win.setMenu(null);
|
457
|
+
|
458
|
+
/*** les dimenssions de la fenêtre principale */
|
459
|
+
let mWindowSessinName = "mainWindowSizes";
|
460
|
+
let mWindowPositionSName = mWindowSessinName+"-positions";
|
461
|
+
let sizeW = session.get(mWindowSessinName);
|
462
|
+
if(!sizeW || typeof sizeW !== 'object'){
|
463
|
+
sizeW = {};
|
464
|
+
}
|
465
|
+
let sPositions = session.get(mWindowPositionSName);
|
466
|
+
if(!sPositions || typeof sPositions !=='object'){
|
467
|
+
sPositions = {};
|
468
|
+
}
|
469
|
+
let isNumber = x => typeof x =="number";
|
470
|
+
if(isNumber(sizeW.width) && isNumber(sizeW.height)){
|
471
|
+
win.setSize(sizeW.width,sizeW.height);
|
472
|
+
if(isNumber(sPositions.x) && isNumber(sPositions.y)){
|
473
|
+
win.setPosition(sPositions.x,sPositions.y);
|
474
|
+
}
|
475
|
+
}
|
476
|
+
const onWinResizeEv = debounce(function () {
|
477
|
+
if(win){
|
478
|
+
let wSize = win.getSize();
|
479
|
+
if(Array.isArray(wSize) && wSize.length == 2){
|
480
|
+
let [width,height] = wSize;
|
481
|
+
if(width && height){
|
482
|
+
session.set(mWindowSessinName,{width,height});
|
483
|
+
}
|
484
|
+
let [x,y] = win.getPosition();
|
485
|
+
session.set(mWindowPositionSName,{x,y});
|
486
|
+
}
|
487
|
+
}
|
488
|
+
}, 100);
|
489
|
+
win.off('resize',onWinResizeEv);
|
490
|
+
win.on('resize',onWinResizeEv);
|
491
|
+
win.off('move',onWinResizeEv);
|
492
|
+
win.on('move',onWinResizeEv);
|
493
|
+
if(typeof mainProcess.onCreateMainWindow =='function'){
|
494
|
+
mainProcess.onCreateMainWindow(win);
|
495
|
+
}
|
496
|
+
return win;
|
497
|
+
}
|
498
|
+
}
|
499
|
+
|
500
|
+
function createBrowserWindow (options){
|
501
|
+
const {isMainWindow} = options;
|
502
|
+
options = Object.assign({},options);
|
503
|
+
const menu = options.menu;
|
504
|
+
options.webPreferences = isObj(options.webPreferences)? options.webPreferences : {};
|
505
|
+
const mainProcess = typeof mainProcessRef.current == "object" && mainProcessRef.current || {};
|
506
|
+
options.webPreferences = {
|
507
|
+
sandbox: false,
|
508
|
+
webSecurity : true,
|
509
|
+
plugin:false,
|
510
|
+
autoHideMenuBar: true,
|
511
|
+
contextIsolation: true,
|
512
|
+
contentSecurityPolicy: `
|
513
|
+
default-src 'none';
|
514
|
+
script-src 'self';
|
515
|
+
img-src 'self' data:;
|
516
|
+
style-src 'self';
|
517
|
+
font-src 'self';
|
518
|
+
`,
|
519
|
+
...options.webPreferences,
|
520
|
+
devTools: typeof options.webPreferences.devTools === 'boolean'? options.webPreferences.devTools : false,
|
521
|
+
allowRunningInsecureContent: false,
|
522
|
+
nodeIntegration: false,
|
523
|
+
preload: options.preload ? options.preload : null,
|
524
|
+
}
|
525
|
+
if(options.modal && !options.parent && win){
|
526
|
+
options.parent = win;
|
527
|
+
}
|
528
|
+
if(typeof options.show ==='undefined'){
|
529
|
+
options.show = false;
|
530
|
+
}
|
531
|
+
let showOnLoad = options.showOnLoad ===true ? true : undefined;
|
532
|
+
if(showOnLoad){
|
533
|
+
options.show = false;
|
534
|
+
}
|
535
|
+
if(typeof mainProcess?.beforeCreateWindow =='function'){
|
536
|
+
const opts = Object.assign({},mainProcess.beforeCreateWindow(options));
|
537
|
+
options = {...options,...opts};
|
538
|
+
}
|
539
|
+
let _win = new BrowserWindow(options);
|
540
|
+
if(!menu){
|
541
|
+
_win.setMenu(null);
|
542
|
+
_win.removeMenu();
|
543
|
+
_win.setMenuBarVisibility(false)
|
544
|
+
_win.setAutoHideMenuBar(true)
|
545
|
+
}
|
546
|
+
const url = isValidUrl(options.loadURL) || typeof options.loadURL ==='string' && options.loadURL.trim().startsWith("file://") ? options.loadURL : undefined;
|
547
|
+
if(url){
|
548
|
+
_win.loadURL(url);
|
549
|
+
} else if(options.file && fs.existsSync(options.file)){
|
550
|
+
_win.loadFile(options.file);
|
551
|
+
}
|
552
|
+
if(showOnLoad){
|
553
|
+
_win.once('ready-to-show', () => {
|
554
|
+
_win.show();
|
555
|
+
_win.webContents.send("window-ready-to-show",JSON.stringify(options.readyToShowOptions));
|
556
|
+
});
|
557
|
+
}
|
558
|
+
_win.on('closed', function() {
|
559
|
+
if(isMainWindow && typeof mainProcess?.onMainWindowClosed == "function"){
|
560
|
+
mainProcess.onMainWindowClosed(_win);
|
561
|
+
}
|
562
|
+
_win = null;
|
563
|
+
});
|
564
|
+
return _win;
|
565
|
+
}
|
566
|
+
|
567
|
+
module.exports.createBrowserWindow = createBrowserWindow;
|
package/electron/pload.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
const { machineIdSync} = require('node-machine-id');
|
2
2
|
const fs = require("fs");
|
3
3
|
const path = require("path");
|
4
|
-
module.exports = (ELECTRON,{projectRoot
|
4
|
+
module.exports = (ELECTRON,{projectRoot})=>{
|
5
5
|
const isWin = process.platform === "win32"? true : false;
|
6
6
|
const isLinux = process.platform === "linux"? true : false;
|
7
7
|
const {ipcRenderer} = require("electron");
|
@@ -79,7 +79,7 @@ module.exports = (ELECTRON,{projectRoot,electronProjectRoot})=>{
|
|
79
79
|
process.env.USERNAME || '';
|
80
80
|
|
81
81
|
const mainRendererPath = path.resolve('processes',"renderer","index.js");
|
82
|
-
const rendererProcessIndex =
|
82
|
+
const rendererProcessIndex = projectRoot && fs.existsSync(path.resolve(projectRoot,mainRendererPath)) && path.resolve(projectRoot,mainRendererPath);
|
83
83
|
//pour étendre les fonctionnalités au niveau du renderer proceess, bien vouloir écrire dans le fichier projectRoot/electron/processes/renderer/index.js
|
84
84
|
// dans lequel exporter une fonction prenant en paramètre l'objet electron, que l'on peut étendre et le rendre accessible depuis l'application
|
85
85
|
const rendererProcess = rendererProcessIndex && require(`${rendererProcessIndex}`);
|
package/electron/preload.js
CHANGED
@@ -9,13 +9,13 @@ const isBase64 = require("./utils/isBase64");
|
|
9
9
|
const isNonNullString = x=>x && typeof x =='string';
|
10
10
|
require("./utils/replaceAll");
|
11
11
|
const appName = ipcRenderer.sendSync("get-app-name");
|
12
|
-
const
|
12
|
+
const projectRoot = ipcRenderer.sendSync("get-project-root");
|
13
13
|
const sanitize = require("sanitize-filename");
|
14
14
|
const uniqid = require("./utils/uniqid");
|
15
15
|
if(!appName || typeof appName !=='string'){
|
16
|
-
console.error("Nom de l'application invalide!! Veuillez spécifier un nom valide d'application ",
|
16
|
+
console.error("Nom de l'application invalide!! Veuillez spécifier un nom valide d'application ",projectRoot," is electron project root")
|
17
17
|
}
|
18
|
-
const APP_NAME = appName
|
18
|
+
const APP_NAME = appName?.toUpperCase() || "";
|
19
19
|
let backupPathField = "_e_backupDataPath";
|
20
20
|
let cBackupPathField = "company"+backupPathField;
|
21
21
|
let dbPathField = "_electron_DBPathField";
|
@@ -421,7 +421,7 @@ const ELECTRON = {
|
|
421
421
|
},
|
422
422
|
};
|
423
423
|
|
424
|
-
require("./pload")(ELECTRON,{
|
424
|
+
require("./pload")(ELECTRON,{projectRoot});
|
425
425
|
ELECTRON.getBackupPath();
|
426
426
|
//require("./app/index")(ELECTRON)
|
427
427
|
//require('v8-compile-cache');
|
package/package.json
CHANGED
package/electron/init/index.js
DELETED
File without changes
|