Files
kiosco_desk/main/background.ts
T

317 lines
9.1 KiB
TypeScript
Raw Normal View History

2024-02-07 13:13:07 -06:00
import path, { resolve } from "path";
import { app, ipcMain } from "electron";
import serve from "electron-serve";
import { createWindow } from "./helpers";
import { SerialPort } from "serialport";
import { print } from "pdf-to-printer";
import fs from "fs";
import download from "download";
const isProd = process.env.NODE_ENV === "production";
if (isProd) {
serve({ directory: "app" });
} else {
app.setPath("userData", `${app.getPath("userData")} (development)`);
}
(async () => {
await app.whenReady();
const mainWindow = createWindow("main", {
width: 1000,
height: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
},
});
if (isProd) {
await mainWindow.loadURL("app://./home");
2024-02-12 17:57:02 -06:00
mainWindow.setMenuBarVisibility(false);
mainWindow.setFullScreen(true);
2024-02-07 13:13:07 -06:00
} else {
const port = process.argv[2];
2024-02-08 15:13:29 -06:00
await mainWindow.loadURL(`http://localhost:${port}/configuracionMonedero`);
2024-02-07 13:13:07 -06:00
mainWindow.setMenuBarVisibility(false);
mainWindow.webContents.openDevTools();
}
})();
app.on("window-all-closed", () => {
app.quit();
});
ipcMain.on("message", async (event, arg) => {
event.reply("message", `${arg} World!`);
});
/* Variables */
const api = process.env.REACT_APP_ROOT;
let PuertoSerialMonedero = null;
let dinero: number = 0;
/* Configuracion del kiosco*/
ipcMain.on("getApi", async (event, arg) => {
event.reply("getApi", api);
});
ipcMain.on("BuscarMonedero", async (event, path) => {
try {
const list = await SerialPort.list();
if (list.length === 0) {
throw new Error("La lista de puertos está vacia");
}
const puerto = buscarPuerto(list);
if (!puerto) {
throw new Error("No se pudo detectar el monedero");
}
const puertoMonedero = puerto.path;
event.sender.send("GetPuertoMonedero", `${puertoMonedero}`);
} catch (error) {
console.log("Ha ocurrido un error en: Monedero");
}
});
ipcMain.on("AbrirPuerto", async (event, path) => {
try {
if (!PuertoSerialMonedero) {
// Si el puerto es null, creamos una nueva instancia del puerto serie
PuertoSerialMonedero = new SerialPort({
path: path,
baudRate: 9600,
});
// Evento 'open' para cuando el puerto se abre con éxito
PuertoSerialMonedero.on("open", () => {
2024-02-27 12:05:26 -06:00
event.reply("EstadoPuerto", { abierto: true }); // Enviar mensaje si el puerto está abierto
2024-02-07 13:13:07 -06:00
});
// Evento 'error' para manejar errores que puedan ocurrir durante la operación del puerto
PuertoSerialMonedero.on("error", (error) => {
console.error("Error en Puerto Serial:", error);
2024-02-27 12:05:26 -06:00
event.reply("EstadoPuerto", { abierto: false }); // Enviar mensaje si se produce un error al abrir el puerto
2024-02-07 13:13:07 -06:00
});
} else if (!PuertoSerialMonedero.isOpen) {
// Si el puerto existe pero está cerrado, intentamos abrirlo
PuertoSerialMonedero.open((error) => {
if (error) {
console.error("Error al abrir el puerto:", error);
2024-02-27 12:05:26 -06:00
event.reply("EstadoPuerto", { abierto: false }); // Enviar mensaje si se produce un error al abrir el puerto
2024-02-07 13:13:07 -06:00
} else {
2024-02-27 12:05:26 -06:00
event.reply("EstadoPuerto", { abierto: true }); // Enviar mensaje si el puerto está abierto
2024-02-07 13:13:07 -06:00
}
});
} else {
// Si el puerto ya está abierto, mostramos un mensaje indicando que ya está en uso
console.log("El Puerto Serial ya está abierto");
2024-02-27 12:05:26 -06:00
event.reply("EstadoPuerto", { abierto: true }); // Enviar mensaje si el puerto está abierto
2024-02-07 13:13:07 -06:00
}
PuertoSerialMonedero.on("data", (data) => {
let coin = parseInt(data, 10);
dinero = dinero + coin;
2024-02-27 12:05:26 -06:00
console.log("Dinero Depositado: ", dinero);
2024-02-07 13:13:07 -06:00
event.sender.send("CantidadDinero", dinero);
});
} catch (error) {
console.error("Ha ocurrido un error en: AbrirPuerto", error);
event.sender.send("EstadoPuerto", { abierto: false }); // Enviar mensaje si se produce un error
}
});
ipcMain.on("openDial", async (event, data) => {
2024-02-27 12:05:26 -06:00
console.log("Peticion de impresion");
2024-02-07 13:13:07 -06:00
try {
if (!data.api || !data.fileId || !data.token) {
throw new Error("Datos incompletos");
}
2024-02-27 12:05:26 -06:00
const filePath = await descargarArchivo(data.api, data.fileId, data.token);
const res = await imprimirArchivo(filePath);
2024-02-07 13:13:07 -06:00
2024-02-27 12:05:26 -06:00
/* console.log(res); */
if (res) {
2024-02-27 12:05:26 -06:00
console.log("Proceso Main de impresion finalizado con exito");
event.reply("finishPrint", data.fileId);
2024-02-07 13:13:07 -06:00
}
2024-02-27 12:05:26 -06:00
// Limpiar eventos adicionales si es necesario
event.reply("cleanFinishPrint", "");
2024-02-07 13:13:07 -06:00
} catch (error) {
2024-02-27 12:05:26 -06:00
console.error(error);
// Enviar mensaje de error al cliente
event.reply("finishPrintError", error.message);
2024-02-07 13:13:07 -06:00
}
});
/* Auxiliares */
const buscarPuerto = (puertos) => {
for (const puerto of puertos) {
const friendlyName = puerto.friendlyName.substring(0, 10);
if (friendlyName === "USB-SERIAL") {
return puerto;
}
}
return undefined;
};
ipcMain.on("getApi", async (event, arg) => {
event.reply("getApi", api);
});
ipcMain.on("LimpiarDinero", (event, path) => {
dinero = 0;
2024-02-27 12:05:26 -06:00
console.log("Dinero Limpio: ", dinero);
event.reply("LimpiarDinero", dinero);
2024-02-07 13:13:07 -06:00
});
2024-02-08 12:00:47 -06:00
ipcMain.on("statusPuerto", async (event, arg) => {
try {
if (PuertoSerialMonedero && PuertoSerialMonedero.isOpen) {
event.reply("statusPuerto", { abierto: true });
} else {
event.reply("statusPuerto", { abierto: false });
}
} catch (error) {
console.error("Error al verificar estado del puerto:", error);
event.reply("statusPuerto", { abierto: false }); // Enviar mensaje de estado false en caso de error
}
});
2024-02-27 12:05:26 -06:00
async function descargarArchivo(api, fileId, token) {
const url = `${api}/getFile/${fileId}/${token}`;
const filePath = "public/file.pdf";
await download(url).pipe(fs.createWriteStream(filePath));
return filePath;
}
async function imprimirArchivo(filePath) {
try {
await print(filePath, {});
console.log("Exito al imprimir");
return true;
} catch (error) {
console.log("Error al imprimir", error);
throw error;
}
}
2025-10-17 18:56:19 -06:00
2025-11-27 11:02:45 -06:00
import { BrowserWindow, BrowserView, WebContentsView } from "electron";
2025-10-17 18:56:19 -06:00
import { URL } from "url";
import axios from "axios";
ipcMain.handle("login-with-google", async () => {
return new Promise(async (resolve, reject) => {
const authWindow = new BrowserWindow({
2025-11-26 11:45:21 -06:00
width: 800,
height: 700,
2025-10-17 18:56:19 -06:00
fullscreen: true,
frame: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
},
});
await authWindow.webContents.session.clearStorageData({
storages: ["cookies"],
});
2025-11-27 11:02:45 -06:00
await authWindow.loadURL("http://localhost:3000/persona/google");
2025-10-17 18:56:19 -06:00
2025-11-27 11:02:45 -06:00
// ---------------------------------------------------------
// 🔹 Teclado virtual en WebContentsView
// ---------------------------------------------------------
const keyboardView = new BrowserView({
webPreferences: {
preload: path.join(__dirname, "preload.js"),
nodeIntegration: false,
contextIsolation: true,
},
});
authWindow.addBrowserView(keyboardView);
keyboardView.webContents.loadURL("http://localhost:8888/teclado");
const bounds = authWindow.getBounds();
keyboardView.setBounds({
x: 0,
y: bounds.height - 260, // altura del teclado
width: bounds.width,
height: 260,
});
keyboardView.setAutoResize({
width: true,
horizontal: true,
vertical: false,
});
// ---------------------------------------------------------
// BOTÓN DE CANCELAR
2025-11-26 11:45:21 -06:00
const cancelView = new BrowserView({
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
2025-10-29 18:45:45 -06:00
});
2025-11-26 11:45:21 -06:00
authWindow.addBrowserView(cancelView);
cancelView.setBounds({ x: 1000, y: 50, width: 50, height: 50 });
cancelView.webContents.loadURL(
"data:text/html," +
encodeURIComponent(`
2025-10-29 18:45:45 -06:00
<button id="cancel" style="width:100%;height:100%;font-size:20px;color:white;background:red;border:none;borderRadius:10px;">X</button>
<script>
const { ipcRenderer } = require('electron');
document.getElementById('cancel').addEventListener('click', () => {
ipcRenderer.send('google-login-cancel');
});
</script>
`)
);
2025-11-26 11:45:21 -06:00
ipcMain.once("google-login-cancel", () => {
2025-10-29 18:45:45 -06:00
authWindow.close();
reject(new Error("Login cancelado por el usuario"));
2025-11-26 11:45:21 -06:00
});
2025-10-29 18:45:45 -06:00
2025-10-17 18:56:19 -06:00
authWindow.webContents.on("will-redirect", async (event, url) => {
if (url.startsWith("http://localhost:8888/oauth-callback")) {
2025-10-29 18:45:45 -06:00
event.preventDefault();
2025-10-17 18:56:19 -06:00
const token = new URL(url).searchParams.get("token");
2025-10-29 18:45:45 -06:00
const error = new URL(url).searchParams.get("error");
2025-10-29 18:26:25 -06:00
if (error || !token) {
authWindow.close();
2025-11-26 11:45:21 -06:00
return reject(new Error("Login cancelado o fallido"));
2025-10-29 18:26:25 -06:00
}
2025-10-17 18:56:19 -06:00
try {
const response = await axios.get("http://localhost:3000/persona/me", {
headers: { Authorization: `Bearer ${token}` },
});
2025-10-29 18:45:45 -06:00
resolve({ data: { ...response.data.data, token } });
2025-10-17 18:56:19 -06:00
} catch (err) {
reject(err);
} finally {
authWindow.close();
}
}
});
authWindow.on("closed", () => reject(new Error("Login cancelado")));
});
2025-10-29 18:45:45 -06:00
});