1- import { app , shell , BrowserWindow , ipcMain , Menu } from 'electron'
1+ import { app , shell , BrowserWindow , ipcMain , Menu , SerialPort } from 'electron'
22import { join } from 'path'
33import { electronApp , optimizer , is } from '@electron-toolkit/utils'
44import icon from '../../resources/icon.png?asset'
@@ -14,6 +14,7 @@ export { mainWindow }
1414
1515const isMac = process . platform === 'darwin'
1616
17+ let triedToQuit = false
1718const template : unknown = [
1819 // { role: 'appMenu' }
1920 ...( isMac
@@ -181,9 +182,9 @@ app.on('window-all-closed', () => {
181182} )
182183app . on ( 'before-quit' , ( event ) => {
183184 // Prevent the default behavior of this event
184- if ( debugPort !== undefined ) {
185+ if ( debugPort !== undefined && ! triedToQuit ) {
185186 event . preventDefault ( )
186-
187+ triedToQuit = true
187188 console . log ( 'Preparing to quit...' )
188189 debugPort . close ( ( ) => {
189190 console . log ( 'Port closed' )
@@ -233,19 +234,23 @@ const chunksize = 1200
233234
234235const getBoardInfo = ( port ) => {
235236 return new Promise ( ( res , rej ) => {
236- // connect to port and get the response
237- const sport = new serialPort . SerialPort (
238- { path : port . path , baudRate, autoOpen : true } ,
239- ( e ) => { }
240- )
237+ // connect to port and get the response just once
238+ const sport = new serialPort . SerialPort ( { path : port . path , baudRate, autoOpen : true } , ( e ) => {
239+ // if the connection fails reject the promise
240+ if ( e ) return rej ( e )
241+ } )
242+
241243 const sparser = sport . pipe ( new ReadlineParser ( { delimiter : '\n' } ) )
242244 sparser . once ( 'data' , ( data ) => {
243245 sport . close ( )
244- res ( { ...port , ...JSON . parse ( data ) } )
246+ return res ( { ...port , ...JSON . parse ( data ) } )
245247 } )
248+ // request the info
246249 sport . write ( 'info_simple\n' )
247250 } )
248251}
252+
253+ // timer helper function
249254const timeout = ( prom , time ) => {
250255 let timer
251256 return Promise . race ( [ prom , new Promise ( ( _r , rej ) => ( timer = setTimeout ( rej , time ) ) ) ] ) . finally (
@@ -261,14 +266,15 @@ const scanForKeyboards = async () => {
261266 if ( connectedKeyboardPort && connectedKeyboardPort . isOpen ) connectedKeyboardPort . close ( )
262267 const ports = await serialPort . SerialPort . list ( )
263268 console . log ( 'found the following raw ports:' , ports )
264- const circuitPythonPorts = ports . filter ( port => {
269+ const circuitPythonPorts = ports . filter ( ( port ) => {
265270 // TODO: make sure the port is used for a pog keyboard
266271 // we dont want to send serial data to a REPL that is not a keyboard with pog firmware
267- // maybe whitelist serialnumbers?
268- let manufacturer = port . manufacturer
269- manufacturer = manufacturer ? manufacturer . toLowerCase ( ) : ''
270- return manufacturer . endsWith ( "-pog" ) || manufacturer . startsWith ( "pog-" ) || manufacturer === 'pog'
271- } ) ;
272+ const manufacturer = port . manufacturer ? port . manufacturer . toLowerCase ( ) : ''
273+ // if the manufactuer is pog or has pog as suffix or prefix with the - we assume its a pog keyboard
274+ return (
275+ manufacturer . endsWith ( '-pog' ) || manufacturer . startsWith ( 'pog-' ) || manufacturer === 'pog'
276+ )
277+ } )
272278 const boards = ( await Promise . allSettled (
273279 circuitPythonPorts . map ( async ( a ) => await timeout ( getBoardInfo ( a ) , 2000 ) )
274280 ) ) as {
@@ -290,7 +296,7 @@ const scanForKeyboards = async () => {
290296
291297let currentPackage = ''
292298let addedChunks = 0
293- function crossSum ( s ) {
299+ function crossSum ( s : string ) {
294300 // Compute the cross sum
295301 let total = 0
296302 for ( let i = 0 ; i < s . length ; i ++ ) {
0 commit comments