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