137 lines
3.6 KiB
JavaScript
137 lines
3.6 KiB
JavaScript
import { BrowserWindow, ipcMain, globalShortcut } from 'electron'
|
|
import path, { dirname } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const __filename = fileURLToPath(import.meta.url)
|
|
const __dirname = dirname(__filename)
|
|
|
|
let spotlightWin
|
|
|
|
function getSpotlightRouteUrl() {
|
|
const routePath = '/dashboard/electron/spotlightcontent'
|
|
|
|
// Dev: BrowserRouter, so use a real path.
|
|
if (process.env.ELECTRON_START_URL) {
|
|
const base = String(process.env.ELECTRON_START_URL).replace(/\/$/, '')
|
|
return `${base}${routePath}`
|
|
}
|
|
|
|
// Prod (file://): App.jsx chooses HashRouter when `index.html` is in the URL.
|
|
// So we must load `index.html#/electron/spotlightcontent`.
|
|
return {
|
|
filePath: path.join(__dirname, '../build/index.html'),
|
|
hash: routePath
|
|
}
|
|
}
|
|
|
|
export function openSpotlightContentWindow() {
|
|
// If already open, just focus it (avoids accidental window spam).
|
|
if (spotlightWin && !spotlightWin.isDestroyed()) {
|
|
spotlightWin.show()
|
|
spotlightWin.focus()
|
|
return
|
|
}
|
|
|
|
spotlightWin = new BrowserWindow({
|
|
width: 700,
|
|
height: 40,
|
|
frame: false,
|
|
resizable: false,
|
|
center: true,
|
|
vibrancy: 'menu',
|
|
transparent: true,
|
|
icon: path.join(__dirname, './logo512.png'),
|
|
webPreferences: {
|
|
nodeIntegration: true,
|
|
contextIsolation: false
|
|
}
|
|
})
|
|
|
|
const target = getSpotlightRouteUrl()
|
|
if (typeof target === 'string') {
|
|
spotlightWin.loadURL(target)
|
|
} else {
|
|
spotlightWin.loadFile(target.filePath, { hash: target.hash })
|
|
}
|
|
|
|
// Hide spotlight window instead of destroying it when closed
|
|
spotlightWin.on('close', (event) => {
|
|
event.preventDefault()
|
|
if (spotlightWin && !spotlightWin.isDestroyed()) {
|
|
spotlightWin.hide()
|
|
}
|
|
})
|
|
|
|
// Hide spotlight window when it loses focus (clicking outside)
|
|
spotlightWin.on('blur', () => {
|
|
if (spotlightWin && !spotlightWin.isDestroyed()) {
|
|
spotlightWin.hide()
|
|
}
|
|
})
|
|
|
|
attachSpotlightKeyboardShortcuts(spotlightWin)
|
|
}
|
|
|
|
function attachSpotlightKeyboardShortcuts(browserWindow) {
|
|
if (!browserWindow) return
|
|
|
|
browserWindow.webContents.on('before-input-event', (event, input) => {
|
|
// ESC -> hide SpotlightContent window (if it's the spotlight window)
|
|
if (
|
|
input?.type === 'keyDown' &&
|
|
String(input?.key || '').toLowerCase() === 'escape' &&
|
|
browserWindow === spotlightWin
|
|
) {
|
|
event.preventDefault()
|
|
if (spotlightWin && !spotlightWin.isDestroyed()) {
|
|
spotlightWin.hide()
|
|
}
|
|
return
|
|
}
|
|
|
|
// Alt+Shift+Q -> open SpotlightContent window
|
|
if (
|
|
input?.type === 'keyDown' &&
|
|
input?.alt === true &&
|
|
input?.shift === true &&
|
|
String(input?.key || '').toLowerCase() === 'q'
|
|
) {
|
|
event.preventDefault()
|
|
openSpotlightContentWindow()
|
|
}
|
|
})
|
|
}
|
|
|
|
export function registerGlobalShortcuts() {
|
|
try {
|
|
const registered = globalShortcut.register('Alt+Shift+Q', () => {
|
|
openSpotlightContentWindow()
|
|
})
|
|
|
|
if (!registered) {
|
|
console.warn('[globalShortcut] Failed to register Alt+Shift+Q')
|
|
}
|
|
} catch (e) {
|
|
console.warn(
|
|
'[globalShortcut] Error registering Alt+Shift+Q',
|
|
e?.message || e
|
|
)
|
|
}
|
|
}
|
|
|
|
export function setupSpotlightIPC() {
|
|
// IPC handler to resize spotlight window
|
|
ipcMain.handle('spotlight-window-resize', (event, height) => {
|
|
if (!spotlightWin || spotlightWin.isDestroyed()) return false
|
|
try {
|
|
const currentBounds = spotlightWin.getBounds()
|
|
spotlightWin.setSize(currentBounds.width, height)
|
|
spotlightWin.center()
|
|
return true
|
|
} catch (e) {
|
|
console.warn('[spotlight] Failed to resize window.', e?.message || e)
|
|
return false
|
|
}
|
|
})
|
|
}
|