@@ -119,7 +111,6 @@ export default function Countdown(props) {
) : (
-
Time Now
{clock}
@@ -127,11 +118,7 @@ export default function Countdown(props) {
{runningMessage}
-
+
{formattedTimer}
{follow?.title || 'Untitled Event'}
@@ -139,18 +126,13 @@ export default function Countdown(props) {
Start Time
-
- {startTime}
-
+
{startTime}
End Time
-
- {endTime}
-
+
{endTime}
-
)}
diff --git a/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx b/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx
index 69eb3b2fb..0a745f2eb 100644
--- a/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx
+++ b/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx
@@ -1,10 +1,8 @@
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
-import { useAtom } from 'jotai';
import { EventData, Message, Playback, TimerType, ViewSettings } from 'ontime-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
-import { mirrorViewersAtom } from '../../../common/atoms/ViewerSettings';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
import { TimeManagerType } from '../../../common/models/TimeManager.type';
@@ -14,6 +12,7 @@ import { formatTimerDisplay, getTimerByType } from '../common/viewerUtils';
import './MinimalTimer.scss';
interface MinimalTimerProps {
+ isMirrored: boolean;
pres: Message;
time: TimeManagerType;
viewSettings: ViewSettings;
@@ -21,10 +20,9 @@ interface MinimalTimerProps {
}
export default function MinimalTimer(props: MinimalTimerProps) {
- const { pres, time, viewSettings, general } = props;
+ const { isMirrored, pres, time, viewSettings, general } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const [searchParams] = useSearchParams();
- const [isMirrored] = useAtom(mirrorViewersAtom);
useEffect(() => {
document.title = 'ontime - Minimal Timer';
diff --git a/apps/client/src/features/viewers/public/Public.tsx b/apps/client/src/features/viewers/public/Public.tsx
index 02d44b0a5..f28f8a4c2 100644
--- a/apps/client/src/features/viewers/public/Public.tsx
+++ b/apps/client/src/features/viewers/public/Public.tsx
@@ -1,19 +1,19 @@
import { useEffect } from 'react';
import QRCode from 'react-qr-code';
import { AnimatePresence, motion } from 'framer-motion';
-import { useAtom } from 'jotai';
-import PropTypes from 'prop-types';
+import { EventData, Message, OntimeEvent, ViewSettings } from 'ontime-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
-import { mirrorViewersAtom } from '../../../common/atoms/ViewerSettings';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import Schedule from '../../../common/components/schedule/Schedule';
import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext';
import ScheduleNav from '../../../common/components/schedule/ScheduleNav';
import TitleCard from '../../../common/components/title-card/TitleCard';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
+import { TimeManagerType } from '../../../common/models/TimeManager.type';
import { formatTime } from '../../../common/utils/time';
import { titleVariants } from '../common/animation';
+import { TitleManager } from '../ViewWrapper';
import './Public.scss';
@@ -22,21 +22,20 @@ const formatOptions = {
format: 'hh:mm:ss a',
};
-Public.propTypes = {
- publ: PropTypes.object,
- publicTitle: PropTypes.object,
- time: PropTypes.object,
- events: PropTypes.array,
- publicSelectedId: PropTypes.string,
- general: PropTypes.object,
- viewSettings: PropTypes.object,
-};
+interface BackstageProps {
+ isMirrored: boolean;
+ publ: Message;
+ publicTitle: TitleManager;
+ time: TimeManagerType;
+ events: OntimeEvent[];
+ publicSelectedId: string | null;
+ general: EventData;
+ viewSettings: ViewSettings;
+}
-// @ts-expect-error unable to type just yet
-export default function Public(props) {
- const { publ, publicTitle, time, events, publicSelectedId, general, viewSettings } = props;
+export default function Public(props: BackstageProps) {
+ const { isMirrored, publ, publicTitle, time, events, publicSelectedId, general, viewSettings } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
- const [isMirrored] = useAtom(mirrorViewersAtom);
useEffect(() => {
document.title = 'ontime - Public Screen';
diff --git a/apps/client/src/features/viewers/studio/StudioClock.jsx b/apps/client/src/features/viewers/studio/StudioClock.jsx
index 35e323cf1..78f540e2c 100644
--- a/apps/client/src/features/viewers/studio/StudioClock.jsx
+++ b/apps/client/src/features/viewers/studio/StudioClock.jsx
@@ -1,10 +1,9 @@
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
-import { useAtom } from 'jotai';
+import { millisToString } from 'ontime-utils';
import PropTypes from 'prop-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
-import { mirrorViewersAtom } from '../../../common/atoms/ViewerSettings';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import useFitText from '../../../common/hooks/useFitText';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
@@ -13,7 +12,6 @@ import { formatEventList, getEventsWithDelay, trimEventlist } from '../../../com
import { formatTime } from '../../../common/utils/time';
import './StudioClock.scss';
-import { millisToString } from 'ontime-utils';
const formatOptions = {
showSeconds: false,
@@ -21,6 +19,7 @@ const formatOptions = {
};
StudioClock.propTypes = {
+ isMirrored: PropTypes.bool,
title: PropTypes.object,
time: PropTypes.object,
backstageEvents: PropTypes.array,
@@ -31,14 +30,13 @@ StudioClock.propTypes = {
};
export default function StudioClock(props) {
- const { title, time, backstageEvents, selectedId, nextId, onAir, viewSettings } = props;
+ const { isMirrored, title, time, backstageEvents, selectedId, nextId, onAir, viewSettings } = props;
// deferring rendering seems to affect styling (font and useFitText)
useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
const { fontSize: titleFontSize, ref: titleRef } = useFitText({ maxFontSize: 500 });
const [schedule, setSchedule] = useState([]);
- const [isMirrored] = useAtom(mirrorViewersAtom);
const activeIndicators = [...Array(12).keys()];
const secondsIndicators = [...Array(60).keys()];
diff --git a/apps/client/src/features/viewers/timer/Timer.tsx b/apps/client/src/features/viewers/timer/Timer.tsx
index 94de478eb..f52c53494 100644
--- a/apps/client/src/features/viewers/timer/Timer.tsx
+++ b/apps/client/src/features/viewers/timer/Timer.tsx
@@ -1,17 +1,16 @@
import { useEffect } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
-import { useAtom } from 'jotai';
-import { Playback, TimerType } from 'ontime-types';
-import PropTypes from 'prop-types';
+import { EventData, Message, Playback, TimerType, ViewSettings } from 'ontime-types';
import { overrideStylesURL } from '../../../common/api/apiConstants';
-import { mirrorViewersAtom } from '../../../common/atoms/ViewerSettings';
import NavigationMenu from '../../../common/components/navigation-menu/NavigationMenu';
import ProgressBar from '../../../common/components/progress-bar/ProgressBar';
import TitleCard from '../../../common/components/title-card/TitleCard';
import { useRuntimeStylesheet } from '../../../common/hooks/useRuntimeStylesheet';
+import { TimeManagerType } from '../../../common/models/TimeManager.type';
import { formatTime } from '../../../common/utils/time';
import { formatTimerDisplay, getTimerByType } from '../common/viewerUtils';
+import { TitleManager } from '../ViewWrapper';
import './Timer.scss';
@@ -36,19 +35,18 @@ const titleVariants = {
},
};
-Timer.propTypes = {
- general: PropTypes.object,
- pres: PropTypes.object,
- title: PropTypes.object,
- time: PropTypes.object,
- viewSettings: PropTypes.object,
-};
+interface TimerProps {
+ isMirrored: boolean;
+ general: EventData;
+ pres: Message;
+ title: TitleManager;
+ time: TimeManagerType;
+ viewSettings: ViewSettings;
+}
-// @ts-expect-error unable to type just yet
-export default function Timer(props) {
- const { general, pres, title, time, viewSettings } = props;
+export default function Timer(props: TimerProps) {
+ const { isMirrored, general, pres, title, time, viewSettings } = props;
const { shouldRender } = useRuntimeStylesheet(viewSettings?.overrideStyles && overrideStylesURL);
- const [isMirrored] = useAtom(mirrorViewersAtom);
useEffect(() => {
document.title = 'ontime - Timer';
diff --git a/apps/electron/main.js b/apps/electron/main.js
index 19842b6a7..821d67e73 100644
--- a/apps/electron/main.js
+++ b/apps/electron/main.js
@@ -1,14 +1,4 @@
-const {
- app,
- BrowserWindow,
- Menu,
- globalShortcut,
- Tray,
- dialog,
- ipcMain,
- shell,
- Notification,
-} = require('electron');
+const { app, BrowserWindow, Menu, globalShortcut, Tray, dialog, ipcMain, shell, Notification } = require('electron');
const path = require('path');
const electronConfig = require('./electron.config');
@@ -40,14 +30,13 @@ let splash;
let tray = null;
(async () => {
-
// in dev mode, we expect both UI and server to be running
- if (!isProduction) {
- return
+ if (!isProduction) {
+ return;
}
try {
- const ontimeServer = require(nodePath)
+ const ontimeServer = require(nodePath);
const { startDb, startServer, startOSCServer, startIntegrations } = ontimeServer;
await startDb();
@@ -76,9 +65,7 @@ function showNotification(title, text) {
function appShutdown() {
// terminate node service
(async () => {
- console.log('asking for shutdown 1', nodePath)
- const ontimeServer = require(nodePath)
- console.log('asking for shutdown 2', ontimeServer)
+ const ontimeServer = require(nodePath);
const { shutdown } = ontimeServer;
await shutdown(electronConfig.appIni.shutdownCode);
})();
@@ -129,7 +116,8 @@ function createWindow() {
skipTaskbar: true,
});
splash.setIgnoreMouseEvents(true);
- splash.loadURL(`file://${__dirname}/src/splash/splash.html`);
+ const splashPath = path.join('file://', __dirname, '/src/splash/splash.html');
+ splash.loadURL(splashPath);
win = new BrowserWindow({
width: 1920,
@@ -167,15 +155,13 @@ app.whenReady().then(() => {
// (available regardless of whether app is in focus)
// bring focus to window
globalShortcut.register('Alt+1', () => {
- bringToFront();
+ bringToFront();
});
// cheat to schedule process
setTimeout(() => {
// 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 : electronConfig.reactAppUrl.development;
win.loadURL(clientUrl).then(() => {
win.webContents.setBackgroundThrottling(false);
@@ -212,13 +198,13 @@ app.whenReady().then(() => {
// Define context menu
const { getTrayMenu } = require('./src/menu/trayMenu.js');
- const trayMenuTemplate = getTrayMenu(bringToFront, askToQuit)
+ const trayMenuTemplate = getTrayMenu(bringToFront, askToQuit);
const trayContextMenu = Menu.buildFromTemplate(trayMenuTemplate);
tray.setContextMenu(trayContextMenu);
});
const { getApplicationMenu } = require('./src/menu/applicationMenu.js');
-const template = getApplicationMenu(isMac, askToQuit)
+const template = getApplicationMenu(isMac, askToQuit);
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
@@ -227,16 +213,10 @@ app.once('will-quit', () => {
globalShortcut.unregisterAll();
});
-// Get messages from react
-// Test message
-ipcMain.on('test-message', (event, arg) => {
- showNotification('Test Message', 'test from react', arg);
-});
-
// Ask for main window reload
// Test message
ipcMain.on('reload', () => {
- win?.reload();
+ win?.reload();
});
// Terminate
@@ -258,7 +238,7 @@ ipcMain.on('set-window', (event, arg) => {
win.webContents.openDevTools({ mode: 'detach' });
break;
default:
- console.log('Electron unhandled window request', arg)
+ console.log('Electron unhandled window request', arg);
}
});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 29113d34b..89608cea4 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -70,7 +70,6 @@ importers:
eslint-plugin-simple-import-sort: ^8.0.0
eslint-plugin-testing-library: ^5.9.1
framer-motion: ^8.0.2
- jotai: ^1.10.0
jsdom: ^21.1.0
luxon: ^3.3.0
ontime-types: workspace:*
@@ -114,7 +113,6 @@ importers:
csv-stringify: 6.2.3
deepmerge: 4.3.0
framer-motion: 8.4.3_biqbaboplfbrettd7655fr4n2y
- jotai: 1.13.0_react@18.2.0
luxon: 3.3.0
react: 18.2.0
react-beautiful-dnd: 13.1.1_biqbaboplfbrettd7655fr4n2y
@@ -6219,49 +6217,6 @@ packages:
'@sideway/pinpoint': 2.0.0
dev: true
- /jotai/1.13.0_react@18.2.0:
- resolution: {integrity: sha512-SPTO46Jw1aJTp2i18tiKgk++nKNKJTMNw4qYFy9QRTydceWvD2Eys+YgB7cb1S6pzbM9i0Ik/y7Yl7IH8k9Lig==}
- engines: {node: '>=12.20.0'}
- peerDependencies:
- '@babel/core': '*'
- '@babel/template': '*'
- jotai-devtools: '*'
- jotai-immer: '*'
- jotai-optics: '*'
- jotai-redux: '*'
- jotai-tanstack-query: '*'
- jotai-urql: '*'
- jotai-valtio: '*'
- jotai-xstate: '*'
- jotai-zustand: '*'
- react: '>=16.8'
- peerDependenciesMeta:
- '@babel/core':
- optional: true
- '@babel/template':
- optional: true
- jotai-devtools:
- optional: true
- jotai-immer:
- optional: true
- jotai-optics:
- optional: true
- jotai-redux:
- optional: true
- jotai-tanstack-query:
- optional: true
- jotai-urql:
- optional: true
- jotai-valtio:
- optional: true
- jotai-xstate:
- optional: true
- jotai-zustand:
- optional: true
- dependencies:
- react: 18.2.0
- dev: false
-
/js-sdsl/4.2.0:
resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==}
dev: true