11
2- import { app , shell , BrowserWindow , ipcMain , dialog } from 'electron'
2+ import { app , shell , BrowserWindow , ipcMain , dialog , session , screen } from 'electron'
33import { join } from 'path'
44import { electronApp , optimizer , is } from '@electron-toolkit/utils'
55import icon from '../../resources/icon.png?asset'
66import sharp from 'sharp'
7- import { promises as fs } from 'fs'
7+ import fs from 'fs'
88import path from 'path'
9-
9+ import { checkPluginInstalled , getSupportedFormats , documentConvert , isFormatSupported } from './initPlugin'
1010function createWindow ( ) {
11- // Create the browser window.
11+ const primaryDisplay = screen . getPrimaryDisplay ( ) ;
12+ const { width, height} = primaryDisplay . workAreaSize
1213 const mainWindow = new BrowserWindow ( {
13- width : 900 ,
14- height : 670 ,
14+ minWidth : width / 2 ,
15+ minHeight : height / 1.5 ,
16+ maxHeight : height ,
17+ maxWidth : width ,
1518 show : false ,
1619 autoHideMenuBar : true ,
1720 ...( process . platform === 'linux' ? { icon } : { } ) ,
@@ -48,7 +51,6 @@ app.whenReady().then(() => {
4851
4952 // Default open or close DevTools by F12 in development
5053 // and ignore CommandOrControl + R in production.
51- // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
5254 app . on ( 'browser-window-created' , ( _ , window ) => {
5355 optimizer . watchWindowShortcuts ( window )
5456 } )
@@ -64,9 +66,7 @@ app.whenReady().then(() => {
6466 } )
6567
6668 // Handle image processing with Sharp
67- // In your main process
6869ipcMain . handle ( 'process:image' , async ( _ , { filepath, name, options, savePath } ) => {
69- console . log ( filepath )
7070 try {
7171 let pipeline = sharp ( filepath ) ;
7272
@@ -94,12 +94,10 @@ ipcMain.handle('process:image', async (_, { filepath, name, options, savePath })
9494 } else if ( options . format === 'jxl' ) {
9595 pipeline = pipeline . jxl ( { quality : options . quality } ) ;
9696 }
97-
9897 // control if output type is tile
9998 if ( options . format === 'tile' ) {
10099 options . format = 'zip'
101100 }
102-
103101 // Generate output filename
104102 const parsedName = path . parse ( name ) ;
105103 const outputName = `${ parsedName . name } .${ options . format } ` ;
@@ -121,7 +119,7 @@ ipcMain.handle('process:image', async (_, { filepath, name, options, savePath })
121119 } ;
122120 }
123121} ) ;
124-
122+
125123 createWindow ( )
126124
127125 app . on ( 'activate' , function ( ) {
@@ -131,14 +129,109 @@ ipcMain.handle('process:image', async (_, { filepath, name, options, savePath })
131129 } )
132130} )
133131
134- // Quit when all windows are closed, except on macOS. There, it's common
135- // for applications and their menu bar to stay active until the user quits
136- // explicitly with Cmd + Q.
137132app . on ( 'window-all-closed' , ( ) => {
138133 if ( process . platform !== 'darwin' ) {
139134 app . quit ( )
140135 }
141136} )
137+ // handle document conversion
138+ ipcMain . handle ( "document:convert" , async ( event , { filename, inputPath, outputPath, options} ) => {
139+ console . log ( 'parameters' , inputPath , outputPath , filename ) ;
140+ try {
141+ const isInstalled = await checkPluginInstalled ( ) ;
142+ if ( ! isInstalled ) {
143+ return {
144+ success : false ,
145+ message : 'MuPDF is not installed. Please install it from Plugins page'
146+ } ;
147+ }
142148
143- // In this file you can include the rest of your app's specific main process
144- // code. You can also put them in separate files and require them here.
149+ // Validate input format
150+ const inputFormat = path . extname ( inputPath ) . slice ( 1 ) ;
151+ if ( ! isFormatSupported ( inputFormat , 'input' ) ) {
152+ return {
153+ success : false ,
154+ message : `Unsupported input format: ${ inputFormat } `
155+ } ;
156+ }
157+
158+ // Validate output format
159+ const outputFormat = options ?. format || getDefaultOutputFormat ( inputFormat ) ;
160+ if ( ! isFormatSupported ( outputFormat , 'output' ) ) {
161+ return {
162+ success : false ,
163+ message : `Unsupported output format: ${ outputFormat } `
164+ } ;
165+ }
166+
167+ // Convert document
168+ const result = await documentConvert ( filename , inputPath , outputPath , {
169+ format : outputFormat ,
170+ ...options
171+ } ) ;
172+
173+ return result ;
174+ } catch ( error ) {
175+ console . error ( 'Document conversion error:' , error ) ;
176+ return {
177+ success : false ,
178+ message : error . message
179+ } ;
180+ }
181+ } ) ;
182+ ipcMain . handle ( 'document:get-formats' , async ( ) => {
183+ return getSupportedFormats ( ) ;
184+ } )
185+ //check if plugin is installed
186+ ipcMain . handle ( 'plugin:check-installed' , async ( event , pluginId ) => {
187+ const pluginPath = path . join ( app . getAppPath ( ) , 'out' , 'Plugins' , `${ pluginId } .exe` )
188+ return fs . existsSync ( pluginPath )
189+ } )
190+
191+ // plugin installation
192+ ipcMain . handle ( 'plugin:install' , async ( event , { url, id} ) => {
193+ const sess = session . defaultSession ;
194+ return new Promise ( ( resolve , reject ) => {
195+
196+
197+ session . defaultSession . on ( 'will-download' , ( event , item ) => {
198+ const PLUGINS_DIR = path . join ( app . getAppPath ( ) , 'out' , 'Plugins' )
199+
200+ // Create plugins directory if it doesn't exist
201+ if ( ! fs . existsSync ( PLUGINS_DIR ) ) {
202+ fs . mkdirSync ( PLUGINS_DIR , { recursive : true } )
203+ }
204+
205+ const pluginPath = path . join ( PLUGINS_DIR , `${ id } .exe` )
206+ item . setSavePath ( pluginPath )
207+
208+ item . on ( 'updated' , ( event , state ) => {
209+ if ( state === 'interrupted' ) {
210+ reject ( new Error ( 'Download interrupted' ) )
211+ }
212+ } )
213+
214+ item . once ( 'done' , ( event , state ) => {
215+ if ( state === 'completed' ) {
216+ resolve ( true )
217+ } else {
218+ reject ( new Error ( `Download failed with state: ${ state } ` ) )
219+ }
220+ } )
221+ } )
222+ sess . downloadURL ( url )
223+ } )
224+ } )
225+ // delete plugin
226+ ipcMain . handle ( 'plugin:uninstall' , async ( event , pluginId ) => {
227+ const pluginPath = path . join ( app . getAppPath ( ) , 'out' , 'Plugins' , `${ pluginId } .exe` )
228+ try {
229+ if ( fs . existsSync ( pluginPath ) ) {
230+ await fs . promises . unlink ( pluginPath )
231+ return true
232+ }
233+ } catch ( error ) {
234+ console . error ( 'Failed to delete plugin: ' , error )
235+ throw error
236+ }
237+ } )
0 commit comments