import { inject } from "inversify"; import { PrimariaApi } from "../../api/api"; import { PluginBusyList } from "../../api/plugin-busy-manager/plugin-busy-list/component"; import { PluginTask } from "../../api/plugin-busy-manager/plugin-busy-manager"; import { disposeShell, raiseCloseEvent, raiseCustomCloseEvent } from "../../disposer"; import { disposePlugins } from "../../handle-plugins"; import { TYPES } from "../../infrastructure/ioc/types"; import { translate } from "../../locales"; import { ExitShell } from "./request"; export class ExitShellHandler { constructor(@inject(TYPES.primaryApi) private api: PrimariaApi) {} async handle(exitEvent: ExitShell): Promise { const evt = exitEvent && exitEvent.ecapEvent !== undefined ? exitEvent : undefined; try { const canExit = await this.api.exitGuardManager.canExit(); if (!canExit) return; // Backwards-compat: external plugins still using the deprecated pluginBusyManager // would otherwise lose their exit-confirmation modal. Remove once all consumers migrate. const busyTasks = this.api.pluginBusyManager.getTasks(); if (busyTasks.length > 0) { const { confirmed } = await this.askForClose(busyTasks); if (!confirmed) return; } // Per si un plugin tarda molt en fer dispose, màxim deixarem 5 segons, per no interrompre el tancar infinitament await Promise.race([ disposePlugins(), // S'intenta executar un dispose normal this.timeout(10000), // Si passen 5s, es segueix amb l'execució ]); disposeShell(); this.emitClose(evt); } catch (error) { this.api.notificationService.error(translate("errors.exit")); this.emitClose(evt); } } private timeout(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } private askForClose(busyTasks: PluginTask[]) { return this.api.interactionService.confirm( { busyTasks }, { component: PluginBusyList }, { title: translate("actions.askExit"), state: "error", confirmButtonText: "Sí", cancelButtonText: "No", }, ); } private emitClose(exitEvent?: ExitShell): void { if (exitEvent) { raiseCustomCloseEvent(exitEvent); } else { raiseCloseEvent(); } } }