mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-19 22:24:11 +00:00
feat: unlock changing port in UI (#476)
* refactor: unlock changing port in UI * Change server port (#464) * Ability to save custom port * Launch server on custom port & pass that port to electron * Add serverPort validation * Prevent changing port in docker --------- Co-authored-by: Snehanshu Phukon <snehanshu@mamboemm.com> --------- Co-authored-by: স্নেহাংশু ফুকন <hello@snehanshu.com> Co-authored-by: Snehanshu Phukon <snehanshu@mamboemm.com>
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
export const STATIC_PORT = 4001;
|
|
||||||
|
|
||||||
// REST stuff
|
// REST stuff
|
||||||
export const EVENT_DATA = ['eventdata'];
|
export const EVENT_DATA = ['eventdata'];
|
||||||
export const ALIASES = ['aliases'];
|
export const ALIASES = ['aliases'];
|
||||||
@@ -15,8 +13,9 @@ export const RUNTIME = ['runtimeStore'];
|
|||||||
const location = window.location;
|
const location = window.location;
|
||||||
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||||
|
|
||||||
|
const STATIC_PORT = 4001;
|
||||||
export const serverPort = import.meta.env.DEV ? STATIC_PORT : location.port;
|
export const serverPort = import.meta.env.DEV ? STATIC_PORT : location.port;
|
||||||
export const serverURL = import.meta.env.DEV ? `http://${location.hostname}:${serverPort}` : location.origin;
|
export const serverURL = `${location.protocol}//${location.hostname}:${serverPort}`;
|
||||||
export const websocketUrl = `${socketProtocol}://${location.hostname}:${serverPort}/ws`;
|
export const websocketUrl = `${socketProtocol}://${location.hostname}:${serverPort}/ws`;
|
||||||
|
|
||||||
export const eventURL = `${serverURL}/eventdata`;
|
export const eventURL = `${serverURL}/eventdata`;
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import {
|
import { Alias, EventData, OSCSettings, OscSubscription, Settings, UserFields, ViewSettings } from 'ontime-types';
|
||||||
Alias,
|
|
||||||
EventData,
|
|
||||||
OSCSettings,
|
|
||||||
OscSubscription,
|
|
||||||
Settings,
|
|
||||||
UserFields,
|
|
||||||
ViewSettings,
|
|
||||||
} from 'ontime-types';
|
|
||||||
|
|
||||||
import { apiRepoLatest } from '../../externals';
|
import { apiRepoLatest } from '../../externals';
|
||||||
import { InfoType } from '../models/Info';
|
import { InfoType } from '../models/Info';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp';
|
import { IoArrowUp } from '@react-icons/all-files/io5/IoArrowUp';
|
||||||
|
|
||||||
|
import { serverPort } from '../../common/api/apiConstants';
|
||||||
import useInfo from '../../common/hooks-query/useInfo';
|
import useInfo from '../../common/hooks-query/useInfo';
|
||||||
import { openLink } from '../../common/utils/linkUtils';
|
import { openLink } from '../../common/utils/linkUtils';
|
||||||
|
|
||||||
@@ -9,7 +10,7 @@ export default function InfoNif() {
|
|||||||
const { data } = useInfo();
|
const { data } = useInfo();
|
||||||
|
|
||||||
const handleClick = (address: string) => {
|
const handleClick = (address: string) => {
|
||||||
const baseURL = 'http://__IP__:4001';
|
const baseURL = `http://__IP__:${serverPort}`;
|
||||||
openLink(baseURL.replace('__IP__', address));
|
openLink(baseURL.replace('__IP__', address));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default function AppSettingsModal() {
|
|||||||
<ModalSplitInput
|
<ModalSplitInput
|
||||||
field='serverPort'
|
field='serverPort'
|
||||||
title='Ontime is available on port'
|
title='Ontime is available on port'
|
||||||
description='Default 4001'
|
description='Default 4001 (needs app restart to change)'
|
||||||
error={errors.serverPort?.message}
|
error={errors.serverPort?.message}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
@@ -69,7 +69,6 @@ export default function AppSettingsModal() {
|
|||||||
size='sm'
|
size='sm'
|
||||||
textAlign='right'
|
textAlign='right'
|
||||||
maxLength={5}
|
maxLength={5}
|
||||||
disabled
|
|
||||||
variant='ontime-filled-on-light'
|
variant='ontime-filled-on-light'
|
||||||
{...register('serverPort', {
|
{...register('serverPort', {
|
||||||
required: { value: true, message: 'Required field' },
|
required: { value: true, message: 'Required field' },
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ module.exports = {
|
|||||||
shutdownCode: 99,
|
shutdownCode: 99,
|
||||||
},
|
},
|
||||||
reactAppUrl: {
|
reactAppUrl: {
|
||||||
development: 'http://localhost:3000/editor',
|
development: (port = 4001) => `http://localhost:${port}/editor`,
|
||||||
production: 'http://localhost:4001/editor',
|
production: (port = 4001) => `http://localhost:${port}/editor`,
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
pathToEntrypoint: '../extraResources/server/index.cjs'
|
pathToEntrypoint: '../extraResources/server/index.cjs',
|
||||||
},
|
},
|
||||||
assets: {
|
assets: {
|
||||||
pathToAssets: './assets/',
|
pathToAssets: './assets/',
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+18
-14
@@ -30,21 +30,23 @@ let splash;
|
|||||||
let tray = null;
|
let tray = null;
|
||||||
|
|
||||||
async function startBackend() {
|
async function startBackend() {
|
||||||
await (async () => {
|
// in dev mode, we expect both UI and server to be running
|
||||||
// in dev mode, we expect both UI and server to be running
|
if (!isProduction) {
|
||||||
if (!isProduction) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const ontimeServer = require(nodePath);
|
const ontimeServer = require(nodePath);
|
||||||
const { initAssets, startServer, startOSCServer, startIntegrations } = ontimeServer;
|
const { initAssets, startServer, startOSCServer, startIntegrations } = ontimeServer;
|
||||||
|
|
||||||
await initAssets();
|
await initAssets();
|
||||||
|
|
||||||
loaded = await startServer();
|
const result = await startServer();
|
||||||
await startOSCServer();
|
loaded = result.message;
|
||||||
await startIntegrations();
|
|
||||||
})();
|
await startOSCServer();
|
||||||
|
await startIntegrations();
|
||||||
|
|
||||||
|
return result.serverPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,9 +157,11 @@ app.whenReady().then(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
startBackend()
|
startBackend()
|
||||||
.then(() => {
|
.then((port) => {
|
||||||
// Load page served by node or use React dev run
|
// Load page served by node or use React dev run
|
||||||
const clientUrl = isProduction ? electronConfig.reactAppUrl.production : electronConfig.reactAppUrl.development;
|
const clientUrl = isProduction
|
||||||
|
? electronConfig.reactAppUrl.production(port)
|
||||||
|
: electronConfig.reactAppUrl.development(port);
|
||||||
|
|
||||||
win
|
win
|
||||||
.loadURL(clientUrl)
|
.loadURL(clientUrl)
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ export const initAssets = async () => {
|
|||||||
export const startServer = async () => {
|
export const startServer = async () => {
|
||||||
checkStart(OntimeStartOrder.InitServer);
|
checkStart(OntimeStartOrder.InitServer);
|
||||||
|
|
||||||
const serverPort = 4001; // hardcoded for now
|
const { serverPort } = DataProvider.getSettings();
|
||||||
const returnMessage = `Ontime is listening on port ${serverPort}`;
|
const returnMessage = `Ontime is listening on port ${serverPort}`;
|
||||||
|
|
||||||
expressServer = http.createServer(app);
|
expressServer = http.createServer(app);
|
||||||
@@ -144,7 +144,7 @@ export const startServer = async () => {
|
|||||||
|
|
||||||
expressServer.listen(serverPort, '0.0.0.0');
|
expressServer.listen(serverPort, '0.0.0.0');
|
||||||
|
|
||||||
return returnMessage;
|
return { message: returnMessage, serverPort };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { failEmptyObjects, failIsNotArray } from '../utils/routerUtils.js';
|
|||||||
import { mergeObject } from '../utils/parserUtils.js';
|
import { mergeObject } from '../utils/parserUtils.js';
|
||||||
import { PlaybackService } from '../services/PlaybackService.js';
|
import { PlaybackService } from '../services/PlaybackService.js';
|
||||||
import { eventStore } from '../stores/EventStore.js';
|
import { eventStore } from '../stores/EventStore.js';
|
||||||
import { resolveDbPath } from '../setup.js';
|
import { isDocker, resolveDbPath } from '../setup.js';
|
||||||
import { oscIntegration } from '../services/integration-service/OscIntegration.js';
|
import { oscIntegration } from '../services/integration-service/OscIntegration.js';
|
||||||
import { logger } from '../classes/Logger.js';
|
import { logger } from '../classes/Logger.js';
|
||||||
import { deleteAllEvents, forceReset } from '../services/rundown-service/RundownService.js';
|
import { deleteAllEvents, forceReset } from '../services/rundown-service/RundownService.js';
|
||||||
@@ -208,6 +208,11 @@ export const postSettings = async (req, res) => {
|
|||||||
const editorKey = extractPin(req.body?.editorKey, settings.editorKey);
|
const editorKey = extractPin(req.body?.editorKey, settings.editorKey);
|
||||||
const operatorKey = extractPin(req.body?.operatorKey, settings.operatorKey);
|
const operatorKey = extractPin(req.body?.operatorKey, settings.operatorKey);
|
||||||
|
|
||||||
|
if (isDocker && req.body?.serverPort) {
|
||||||
|
return res.status(403).json({ message: `Can't change port when running inside docker` });
|
||||||
|
}
|
||||||
|
const serverPort = parseInt(req.body?.serverPort ?? settings.serverPort, 10);
|
||||||
|
|
||||||
let timeFormat = settings.timeFormat;
|
let timeFormat = settings.timeFormat;
|
||||||
if (req.body?.timeFormat === '12' || req.body?.timeFormat === '24') {
|
if (req.body?.timeFormat === '12' || req.body?.timeFormat === '24') {
|
||||||
timeFormat = req.body.timeFormat;
|
timeFormat = req.body.timeFormat;
|
||||||
@@ -221,6 +226,7 @@ export const postSettings = async (req, res) => {
|
|||||||
operatorKey,
|
operatorKey,
|
||||||
timeFormat,
|
timeFormat,
|
||||||
language,
|
language,
|
||||||
|
serverPort,
|
||||||
};
|
};
|
||||||
await DataProvider.setSettings(newData);
|
await DataProvider.setSettings(newData);
|
||||||
res.status(200).send(newData);
|
res.status(200).send(newData);
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ export const validateSettings = [
|
|||||||
body('operatorKey').isString().isLength({ min: 0, max: 4 }).optional({ nullable: true }),
|
body('operatorKey').isString().isLength({ min: 0, max: 4 }).optional({ nullable: true }),
|
||||||
body('timeFormat').isString().isIn(['12', '24']),
|
body('timeFormat').isString().isIn(['12', '24']),
|
||||||
body('language').isString(),
|
body('language').isString(),
|
||||||
|
body('serverPort').isPort().optional(),
|
||||||
(req, res, next) => {
|
(req, res, next) => {
|
||||||
const errors = validationResult(req);
|
const errors = validationResult(req);
|
||||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||||
|
|||||||
@@ -130,6 +130,7 @@ export const parseSettings = (data, enforce): Settings => {
|
|||||||
console.log('ERROR: unknown app version, skipping');
|
console.log('ERROR: unknown app version, skipping');
|
||||||
} else {
|
} else {
|
||||||
const settings = {
|
const settings = {
|
||||||
|
serverPort: s.serverPort || dbModel.settings.serverPort,
|
||||||
editorKey: s.editorKey || null,
|
editorKey: s.editorKey || null,
|
||||||
operatorKey: s.operatorKey || null,
|
operatorKey: s.operatorKey || null,
|
||||||
timeFormat: s.timeFormat || '24',
|
timeFormat: s.timeFormat || '24',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { TimeFormat } from './TimeFormat.type';
|
|||||||
export type Settings = {
|
export type Settings = {
|
||||||
app: 'ontime';
|
app: 'ontime';
|
||||||
version: 2;
|
version: 2;
|
||||||
serverPort: 4001;
|
serverPort: number;
|
||||||
editorKey: null | string;
|
editorKey: null | string;
|
||||||
operatorKey: null | string;
|
operatorKey: null | string;
|
||||||
timeFormat: TimeFormat;
|
timeFormat: TimeFormat;
|
||||||
|
|||||||
Reference in New Issue
Block a user