1- import { app , shell , BrowserWindow , ipcMain , Menu , SerialPort } from 'electron'
1+ import { app , shell , BrowserWindow , ipcMain , Menu } from 'electron'
22import { join } from 'path'
33import { electronApp , optimizer , is } from '@electron-toolkit/utils'
44import icon from '../../resources/icon.png?asset'
5+ import drivelist from 'drivelist'
6+ import { flashFirmware } from './kmkUpdater'
7+ // import './saveConfig'
58import { checkForUSBKeyboards , handleSelectDrive , selectKeyboard } from './selectKeyboard'
69import { updateFirmware } from './kmkUpdater'
7- import { saveConfiguration } from './saveConfig'
8- import { autoUpdater } from 'electron-updater'
10+ import './keyboardDetector' // Import keyboard detector
911import serialPort from 'serialport'
1012import { ReadlineParser } from '@serialport/parser-readline'
11- import { log } from 'util'
12-
13+ import fs from 'fs'
14+ import { currentKeyboard } from './store'
15+ import { saveConfiguration } from './saveConfig'
1316let mainWindow : BrowserWindow | null = null
1417export { mainWindow }
1518
@@ -24,12 +27,12 @@ const template: unknown = [
2427 label : app . name ,
2528 submenu : [
2629 { role : 'about' } ,
27- {
28- label : 'Check for Updates...' ,
29- click : ( ) => {
30- autoUpdater . checkForUpdatesAndNotify ( )
31- }
32- } ,
30+ // {
31+ // label: 'Check for Updates...',
32+ // click: () => {
33+ // autoUpdater.checkForUpdates ()
34+ // }
35+ // },
3336 { type : 'separator' } ,
3437 { role : 'services' } ,
3538 { type : 'separator' } ,
@@ -117,23 +120,23 @@ Menu.setApplicationMenu(menu)
117120const createWindow = async ( ) => {
118121 // Create the browser window.
119122 mainWindow = new BrowserWindow ( {
120- width : 1100 ,
121- height : 800 ,
122- minWidth : 700 ,
123- minHeight : 200 ,
123+ width : 900 ,
124+ height : 670 ,
124125 show : false ,
125- // autoHideMenuBar: true,
126+ autoHideMenuBar : true ,
126127 backgroundColor : '#000000' ,
127128 ...( process . platform === 'linux' ? { icon } : { } ) ,
128129 webPreferences : {
129130 preload : join ( __dirname , '../preload/index.js' ) ,
130131 sandbox : false ,
132+ nodeIntegration : true ,
133+ contextIsolation : true ,
131134 experimentalFeatures : true
132135 }
133136 } )
134137
135138 mainWindow . on ( 'ready-to-show' , ( ) => {
136- if ( mainWindow ) mainWindow . show ( )
139+ mainWindow ? .show ( )
137140 } )
138141
139142 mainWindow . webContents . setWindowOpenHandler ( ( details ) => {
@@ -153,9 +156,9 @@ const createWindow = async () => {
153156// This method will be called when Electron has finished
154157// initialization and is ready to create browser windows.
155158// Some APIs can only be used after this event occurs.
156- app . whenReady ( ) . then ( async ( ) => {
159+ app . whenReady ( ) . then ( ( ) => {
157160 // Set app user model id for windows
158- electronApp . setAppUserModelId ( 'de.heaper .pog' )
161+ electronApp . setAppUserModelId ( 'de.janlunge .pog' )
159162
160163 // Default open or close DevTools by F12 in development
161164 // and ignore CommandOrControl + R in production.
@@ -219,12 +222,12 @@ ipcMain.on('serialSend', (_event, data) => sendSerial(data))
219222ipcMain . handle ( 'serialConnect' , ( _event , data ) => serialConnect ( data ) )
220223ipcMain . handle ( 'openExternal' , ( _event , data ) => openExternal ( data ) )
221224
222- autoUpdater . on ( 'update-available' , ( ) => {
223- if ( mainWindow ) mainWindow . webContents . send ( 'update_available' )
224- } )
225- autoUpdater . on ( 'update-downloaded' , ( ) => {
226- if ( mainWindow ) mainWindow . webContents . send ( 'update_downloaded' )
227- } )
225+ // autoUpdater.on('update-available', () => {
226+ // if (mainWindow) mainWindow.webContents.send('update_available')
227+ // })
228+ // autoUpdater.on('update-downloaded', () => {
229+ // if (mainWindow) mainWindow.webContents.send('update_downloaded')
230+ // })
228231
229232const baudRate = 9600
230233const startTime = new Date ( )
@@ -489,59 +492,55 @@ const closeDebugPort = () => {
489492
490493const serialConnect = async ( port ) => {
491494 console . log ( 'connecting to serial port' , port )
492-
495+
493496 try {
494497 // First ensure any existing connection is properly closed
495498 await closeDebugPort ( )
496-
499+
497500 // Create a promise that will reject after timeout
498501 const timeoutPromise = new Promise ( ( _ , reject ) => {
499502 setTimeout ( ( ) => reject ( new Error ( 'Connection timeout' ) ) , CONNECTION_TIMEOUT )
500503 } )
501-
504+
502505 // Create the connection promise
503506 const connectionPromise = new Promise ( ( resolve , reject ) => {
504507 try {
505- debugPort = new serialPort . SerialPort (
506- { path : port , baudRate, autoOpen : true } ,
507- ( err ) => {
508- if ( err ) {
509- reject ( err )
510- return
511- }
512-
513- const parser = debugPort . pipe ( new ReadlineParser ( { delimiter : '\n' } ) )
514-
515- parser . on ( 'data' , ( data ) => {
516- console . log ( 'got data from serial' , data )
517- mainWindow ?. webContents . send ( 'serialData' , { message : data + '\n' } )
518- } )
519-
520- debugPort . on ( 'error' , ( error ) => {
521- console . error ( 'Serial port error:' , error )
522- notifyConnectionStatus ( false , error . message )
523- closeDebugPort ( )
524- } )
525-
526- debugPort . on ( 'close' , ( ) => {
527- console . log ( 'Serial port closed' )
528- notifyConnectionStatus ( false )
529- } )
530-
531- resolve ( true )
508+ debugPort = new serialPort . SerialPort ( { path : port , baudRate, autoOpen : true } , ( err ) => {
509+ if ( err ) {
510+ reject ( err )
511+ return
532512 }
533- )
513+
514+ const parser = debugPort . pipe ( new ReadlineParser ( { delimiter : '\n' } ) )
515+
516+ parser . on ( 'data' , ( data ) => {
517+ console . log ( 'got data from serial' , data )
518+ mainWindow ?. webContents . send ( 'serialData' , { message : data + '\n' } )
519+ } )
520+
521+ debugPort . on ( 'error' , ( error ) => {
522+ console . error ( 'Serial port error:' , error )
523+ notifyConnectionStatus ( false , error . message )
524+ closeDebugPort ( )
525+ } )
526+
527+ debugPort . on ( 'close' , ( ) => {
528+ console . log ( 'Serial port closed' )
529+ notifyConnectionStatus ( false )
530+ } )
531+
532+ resolve ( true )
533+ } )
534534 } catch ( err ) {
535535 reject ( err )
536536 }
537537 } )
538-
538+
539539 // Wait for either connection or timeout
540540 await Promise . race ( [ connectionPromise , timeoutPromise ] )
541-
541+
542542 console . log ( 'Successfully connected to serial port' )
543543 notifyConnectionStatus ( true )
544-
545544 } catch ( error : any ) {
546545 console . error ( 'Failed to connect:' , error )
547546 await closeDebugPort ( )
@@ -555,10 +554,10 @@ const sendSerial = (message) => {
555554 console . error ( 'Cannot send: port not open' )
556555 return
557556 }
558-
557+
559558 console . log ( 'sending serial' , message )
560559 mainWindow ?. webContents . send ( 'serialData' , { message : `> sent: ${ message } \n` } )
561-
560+
562561 try {
563562 let buffer
564563 if ( message === 'ctrlc' ) {
@@ -568,7 +567,7 @@ const sendSerial = (message) => {
568567 } else {
569568 buffer = Buffer . from ( message + '\r\n' , 'utf8' )
570569 }
571-
570+
572571 debugPort . write ( buffer , ( err ) => {
573572 if ( err ) {
574573 console . error ( 'error sending serial' , err )
@@ -615,3 +614,96 @@ const checkSerialDevices = async () => {
615614const openExternal = ( url ) => {
616615 shell . openExternal ( url )
617616}
617+
618+ // Drive and Firmware handlers
619+ ipcMain . handle ( 'list-drives' , async ( ) => {
620+ try {
621+ const drives = await drivelist . list ( )
622+ const filteredDrives = drives
623+ . map ( ( drive ) => ( {
624+ path : drive . mountpoints [ 0 ] ?. path || '' ,
625+ name : drive . mountpoints [ 0 ] ?. label || drive . description || 'Unknown Drive' ,
626+ isReadOnly : drive . isReadOnly ,
627+ isRemovable : drive . isRemovable ,
628+ isSystem : drive . isSystem ,
629+ isUSB : drive . isUSB ,
630+ isCard : drive . isCard
631+ } ) )
632+ . filter ( ( drive ) => drive . path !== '' && drive . isUSB )
633+ console . log ( 'drives' , filteredDrives )
634+ return filteredDrives
635+ } catch ( error ) {
636+ console . error ( 'Failed to list drives:' , error )
637+ throw error
638+ }
639+ } )
640+
641+ ipcMain . handle (
642+ 'flash-detection-firmware' ,
643+ async ( _event , { drivePath, serialNumber } : { drivePath : string ; serialNumber : string } ) => {
644+ try {
645+ // Set the current keyboard path
646+ currentKeyboard . path = drivePath
647+ currentKeyboard . name = 'New Keyboard'
648+ currentKeyboard . id = Date . now ( ) . toString ( )
649+ currentKeyboard . serialNumber = serialNumber
650+ console . log ( 'flashing detection firmware currentKeyboard' , currentKeyboard )
651+
652+ // Create necessary directories if they don't exist
653+ if ( ! fs . existsSync ( drivePath ) ) {
654+ throw new Error ( `Drive path ${ drivePath } does not exist` )
655+ }
656+
657+ // Flash the detection firmware
658+ await flashFirmware ( drivePath )
659+
660+ // setup both ports to listen for detection
661+ return { success : true }
662+ } catch ( error ) {
663+ console . error ( 'Failed to flash firmware:' , error )
664+ throw error
665+ }
666+ }
667+ )
668+
669+ // Keyboard History handlers
670+ ipcMain . handle ( 'list-keyboards' , ( ) => {
671+ try {
672+ return listKeyboards ( )
673+ } catch ( error ) {
674+ console . error ( 'Failed to list keyboards:' , error )
675+ throw error
676+ }
677+ } )
678+
679+ // Serial Port handlers
680+ ipcMain . handle ( 'serial-ports' , async ( ) => {
681+ try {
682+ console . log ( 'checking serial devices' )
683+ const ports = await serialPort . SerialPort . list ( )
684+
685+ if ( ports . length === 0 ) {
686+ console . log ( 'No serial ports found' )
687+ return [ ]
688+ }
689+
690+ const returnPorts = ports . map ( ( port ) => ( {
691+ port : port . path ,
692+ manufacturer : port . manufacturer ,
693+ serialNumber : port . serialNumber
694+ } ) )
695+ console . log ( 'found serial ports' , returnPorts )
696+ return returnPorts
697+ } catch ( error ) {
698+ console . error ( 'Error fetching the list of serial ports:' , error )
699+ return [ ]
700+ }
701+ } )
702+
703+ ipcMain . handle ( 'serial-connect' , async ( _event , port : string ) => {
704+ return serialConnect ( port )
705+ } )
706+
707+ ipcMain . handle ( 'serial-disconnect' , async ( ) => {
708+ return closeDebugPort ( )
709+ } )
0 commit comments