mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-13 11:23:50 +00:00
feat: optional welcome modal
welcome modal is persisted in app state created endpoints to set the visibility added UI to support feature Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
This commit is contained in:
@@ -34,7 +34,7 @@ export class SocketServer implements IAdapter {
|
||||
private wss: WebSocketServer | null;
|
||||
private readonly clients: Map<string, Client>;
|
||||
private lastConnection: Date | null = null;
|
||||
private isFirstEditor = true;
|
||||
private shouldShowWelcome = true;
|
||||
|
||||
constructor() {
|
||||
if (instance) {
|
||||
@@ -47,7 +47,8 @@ export class SocketServer implements IAdapter {
|
||||
this.wss = null;
|
||||
}
|
||||
|
||||
init(server: Server, prefix?: string) {
|
||||
init(server: Server, showWelcome: boolean, prefix?: string) {
|
||||
this.shouldShowWelcome = showWelcome;
|
||||
this.wss = new WebSocketServer({ path: `${prefix}/ws`, server, maxPayload: this.MAX_PAYLOAD });
|
||||
|
||||
this.wss.on('connection', (ws) => {
|
||||
@@ -136,8 +137,8 @@ export class SocketServer implements IAdapter {
|
||||
previousData.path = payload;
|
||||
this.clients.set(clientId, previousData);
|
||||
|
||||
if (payload.includes('editor') && this.isFirstEditor) {
|
||||
this.isFirstEditor = false;
|
||||
if (payload.includes('editor') && this.shouldShowWelcome) {
|
||||
this.shouldShowWelcome = false;
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: 'dialog',
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { Request, Response } from 'express';
|
||||
import { isDocker } from '../../externals.js';
|
||||
import { failEmptyObjects } from '../../utils/routerUtils.js';
|
||||
import { getDataProvider } from '../../classes/data-provider/DataProvider.js';
|
||||
import * as appState from '../../services/app-state-service/AppStateService.js';
|
||||
|
||||
import { extractPin } from './settings.utils.js';
|
||||
|
||||
@@ -65,3 +66,8 @@ export async function postSettings(req: Request, res: Response<Settings | ErrorR
|
||||
res.status(400).send({ message });
|
||||
}
|
||||
}
|
||||
|
||||
export async function postWelcomeDialog(req: Request, res: Response) {
|
||||
const show = await appState.setShowWelcomeDialog(req.body.show);
|
||||
res.status(200).send({ show });
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import express from 'express';
|
||||
import { getSettings, postSettings } from './settings.controller.js';
|
||||
import { validateSettings } from './settings.validation.js';
|
||||
import { getSettings, postSettings, postWelcomeDialog } from './settings.controller.js';
|
||||
import { validateSettings, validateWelcomeDialog } from './settings.validation.js';
|
||||
|
||||
export const router = express.Router();
|
||||
|
||||
router.post('/welcomedialog', validateWelcomeDialog, postWelcomeDialog);
|
||||
|
||||
router.get('/', getSettings);
|
||||
router.post('/', validateSettings, postSettings);
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import { body, validationResult } from 'express-validator';
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/settings/welcomedialog
|
||||
*/
|
||||
export const validateWelcomeDialog = [
|
||||
body('show').exists().isBoolean(),
|
||||
(req: Request, res: Response, next: NextFunction) => {
|
||||
const errors = validationResult(req);
|
||||
if (!errors.isEmpty()) return res.status(422).json({ errors: errors.array() });
|
||||
next();
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* @description Validates object for POST /ontime/settings
|
||||
*/
|
||||
|
||||
@@ -44,6 +44,7 @@ import { clearUploadfolder } from './utils/upload.js';
|
||||
import { generateCrashReport } from './utils/generateCrashReport.js';
|
||||
import { timerConfig } from './config/config.js';
|
||||
import { serverTryDesiredPort, getNetworkInterfaces } from './utils/network.js';
|
||||
import { getShowWelcomeDialog } from './services/app-state-service/AppStateService.js';
|
||||
|
||||
console.log('\n');
|
||||
consoleHighlight(`Starting Ontime version ${ONTIME_VERSION}`);
|
||||
@@ -166,8 +167,9 @@ export const startServer = async (
|
||||
// the express server must be started before the socket otherwise the on error event listener will not attach properly
|
||||
const resultPort = await serverTryDesiredPort(expressServer, desiredPort);
|
||||
await getDataProvider().setSettings({ ...settings, serverPort: resultPort });
|
||||
const showWelcome = await getShowWelcomeDialog();
|
||||
|
||||
socket.init(expressServer, prefix);
|
||||
socket.init(expressServer, showWelcome, prefix);
|
||||
|
||||
/**
|
||||
* Module initialises the services and provides initial payload for the store
|
||||
|
||||
@@ -8,6 +8,7 @@ import { shouldCrashDev } from '../../utils/development.js';
|
||||
|
||||
interface AppState {
|
||||
lastLoadedProject?: string;
|
||||
showWelcomeDialog?: boolean;
|
||||
}
|
||||
|
||||
const adapter = new JSONFile<AppState>(publicFiles.appState);
|
||||
@@ -34,3 +35,19 @@ export async function setLastLoadedProject(filename: string): Promise<void> {
|
||||
config.data.lastLoadedProject = filename;
|
||||
await config.write();
|
||||
}
|
||||
|
||||
export async function getShowWelcomeDialog(): Promise<boolean> {
|
||||
// in test environment, we do not want the dialog
|
||||
if (isTest) return false;
|
||||
|
||||
await config.read();
|
||||
return config.data.showWelcomeDialog ?? true; // default to true
|
||||
}
|
||||
|
||||
export async function setShowWelcomeDialog(show: boolean): Promise<boolean> {
|
||||
if (isTest) return;
|
||||
|
||||
config.data.showWelcomeDialog = show;
|
||||
await config.write();
|
||||
return show;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user