Deps migration (#1988)

* chore: migrate eslint to oxlint

* chore: migrate prettier to oxfmt

* chore: migrate typescript

* chore: toThrow should have a expected value

* chore: cast test value as Day

* chore: small title fix

* chore: mocks should be hoisted

* chore: incorrect async useage

* chore: test should be inside description

* chore: test sohuld include an expeced

* chore: oxfmt

---------

Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
This commit is contained in:
Carlos Valente
2026-03-08 16:22:12 +01:00
committed by GitHub
parent 9516ac21bb
commit 1849b4d39f
501 changed files with 2678 additions and 4654 deletions
+1 -2
View File
@@ -2,8 +2,7 @@ import axios from 'axios';
import { TranslationObject } from 'ontime-types';
import { ontimeQueryClient } from '../../common/queryClient';
import { apiEntryUrl, customTranslationsURL, TRANSLATION } from './constants';
import { TRANSLATION, apiEntryUrl, customTranslationsURL } from './constants';
import type { RequestOptions } from './requestOptions';
const assetsPath = `${apiEntryUrl}/assets`;
-1
View File
@@ -1,7 +1,6 @@
import axios from 'axios';
import { apiRepoLatest } from '../../externals';
import type { RequestOptions } from './requestOptions';
export type HasUpdate = {
+1 -2
View File
@@ -2,8 +2,7 @@ import axios from 'axios';
import { OntimeReport } from 'ontime-types';
import { ontimeQueryClient } from '../../common/queryClient';
import { apiEntryUrl, REPORT } from './constants';
import { REPORT, apiEntryUrl } from './constants';
import type { RequestOptions } from './requestOptions';
export const reportUrl = `${apiEntryUrl}/report`;
+4 -8
View File
@@ -76,14 +76,10 @@ export const previewRundown = async (
};
export const getWorksheetNames = async (sheetId: string, requestOptions?: RequestOptions): Promise<string[]> => {
const response: AxiosResponse<string[]> = await axios.post(
`${sheetsPath}/${sheetId}/worksheets`,
undefined,
{
signal: requestOptions?.signal,
timeout: requestOptions?.timeout ?? axiosConfig.longTimeout,
},
);
const response: AxiosResponse<string[]> = await axios.post(`${sheetsPath}/${sheetId}/worksheets`, undefined, {
signal: requestOptions?.signal,
timeout: requestOptions?.timeout ?? axiosConfig.longTimeout,
});
return response.data;
};
@@ -1,5 +1,5 @@
import { IoCheckmark } from 'react-icons/io5';
import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
import { IoCheckmark } from 'react-icons/io5';
import style from './Checkbox.module.scss';
@@ -2,8 +2,8 @@ import { useState } from 'react';
import { IoArrowForward } from 'react-icons/io5';
import { navigatorConstants } from '../../../viewerConfig';
import { setClientRemote } from '../../hooks/useSocket';
import useUrlPresets from '../../hooks-query/useUrlPresets';
import { setClientRemote } from '../../hooks/useSocket';
import Button from '../buttons/Button';
import Dialog from '../dialog/Dialog';
import Info from '../info/Info';
@@ -1,6 +1,6 @@
import { Dialog as BaseDialog } from '@base-ui/react/dialog';
import type { ReactNode } from 'react';
import { IoClose } from 'react-icons/io5';
import { Dialog as BaseDialog } from '@base-ui/react/dialog';
import IconButton from '../buttons/IconButton';
@@ -1,6 +1,6 @@
import { Menu as BaseMenu } from '@base-ui/react/menu';
import { PropsWithChildren } from 'react';
import { IconType } from 'react-icons';
import { Menu as BaseMenu } from '@base-ui/react/menu';
import style from './DropdownMenu.module.scss';
@@ -1,7 +1,7 @@
/* eslint-disable react/destructuring-assignment */
import React from 'react';
// skipcq: JS-C1003 - sentry does not expose itself as an ES Module.
import * as Sentry from '@sentry/react';
/* eslint-disable react/destructuring-assignment */
import React from 'react';
import { hasConnected, reconnectAttempts } from '../../../common/utils/socket';
import { runtimeStore } from '../../stores/runtime';
@@ -1,6 +1,6 @@
import { MILLIS_PER_MINUTE } from 'ontime-utils';
import { useCallback, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import { MILLIS_PER_MINUTE } from 'ontime-utils';
import { setClientRemote } from '../../hooks/useSocket';
import { useClientStore } from '../../stores/clientStore';
@@ -1,6 +1,6 @@
import { RefObject, useEffect } from 'react';
// @ts-expect-error no types from library
import autosize from 'autosize/dist/autosize';
import { RefObject, useEffect } from 'react';
import Textarea, { type TextareaProps } from '../textarea/Textarea';
@@ -1,7 +1,7 @@
import { useController, UseControllerProps } from 'react-hook-form';
import { IoEyedrop } from 'react-icons/io5';
import { useDebouncedCallback } from '@mantine/hooks';
import { ViewSettings } from 'ontime-types';
import { UseControllerProps, useController } from 'react-hook-form';
import { IoEyedrop } from 'react-icons/io5';
import { cx, getAccessibleColour } from '../../../utils/styleUtils';
import PopoverPicker from '../popover-picker/PopoverPicker';
@@ -1,4 +1,4 @@
import { forwardRef, InputHTMLAttributes } from 'react';
import { InputHTMLAttributes, forwardRef } from 'react';
import { cx } from '../../../utils/styleUtils';
@@ -1,6 +1,6 @@
import { Popover } from '@base-ui/react/popover';
import { PropsWithChildren } from 'react';
import { HexAlphaColorPicker, HexColorInput } from 'react-colorful';
import { Popover } from '@base-ui/react/popover';
import PopoverContents from '../../popover/Popover';
@@ -1,5 +1,5 @@
import { HotkeyItem, getHotkeyHandler } from '@mantine/hooks';
import { ChangeEvent, KeyboardEvent, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { getHotkeyHandler, HotkeyItem } from '@mantine/hooks';
interface UseReactiveTextInputReturn {
value: string;
@@ -1,4 +1,4 @@
import { forwardRef, TextareaHTMLAttributes } from 'react';
import { TextareaHTMLAttributes, forwardRef } from 'react';
import { cx } from '../../../utils/styleUtils';
@@ -1,5 +1,5 @@
import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';
import { millisToString, parseUserTime } from 'ontime-utils';
import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';
import { cx } from '../../../utils/styleUtils';
import Input from '../input/Input';
@@ -1,5 +1,5 @@
import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';
import { millisToString, parseUserTime } from 'ontime-utils';
import { FocusEvent, KeyboardEvent, useCallback, useEffect, useRef, useState } from 'react';
import { cx } from '../../../utils/styleUtils';
import Input from '../input/Input';
@@ -18,7 +18,7 @@
}
&:focus {
outline: none;
outline: none;
box-shadow: 0 1px 0 0 currentColor;
}
}
}
@@ -3,7 +3,7 @@
top: 10vh;
left: 50%;
transform: translateX(-50%);
padding-inline: 1rem;
min-width: min(880px, 90vw);
min-height: min(200px, 10vh);
@@ -1,6 +1,6 @@
import { Dialog as BaseDialog } from '@base-ui/react/dialog';
import type { ReactNode } from 'react';
import { IoClose } from 'react-icons/io5';
import { Dialog as BaseDialog } from '@base-ui/react/dialog';
import IconButton from '../buttons/IconButton';
@@ -1,9 +1,9 @@
import { Dialog } from '@base-ui/react/dialog';
import { useDisclosure, useFullscreen } from '@mantine/hooks';
import { memo } from 'react';
import { IoClose, IoContract, IoExpand, IoLockClosedOutline, IoSwapVertical } from 'react-icons/io5';
import { LuCoffee } from 'react-icons/lu';
import { useLocation } from 'react-router';
import { Dialog } from '@base-ui/react/dialog';
import { useDisclosure, useFullscreen } from '@mantine/hooks';
import { isLocalhost, supportsFullscreen } from '../../../externals';
import { canUseWakeLock, useKeepAwakeOptions } from '../../../features/keep-awake/useWakeLock';
@@ -13,7 +13,6 @@ import { useClientStore } from '../../stores/clientStore';
import { useViewOptionsStore } from '../../stores/viewOptions';
import IconButton from '../buttons/IconButton';
import { RenameClientModal } from '../client-modal/RenameClientModal';
import ClientLink from './client-link/ClientLink';
import EditorNavigation from './editor-navigation/EditorNavigation';
import NavigationMenuItem from './navigation-menu-item/NavigationMenuItem';
@@ -1,11 +1,10 @@
import { memo } from 'react';
import { useDisclosure, useHotkeys } from '@mantine/hooks';
import { memo } from 'react';
import { useViewParamsEditorStore } from '../view-params-editor/viewParamsEditor.store';
import FloatingNavigation from './floating-navigation/FloatingNavigation';
import ViewLockedIcon from './view-locked-icon/ViewLockedIcon';
import NavigationMenu from './NavigationMenu';
import ViewLockedIcon from './view-locked-icon/ViewLockedIcon';
interface ViewNavigationMenuProps {
/** prevent navigation */
@@ -24,7 +24,9 @@ export default function NavigationMenuItem({
role='button'
onClick={onClick}
onKeyDown={(event) => {
isKeyEnter(event) && onClick();
if (isKeyEnter(event)) {
onClick();
}
}}
>
{children}
@@ -5,7 +5,7 @@
color: $ui-white;
background-color: $gray-1250;
border-radius: 3px;
border-radius: 3px;
box-shadow: $box-shadow-l1;
border: 1px solid $gray-1000;
@@ -27,4 +27,3 @@
font-size: 1rem;
margin-bottom: 0.5rem;
}
@@ -1,5 +1,5 @@
import { PropsWithChildren } from 'react';
import { Popover } from '@base-ui/react/popover';
import { PropsWithChildren } from 'react';
import style from './Popover.module.scss';
@@ -2,7 +2,6 @@ import { PropsWithChildren, useCallback, useContext } from 'react';
import { isLocalhost } from '../../../externals';
import { AppContext } from '../../context/AppContext';
import PinPage from './PinPage';
interface ProtectRouteProps {
@@ -16,7 +16,7 @@ $thumb-color-hover: $white-60;
width: 100%;
overscroll-behavior: contain;
&:focus-visible {
&:focus-visible {
outline: 2px solid $blue-500;
outline-offset: -2px;
}
@@ -1,5 +1,5 @@
import { CSSProperties, PropsWithChildren, Ref } from 'react';
import { ScrollArea } from '@base-ui/react/scroll-area';
import { CSSProperties, PropsWithChildren, Ref } from 'react';
import { cx } from '../../utils/styleUtils';
@@ -1,6 +1,6 @@
import { Select as BaseSelect } from '@base-ui/react/select';
import { IoCheckmark } from 'react-icons/io5';
import { LuChevronsUpDown } from 'react-icons/lu';
import { Select as BaseSelect } from '@base-ui/react/select';
import { cx } from '../../utils/styleUtils';
@@ -10,7 +10,7 @@
.text {
display: block;
margin-inline: auto;;
margin-inline: auto;
font-weight: 600;
font-size: 2em;
max-width: 600px;
@@ -2,13 +2,13 @@
position: relative;
display: flex;
align-items: center;
/* Reset and base styles */
appearance: none;
border: 1px solid transparent;
border-radius: 99px;
background-color: $gray-1100;
/* Transitions */
transition: background-color 125ms cubic-bezier(0.26, 0.75, 0.38, 0.45);
@@ -1,7 +1,7 @@
.tooltip {
font-size: calc(1rem - 3px);
background-color: $ui-white;
color: $ui-black;
color: $ui-black;
padding: 0.125rem 0.5rem;
border-radius: 2px;
line-height: 1.25em;
@@ -1,5 +1,5 @@
import { PropsWithChildren } from 'react';
import { Tooltip as BaseTooltip } from '@base-ui/react/tooltip';
import { PropsWithChildren } from 'react';
import style from './Tooltip.module.scss';
@@ -6,7 +6,6 @@ import Checkbox from '../checkbox/Checkbox';
import Input from '../input/input/Input';
import Select, { SelectOption } from '../select/Select';
import Switch from '../switch/Switch';
import InlineColourPicker from './InlineColourPicker';
import { ParamField } from './viewParams.types';
@@ -44,7 +43,7 @@ export default function ParamInput({ paramField }: ParamInputProps) {
return (
<MultiOption
paramField={paramField}
options={optionFromParams.length ? optionFromParams : paramField.defaultValue ?? ['']}
options={optionFromParams.length ? optionFromParams : (paramField.defaultValue ?? [''])}
/>
);
}
@@ -1,15 +1,14 @@
import { Dialog } from '@base-ui/react/dialog';
import { OntimeView } from 'ontime-types';
import { FormEvent, memo } from 'react';
import { IoClose } from 'react-icons/io5';
import { useSearchParams } from 'react-router';
import { Dialog } from '@base-ui/react/dialog';
import { OntimeView } from 'ontime-types';
import { useIsSmallScreen } from '../../hooks/useIsSmallScreen';
import useViewSettings from '../../hooks-query/useViewSettings';
import { useIsSmallScreen } from '../../hooks/useIsSmallScreen';
import Button from '../buttons/Button';
import IconButton from '../buttons/IconButton';
import Info from '../info/Info';
import { ViewOption } from './viewParams.types';
import { getPreservedSearchParams, getURLSearchParamsFromObj } from './viewParams.utils';
import { useViewParamsEditorStore } from './viewParamsEditor.store';
@@ -1,5 +1,5 @@
import { useSearchParams } from 'react-router';
import { OntimeView, URLPreset } from 'ontime-types';
import { useSearchParams } from 'react-router';
import { useViewUrlPresets } from '../../hooks-query/useUrlPresets';
import { cx } from '../../utils/styleUtils';
@@ -47,4 +47,4 @@
.hidden {
display: none;
}
}
@@ -1,8 +1,7 @@
import { IoChevronDown } from 'react-icons/io5';
import { useLocalStorage } from '@mantine/hooks';
import { IoChevronDown } from 'react-icons/io5';
import { cx } from '../../utils/styleUtils';
import { OptionTitle } from './constants';
import ParamInput from './ParamInput';
import { type ParamField } from './viewParams.types';
@@ -1,7 +1,6 @@
import type { CustomFields, ProjectData } from 'ontime-types';
import type { SelectOption } from '../select/Select';
import type { MultiselectOption, ViewOption } from './viewParams.types';
/**
@@ -1,4 +1,4 @@
import { createContext, PropsWithChildren, useCallback, useEffect, useState } from 'react';
import { PropsWithChildren, createContext, useCallback, useEffect, useState } from 'react';
import useSettings from '../hooks-query/useSettings';
@@ -1,4 +1,4 @@
import { createContext, PropsWithChildren, useContext } from 'react';
import { PropsWithChildren, createContext, useContext } from 'react';
import { useEntryActions } from '../hooks/useEntryAction';
@@ -1,4 +1,4 @@
import { createContext } from 'react';
import { URLPreset } from 'ontime-types';
import { createContext } from 'react';
export const PresetContext = createContext<URLPreset | undefined>(undefined);
@@ -4,7 +4,7 @@ import { dayInMs } from 'ontime-utils';
import { version } from '../../../../../package.json';
import { isLocalhost } from '../../externals';
import { APP_VERSION } from '../api/constants';
import { getLatestVersion, HasUpdate } from '../api/external';
import { HasUpdate, getLatestVersion } from '../api/external';
const placeholder: HasUpdate & { hasUpdates: boolean } = { url: '', version: '', hasUpdates: false };
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { ProjectFile, ProjectFileList, ProjectFileListResponse } from 'ontime-types';
import { useMemo } from 'react';
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
import { PROJECT_LIST } from '../api/constants';
@@ -3,7 +3,14 @@ import { ProjectRundownsList } from 'ontime-types';
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
import { PROJECT_RUNDOWNS } from '../api/constants';
import { createRundown, deleteRundown, duplicateRundown, fetchProjectRundownList, loadRundown, renameRundown } from '../api/rundown';
import {
createRundown,
deleteRundown,
duplicateRundown,
fetchProjectRundownList,
loadRundown,
renameRundown,
} from '../api/rundown';
/**
* Project rundowns
@@ -30,7 +37,7 @@ export function useMutateProjectRundowns() {
ontimeQueryClient.setQueryData(PROJECT_RUNDOWNS, response.data);
},
});
const { mutateAsync: duplicate } = useMutation({
mutationFn: duplicateRundown,
onMutate: () => {
@@ -40,7 +47,7 @@ export function useMutateProjectRundowns() {
ontimeQueryClient.setQueryData(PROJECT_RUNDOWNS, response.data);
},
});
const { mutateAsync: rename } = useMutation({
mutationFn: ([rundownId, title]: Parameters<typeof renameRundown>) => renameRundown(rundownId, title),
onMutate: () => {
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { EntryId, OntimeEntry, Rundown } from 'ontime-types';
import { useMemo } from 'react';
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
import { RUNDOWN } from '../api/constants';
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { OntimeView, URLPreset } from 'ontime-types';
import { useMemo } from 'react';
import { queryRefetchIntervalSlow } from '../../ontimeConfig';
import { URL_PRESETS } from '../api/constants';
@@ -1,11 +1,10 @@
import { MessageTag } from 'ontime-types';
import { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router';
import { MessageTag } from 'ontime-types';
import { useShallow } from 'zustand/shallow';
import { useClientStore } from '../stores/clientStore';
import { sendSocket } from '../utils/socket';
import { useIsOnline } from './useSocket';
export const useClientPath = () => {
@@ -1,10 +1,7 @@
import { useCallback, useMemo } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import {
EntryId,
InsertOptions,
isOntimeEvent,
isOntimeGroup,
MaybeString,
OntimeDelay,
OntimeEntry,
@@ -16,8 +13,11 @@ import {
SupportedEntry,
TimeField,
TimeStrategy,
isOntimeEvent,
isOntimeGroup,
} from 'ontime-types';
import {
MILLIS_PER_SECOND,
addToRundown,
createDelay,
createEvent,
@@ -26,22 +26,22 @@ import {
dayInMs,
generateId,
getInsertAfterId,
MILLIS_PER_SECOND,
parseUserTime,
resolveInsertParent,
swapEventData,
} from 'ontime-utils';
import { useCallback, useMemo } from 'react';
import { moveDown, moveUp, orderEntries } from '../../features/rundown/rundown.utils';
import { RUNDOWN } from '../api/constants';
import {
ReorderEntry,
deleteEntries,
patchReorderEntry,
postAddEntry,
postCloneEntry,
putBatchEditEvents,
putEditEntry,
ReorderEntry,
requestApplyDelay,
requestDeleteAll,
requestEventSwap,
@@ -1,5 +1,5 @@
import { RefObject, useCallback, useEffect } from 'react';
import { MaybeString } from 'ontime-types';
import { RefObject, useCallback, useEffect } from 'react';
function scrollToComponent<ComponentRef extends HTMLElement, ScrollRef extends HTMLElement>(
componentRef: RefObject<ComponentRef>,
@@ -1,5 +1,5 @@
import { RefObject, useCallback, useEffect } from 'react';
import { EntryId } from 'ontime-types';
import { RefObject, useCallback, useEffect } from 'react';
function scrollToComponent<ComponentRef extends HTMLElement, ScrollRef extends HTMLElement>(
componentRef: RefObject<ComponentRef> | null,
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { useOs, useViewportSize } from '@mantine/hooks';
import { useMemo } from 'react';
export function useIsMobileDevice(): boolean {
const { width } = useViewportSize();
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { useViewportSize } from '@mantine/hooks';
import { useMemo } from 'react';
export function useIsMobileScreen(): boolean {
const { width } = useViewportSize();
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { useOs, useViewportSize } from '@mantine/hooks';
import { useMemo } from 'react';
export function useIsSmallDevice(): boolean {
const { width } = useViewportSize();
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { useViewportSize } from '@mantine/hooks';
import { useMemo } from 'react';
export function useIsSmallScreen(): boolean {
const { width } = useViewportSize();
@@ -1,5 +1,5 @@
import { EndAction, TimerType, TimeStrategy } from 'ontime-types';
import { validateEndAction, validateTimerType, validateTimeStrategy } from 'ontime-utils';
import { EndAction, TimeStrategy, TimerType } from 'ontime-types';
import { validateEndAction, validateTimeStrategy, validateTimerType } from 'ontime-utils';
import { create } from 'zustand';
import { booleanFromLocalStorage } from '../utils/localStorage';
+1 -1
View File
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { Log, LogLevel, LogOrigin, MessageTag } from 'ontime-types';
import { generateId, millisToString } from 'ontime-utils';
import { useCallback } from 'react';
import { useStore } from 'zustand';
import { createStore } from 'zustand/vanilla';
+1 -1
View File
@@ -1,5 +1,5 @@
import isEqual from 'react-fast-compare';
import { RuntimeStore, runtimeStorePlaceholder } from 'ontime-types';
import isEqual from 'react-fast-compare';
import { createWithEqualityFn, useStoreWithEqualityFn } from 'zustand/traditional';
const deepCompare = <T>(a: T, b: T) => isEqual(a, b);
@@ -1,2 +1,4 @@
.test {}
.another {}
.test {
}
.another {
}
@@ -3,15 +3,19 @@ import { MILLIS_PER_HOUR, MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-ut
import { formatDuration, formatTime, nowInMillis } from '../time';
describe('nowInMillis()', () => {
afterEach(() => {
vi.useRealTimers();
});
it('should return the current time in milliseconds', () => {
const mockDate = new Date(2022, 1, 1, 13, 0, 0); // This date corresponds to 13:00:00
const expectedMillis = 13 * 60 * 60 * 1000;
const dateSpy = vi.spyOn(global, 'Date').mockImplementation(() => mockDate as any);
vi.useFakeTimers();
vi.setSystemTime(mockDate);
const result = nowInMillis();
expect(result).toBe(expectedMillis);
dateSpy.mockRestore();
});
});
@@ -1,5 +1,5 @@
import { Path, resolvePath } from 'react-router';
import { OntimeView, URLPreset } from 'ontime-types';
import { Path, resolvePath } from 'react-router';
import {
arePathsEquivalent,
@@ -231,11 +231,11 @@ describe('generateUrlPresetOptions', () => {
});
it('throws on invalid URL', () => {
expect(() => generateUrlPresetOptions('test', 'invalid-url')).toThrow();
expect(() => generateUrlPresetOptions('test', 'invalid-url')).toThrow('Invalid target view:');
});
it('throws on invalid route', () => {
expect(() => generateUrlPresetOptions('test', 'www.getontime.no/somethingelse/')).toThrow();
expect(() => generateUrlPresetOptions('test', 'www.getontime.no/somethingelse/')).toThrow('Invalid target view:');
});
});
+1 -1
View File
@@ -1,5 +1,5 @@
import { MaybeNumber } from 'ontime-types';
import { formatFromMillis, MILLIS_PER_HOUR, MILLIS_PER_MINUTE } from 'ontime-utils';
import { MILLIS_PER_HOUR, MILLIS_PER_MINUTE, formatFromMillis } from 'ontime-utils';
/**
* Parses a value in millis to a string which encodes a delay
+10 -2
View File
@@ -2,14 +2,22 @@ import type { MouseEvent } from 'react';
import { baseURI, serverURL } from '../../externals';
type ElectronWindow = Window & {
process?: { type?: string };
ipcRenderer?: {
send: (channel: string, args?: string | object) => void;
};
};
/**
* Open an external URLs: specifically for a electron / browser case
* If electron: ask main process to call a new browser window
* If browser: open in new tab
*/
export function openLink(url: string) {
if (window.process?.type === 'renderer') {
window.ipcRenderer.send('send-to-link', url);
const electronWindow = window as ElectronWindow;
if (electronWindow.process?.type === 'renderer' && electronWindow.ipcRenderer) {
electronWindow.ipcRenderer.send('send-to-link', url);
} else {
window.open(url);
}
@@ -1,7 +1,4 @@
import {
isOntimeEvent,
isOntimeGroup,
isPlayableEvent,
MaybeString,
OntimeDelay,
OntimeEntry,
@@ -9,6 +6,9 @@ import {
OntimeMilestone,
PlayableEvent,
Rundown,
isOntimeEvent,
isOntimeGroup,
isPlayableEvent,
} from 'ontime-types';
import { checkIsNextDay, isNewLatest } from 'ontime-utils';
@@ -151,13 +151,13 @@ function processEntry(
if (isPlayableEvent(entry)) {
processedData.isNextDay = checkIsNextDay(entry, processedData.previousEvent);
if (!processedData.isPast && !processedData.isLoaded) {
/**
* isLinkToLoaded is a chain value that we maintain until we
* a) find an unlinked event
* b) find a countToEnd event
*/
*/
processedData.totalGap += entry.gap;
processedData.isLinkedToLoaded =
entry.linkStart && !processedData.previousEvent?.countToEnd && processedData.isLinkedToLoaded;
+2 -3
View File
@@ -1,17 +1,16 @@
import { MaybeNumber, OntimeEvent, Settings, TimeFormat } from 'ontime-types';
import {
formatFromMillis,
getExpectedStart,
MILLIS_PER_HOUR,
MILLIS_PER_MINUTE,
MILLIS_PER_SECOND,
formatFromMillis,
getExpectedStart,
} from 'ontime-utils';
import { FORMAT_12, FORMAT_24 } from '../../viewerConfig';
import { APP_SETTINGS } from '../api/constants';
import { useExpectedStartData } from '../hooks/useSocket';
import { ontimeQueryClient } from '../queryClient';
import { ExtendedEntry } from './rundownMetadata';
/**
+1 -1
View File
@@ -1,6 +1,6 @@
import { Path, resolvePath } from 'react-router';
import { OntimeView, OntimeViewPresettable, URLPreset } from 'ontime-types';
import { checkRegex } from 'ontime-utils';
import { Path, resolvePath } from 'react-router';
/**
* Validates a preset against defined parameters