diff --git a/electron/main.ts b/electron/main.ts index 128270bf4..19192bd99 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -31,6 +31,7 @@ import { registerGlobalShortcuts } from './utils/shortcut' import { registerLogger } from './utils/logger' const preloadPath = join(__dirname, 'preload.js') +const preloadQuickAskPath = join(__dirname, 'preload.quickask.js') const rendererPath = join(__dirname, '..', 'renderer') const quickAskPath = join(rendererPath, 'search.html') const mainPath = join(rendererPath, 'index.html') @@ -133,7 +134,7 @@ function createQuickAskWindow() { // Feature Toggle for Quick Ask if (!getAppConfigurations().quick_ask) return const startUrl = app.isPackaged ? `file://${quickAskPath}` : quickAskUrl - windowManager.createQuickAskWindow(preloadPath, startUrl) + windowManager.createQuickAskWindow(preloadQuickAskPath, startUrl) } /** diff --git a/electron/managers/quickAskWindowConfig.ts b/electron/managers/quickAskWindowConfig.ts index eb30e8ebc..93180dd07 100644 --- a/electron/managers/quickAskWindowConfig.ts +++ b/electron/managers/quickAskWindowConfig.ts @@ -13,10 +13,10 @@ export const quickAskWindowConfig: Electron.BrowserWindowConstructorOptions = { fullscreenable: false, resizable: false, center: true, - movable: false, + movable: true, maximizable: false, focusable: true, - transparent: true, + transparent: false, frame: false, type: 'panel', } diff --git a/electron/managers/window.ts b/electron/managers/window.ts index 918036365..dbb3a5101 100644 --- a/electron/managers/window.ts +++ b/electron/managers/window.ts @@ -141,6 +141,9 @@ class WindowManager { return this._quickAskWindow?.isDestroyed() ?? true } + /** + * Expand the quick ask window + */ expandQuickAskWindow(heightOffset: number): void { const width = quickAskWindowConfig.width! const height = quickAskWindowConfig.height! + heightOffset @@ -148,6 +151,9 @@ class WindowManager { this._quickAskWindow?.setSize(width, height, true) } + /** + * Send the selected text to the quick ask window. + */ sendQuickAskSelectedText(selectedText: string): void { this._quickAskWindow?.webContents.send( AppEvent.onSelectedText, @@ -180,6 +186,9 @@ class WindowManager { } } + /** + * Clean up all windows. + */ cleanUp(): void { if (!this.mainWindow?.isDestroyed()) { this.mainWindow?.close() diff --git a/electron/preload.quickask.ts b/electron/preload.quickask.ts new file mode 100644 index 000000000..7c2cadeb6 --- /dev/null +++ b/electron/preload.quickask.ts @@ -0,0 +1,32 @@ +/** + * Exposes a set of APIs to the renderer process via the contextBridge object. + * @module preload + */ + +import { APIEvents, APIRoutes } from '@janhq/core/node' +import { contextBridge, ipcRenderer } from 'electron' + +const interfaces: { [key: string]: (...args: any[]) => any } = {} + +// Loop over each route in APIRoutes +APIRoutes.forEach((method) => { + // For each method, create a function on the interfaces object + // This function invokes the method on the ipcRenderer with any provided arguments + + interfaces[method] = (...args: any[]) => ipcRenderer.invoke(method, ...args) +}) + +// Loop over each method in APIEvents +APIEvents.forEach((method) => { + // For each method, create a function on the interfaces object + // This function sets up an event listener on the ipcRenderer for the method + // The handler for the event is provided as an argument to the function + interfaces[method] = (handler: any) => ipcRenderer.on(method, handler) +}) + +// Expose the 'interfaces' object in the main world under the name 'electronAPI' +// This allows the renderer process to access these methods directly +contextBridge.exposeInMainWorld('electronAPI', { + ...interfaces, + isQuickAsk: () => true, +}) diff --git a/electron/preload.ts b/electron/preload.ts index 05f48d37a..dbfcd1f1e 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -3,7 +3,7 @@ * @module preload */ -import { APIEvents, APIRoutes, AppConfiguration, getAppConfigurations, updateAppConfiguration } from '@janhq/core/node' +import { APIEvents, APIRoutes, AppConfiguration } from '@janhq/core/node' import { contextBridge, ipcRenderer } from 'electron' import { readdirSync } from 'fs' @@ -13,9 +13,8 @@ const interfaces: { [key: string]: (...args: any[]) => any } = {} APIRoutes.forEach((method) => { // For each method, create a function on the interfaces object // This function invokes the method on the ipcRenderer with any provided arguments - + interfaces[method] = (...args: any[]) => ipcRenderer.invoke(method, ...args) - }) // Loop over each method in APIEvents @@ -26,20 +25,21 @@ APIEvents.forEach((method) => { interfaces[method] = (handler: any) => ipcRenderer.on(method, handler) }) - -interfaces['changeDataFolder'] = async path => { - const appConfiguration: AppConfiguration = await ipcRenderer.invoke('getAppConfigurations') +interfaces['changeDataFolder'] = async (path) => { + const appConfiguration: AppConfiguration = await ipcRenderer.invoke( + 'getAppConfigurations' + ) const currentJanDataFolder = appConfiguration.data_folder appConfiguration.data_folder = path const reflect = require('@alumna/reflect') const { err } = await reflect({ - src: currentJanDataFolder, - dest: path, - recursive: true, - delete: false, - overwrite: true, - errorOnExist: false, - }) + src: currentJanDataFolder, + dest: path, + recursive: true, + delete: false, + overwrite: true, + errorOnExist: false, + }) if (err) { console.error(err) throw err @@ -47,7 +47,7 @@ interfaces['changeDataFolder'] = async path => { await ipcRenderer.invoke('updateAppConfiguration', appConfiguration) } -interfaces['isDirectoryEmpty'] = async path => { +interfaces['isDirectoryEmpty'] = async (path) => { const dirChildren = await readdirSync(path) return dirChildren.filter((x) => x !== '.DS_Store').length === 0 } @@ -56,4 +56,5 @@ interfaces['isDirectoryEmpty'] = async path => { // This allows the renderer process to access these methods directly contextBridge.exposeInMainWorld('electronAPI', { ...interfaces, + isQuickAsk: () => false, }) diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 5f14d6f5c..aaa905a49 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -13,10 +13,7 @@ export const metadata: Metadata = { export default function RootLayout({ children }: PropsWithChildren) { return ( -
- - {children} - + {children} ) } diff --git a/web/app/search/UserInput.tsx b/web/app/search/UserInput.tsx index cec694c90..fcabc8ea4 100644 --- a/web/app/search/UserInput.tsx +++ b/web/app/search/UserInput.tsx @@ -66,7 +66,7 @@ const UserInput = () => {