Skip to content

Commit

Permalink
wip: move http/api config to electron window
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Nov 12, 2023
1 parent 4963fd3 commit f373838
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 110 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"devDependencies": {
"@electron/notarize": "^2.1.0",
"@sofie-automation/code-standard-preset": "~2.5.2",
"@types/electron-prompt": "^1.6.5",
"@types/koa": "^2.13.11",
"@types/koa-router": "^7.4.7",
"@types/koa-static": "^4.0.4",
Expand All @@ -62,7 +61,6 @@
"@xencelabs-quick-keys/node": "^0.4.0",
"conf": "^10.2.0",
"electron-about-window": "^1.15.2",
"electron-prompt": "^1.7.0",
"electron-store": "^8.1.0",
"eventemitter3": "^4.0.7",
"exit-hook": "^2.2.1",
Expand Down
9 changes: 9 additions & 0 deletions src/apiTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export interface ApiStatusResponse {
export interface ApiConfigData {
host: string
port: number

httpEnabled: boolean
httpPort: number
}

export function compileStatus(client: CompanionSatelliteClient): ApiStatusResponse {
Expand All @@ -25,10 +28,16 @@ export function compileConfig(appConfig: Conf<SatelliteConfig>): ApiConfigData {
return {
host: appConfig.get('remoteIp'),
port: appConfig.get('remotePort'),

httpEnabled: appConfig.get('restEnabled'),
httpPort: appConfig.get('restPort'),
}
}

export function updateConfig(appConfig: Conf<SatelliteConfig>, newConfig: Partial<ApiConfigData>): void {
if (newConfig.host !== undefined) appConfig.set('remoteIp', newConfig.host)
if (newConfig.port !== undefined) appConfig.set('remotePort', newConfig.port)

if (newConfig.httpEnabled !== undefined) appConfig.set('restEnabled', newConfig.httpEnabled)
if (newConfig.httpPort !== undefined) appConfig.set('restPort', newConfig.httpPort)
}
76 changes: 9 additions & 67 deletions src/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import * as path from 'path'
// eslint-disable-next-line node/no-unpublished-import
import electronStore from 'electron-store'
// eslint-disable-next-line node/no-unpublished-import
import prompt from 'electron-prompt'
// eslint-disable-next-line node/no-unpublished-import
import openAboutWindow from 'electron-about-window'
import { DeviceManager } from './devices'
import { CompanionSatelliteClient } from './client'
import { DEFAULT_PORT, DEFAULT_REST_PORT } from './lib'
import { DEFAULT_PORT } from './lib'
import { RestServer } from './rest'
import { SatelliteConfig, ensureFieldsPopulated } from './config'
import { ApiConfigData, ApiStatusResponse, compileConfig, compileStatus, updateConfig } from './apiTypes'
Expand Down Expand Up @@ -52,18 +50,13 @@ function restartRestApi() {
server.open()
}

const menuItemApiEnableDisable = new MenuItem({
label: 'Enable API',
type: 'checkbox',
click: toggleRestApi,
})
const menuItemApiPort = new MenuItem({
label: 'Change API Port',
click: changeRestPort,
})
const trayMenu = new Menu()
trayMenu.append(menuItemApiEnableDisable)
trayMenu.append(menuItemApiPort)
trayMenu.append(
new MenuItem({
label: 'Scan devices',
click: trayScanDevices,
})
)
trayMenu.append(
new MenuItem({
label: 'Configure',
Expand Down Expand Up @@ -107,12 +100,6 @@ trayMenu.append(
},
})
)
trayMenu.append(
new MenuItem({
label: 'Scan devices',
click: trayScanDevices,
})
)
trayMenu.append(
new MenuItem({
label: 'About',
Expand All @@ -126,18 +113,6 @@ trayMenu.append(
})
)

function updateTray() {
if (!tray) throw new Error(`Tray not ready`)

const restEnabled = !!appConfig.get('restEnabled')

menuItemApiEnableDisable.checked = restEnabled
menuItemApiPort.enabled = restEnabled

console.log('set tray')
tray.setContextMenu(trayMenu)
}

app.whenReady()
.then(async () => {
console.log('App ready')
Expand Down Expand Up @@ -169,46 +144,13 @@ app.whenReady()
tray?.setImage(trayImageOffline)
})

updateTray()
console.log('set tray')
tray.setContextMenu(trayMenu)
})
.catch((e) => {
dialog.showErrorBox(`Startup error`, `Failed to launch: ${e}`)
})

function changeRestPort() {
const current = appConfig.get('restPort')
prompt({
title: 'Companion Satellite API Port Number',
label: 'API Port',
value: `${current ?? DEFAULT_REST_PORT}`,
inputAttrs: {},
type: 'input',
})
.then((r) => {
if (r === null) {
console.log('user cancelled')
} else {
const r2 = Number(r)
console.log('new rest port', r2)
if (!isNaN(r2)) {
appConfig.set('restPort', r)
restartRestApi()
}
}
})
.catch((e) => {
console.error('Failed to change hrest port', e)
})
}
function toggleRestApi() {
const current = appConfig.get('restEnabled')
appConfig.set('restEnabled', !current)

restartRestApi()

updateTray()
}

function trayQuit() {
console.log('quit click')
dialog
Expand Down
1 change: 0 additions & 1 deletion src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const DEFAULT_PORT = 16622
export const DEFAULT_REST_PORT = 9999 // Note: this is also defined elsewhere

export function assertNever(_v: never): void {
// Nothing to do
Expand Down
8 changes: 8 additions & 0 deletions src/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export class RestServer {
this.client = client
this.devices = devices

// Monitor for config changes
this.appConfig.onDidChange('restEnabled', this.open.bind(this))
this.appConfig.onDidChange('restPort', this.open.bind(this))

this.app = new Koa()
this.app.use(serve(path.join(__dirname, '../webui/dist')))

Expand Down Expand Up @@ -104,6 +108,10 @@ export class RestServer {
partialConfig.port = port
}

// Ensure some fields cannot be changed
delete partialConfig.httpEnabled
delete partialConfig.httpPort

updateConfig(this.appConfig, partialConfig)
ctx.body = compileConfig(this.appConfig)
}
Expand Down
4 changes: 1 addition & 3 deletions webui/src/Api/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { ApiConfigData } from '../../../src/apiTypes'

export type ApiConfigData2 = ApiConfigData

export type SaveApiConfigData = (newConfig: Partial<ApiConfigData2>) => Promise<void>
export type SaveApiConfigData = (newConfig: Partial<ApiConfigData>) => Promise<void>
2 changes: 1 addition & 1 deletion webui/src/ElectronApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function ElectronApp() {
</MyErrorBoundary>

<MyErrorBoundary>
<SettingsForm {...restConfigApi} />
<SettingsForm {...restConfigApi} includeApiEnable={true} />
</MyErrorBoundary>
</Col>
</Row>
Expand Down
62 changes: 59 additions & 3 deletions webui/src/SettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ interface SettingsFormProps {
currentConfig: ApiConfigData | null
loadError: Error | null
saveConfig: SaveApiConfigData
includeApiEnable: boolean
}
export function SettingsForm({ currentConfig, loadError, saveConfig }: SettingsFormProps) {
export function SettingsForm({ currentConfig, loadError, saveConfig, includeApiEnable }: SettingsFormProps) {
const [modifiedConfig, setModifiedConfig] = useState<Partial<ApiConfigData>>({})
const fullModifiedConfig: ApiConfigData | undefined = useMemo(() => {
return currentConfig ? { ...currentConfig, ...modifiedConfig } : undefined
Expand Down Expand Up @@ -37,6 +38,7 @@ export function SettingsForm({ currentConfig, loadError, saveConfig }: SettingsF
hasChanges={Object.keys(modifiedConfig).length > 0}
setModifiedConfig={setModifiedConfig}
saveConfig={mySaveConfig}
includeApiEnable={includeApiEnable}
/>
) : (
'Loading...'
Expand All @@ -50,8 +52,15 @@ interface SettingsFormInnerProps {
hasChanges: boolean
setModifiedConfig: React.Dispatch<React.SetStateAction<Partial<ApiConfigData>>>
saveConfig: () => void
includeApiEnable: boolean
}
function SettingsFormInner({ fullConfig, hasChanges, setModifiedConfig, saveConfig }: SettingsFormInnerProps) {
function SettingsFormInner({
fullConfig,
hasChanges,
setModifiedConfig,
saveConfig,
includeApiEnable,
}: SettingsFormInnerProps) {
const setHost = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.currentTarget.value
Expand All @@ -74,6 +83,29 @@ function SettingsFormInner({ fullConfig, hasChanges, setModifiedConfig, saveConf
},
[setModifiedConfig]
)
const setHttpEnabled = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const value = !!e.currentTarget.checked

setModifiedConfig((oldConfig) => ({
...oldConfig,
httpEnabled: value,
}))
},
[setModifiedConfig]
)

const setHttpPort = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const value = Number(e.currentTarget.value)

setModifiedConfig((oldConfig) => ({
...oldConfig,
httpPort: value,
}))
},
[setModifiedConfig]
)

const saveConfigFull = useCallback(
(e: React.FormEvent<HTMLFormElement>) => {
Expand All @@ -86,8 +118,10 @@ function SettingsFormInner({ fullConfig, hasChanges, setModifiedConfig, saveConf

return (
<Form onSubmit={saveConfigFull}>
<legend>Companion Connection</legend>

<Form.Group className="mb-3" controlId="formCompanionAddress">
<Form.Label>Companion Address</Form.Label>
<Form.Label>Address</Form.Label>
<Form.Control
type="text"
placeholder="Companion address (eg 127.0.0.1 or companion.local)"
Expand All @@ -111,6 +145,28 @@ function SettingsFormInner({ fullConfig, hasChanges, setModifiedConfig, saveConf
</Form.Text>
</Form.Group>

{includeApiEnable && (
<>
<legend>HTTP Interface & API</legend>

<Form.Group className="mb-3" controlId="formHttpPort">
<Form.Check type="switch" label="Enabled" checked={fullConfig.httpEnabled} onChange={setHttpEnabled} />
</Form.Group>

<Form.Group className="mb-3" controlId="formHttpPort">
<Form.Label>Port</Form.Label>
<Form.Control
type="number"
placeholder="9999"
min={1}
max={65535}
value={fullConfig.httpPort}
onChange={setHttpPort}
/>
</Form.Group>
</>
)}

<Button variant="primary" type="submit" disabled={!hasChanges}>
Save
</Button>
Expand Down
2 changes: 1 addition & 1 deletion webui/src/WebApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function WebApp() {
</MyErrorBoundary>

<MyErrorBoundary>
<SettingsForm {...restApi} />
<SettingsForm {...restApi} includeApiEnable={false} />
</MyErrorBoundary>
</Col>
</Row>
Expand Down
1 change: 0 additions & 1 deletion webui/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default defineConfig({
input: {
main: resolve(__dirname, 'index.html'),
electron: resolve(__dirname, 'electron.html'),
preload: resolve(__dirname, 'src/electronPreload.ts'),
},
},
},
Expand Down
31 changes: 0 additions & 31 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -711,15 +711,6 @@ __metadata:
languageName: node
linkType: hard

"@types/electron-prompt@npm:^1.6.5":
version: 1.6.5
resolution: "@types/electron-prompt@npm:1.6.5"
dependencies:
electron: "npm:latest"
checksum: bf9be343a960fa6e54dbb907a54d68bef3cf1c9f9ca24271e3ea9a165d27f9d4e90b300c62b2762ded4d7083411b4101418a47ed478ae25e4e7959cfffe7a489
languageName: node
linkType: hard

"@types/express-serve-static-core@npm:^4.17.33":
version: 4.17.41
resolution: "@types/express-serve-static-core@npm:4.17.41"
Expand Down Expand Up @@ -2026,7 +2017,6 @@ __metadata:
"@julusian/skia-canvas": "npm:^1.0.5"
"@loupedeck/node": "npm:^1.0.0"
"@sofie-automation/code-standard-preset": "npm:~2.5.2"
"@types/electron-prompt": "npm:^1.6.5"
"@types/koa": "npm:^2.13.11"
"@types/koa-router": "npm:^7.4.7"
"@types/koa-static": "npm:^4.0.4"
Expand All @@ -2039,7 +2029,6 @@ __metadata:
electron: "npm:^25.9.4"
electron-about-window: "npm:^1.15.2"
electron-builder: "npm:^24.6.4"
electron-prompt: "npm:^1.7.0"
electron-store: "npm:^8.1.0"
eventemitter3: "npm:^4.0.7"
exit-hook: "npm:^2.2.1"
Expand Down Expand Up @@ -2531,13 +2520,6 @@ __metadata:
languageName: node
linkType: hard

"electron-prompt@npm:^1.7.0":
version: 1.7.0
resolution: "electron-prompt@npm:1.7.0"
checksum: 5c2be70739838257944c8e9ade800b13b8efe4f908d46d3fd28740c8f4460150df70a80acd8138e66bd782befb64ccf8d30c616ad2762644d8998d5a6bdd34da
languageName: node
linkType: hard

"electron-publish@npm:24.5.0":
version: 24.5.0
resolution: "electron-publish@npm:24.5.0"
Expand Down Expand Up @@ -2576,19 +2558,6 @@ __metadata:
languageName: node
linkType: hard

"electron@npm:latest":
version: 27.0.4
resolution: "electron@npm:27.0.4"
dependencies:
"@electron/get": "npm:^2.0.0"
"@types/node": "npm:^18.11.18"
extract-zip: "npm:^2.0.1"
bin:
electron: cli.js
checksum: ef8c45ec3e18e6c8616671bfb2adab9e6d4a58450a5bda6e862072cd4726b1d65b3949b3f4e3de1885b7af3a5105b05e66b0d9dc26745eb7ed429ce32a1a6654
languageName: node
linkType: hard

"emoji-regex@npm:^8.0.0":
version: 8.0.0
resolution: "emoji-regex@npm:8.0.0"
Expand Down

0 comments on commit f373838

Please sign in to comment.