diff --git a/Alert.d.ts b/Alert.d.ts index 3f71bc1..8d14c66 100644 --- a/Alert.d.ts +++ b/Alert.d.ts @@ -78,7 +78,7 @@ declare module 'electron-alert' { * }) * ); */ - function uncaughtException(hideTrace?: boolean, closure?: function, alwaysOnTop?: boolean): Promise + function uncaughtException(hideTrace?: boolean, closure?: function, alwaysOnTop?: boolean): void /** * An enum of possible reasons that can explain an alert dismissal. @@ -162,7 +162,7 @@ declare module 'electron-alert' { function enableInput(): void; /** - * If `timer` parameter is set, returns number of milliseconds of timer remained. + * If `timer` property is set/defined, returns number of milliseconds of timer remained. * Otherwise, returns undefined. */ function getTimerLeft(): Promise; @@ -328,24 +328,6 @@ declare module 'electron-alert' { */ footer?: string | HTMLElement | JQuery; - /** - * The type of the modal. - * SweetAlert2 comes with 5 built-in types which will show a corresponding icon animation: 'warning', 'error', - * 'success', 'info' and 'question'. - * It can either be put in the array under the key "type" or passed as the third parameter of the function. - * - * @default null - */ - type?: SweetAlertType; - - /** - * Whether or not SweetAlert2 should show a full screen click-to-dismiss backdrop. - * Either a boolean value or a css background value (hex, rgb, rgba, url, etc.) - * - * @default true - */ - backdrop?: boolean | string; - /** * Whether or not an alert should be treated as a toast notification. * This option is normally coupled with the `position` parameter and a timer. @@ -470,15 +452,6 @@ declare module 'electron-alert' { */ heightAuto?: boolean; - /** - * If set to false, the user can't dismiss the modal by clicking outside it. - * You can also pass a custom function returning a boolean value, e.g. if you want - * to disable outside clicks for the loading state of a modal. - * - * @default true - */ - allowOutsideClick?: ValueOrThunk; - /** * If set to false, the user can't dismiss the modal by pressing the Escape key. * You can also pass a custom function returning a boolean value, e.g. if you want diff --git a/dist/Alert.js b/dist/Alert.js index bec3798..46ecc0b 100644 --- a/dist/Alert.js +++ b/dist/Alert.js @@ -13,7 +13,7 @@ const DismissReason = Object.freeze({ timer: "timer" }); -var isMac = process.platform === "darwin"; +const isMac = process.platform === "darwin"; class Alert { constructor(head, devTools) { @@ -27,55 +27,91 @@ class Alert { this._isVisible = false; } + /** + * An enum of possible reasons that can explain an alert dismissal. + */ static get DismissReason() { return DismissReason; } + /** + * Determine if a modal is shown. + */ isVisible() { return this._isVisible; } + /** + * Enable "Confirm" and "Cancel" buttons. + */ enableButtons() { this.execJS(`Swal.enableButtons()`); } + /** + * Disable "Confirm" and "Cancel" buttons. + */ disableButtons() { this.execJS(`Swal.disableButtons()`); } + /** + * Disable buttons and show loader. This is useful with AJAX requests. + */ showLoading() { this.execJS(`Swal.showLoading()`); } + /** + * Disable buttons and show loader. This is useful with AJAX requests. + */ enableLoading() { this.showLoading(); } + /** + * Enable buttons and hide loader. + */ hideLoading() { this.execJS(`Swal.hideLoading()`); } + /** + * Enable buttons and hide loader. + */ disableLoading() { this.hideLoading(); } + /** + * Determine if modal is in the loading state. + * + * @returns {Promise} Promise which resolves with a boolean + */ isLoading() { - //: boolean return this.execJS(`Swal.isLoading()`); } + /** + * Click the "Confirm"-button programmatically. + */ clickConfirm() { - //: void this.execJS(`Swal.clickConfirm()`); } + /** + * Click the "Cancel"-button programmatically. + */ clickCancel() { - //: void this.execJS(`Swal.clickCancel()`); } + /** + * Show a validation message. + * + * @param {string} validationMessage The validation message. + */ showValidationMessage(validationMessage) { - //: void this.execJS(`Swal.showValidationMessage('${validationMessage}')`, () => { if (this.browserWindow) { this.browserWindow.webContents.send(`${this.uid}resizeToFit`, 25); @@ -83,8 +119,10 @@ class Alert { }); } + /** + * Hide validation message. + */ resetValidationMessage() { - //: void; this.execJS(`Swal.resetValidationMessage()`, () => { if (this.browserWindow) { this.browserWindow.webContents.send(`${this.uid}resizeToFit`, 25); @@ -92,73 +130,144 @@ class Alert { }); } + /** + * Disable the modal input. A disabled input element is unusable and un-clickable. + */ disableInput() { - //: void; this.execJS(`Swal.disableInput()`); } + /** + * Enable the modal input. + */ enableInput() { - //: void; this.execJS(`Swal.enableInput()`); } + /** + * If `timer` property is is set/defined in swalOptions, returns number of milliseconds of timer remained. + * Otherwise, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ getTimerLeft() { - //: promise => number | undefined; return this.execJS(`Swal.getTimerLeft()`); } + /** + * Stop timer. Returns number of milliseconds of timer remained. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ stopTimer() { - //promise => number | undefined; return this.execJS(`Swal.stopTimer()`); } + /** + * Resume timer. Returns number of milliseconds of timer remained. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ resumeTimer() { - //: promise => number | undefined; return this.execJS(`Swal.resumeTimer()`); } + /** + * Toggle timer. Returns number of milliseconds of timer remained. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ toggleTimer() { - //: promise => number | undefined; return this.execJS(`Swal.toggleTimer()`); } + /** + * Check if timer is running. Returns true if timer is running, + * and false is timer is paused / stopped. + * + * @returns {Promise} Promise which resolves with a boolean or undefined + */ isTimerRunning() { - //: promise => boolean | undefined; return this.execJS(`Swal.isTimerRunning()`); } - increaseTimer( - n //: promise => number | undefined; - ) { + /** + * Increase timer. Returns number of milliseconds of an updated timer. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @param {number} n The number of milliseconds to add to the current timer + * + * @returns {Promise} Promise which resolves with a number or undefined + */ + increaseTimer(n) { return this.execJS(`Swal.increaseTimer(${n})`); } + /** + * Shows progress steps. + */ showProgressSteps() { - //: void; this.execJS(`Swal.showProgressSteps()`); } + /** + * Hides progress steps. + */ hideProgressSteps() { - //: void; this.execJS(`Swal.hideProgressSteps()`); } - isValidParameter( - paramName //: promise => boolean; - ) { + /** + * Determine if a given parameter name is valid. + * + * @param paramName The parameter to check + * + * @returns {Promise} Promise which resolves with a boolean or undefined + */ + isValidParameter(paramName) { return this.execJS(`Swal.isValidParameter('${paramName}')`); } - isUpdatableParameter( - paramName //: promise => boolean; - ) { + /** + * Determines if a given parameter name is valid for Swal.update() method. + * + * @param paramName The parameter to check + * + * @returns {Promise} Promise which resolves with a boolean or undefined + */ + isUpdatableParameter(paramName) { return this.execJS(`isUpdatableParameter('${paramName}')`); } + /** + * + * @param options Options object of type `SweetAlertOptions` or `ElectronAlertOptions`. + * + * __Possible `options` for type `SweetAlertOptions`:__ + * See TS definition file (Alert.d.ts) or the original [sweetAlert2](https://sweetalert2.github.io) docs for list of sweetAlert2 options; + * + * __Possible `options` for type `ElectronAlertOptions`:__ { + * > `swalOptions`?: SweetAlertOptions, + * `bwOptions`?: BrowserWindowOptions, + * `title`?: string, + * `parent`?: boolean, + * `alwaysOnTop`?: boolean, + * `sound`?: object + * + * }; + * + * __Note:__ + * If `swalOptions` is defined in `options`, method will assume `options` (arg) to be of type `ElectronAlertOptions`; and if not defined, of type `SweetAlertOptions`. + * + * @returns {Promise} Promise which resolves with a value of type SweetAlertResult + */ fireFrameless(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); let swalOptions = options.swalOptions @@ -181,7 +290,7 @@ class Alert { swalOptions.backdrop = `rgba(0,0,0,0.0)`; swalOptions.allowOutsideClick = false; - if (size !== undefined) { + if (size) { if (size.hasOwnProperty("width")) { bwOptions.width = size.width; } @@ -200,10 +309,34 @@ class Alert { }); } + /** + * + * @param options Options object of type `SweetAlertOptions` or `ElectronAlertOptions`. + * + * __Possible `options` for type `SweetAlertOptions`:__ + * See TS definition file (Alert.d.ts) or the original [sweetAlert2](https://sweetalert2.github.io) docs for list of sweetAlert2 options; + * + * __Possible `options` for type `ElectronAlertOptions`:__ { + * > `swalOptions`?: SweetAlertOptions, + * `bwOptions`?: BrowserWindowOptions, + * `title`?: string, + * `parent`?: boolean, + * `alwaysOnTop`?: boolean, + * `draggable`?: boolean, + * `sound`?: object + * + * }; + * + * __Note:__ + * If `swalOptions` is defined in `options`, method will assume `options` (arg) to be of type `ElectronAlertOptions`; and if not defined, of type `SweetAlertOptions`. + * + * + * @returns {Promise} Promise which resolves with a value of type SweetAlertResult + */ fireWithFrame(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); let swalOptions = options.swalOptions @@ -226,7 +359,7 @@ class Alert { swalOptions.allowOutsideClick = false; swalOptions.animation = false; - if (size !== undefined) { + if (size) { if (size.hasOwnProperty("width")) bwOptions.width = size.width; if (size.hasOwnProperty("height")) bwOptions.height = size.height; } @@ -247,10 +380,33 @@ class Alert { }); } + /** + * + * @param options Options object of type `SweetAlertOptions` or `ElectronAlertOptions`. + * + * __Possible `options` for type `SweetAlertOptions`:__ + * See TS definition file (Alert.d.ts) or the original [sweetAlert2](https://sweetalert2.github.io) docs for list of sweetAlert2 options; + * + * __Possible `options` for type `ElectronAlertOptions`:__ { + * > `swalOptions`?: SweetAlertOptions, + * `bwOptions`?: BrowserWindowOptions, + * `title`?: string, + * `parent`?: boolean, + * `alwaysOnTop`?: boolean, + * `draggable`?: boolean, + * `sound`?: object + * + * }; + * + * __Note:__ + * If `swalOptions` is defined in `options`, method will assume `options` (arg) to be of type `ElectronAlertOptions`; and if not defined, of type `SweetAlertOptions`. + * + * @returns {Promise} Promise which resolves with a value of type SweetAlertResult + */ static fireToast(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); // Animation: https://github.com/electron/electron/issues/2407 // https://stackoverflow.com/questions/54413142/how-can-i-modify-sweetalert2s-toast-animation-settings @@ -283,7 +439,7 @@ class Alert { let bwOptions = {}; - if (size !== undefined) { + if (size) { if (size.hasOwnProperty("width")) { bwOptions.width = size.width; } @@ -304,7 +460,7 @@ class Alert { fire(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); let swalOptions = options.swalOptions @@ -324,7 +480,7 @@ class Alert { let uid = this.uid, head = this.head; - var bwOptionsBase = { + let bwOptionsBase = { width: 800, height: 600, resizable: false, @@ -338,7 +494,7 @@ class Alert { } }; - var bwOptionsFinal = Object.assign(bwOptionsBase, bwOptions, { + let bwOptionsFinal = Object.assign(bwOptionsBase, bwOptions, { show: false }); @@ -395,7 +551,13 @@ class Alert { - ${Array.isArray(head) ? head.join("\n") : ""} + ${ + Array.isArray(head) + ? head.join("\n") + : typeof head === "string" + ? head + : null + } let _sound = ${JSON.stringify(sound)} let _config = ${JSON.stringify(swalOptions)} - const{ipcRenderer:e,remote:o}=require("electron");let sound=_sound,config=_config,n=o.getCurrentWindow();config.onBeforeOpen=o=>{e.send("${uid}onBeforeOpen",o),e.on("${uid}showLoading",()=>Swal.showLoading()),void 0!==sound&&function(e,o,n){let i={C:[16.35,32.7,65.41,130.8,261.6,523.3,1047,2093,4186],"C#":[17.32,34.65,69.3,138.6,277.2,554.4,1109,2217,4435],D:[18.35,36.71,73.42,146.8,293.7,587.3,1175,2349,4699],Eb:[19.45,38.89,77.78,155.6,311.1,622.3,1245,2489,4978],E:[20.6,41.2,82.41,164.8,329.6,659.3,1319,2637,5274],F:[21.83,43.65,87.31,174.6,349.2,698.5,1397,2794,5588],"F#":[23.12,46.25,92.5,185,370,740,1480,2960,5920],G:[24.5,49,98,196,392,784,1568,3136,6272],"G#":[25.96,51.91,103.8,207.7,415.3,830.6,1661,3322,6645],A:[27.5,55,110,220,440,880,1760,3520,7040],Bb:[29.14,58.27,116.5,233.1,466.2,932.3,1865,3729,7459],B:[30.87,61.74,123.5,246.9,493.9,987.8,1976,3951,7902]};if(isNaN(o)){regexStr=o.match(/^(.+)([0-9])$/i);let e=regexStr[1].toUpperCase(),n=regexStr[2];o=i[e][n]}var t=new AudioContext,r=t.createOscillator(),d=t.createGain();r.type=e,r.connect(d),r.frequency.value=o,d.connect(t.destination),r.start(0),d.gain.exponentialRampToValueAtTime(1e-5,t.currentTime+n)}(sound.type,sound.freq,sound.duration)},config.onAfterClose=()=>{e.send("${uid}onAfterClose")},config.onOpen=o=>{let i=n.getSize()[1]-n.getContentSize()[1];o.parentNode.style.padding="0px 0px 0px 0px",window.resizeTo(o.scrollWidth,o.scrollHeight+i+1),e.send("${uid}reposition"),window.setTimeout(()=>{e.send("${uid}reposition")},25),e.send("${uid}onOpen",o),e.on("${uid}resizeToFit",e=>{void 0!==e?window.setTimeout(()=>{window.resizeTo(o.scrollWidth,o.scrollHeight+i+1)},e):window.resizeTo(o.scrollWidth,o.scrollHeight+i+1)}),e.on("${uid}hideLoading",()=>Swal.hideLoading())},config.onClose=o=>{e.send("${uid}onClose",o)},Swal.fire(config).then((function(o){e.send("${uid}return-promise",o)})); + const{ipcRenderer:e,remote:o}=require("electron");let sound=_sound,config=_config,n=o.getCurrentWindow();config.onBeforeOpen=o=>{e.send("${uid}onBeforeOpen",o),e.on("${uid}showLoading",()=>Swal.showLoading()),void 0!==sound&&function(e,o,n){let i={C:[16.35,32.7,65.41,130.8,261.6,523.3,1047,2093,4186],"C#":[17.32,34.65,69.3,138.6,277.2,554.4,1109,2217,4435],D:[18.35,36.71,73.42,146.8,293.7,587.3,1175,2349,4699],Eb:[19.45,38.89,77.78,155.6,311.1,622.3,1245,2489,4978],E:[20.6,41.2,82.41,164.8,329.6,659.3,1319,2637,5274],F:[21.83,43.65,87.31,174.6,349.2,698.5,1397,2794,5588],"F#":[23.12,46.25,92.5,185,370,740,1480,2960,5920],G:[24.5,49,98,196,392,784,1568,3136,6272],"G#":[25.96,51.91,103.8,207.7,415.3,830.6,1661,3322,6645],A:[27.5,55,110,220,440,880,1760,3520,7040],Bb:[29.14,58.27,116.5,233.1,466.2,932.3,1865,3729,7459],B:[30.87,61.74,123.5,246.9,493.9,987.8,1976,3951,7902]};if(isNaN(o)){regexStr=o.match(/^(.+)([0-9])$/i);let e=regexStr[1].toUpperCase(),n=regexStr[2];o=i[e][n]}let t=new AudioContext,r=t.createOscillator(),d=t.createGain();r.type=e,r.connect(d),r.frequency.value=o,d.connect(t.destination),r.start(0),d.gain.exponentialRampToValueAtTime(1e-5,t.currentTime+n)}(sound.type,sound.freq,sound.duration)},config.onAfterClose=()=>{e.send("${uid}onAfterClose")},config.onOpen=o=>{let i=n.getSize()[1]-n.getContentSize()[1];o.parentNode.style.padding="0px 0px 0px 0px",window.resizeTo(o.scrollWidth,o.scrollHeight+i+1),e.send("${uid}reposition"),window.setTimeout(()=>{e.send("${uid}reposition")},25),e.send("${uid}onOpen",o),e.on("${uid}resizeToFit",e=>{void 0!==e?window.setTimeout(()=>{window.resizeTo(o.scrollWidth,o.scrollHeight+i+1)},e):window.resizeTo(o.scrollWidth,o.scrollHeight+i+1)}),e.on("${uid}hideLoading",()=>Swal.hideLoading())},config.onClose=o=>{e.send("${uid}onClose",o)},Swal.fire(config).then((function(o){e.send("${uid}return-promise",o)})); @@ -497,7 +659,7 @@ class Alert { this.browserWindow = null; // Send signal that browserWindow is closed - ipcMain.emit(uid + "return-promise", undefined, { + ipcMain.emit(uid + "return-promise", null, { dismiss: "close" }); @@ -571,12 +733,10 @@ class Alert { if (closure) swalOptions.onAfterClose = () => closure(error); alert.fireWithFrame({ - swalOptions: swalOptions, + swalOptions, title: error.name, - alwaysOnTop: alwaysOnTop + alwaysOnTop }); - // alert.fireWithFrame(swalOptions, error.name, undefined, alwaysOnTop); - // alert.fireFrameless(swalOptions, undefined, alwaysOnTop, true); }; } } diff --git a/dist/Alert.min.js b/dist/Alert.min.js index 3cab6b3..59a2998 100644 --- a/dist/Alert.min.js +++ b/dist/Alert.min.js @@ -1,17 +1,17 @@ -"use strict";const{ipcMain,globalShortcut,app,BrowserWindow}=require("electron"),tempWrite=require("temp-write"),cryptoRandomString=require("crypto-random-string"),Positioner=require("electron-positioner"),fs=require("fs"),exceptionFormatter=require("exception-formatter"),DismissReason=Object.freeze({cancel:"cancel",close:"close",esc:"esc",timer:"timer"});var isMac="darwin"===process.platform;class Alert{constructor(e,t){this.head=e,this.devTools=t,this.uid=cryptoRandomString({length:10}),this.browserWindow=null,this.position="center",this._isVisible=!1}static get DismissReason(){return DismissReason}isVisible(){return this._isVisible}enableButtons(){this.execJS("Swal.enableButtons()")}disableButtons(){this.execJS("Swal.disableButtons()")}showLoading(){this.execJS("Swal.showLoading()")}enableLoading(){this.showLoading()}hideLoading(){this.execJS("Swal.hideLoading()")}disableLoading(){this.hideLoading()}isLoading(){return this.execJS("Swal.isLoading()")}clickConfirm(){this.execJS("Swal.clickConfirm()")}clickCancel(){this.execJS("Swal.clickCancel()")}showValidationMessage(e){this.execJS(`Swal.showValidationMessage('${e}')`,()=>{this.browserWindow&&this.browserWindow.webContents.send(`${this.uid}resizeToFit`,25)})}resetValidationMessage(){this.execJS("Swal.resetValidationMessage()",()=>{this.browserWindow&&this.browserWindow.webContents.send(`${this.uid}resizeToFit`,25)})}disableInput(){this.execJS("Swal.disableInput()")}enableInput(){this.execJS("Swal.enableInput()")}getTimerLeft(){return this.execJS("Swal.getTimerLeft()")}stopTimer(){return this.execJS("Swal.stopTimer()")}resumeTimer(){return this.execJS("Swal.resumeTimer()")}toggleTimer(){return this.execJS("Swal.toggleTimer()")}isTimerRunning(){return this.execJS("Swal.isTimerRunning()")}increaseTimer(e){return this.execJS(`Swal.increaseTimer(${e})`)}showProgressSteps(){this.execJS("Swal.showProgressSteps()")}hideProgressSteps(){this.execJS("Swal.hideProgressSteps()")}isValidParameter(e){return this.execJS(`Swal.isValidParameter('${e}')`)}isUpdatableParameter(e){return this.execJS(`isUpdatableParameter('${e}')`)}fireFrameless(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Options object expected as param.`);let t=e.swalOptions?e.swalOptions:{...e},s=(e=e.swalOptions?e:{}).size,o={frame:!1,transparent:!0,thickFrame:!1,closable:!1,backgroundColor:"#00000000",hasShadow:!1,...e.bwOptions};return t.backdrop="rgba(0,0,0,0.0)",t.allowOutsideClick=!1,void 0!==s&&(s.hasOwnProperty("width")&&(o.width=s.width),s.hasOwnProperty("height")&&(o.height=s.height)),this.fire({swalOptions:t,bwOptions:o,parent:e.parent,alwaysOnTop:e.alwaysOnTop,draggagle:e.draggable,sound:e.sound})}fireWithFrame(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Options object expected as param.`);let t=e.swalOptions?e.swalOptions:{...e},s=(e=e.swalOptions?e:{}).title,o=e.size,i={frame:!0,transparent:!1,thickFrame:!0,closable:!0,title:s||app.getName(),...e.bwOptions};return t.allowOutsideClick=!1,t.animation=!1,void 0!==o&&(o.hasOwnProperty("width")&&(i.width=o.width),o.hasOwnProperty("height")&&(i.height=o.height)),t.customClass=Object.assign(t.customClass?t.customClass:{},{popup:"border-radius-0"}),this.fire({swalOptions:t,bwOptions:i,parent:e.parent,alwaysOnTop:e.alwaysOnTop,sound:e.sound})}static fireToast(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Options object expected as param.`);let t=e.swalOptions?e.swalOptions:{...e},sound=(e=e.swalOptions?e:{}).sound,s=e.size,o=new this;t.toast=!0;let i={};return void 0!==s&&(s.hasOwnProperty("width")&&(i.width=s.width),s.hasOwnProperty("height")&&(i.height=s.height)),o.fireFrameless({swalOptions:t,bwOptions:i,parent:!0,alwaysOnTop:!1,sound})}fire(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Options object expected as param.`);let t=e.swalOptions?e.swalOptions:{...e},s=(e=e.swalOptions?e:{}).bwOptions?e.bwOptions:{},o=e.parent,i=e.alwaysOnTop,r=e.draggable,sound=e.sound,uid=this.uid,n=this.head;var a={width:800,height:600,resizable:!1,minimizable:!1,maximizable:!1,fullscreen:!1,fullscreenable:!1,webPreferences:{nodeIntegration:!0,devTools:!0===this.devTools}},l=Object.assign(a,s,{show:!1});null!=o&&(l.parent=o,l.modal=!0),l.webPreferences.nodeIntegration=!0,l.skipTaskbar=!0,void 0!==i&&(l.alwaysOnTop=i),!0===r&&(t.customClass=Object.assign(t.customClass?t.customClass:{},{closeButton:"no-drag",confirmButton:"no-drag",cancelButton:"no-drag",input:"no-drag"})),this.browserWindow=new BrowserWindow(l);let w={top:"topCenter","top-start":"topLeft","top-end":"topRight",center:"center","center-start":"leftCenter","center-end":"rightCenter",bottom:"bottomCenter","bottom-start":"bottomLeft","bottom-end":"bottomRight"};t.position&&(this.position=w[t.position]||"center",delete t.position),isMac&&null!=o||new Positioner(this.browserWindow).move(this.position);let c=String.raw` +"use strict";const{ipcMain,globalShortcut,app,BrowserWindow}=require("electron"),tempWrite=require("temp-write"),cryptoRandomString=require("crypto-random-string"),Positioner=require("electron-positioner"),fs=require("fs"),exceptionFormatter=require("exception-formatter"),DismissReason=Object.freeze({cancel:"cancel",close:"close",esc:"esc",timer:"timer"}),isMac="darwin"===process.platform;class Alert{constructor(e,t){this.head=e,this.devTools=t,this.uid=cryptoRandomString({length:10}),this.browserWindow=null,this.position="center",this._isVisible=!1}static get DismissReason(){return DismissReason}isVisible(){return this._isVisible}enableButtons(){this.execJS("Swal.enableButtons()")}disableButtons(){this.execJS("Swal.disableButtons()")}showLoading(){this.execJS("Swal.showLoading()")}enableLoading(){this.showLoading()}hideLoading(){this.execJS("Swal.hideLoading()")}disableLoading(){this.hideLoading()}isLoading(){return this.execJS("Swal.isLoading()")}clickConfirm(){this.execJS("Swal.clickConfirm()")}clickCancel(){this.execJS("Swal.clickCancel()")}showValidationMessage(e){this.execJS(`Swal.showValidationMessage('${e}')`,()=>{this.browserWindow&&this.browserWindow.webContents.send(`${this.uid}resizeToFit`,25)})}resetValidationMessage(){this.execJS("Swal.resetValidationMessage()",()=>{this.browserWindow&&this.browserWindow.webContents.send(`${this.uid}resizeToFit`,25)})}disableInput(){this.execJS("Swal.disableInput()")}enableInput(){this.execJS("Swal.enableInput()")}getTimerLeft(){return this.execJS("Swal.getTimerLeft()")}stopTimer(){return this.execJS("Swal.stopTimer()")}resumeTimer(){return this.execJS("Swal.resumeTimer()")}toggleTimer(){return this.execJS("Swal.toggleTimer()")}isTimerRunning(){return this.execJS("Swal.isTimerRunning()")}increaseTimer(e){return this.execJS(`Swal.increaseTimer(${e})`)}showProgressSteps(){this.execJS("Swal.showProgressSteps()")}hideProgressSteps(){this.execJS("Swal.hideProgressSteps()")}isValidParameter(e){return this.execJS(`Swal.isValidParameter('${e}')`)}isUpdatableParameter(e){return this.execJS(`isUpdatableParameter('${e}')`)}fireFrameless(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.`);let t=e.swalOptions?e.swalOptions:{...e},o=(e=e.swalOptions?e:{}).size,s={frame:!1,transparent:!0,thickFrame:!1,closable:!1,backgroundColor:"#00000000",hasShadow:!1,...e.bwOptions};return t.backdrop="rgba(0,0,0,0.0)",t.allowOutsideClick=!1,o&&(o.hasOwnProperty("width")&&(s.width=o.width),o.hasOwnProperty("height")&&(s.height=o.height)),this.fire({swalOptions:t,bwOptions:s,parent:e.parent,alwaysOnTop:e.alwaysOnTop,draggagle:e.draggable,sound:e.sound})}fireWithFrame(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.`);let t=e.swalOptions?e.swalOptions:{...e},o=(e=e.swalOptions?e:{}).title,s=e.size,i={frame:!0,transparent:!1,thickFrame:!0,closable:!0,title:o||app.getName(),...e.bwOptions};return t.allowOutsideClick=!1,t.animation=!1,s&&(s.hasOwnProperty("width")&&(i.width=s.width),s.hasOwnProperty("height")&&(i.height=s.height)),t.customClass=Object.assign(t.customClass?t.customClass:{},{popup:"border-radius-0"}),this.fire({swalOptions:t,bwOptions:i,parent:e.parent,alwaysOnTop:e.alwaysOnTop,sound:e.sound})}static fireToast(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.`);let t=e.swalOptions?e.swalOptions:{...e},sound=(e=e.swalOptions?e:{}).sound,o=e.size,s=new this;t.toast=!0;let i={};return o&&(o.hasOwnProperty("width")&&(i.width=o.width),o.hasOwnProperty("height")&&(i.height=o.height)),s.fireFrameless({swalOptions:t,bwOptions:i,parent:!0,alwaysOnTop:!1,sound})}fire(e={}){if(e.constructor!==Object)throw new Error(`${e} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.`);let t=e.swalOptions?e.swalOptions:{...e},o=(e=e.swalOptions?e:{}).bwOptions?e.bwOptions:{},s=e.parent,i=e.alwaysOnTop,r=e.draggable,sound=e.sound,uid=this.uid,n=this.head,a={width:800,height:600,resizable:!1,minimizable:!1,maximizable:!1,fullscreen:!1,fullscreenable:!1,webPreferences:{nodeIntegration:!0,devTools:!0===this.devTools}},l=Object.assign(a,o,{show:!1});null!=s&&(l.parent=s,l.modal=!0),l.webPreferences.nodeIntegration=!0,l.skipTaskbar=!0,void 0!==i&&(l.alwaysOnTop=i),!0===r&&(t.customClass=Object.assign(t.customClass?t.customClass:{},{closeButton:"no-drag",confirmButton:"no-drag",cancelButton:"no-drag",input:"no-drag"})),this.browserWindow=new BrowserWindow(l);let w={top:"topCenter","top-start":"topLeft","top-end":"topRight",center:"center","center-start":"leftCenter","center-end":"rightCenter",bottom:"bottomCenter","bottom-start":"bottomLeft","bottom-end":"bottomRight"};t.position&&(this.position=w[t.position]||"center",delete t.position),isMac&&null!=s||new Positioner(this.browserWindow).move(this.position);let c=String.raw` - ${Array.isArray(n)?n.join("\n"):""} + ${Array.isArray(n)?n.join("\n"):"string"==typeof n?n:null} - `;this.browserWindow.removeMenu();let p=tempWrite.sync(c,"swal.html");this.browserWindow.loadURL("file://"+p),isMac&&(this.browserWindow.on("focus",e=>{globalShortcut.registerAll(["CommandOrControl+R","CommandOrControl+Shift+R"],()=>{})}),this.browserWindow.on("blur",e=>{globalShortcut.unregister("CommandOrControl+R"),globalShortcut.unregister("CommandOrControl+Shift+R")})),this.browserWindow.once("ready-to-show",()=>{isMac&&null!=o||new Positioner(this.browserWindow).move(this.position),this.browserWindow.show()}),ipcMain.on(uid+"reposition",(e,t)=>{isMac&&null!=o||new Positioner(this.browserWindow).move(this.position)}),ipcMain.once(uid+"onBeforeOpen",(e,s)=>{t.hasOwnProperty("onBeforeOpen")&&t.onBeforeOpen(s)}),ipcMain.once(uid+"onAfterClose",(e,t)=>{this.browserWindow&&this.browserWindow.destroy()}),ipcMain.once(uid+"onOpen",(e,s)=>{this._isVisible=!0,t.hasOwnProperty("onOpen")&&t.onOpen(s)});let h=!1;return ipcMain.once(uid+"onClose",(e,s)=>{this._isVisible=!1,h=!0,t.hasOwnProperty("onClose")&&t.onClose(s)}),this.browserWindow.once("close",()=>{h||t.hasOwnProperty("onClose")&&t.onClose({})}),this.browserWindow.once("closed",()=>{fs.unlink(p,e=>{}),this.browserWindow.isDestroyed()||this.browserWindow.destroy(),this.browserWindow=null,ipcMain.emit(uid+"return-promise",void 0,{dismiss:"close"}),t.hasOwnProperty("onAfterClose")&&t.onAfterClose(),isMac&&(globalShortcut.unregister("CommandOrControl+R"),globalShortcut.unregister("CommandOrControl+Shift+R")),ipcMain.removeAllListeners([uid+"log",uid+"onBeforeOpen",uid+"onAfterClose",uid+"onOpen",uid+"onClose",uid+"reposition",uid+"return-promise",uid+"resizeToFit"])}),new Promise((e,t)=>{ipcMain.once(uid+"return-promise",(t,s)=>{e(s)})})}execJS(e,t){return null===this.browserWindow?new Promise(e=>e()):this.browserWindow.webContents.executeJavaScript(e,!1,t)}static uncaughtException(e,t,s){return o=>{let i=exceptionFormatter(o,{format:"html",inlineStyle:!0}),r=new Alert([],!1),n={type:"error"};!0!==e?n.html=`\n\t\t\t\t
\n\t\t\t\t\t\t${i.replace(/nowrap/g,"")}\n\t\t\t\t\t
\n\t\t\t\t\t`:n.title=o.message,t&&(n.onAfterClose=()=>t(o)),r.fireWithFrame({swalOptions:n,title:o.name,alwaysOnTop:s})}}}module.exports=Alert; + `;this.browserWindow.removeMenu();let p=tempWrite.sync(c,"swal.html");this.browserWindow.loadURL("file://"+p),isMac&&(this.browserWindow.on("focus",e=>{globalShortcut.registerAll(["CommandOrControl+R","CommandOrControl+Shift+R"],()=>{})}),this.browserWindow.on("blur",e=>{globalShortcut.unregister("CommandOrControl+R"),globalShortcut.unregister("CommandOrControl+Shift+R")})),this.browserWindow.once("ready-to-show",()=>{isMac&&null!=s||new Positioner(this.browserWindow).move(this.position),this.browserWindow.show()}),ipcMain.on(uid+"reposition",(e,t)=>{isMac&&null!=s||new Positioner(this.browserWindow).move(this.position)}),ipcMain.once(uid+"onBeforeOpen",(e,o)=>{t.hasOwnProperty("onBeforeOpen")&&t.onBeforeOpen(o)}),ipcMain.once(uid+"onAfterClose",(e,t)=>{this.browserWindow&&this.browserWindow.destroy()}),ipcMain.once(uid+"onOpen",(e,o)=>{this._isVisible=!0,t.hasOwnProperty("onOpen")&&t.onOpen(o)});let h=!1;return ipcMain.once(uid+"onClose",(e,o)=>{this._isVisible=!1,h=!0,t.hasOwnProperty("onClose")&&t.onClose(o)}),this.browserWindow.once("close",()=>{h||t.hasOwnProperty("onClose")&&t.onClose({})}),this.browserWindow.once("closed",()=>{fs.unlink(p,e=>{}),this.browserWindow.isDestroyed()||this.browserWindow.destroy(),this.browserWindow=null,ipcMain.emit(uid+"return-promise",null,{dismiss:"close"}),t.hasOwnProperty("onAfterClose")&&t.onAfterClose(),isMac&&(globalShortcut.unregister("CommandOrControl+R"),globalShortcut.unregister("CommandOrControl+Shift+R")),ipcMain.removeAllListeners([uid+"log",uid+"onBeforeOpen",uid+"onAfterClose",uid+"onOpen",uid+"onClose",uid+"reposition",uid+"return-promise",uid+"resizeToFit"])}),new Promise((e,t)=>{ipcMain.once(uid+"return-promise",(t,o)=>{e(o)})})}execJS(e,t){return null===this.browserWindow?new Promise(e=>e()):this.browserWindow.webContents.executeJavaScript(e,!1,t)}static uncaughtException(e,t,o){return s=>{let i=exceptionFormatter(s,{format:"html",inlineStyle:!0}),r=new Alert([],!1),n={type:"error"};!0!==e?n.html=`\n\t\t\t\t
\n\t\t\t\t\t\t${i.replace(/nowrap/g,"")}\n\t\t\t\t\t
\n\t\t\t\t\t`:n.title=s.message,t&&(n.onAfterClose=()=>t(s)),r.fireWithFrame({swalOptions:n,title:s.name,alwaysOnTop:o})}}}module.exports=Alert; diff --git a/src/Alert.js b/src/Alert.js index c93e171..7359863 100644 --- a/src/Alert.js +++ b/src/Alert.js @@ -13,7 +13,7 @@ const DismissReason = Object.freeze({ timer: "timer" }); -var isMac = process.platform === "darwin"; +const isMac = process.platform === "darwin"; class Alert { constructor(head, devTools) { @@ -27,55 +27,91 @@ class Alert { this._isVisible = false; } + /** + * An enum of possible reasons that can explain an alert dismissal. + */ static get DismissReason() { return DismissReason; } + /** + * Determine if a modal is shown. + */ isVisible() { return this._isVisible; } + /** + * Enable "Confirm" and "Cancel" buttons. + */ enableButtons() { this.execJS(`Swal.enableButtons()`); } + /** + * Disable "Confirm" and "Cancel" buttons. + */ disableButtons() { this.execJS(`Swal.disableButtons()`); } + /** + * Disable buttons and show loader. This is useful with AJAX requests. + */ showLoading() { this.execJS(`Swal.showLoading()`); } + /** + * Disable buttons and show loader. This is useful with AJAX requests. + */ enableLoading() { this.showLoading(); } + /** + * Enable buttons and hide loader. + */ hideLoading() { this.execJS(`Swal.hideLoading()`); } + /** + * Enable buttons and hide loader. + */ disableLoading() { this.hideLoading(); } + /** + * Determine if modal is in the loading state. + * + * @returns {Promise} Promise which resolves with a boolean + */ isLoading() { - //: boolean return this.execJS(`Swal.isLoading()`); } + /** + * Click the "Confirm"-button programmatically. + */ clickConfirm() { - //: void this.execJS(`Swal.clickConfirm()`); } + /** + * Click the "Cancel"-button programmatically. + */ clickCancel() { - //: void this.execJS(`Swal.clickCancel()`); } + /** + * Show a validation message. + * + * @param {string} validationMessage The validation message. + */ showValidationMessage(validationMessage) { - //: void this.execJS(`Swal.showValidationMessage('${validationMessage}')`, () => { if (this.browserWindow) { this.browserWindow.webContents.send(`${this.uid}resizeToFit`, 25); @@ -83,8 +119,10 @@ class Alert { }); } + /** + * Hide validation message. + */ resetValidationMessage() { - //: void; this.execJS(`Swal.resetValidationMessage()`, () => { if (this.browserWindow) { this.browserWindow.webContents.send(`${this.uid}resizeToFit`, 25); @@ -92,73 +130,144 @@ class Alert { }); } + /** + * Disable the modal input. A disabled input element is unusable and un-clickable. + */ disableInput() { - //: void; this.execJS(`Swal.disableInput()`); } + /** + * Enable the modal input. + */ enableInput() { - //: void; this.execJS(`Swal.enableInput()`); } + /** + * If `timer` property is is set/defined in swalOptions, returns number of milliseconds of timer remained. + * Otherwise, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ getTimerLeft() { - //: promise => number | undefined; return this.execJS(`Swal.getTimerLeft()`); } + /** + * Stop timer. Returns number of milliseconds of timer remained. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ stopTimer() { - //promise => number | undefined; return this.execJS(`Swal.stopTimer()`); } + /** + * Resume timer. Returns number of milliseconds of timer remained. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ resumeTimer() { - //: promise => number | undefined; return this.execJS(`Swal.resumeTimer()`); } + /** + * Toggle timer. Returns number of milliseconds of timer remained. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @returns {Promise} Promise which resolves with a number or undefined + */ toggleTimer() { - //: promise => number | undefined; return this.execJS(`Swal.toggleTimer()`); } + /** + * Check if timer is running. Returns true if timer is running, + * and false is timer is paused / stopped. + * + * @returns {Promise} Promise which resolves with a boolean or undefined + */ isTimerRunning() { - //: promise => boolean | undefined; return this.execJS(`Swal.isTimerRunning()`); } - increaseTimer( - n //: promise => number | undefined; - ) { + /** + * Increase timer. Returns number of milliseconds of an updated timer. + * If `timer` property isn't set in swalOptions, returns undefined. + * + * @param {number} n The number of milliseconds to add to the current timer + * + * @returns {Promise} Promise which resolves with a number or undefined + */ + increaseTimer(n) { return this.execJS(`Swal.increaseTimer(${n})`); } + /** + * Shows progress steps. + */ showProgressSteps() { - //: void; this.execJS(`Swal.showProgressSteps()`); } + /** + * Hides progress steps. + */ hideProgressSteps() { - //: void; this.execJS(`Swal.hideProgressSteps()`); } - isValidParameter( - paramName //: promise => boolean; - ) { + /** + * Determine if a given parameter name is valid. + * + * @param paramName The parameter to check + * + * @returns {Promise} Promise which resolves with a boolean or undefined + */ + isValidParameter(paramName) { return this.execJS(`Swal.isValidParameter('${paramName}')`); } - isUpdatableParameter( - paramName //: promise => boolean; - ) { + /** + * Determines if a given parameter name is valid for Swal.update() method. + * + * @param paramName The parameter to check + * + * @returns {Promise} Promise which resolves with a boolean or undefined + */ + isUpdatableParameter(paramName) { return this.execJS(`isUpdatableParameter('${paramName}')`); } + /** + * + * @param options Options object of type `SweetAlertOptions` or `ElectronAlertOptions`. + * + * __Possible `options` for type `SweetAlertOptions`:__ + * See TS definition file (Alert.d.ts) or the original [sweetAlert2](https://sweetalert2.github.io) docs for list of sweetAlert2 options; + * + * __Possible `options` for type `ElectronAlertOptions`:__ { + * > `swalOptions`?: SweetAlertOptions, + * `bwOptions`?: BrowserWindowOptions, + * `title`?: string, + * `parent`?: boolean, + * `alwaysOnTop`?: boolean, + * `sound`?: object + * + * }; + * + * __Note:__ + * If `swalOptions` is defined in `options`, method will assume `options` (arg) to be of type `ElectronAlertOptions`; and if not defined, of type `SweetAlertOptions`. + * + * @returns {Promise} Promise which resolves with a value of type SweetAlertResult + */ fireFrameless(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); let swalOptions = options.swalOptions @@ -181,7 +290,7 @@ class Alert { swalOptions.backdrop = `rgba(0,0,0,0.0)`; swalOptions.allowOutsideClick = false; - if (size !== undefined) { + if (size) { if (size.hasOwnProperty("width")) { bwOptions.width = size.width; } @@ -200,10 +309,34 @@ class Alert { }); } + /** + * + * @param options Options object of type `SweetAlertOptions` or `ElectronAlertOptions`. + * + * __Possible `options` for type `SweetAlertOptions`:__ + * See TS definition file (Alert.d.ts) or the original [sweetAlert2](https://sweetalert2.github.io) docs for list of sweetAlert2 options; + * + * __Possible `options` for type `ElectronAlertOptions`:__ { + * > `swalOptions`?: SweetAlertOptions, + * `bwOptions`?: BrowserWindowOptions, + * `title`?: string, + * `parent`?: boolean, + * `alwaysOnTop`?: boolean, + * `draggable`?: boolean, + * `sound`?: object + * + * }; + * + * __Note:__ + * If `swalOptions` is defined in `options`, method will assume `options` (arg) to be of type `ElectronAlertOptions`; and if not defined, of type `SweetAlertOptions`. + * + * + * @returns {Promise} Promise which resolves with a value of type SweetAlertResult + */ fireWithFrame(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); let swalOptions = options.swalOptions @@ -226,7 +359,7 @@ class Alert { swalOptions.allowOutsideClick = false; swalOptions.animation = false; - if (size !== undefined) { + if (size) { if (size.hasOwnProperty("width")) bwOptions.width = size.width; if (size.hasOwnProperty("height")) bwOptions.height = size.height; } @@ -247,10 +380,33 @@ class Alert { }); } + /** + * + * @param options Options object of type `SweetAlertOptions` or `ElectronAlertOptions`. + * + * __Possible `options` for type `SweetAlertOptions`:__ + * See TS definition file (Alert.d.ts) or the original [sweetAlert2](https://sweetalert2.github.io) docs for list of sweetAlert2 options; + * + * __Possible `options` for type `ElectronAlertOptions`:__ { + * > `swalOptions`?: SweetAlertOptions, + * `bwOptions`?: BrowserWindowOptions, + * `title`?: string, + * `parent`?: boolean, + * `alwaysOnTop`?: boolean, + * `draggable`?: boolean, + * `sound`?: object + * + * }; + * + * __Note:__ + * If `swalOptions` is defined in `options`, method will assume `options` (arg) to be of type `ElectronAlertOptions`; and if not defined, of type `SweetAlertOptions`. + * + * @returns {Promise} Promise which resolves with a value of type SweetAlertResult + */ static fireToast(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); // Animation: https://github.com/electron/electron/issues/2407 // https://stackoverflow.com/questions/54413142/how-can-i-modify-sweetalert2s-toast-animation-settings @@ -283,7 +439,7 @@ class Alert { let bwOptions = {}; - if (size !== undefined) { + if (size) { if (size.hasOwnProperty("width")) { bwOptions.width = size.width; } @@ -304,7 +460,7 @@ class Alert { fire(options = {}) { if (options.constructor !== Object) throw new Error( - `${options} is not an object. Options object expected as param.` + `${options} is not an object. Object of type ElectronAlertOptions or SweetAlertOptions expected as argument.` ); let swalOptions = options.swalOptions @@ -324,7 +480,7 @@ class Alert { let uid = this.uid, head = this.head; - var bwOptionsBase = { + let bwOptionsBase = { width: 800, height: 600, resizable: false, @@ -338,7 +494,7 @@ class Alert { } }; - var bwOptionsFinal = Object.assign(bwOptionsBase, bwOptions, { + let bwOptionsFinal = Object.assign(bwOptionsBase, bwOptions, { show: false }); @@ -394,7 +550,13 @@ class Alert { - ${Array.isArray(head) ? head.join("\n") : ""} + ${ + Array.isArray(head) + ? head.join("\n") + : typeof head === "string" + ? head + : null + } closure(error); alert.fireWithFrame({ - swalOptions: swalOptions, + swalOptions, title: error.name, - alwaysOnTop: alwaysOnTop + alwaysOnTop }); - // alert.fireWithFrame(swalOptions, error.name, undefined, alwaysOnTop); - // alert.fireFrameless(swalOptions, undefined, alwaysOnTop, true); }; } } diff --git a/src/renderer.js b/src/renderer.js index 90ccd46..8428fc5 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -1,103 +1,96 @@ -const { - ipcRenderer, - remote -} = require("electron"); - +const { ipcRenderer, remote } = require("electron"); + let sound = _sound; let config = _config; let win = remote.getCurrentWindow(); - + function playsound(type, freq, duration) { - let std = { - C: [16.35, 32.7, 65.41, 130.8, 261.6, 523.3, 1047, 2093, 4186], - "C#": [17.32, 34.65, 69.3, 138.6, 277.2, 554.4, 1109, 2217, 4435], - D: [18.35, 36.71, 73.42, 146.8, 293.7, 587.3, 1175, 2349, 4699], - Eb: [19.45, 38.89, 77.78, 155.6, 311.1, 622.3, 1245, 2489, 4978], - E: [20.6, 41.2, 82.41, 164.8, 329.6, 659.3, 1319, 2637, 5274], - F: [21.83, 43.65, 87.31, 174.6, 349.2, 698.5, 1397, 2794, 5588], - "F#": [23.12, 46.25, 92.5, 185.0, 370.0, 740.0, 1480, 2960, 5920], - G: [24.5, 49.0, 98.0, 196.0, 392.0, 784.0, 1568, 3136, 6272], - "G#": [25.96, 51.91, 103.8, 207.7, 415.3, 830.6, 1661, 3322, 6645], - A: [27.5, 55.0, 110.0, 220.0, 440.0, 880.0, 1760, 3520, 7040], - Bb: [29.14, 58.27, 116.5, 233.1, 466.2, 932.3, 1865, 3729, 7459], - B: [30.87, 61.74, 123.5, 246.9, 493.9, 987.8, 1976, 3951, 7902] - }; - - if (isNaN(freq)) { - // not a number - regexStr = freq.match(/^(.+)([0-9])$/i); - let note = regexStr[1].toUpperCase(); - let idx = regexStr[2]; - freq = std[note][idx]; - } - - var context = new AudioContext(); - var o = context.createOscillator(); - var g = context.createGain(); - o.type = type; - o.connect(g); - o.frequency.value = freq; - g.connect(context.destination); - o.start(0); - g.gain.exponentialRampToValueAtTime( - 0.00001, - context.currentTime + duration - ); + let std = { + C: [16.35, 32.7, 65.41, 130.8, 261.6, 523.3, 1047, 2093, 4186], + "C#": [17.32, 34.65, 69.3, 138.6, 277.2, 554.4, 1109, 2217, 4435], + D: [18.35, 36.71, 73.42, 146.8, 293.7, 587.3, 1175, 2349, 4699], + Eb: [19.45, 38.89, 77.78, 155.6, 311.1, 622.3, 1245, 2489, 4978], + E: [20.6, 41.2, 82.41, 164.8, 329.6, 659.3, 1319, 2637, 5274], + F: [21.83, 43.65, 87.31, 174.6, 349.2, 698.5, 1397, 2794, 5588], + "F#": [23.12, 46.25, 92.5, 185.0, 370.0, 740.0, 1480, 2960, 5920], + G: [24.5, 49.0, 98.0, 196.0, 392.0, 784.0, 1568, 3136, 6272], + "G#": [25.96, 51.91, 103.8, 207.7, 415.3, 830.6, 1661, 3322, 6645], + A: [27.5, 55.0, 110.0, 220.0, 440.0, 880.0, 1760, 3520, 7040], + Bb: [29.14, 58.27, 116.5, 233.1, 466.2, 932.3, 1865, 3729, 7459], + B: [30.87, 61.74, 123.5, 246.9, 493.9, 987.8, 1976, 3951, 7902] + }; + + if (isNaN(freq)) { + // not a number + regexStr = freq.match(/^(.+)([0-9])$/i); + let note = regexStr[1].toUpperCase(); + let idx = regexStr[2]; + freq = std[note][idx]; + } + + let context = new AudioContext(); + let o = context.createOscillator(); + let g = context.createGain(); + o.type = type; + o.connect(g); + o.frequency.value = freq; + g.connect(context.destination); + o.start(0); + g.gain.exponentialRampToValueAtTime(0.00001, context.currentTime + duration); } - -// callbacks -config.onBeforeOpen = modalElement => { - ipcRenderer.send("${uid}onBeforeOpen", modalElement); - ipcRenderer.on("${uid}showLoading", () => Swal.showLoading()); - if (sound !== undefined) { - playsound(sound.type, sound.freq, sound.duration); - } +// callbacks +config.onBeforeOpen = modalElement => { + ipcRenderer.send("${uid}onBeforeOpen", modalElement); + ipcRenderer.on("${uid}showLoading", () => Swal.showLoading()); + + if (sound !== undefined) { + playsound(sound.type, sound.freq, sound.duration); + } }; config.onAfterClose = () => { - ipcRenderer.send("${uid}onAfterClose"); + ipcRenderer.send("${uid}onAfterClose"); }; config.onOpen = modalElement => { - let titlebarHeight = win.getSize()[1] - win.getContentSize()[1]; - modalElement.parentNode.style.padding = "0px 0px 0px 0px"; - window.resizeTo( - modalElement.scrollWidth, - modalElement.scrollHeight + titlebarHeight + 1 - ); + let titlebarHeight = win.getSize()[1] - win.getContentSize()[1]; + modalElement.parentNode.style.padding = "0px 0px 0px 0px"; + window.resizeTo( + modalElement.scrollWidth, + modalElement.scrollHeight + titlebarHeight + 1 + ); - ipcRenderer.send("${uid}reposition"); - window.setTimeout(() => { - ipcRenderer.send("${uid}reposition"); - }, 25); + ipcRenderer.send("${uid}reposition"); + window.setTimeout(() => { + ipcRenderer.send("${uid}reposition"); + }, 25); - ipcRenderer.send("${uid}onOpen", modalElement); + ipcRenderer.send("${uid}onOpen", modalElement); - ipcRenderer.on("${uid}resizeToFit", delay => { - if (delay !== undefined) { - window.setTimeout(() => { - window.resizeTo( - modalElement.scrollWidth, - modalElement.scrollHeight + titlebarHeight + 1 - ); - }, delay); - } else { - window.resizeTo( - modalElement.scrollWidth, - modalElement.scrollHeight + titlebarHeight + 1 - ); - } - }); + ipcRenderer.on("${uid}resizeToFit", delay => { + if (delay !== undefined) { + window.setTimeout(() => { + window.resizeTo( + modalElement.scrollWidth, + modalElement.scrollHeight + titlebarHeight + 1 + ); + }, delay); + } else { + window.resizeTo( + modalElement.scrollWidth, + modalElement.scrollHeight + titlebarHeight + 1 + ); + } + }); - ipcRenderer.on("${uid}hideLoading", () => Swal.hideLoading()); + ipcRenderer.on("${uid}hideLoading", () => Swal.hideLoading()); }; config.onClose = modalElement => { - ipcRenderer.send("${uid}onClose", modalElement); + ipcRenderer.send("${uid}onClose", modalElement); }; -let ret = Swal.fire(config); -ret.then(function (result) { - ipcRenderer.send("${uid}return-promise", result); -}); \ No newline at end of file +Swal.fire(config).then(function(result) { + ipcRenderer.send("${uid}return-promise", result); +});