96b099d892
- electron/remote.js: WebSocket client that connects to central server - Smart URL builder: domain+443→wss://, IP/non-443→ws://, http/https→ws/wss - UUID token auth on connect - Auto-reconnect with exponential backoff (3s→60s) - Handles commands: start_stream, stop_stream, update_stream, stop_all - Sends: devices, stream_status, logs - Ping/pong keepalive every 25s - Self-signed cert allowed for local IPs (192.168.x, 10.x, .local) - electron/main.js: IPC handlers remote-connect/disconnect/get-url, generate-token; forwards commands to FFmpeg, status to renderer - electron/preload.js: exposes remoteConnect, remoteDisconnect, remoteGetUrl, generateToken, onRemoteStatus, onRemoteCommand - src/components/RemoteSettings.jsx: new UI tab - Server + port fields (default 443, auto wss/ws) - URL preview - Token display with copy + regenerate - Machine name field - Connection status bar with animated states - src/App.jsx: Remote tab added, remote state persisted to config - src/styles/App.css: remote status bar, token display, actions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
48 lines
2.2 KiB
JavaScript
48 lines
2.2 KiB
JavaScript
const { contextBridge, ipcRenderer } = require('electron')
|
|
|
|
contextBridge.exposeInMainWorld('electronAPI', {
|
|
// Config
|
|
getConfig: () => ipcRenderer.invoke('get-config'),
|
|
saveConfig: (config) => ipcRenderer.invoke('save-config', config),
|
|
|
|
// Devices
|
|
getDevices: () => ipcRenderer.invoke('get-devices'),
|
|
getWindows: () => ipcRenderer.invoke('get-windows'),
|
|
|
|
// Streams
|
|
startStream: (config) => ipcRenderer.invoke('start-stream', config),
|
|
stopStream: (id) => ipcRenderer.invoke('stop-stream', id),
|
|
getActiveStreams: () => ipcRenderer.invoke('get-active-streams'),
|
|
|
|
// Tolbek receiver
|
|
startTolbek: (config) => ipcRenderer.invoke('start-tolbek', config),
|
|
stopTolbek: () => ipcRenderer.invoke('stop-tolbek'),
|
|
|
|
// File system helpers
|
|
pickFolder: () => ipcRenderer.invoke('pick-folder'),
|
|
openFolder: (p) => ipcRenderer.invoke('open-folder', p),
|
|
|
|
// Remote control
|
|
remoteConnect: (cfg) => ipcRenderer.invoke('remote-connect', cfg),
|
|
remoteDisconnect: () => ipcRenderer.invoke('remote-disconnect'),
|
|
remoteGetUrl: (cfg) => ipcRenderer.invoke('remote-get-url', cfg),
|
|
generateToken: () => ipcRenderer.invoke('generate-token'),
|
|
|
|
// Window controls
|
|
minimizeWindow: () => ipcRenderer.invoke('minimize-window'),
|
|
hideWindow: () => ipcRenderer.invoke('hide-window'),
|
|
updateTrayCount: (count) => ipcRenderer.send('update-tray-count', count),
|
|
|
|
// Event listeners
|
|
onStreamStatus: (cb) => ipcRenderer.on('stream-status', (_, d) => cb(d)),
|
|
onStreamLog: (cb) => ipcRenderer.on('stream-log', (_, d) => cb(d)),
|
|
onStreamError: (cb) => ipcRenderer.on('stream-error', (_, d) => cb(d)),
|
|
onStreamEnded: (cb) => ipcRenderer.on('stream-ended', (_, d) => cb(d)),
|
|
onStreamReconnecting: (cb) => ipcRenderer.on('stream-reconnecting', (_, d) => cb(d)),
|
|
onAllStreamsStopped: (cb) => ipcRenderer.on('all-streams-stopped', () => cb()),
|
|
onRemoteStatus: (cb) => ipcRenderer.on('remote-status', (_, d) => cb(d)),
|
|
onRemoteCommand: (cb) => ipcRenderer.on('remote-command', (_, d) => cb(d)),
|
|
|
|
removeAllListeners: (channel) => ipcRenderer.removeAllListeners(channel)
|
|
})
|