import { createContext, useEffect, useState } from 'react' import PropTypes from 'prop-types' import { useNavigate } from 'react-router-dom' // Only available in Electron renderer const electron = window.require ? window.require('electron') : null const ipcRenderer = electron ? electron.ipcRenderer : null // Utility to check if running in Electron export function isElectron() { // Renderer process if ( typeof window !== 'undefined' && window.process && window.process.type === 'renderer' ) { return true } // User agent if ( typeof navigator === 'object' && typeof navigator.userAgent === 'string' && navigator.userAgent.indexOf('Electron') >= 0 ) { return true } return false } const ElectronContext = createContext() const ElectronProvider = ({ children }) => { const [platform, setPlatform] = useState('unknown') const [isMaximized, setIsMaximized] = useState(false) const [isFullScreen, setIsFullScreen] = useState(false) const [electronAvailable] = useState(isElectron()) const navigate = useNavigate() // Function to open external URL via Electron const openExternalUrl = (url) => { if (electronAvailable && ipcRenderer) { ipcRenderer.invoke('open-external-url', url) return true } return false } // Function to open internal URL via Electron const openInternalUrl = (url) => { if (electronAvailable && ipcRenderer) { ipcRenderer.invoke('open-internal-url', url) return true } return false } useEffect(() => { if (!ipcRenderer) return // Get initial platform ipcRenderer.invoke('os-info').then((info) => { if (info && info.platform) setPlatform(info.platform) }) // Get initial window state ipcRenderer.invoke('window-state').then((state) => { if (state && typeof state.isMaximized === 'boolean') { setIsMaximized(state.isMaximized) } if (state && typeof state.isFullScreen === 'boolean') { setIsFullScreen(state.isFullScreen) } }) // Listen for window state changes const windowStateHandler = (event, state) => { if (state && typeof state.isMaximized === 'boolean') { setIsMaximized(state.isMaximized) } if (state && typeof state.isFullScreen === 'boolean') { setIsFullScreen(state.isFullScreen) } } ipcRenderer.on('window-state', windowStateHandler) // Listen for navigate const navigateHandler = (event, url) => { console.log('Navigating to:', url) navigate(url) } ipcRenderer.on('navigate', navigateHandler) return () => { ipcRenderer.removeListener('navigate', navigateHandler) ipcRenderer.removeListener('window-state', windowStateHandler) } }, []) // Window control handler const handleWindowControl = (action) => { if (electronAvailable && ipcRenderer) { ipcRenderer.send('window-control', action) } } const getAuthSession = async () => { if (!electronAvailable || !ipcRenderer) return null return await ipcRenderer.invoke('auth-session-get') } const setAuthSession = async (session) => { if (!electronAvailable || !ipcRenderer) return false return await ipcRenderer.invoke('auth-session-set', session) } const clearAuthSession = async () => { if (!electronAvailable || !ipcRenderer) return false return await ipcRenderer.invoke('auth-session-clear') } // Backwards-compatible helpers const getToken = async () => { const session = await getAuthSession() return session?.token || null } const setToken = async (token) => { const session = (await getAuthSession()) || {} return await setAuthSession({ ...session, token }) } const resizeSpotlightWindow = async (height) => { if (!electronAvailable || !ipcRenderer) return false try { return await ipcRenderer.invoke('spotlight-window-resize', height) } catch (error) { console.warn( '[ElectronContext] Failed to resize spotlight window:', error ) return false } } return ( {children} ) } ElectronProvider.propTypes = { children: PropTypes.node.isRequired } export { ElectronContext, ElectronProvider }