From 1ba075ce98d89499832682dcc9f84ca73a3e97f1 Mon Sep 17 00:00:00 2001 From: Hugo Ruscitti Date: Sat, 5 Aug 2023 18:29:39 -0300 Subject: [PATCH] =?UTF-8?q?Corrigiendo=20el=20bug=20que=20imped=C3=ADa=20c?= =?UTF-8?q?errar=20la=20ventana=20en=20la=20versi=C3=B3n=20offiline.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/routes/editor.js | 22 +++++++++++++++------ app/services/proyecto.js | 24 +++++++++++++++++++++++ electron.js | 41 +++++++++++++++++++++++++++++++++++++++ prod-electron.js | 42 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 6 deletions(-) diff --git a/app/routes/editor.js b/app/routes/editor.js index d3305097..d58e32aa 100644 --- a/app/routes/editor.js +++ b/app/routes/editor.js @@ -12,12 +12,22 @@ export default Route.extend({ }, conectar_manejador_para_evitar_cierres_accidentales() { - // Evita que el usuario cierre accidentalmente la ventana. - window.onbeforeunload = () => { - if (ENV.environment !== "test" && this.serviceProyecto.hay_cambios_por_guardar) { - return 'Hay cambios sin guardar, ¿Quieres salir?'; - } - }; + // Evita que el usuario cierre accidentalmente la ventana cuando + // no se usa electron. + // + // Se evita usar este código en electron porque hay varios problemas + // en utilizar "onbeforeunload" en electron. Para evitar que el usuario + // cierre la ventana y pierda cambios se usa otra estrategia, ver el archivo + // electron.js o prod-electron.js. + if (!window.enElectron) { + window.onbeforeunload = () => { + + if (ENV.environment !== "test" && this.serviceProyecto.hay_cambios_por_guardar) { + return 'Hay cambios sin guardar, ¿Quieres salir?'; + } + + }; + } }, actions: { diff --git a/app/services/proyecto.js b/app/services/proyecto.js index 1de7e2c9..fe8c416d 100644 --- a/app/services/proyecto.js +++ b/app/services/proyecto.js @@ -37,10 +37,34 @@ export default Service.extend({ cuando_guarda() { this.set("hay_cambios_por_guardar", false); + this.avisar_a_electron_si_hay_cambios_por_guardar(); }, cuando_realiza_un_cambio() { this.set("hay_cambios_por_guardar", true); + this.avisar_a_electron_si_hay_cambios_por_guardar(); + + }, + + avisar_a_electron_si_hay_cambios_por_guardar() { + // Electron necesita poder controlar si la ventana + // de la aplicación se puede cerrar o no, para esto + // ember tiene que avisarle al proceso principal de + // electron si el usuario tiene cambios por guardar + // o no. Este código hace exactamente eso, le envía + // al proceso principal de electron si el usuario + // tiene cambios por guardar o no. Vea el archivo + // electron.js o prod-electron.js para ver cómo gestiona + // electron este cambio del lado del proceso principal. + // + // Este código solo funciona cuando la aplicación + // está funcionando dentro de electron + + if (window.enElectron) { + const { ipcRenderer } = requireNode('electron'); + let cambios = this.get("hay_cambios_por_guardar"); + ipcRenderer.send("cambia-estado-guardado", cambios); + } }, eliminar_proyectos_guardados() { diff --git a/electron.js b/electron.js index 6b5a6b84..18760f0f 100644 --- a/electron.js +++ b/electron.js @@ -11,6 +11,7 @@ const emberAppLocation = `file://${dirname}/dist/index.html`; const fs = require("fs"); let mainWindow = null; +let necesita_confirmar_para_cerrar_la_ventana = false; global.sharedObj = { desarrollo: true }; @@ -18,6 +19,7 @@ app.on("window-all-closed", function onWindowAllClosed() { app.quit(); }); + app.on("ready", function onReady() { mainWindow = new BrowserWindow({ width: 800, @@ -33,6 +35,19 @@ app.on("ready", function onReady() { var rutas = [`${dirname}/dist/index.html`, `${dirname}/dist/pilas-engine.js`, `${dirname}/dist/assets/pilas-engine.js`, `${dirname}/dist/assets/vendor.js`, `${dirname}/dist/assets/pilas-engine.css`]; let ultima_actualizacion = new Date(); + + // Este evento "cambia-estado-guardado" sirve para que electron + // sepa si tiene que pedirle al usuario configuración para cerrar + // la ventana o no. Hay un service de lado de ember llamado Proyecto + // que se encarga de mantener informado a este proceso principal + // el estado de guardado. + ipcMain.on('cambia-estado-guardado', (event, estado) => { + // esta variable se usa nuevamente en el handler para cerrar + // la ventana, buscar "close" en este mismo archivo para más + // detalles. + necesita_confirmar_para_cerrar_la_ventana = estado; + }); + rutas.map(function(ruta) { fs.watch(ruta, function() { let ahora = new Date(); @@ -58,6 +73,32 @@ app.on("ready", function onReady() { mainWindow = null; }); + var close = false; + + mainWindow.on("close", (event) => { + if (necesita_confirmar_para_cerrar_la_ventana && close === false) { + event.preventDefault(); + + electron.dialog.showMessageBox({ + type: 'warning', + buttons: ['No', 'Sí, quiero salir'], + title: '¿Realmente quieres salir?', + message: '¿Realmente quieres salir?, se pueden perder los cambios sin guardar', + cancelId: 1, + defaultId: 1, + noLink: true + }).then((val) => { + + if (val.response === 0) { + // Cancel the close process + } else if (mainWindow) { + close = true + mainWindow.close() + } + }); + } + }); + process.on("uncaughtException", err => { console.log("An exception in the main thread was not handled."); console.log("This is a serious issue that needs to be handled and/or debugged."); diff --git a/prod-electron.js b/prod-electron.js index 40dd90db..05a0ad9b 100644 --- a/prod-electron.js +++ b/prod-electron.js @@ -4,11 +4,13 @@ const electron = require("electron"); const path = require("path"); const app = electron.app; +const ipcMain = electron.ipcMain; const BrowserWindow = electron.BrowserWindow; const dirname = __dirname || path.resolve(path.dirname()); const emberAppLocation = `file://${dirname}/index.html`; let mainWindow = null; +let necesita_confirmar_para_cerrar_la_ventana = false; global.sharedObj = { desarrollo: false }; @@ -27,6 +29,19 @@ app.on("ready", function onReady() { } }); + // Este evento "cambia-estado-guardado" sirve para que electron + // sepa si tiene que pedirle al usuario configuración para cerrar + // la ventana o no. Hay un service de lado de ember llamado Proyecto + // que se encarga de mantener informado a este proceso principal + // el estado de guardado. + ipcMain.on('cambia-estado-guardado', (event, estado) => { + // esta variable se usa nuevamente en el handler para cerrar + // la ventana, buscar "close" en este mismo archivo para más + // detalles. + necesita_confirmar_para_cerrar_la_ventana = estado; + }); + + delete mainWindow.module; mainWindow.loadURL(emberAppLocation); @@ -39,6 +54,33 @@ app.on("ready", function onReady() { mainWindow = null; }); + var close = false; + + mainWindow.on("close", (event) => { + if (necesita_confirmar_para_cerrar_la_ventana && close === false) { + event.preventDefault(); + + electron.dialog.showMessageBox({ + type: 'warning', + buttons: ['No', 'Sí, quiero salir'], + title: '¿Realmente quieres salir?', + message: '¿Realmente quieres salir?, se pueden perder los cambios sin guardar', + cancelId: 1, + defaultId: 1, + noLink: true + }).then((val) => { + + if (val.response === 0) { + // Cancel the close process + } else if (mainWindow) { + close = true + mainWindow.close() + } + }); + } + }); + + process.on("uncaughtException", err => { console.log("An exception in the main thread was not handled."); console.log("This is a serious issue that needs to be handled and/or debugged.");