* refactor: cleanup routes

* style: smaller base font

* chore: upgrade dependencies

* chore: lock node version to electron

* refactor: pass HTTP to integration controller (#652)

* refactor: deprecate onair control

* refactor: remove playback router

* Several project files user folder (#617)

* chore: automated screenshots (#667)

* feat: app settings (#658)

* refactor: remove deprecated event data (#674)

* Studio clock (#663)

---------

Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* Feat: reorder events with alt+ctrl + arrow up/down (#645)

* Warning and danger per event (#677)

---------

Co-authored-by: Fabian Posenau <fabian@fphome.de>

* refactor: stabilise actionHandler (#683)

Co-authored-by: Fabian Posenau <fabian@fphome.de>

* improvement: hide seconds (#675)

* wip: overview (#688)

* fix: focus cursor (#695)

* refactor: update lower third (#665)

* Refactor/time formatting (#696)

---------

Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* feat: multiple selection (#703)

---------

Co-authored-by: asharonbaltazar <asharonbaltazar@outlook.com>
Co-authored-by: Alex <ac@omnivox.dk>

* fix: test - go to `Edit mode` befor tying to click `Event options` button (#708)

* refactor: runtime service (#715)

* fix: issue with loosing cursor position on message (#719)

* remove info panel (#721)

* Event editor continue (#722)

* update API - part  (#709)

---------

Co-authored-by: Carlos Valente <34649812+cpvalente@users.noreply.github.com>
Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* refactor: update timers (#729)

* feat: many timers (#706)

---------

Co-authored-by: arc-alex <ac@omnivox.dk>

* refactor: excel cleanup (#734)

* refactor: allow import of blocks and skip import (#735)

* Project manager (#697)

* refactor: UI for linking events (#763)

* upgraded pipeline actions (#777)

* Over under (#771)

* custom fields (#744)


---------

Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* Sheets settings (#774)

---------

Co-authored-by: arc-alex <ac@omnivox.dk>

* style: tweaks to lower thirds (#785)

* refactor: delays account for gaps (#784)

* refactor: partial state updates (#780)

* feat: generate crash report (#787)

* Sheet use limited input device auth flow (#782)

---------

Co-authored-by: cv <34649812+cpvalente@users.noreply.github.com>
Co-authored-by: Carlos Valente <carlosvalente@pm.me>

* Custom fields views (#789)

* refactor: deprecate presenter and subtitle (#795)

* refactor: organise API around resources (#798)

---------

Co-authored-by: Bianca Procopio <biancahprocopio@gmail.com>

* Time to end (#804)

* Skip fixes (#805)

* fix: onair derives from playback

* Param nav (#822)

---------

Co-authored-by: Alex Christoffer Rasmussen <ac@omnivox.dk>

* refactor: download files from interface (#831)

* Quick options (#814)

* End pause (#832)

* chore: bump node version in docker (#834)

* refactor: follow in run mode (#840)

* fix: uncaught error in http integration (#837)

* Apply project (#843)

Co-authored-by: Matteo Gheza <matteo.gheza07@gmail.com>
Co-authored-by: Ary <arylmoraesn@gmail.com>
Co-authored-by: Alex Christoffer Rasmussen <ac@omnivox.dk>
Co-authored-by: Fabian Posenau <19673098+kellhogs@users.noreply.github.com>
Co-authored-by: Fabian Posenau <fabian@fphome.de>
Co-authored-by: Alex Rohleder <alexrohleder96@gmail.com>
Co-authored-by: asharonbaltazar <asharonbaltazar@outlook.com>
Co-authored-by: Bianca Procopio <biancahprocopio@gmail.com>
Co-authored-by: Fabian Posenau <fabianpos99+github@gmail.com>
This commit is contained in:
Carlos Valente
2024-04-13 10:06:46 +02:00
committed by GitHub
parent debdbd1c5a
commit 55d1aca9b6
640 changed files with 26702 additions and 21623 deletions
+6
View File
@@ -3,8 +3,14 @@
"browser": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": ["simple-import-sort", "@typescript-eslint"],
"rules": {
"simple-import-sort/imports": "error",
"@typescript-eslint/consistent-type-imports": "error"
}
}
+1 -1
View File
@@ -17,6 +17,6 @@
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
"eslint": "^8.53.0",
"typescript": "^5.2.2"
"typescript": "^5.4.3"
}
}
@@ -1,4 +1,4 @@
import { OSCSettings } from '../../definitions/core/OscSettings.type.js';
import type { OSCSettings } from '../../definitions/core/OscSettings.type.js';
export type NetworkInterface = {
name: string;
@@ -12,3 +12,23 @@ export interface GetInfo {
osc: OSCSettings;
cssOverride: string;
}
export type ProjectFile = {
filename: string;
updatedAt: string;
};
export type ProjectFileList = ProjectFile[];
export type ProjectFileListResponse = {
files: ProjectFileList;
lastLoadedProject: string;
};
export type MessageResponse = {
message: string;
};
export type ErrorResponse = MessageResponse;
export type AuthenticationStatus = 'authenticated' | 'not_authenticated' | 'pending';
@@ -1,6 +1,10 @@
import { OntimeRundown } from '../../definitions/core/Rundown.type.js';
import type { OntimeRundownEntry } from '../../definitions/core/Rundown.type.js';
export interface GetRundownCached {
rundown: OntimeRundown;
type EventId = string;
export type NormalisedRundown = Record<EventId, OntimeRundownEntry>;
export interface RundownCached {
rundown: NormalisedRundown;
order: EventId[];
revision: number;
}
@@ -1,19 +1,21 @@
import { Alias } from './core/Alias.type.js';
import { ProjectData } from './core/ProjectData.type.js';
import { OntimeRundown } from './core/Rundown.type.js';
import { OSCSettings } from './core/OscSettings.type.js';
import { Settings } from './core/Settings.type.js';
import { UserFields } from './core/UserFields.type.js';
import { ViewSettings } from './core/Views.type.js';
import { HttpSettings } from '../index.js';
import type {
CustomFields,
HttpSettings,
OntimeRundown,
OSCSettings,
ProjectData,
Settings,
URLPreset,
ViewSettings,
} from '../index.js';
export type DatabaseModel = {
rundown: OntimeRundown;
project: ProjectData;
settings: Settings;
viewSettings: ViewSettings;
aliases: Alias[];
userFields: UserFields;
urlPresets: URLPreset[];
customFields: CustomFields;
osc: OSCSettings;
http: HttpSettings;
};
@@ -1,6 +1,6 @@
export enum EndAction {
None = 'none',
Stop = 'stop',
LoadNext = 'load-next',
None = 'none',
PlayNext = 'play-next',
Stop = 'stop',
}
@@ -0,0 +1,4 @@
export enum TimeStrategy {
LockEnd = 'lock-end',
LockDuration = 'lock-duration',
}
@@ -0,0 +1,10 @@
export type CustomFieldLabel = string;
export type CustomField = {
type: 'string';
colour: string;
label: CustomFieldLabel;
};
export type CustomFields = Record<CustomFieldLabel, CustomField>;
export type EventCustomFields = Record<CustomFieldLabel, { value: string }>;
@@ -1,9 +1,8 @@
import { Subscription } from './Subscription.type.js';
import type { TimerLifeCycleKey } from './TimerLifecycle.type.js';
export type HttpSubscriptionOptions = { message: string; enabled: boolean };
export type HttpSubscription = Subscription<HttpSubscriptionOptions>;
export type HttpSubscription = { id: string; cycle: TimerLifeCycleKey; message: string; enabled: boolean };
export interface HttpSettings {
enabledOut: boolean;
subscriptions: HttpSubscription;
subscriptions: HttpSubscription[];
}
@@ -1,5 +1,4 @@
import { EndAction } from '../EndAction.type.js';
import { TimerType } from '../TimerType.type.js';
import type { EndAction, EventCustomFields, MaybeString, TimerType, TimeStrategy } from '../../index.js';
export enum SupportedEvent {
Event = 'event',
@@ -16,7 +15,6 @@ export type OntimeBaseEvent = {
export type OntimeDelay = OntimeBaseEvent & {
type: SupportedEvent.Delay;
duration: number;
revision: number;
};
export type OntimeBlock = OntimeBaseEvent & {
@@ -28,27 +26,20 @@ export type OntimeEvent = OntimeBaseEvent & {
type: SupportedEvent.Event;
cue: string;
title: string;
subtitle: string;
presenter: string;
note: string;
endAction: EndAction;
timerType: TimerType;
linkStart: MaybeString; // ID of event to link to
timeStrategy: TimeStrategy;
timeStart: number;
timeEnd: number;
duration: number;
isPublic: boolean;
skip: boolean;
colour: string;
user0: string;
user1: string;
user2: string;
user3: string;
user4: string;
user5: string;
user6: string;
user7: string;
user8: string;
user9: string;
revision: number;
delay?: number; // calculated at runtime
timeWarning: number;
timeDanger: number;
custom: EventCustomFields;
};
@@ -1,7 +1,12 @@
import { Subscription } from './Subscription.type.js';
import type { TimerLifeCycleKey } from './TimerLifecycle.type.js';
export type OscSubscriptionOptions = { message: string; enabled: boolean };
export type OscSubscription = Subscription<OscSubscriptionOptions>;
export type OscSubscription = {
id: string;
cycle: TimerLifeCycleKey;
address: string;
payload: string;
enabled: boolean;
};
export interface OSCSettings {
portIn: number;
@@ -9,5 +14,5 @@ export interface OSCSettings {
targetIP: string;
enabledIn: boolean;
enabledOut: boolean;
subscriptions: OscSubscription;
subscriptions: OscSubscription[];
}
@@ -1,4 +1,4 @@
import { OntimeBlock, OntimeDelay, OntimeEvent } from './OntimeEvent.type.js';
import type { OntimeBlock, OntimeDelay, OntimeEvent } from './OntimeEvent.type.js';
export type OntimeRundownEntry = OntimeDelay | OntimeBlock | OntimeEvent;
export type OntimeRundown = OntimeRundownEntry[];
@@ -1,4 +1,4 @@
import { TimeFormat } from './TimeFormat.type.js';
import type { TimeFormat } from './TimeFormat.type.js';
export type Settings = {
app: 'ontime';
@@ -1,3 +0,0 @@
import { TimerLifeCycleKey } from './TimerLifecycle.type.js';
export type Subscription<T> = { [key in TimerLifeCycleKey]: T[] };
@@ -3,6 +3,7 @@ export enum TimerLifeCycle {
onStart = 'onStart',
onPause = 'onPause',
onStop = 'onStop',
onClock = 'onClock',
onUpdate = 'onUpdate',
onFinish = 'onFinish',
}
@@ -1,4 +1,4 @@
export type Alias = {
export type URLPreset = {
enabled: boolean;
alias: string;
pathAndParams: string;
@@ -1,12 +0,0 @@
export type UserFields = {
user0: string;
user1: string;
user2: string;
user3: string;
user4: string;
user5: string;
user6: string;
user7: string;
user8: string;
user9: string;
};
@@ -1,9 +1,8 @@
export type ViewSettings = {
overrideStyles: boolean;
endMessage: string;
normalColor: string;
warningColor: string;
warningThreshold: number;
dangerColor: string;
dangerThreshold: number;
endMessage: string;
freezeEnd: boolean;
normalColor: string;
overrideStyles: boolean;
warningColor: string;
};
@@ -0,0 +1,17 @@
export enum SimplePlayback {
Start = 'start',
Pause = 'pause',
Stop = 'stop',
}
export enum SimpleDirection {
CountUp = 'count-up',
CountDown = 'count-down',
}
export type SimpleTimerState = {
duration: number;
current: number;
playback: SimplePlayback;
direction: SimpleDirection;
};
@@ -4,6 +4,13 @@ export type Message = {
};
export type TimerMessage = Message & {
timerBlink: boolean;
timerBlackout: boolean;
blink: boolean;
blackout: boolean;
};
export type MessageState = {
timer: TimerMessage;
public: Message;
lower: Message;
external: Message;
};
@@ -1,8 +0,0 @@
export type Loaded = {
numEvents: number;
selectedEventIndex: number | null;
selectedEventId: string | null;
selectedPublicEventId: string | null;
nextEventId: string | null;
nextPublicEventId: string | null;
};
@@ -0,0 +1,11 @@
import type { MaybeNumber } from '../../utils/utils.type.js';
export type Runtime = {
numEvents: number;
selectedEventIndex: MaybeNumber;
offset: MaybeNumber;
plannedStart: MaybeNumber;
actualStart: MaybeNumber;
plannedEnd: MaybeNumber;
expectedEnd: MaybeNumber;
};
@@ -1,25 +1,25 @@
import { Playback } from './Playback.type.js';
import { Message, TimerMessage } from './MessageControl.type.js';
import { TimerState } from './TimerState.type.js';
import { Loaded } from './Playlist.type.js';
import { OntimeEvent } from '../core/OntimeEvent.type.js';
import type { OntimeEvent } from '../core/OntimeEvent.type.js';
import type { SimpleTimerState } from './ExtraTimer.type.js';
import type { MessageState } from './MessageControl.type.js';
import type { Runtime } from './Runtime.type.js';
import type { TimerState } from './TimerState.type.js';
export type RuntimeStore = {
// timer service
// timer data
clock: number;
timer: TimerState;
playback: Playback;
// messages service
timerMessage: TimerMessage;
publicMessage: Message;
lowerMessage: Message;
externalMessage: Message;
onAir: boolean;
// event loader
loaded: Loaded;
// messages service
message: MessageState;
// rundown data
runtime: Runtime;
eventNow: OntimeEvent | null;
publicEventNow: OntimeEvent | null;
eventNext: OntimeEvent | null;
publicEventNext: OntimeEvent | null;
// extra timers
auxtimer1: SimpleTimerState;
};
@@ -1,17 +1,14 @@
import { TimerType } from '../TimerType.type.js';
import { EndAction } from '../EndAction.type.js';
import type { MaybeNumber } from '../../index.js';
import type { Playback } from './Playback.type.js';
export type TimerState = {
clock: number; // realtime clock
current: number | null; // running countdown
elapsed: number | null; // elapsed time in current timer
expectedFinish: number | null;
addedTime: number; // time added by user, can be negative
startedAt: number | null;
finishedAt: number | null; // only if timer has already finished
secondaryTimer: number | null; // used for roll mode
selectedEventId: string | null;
duration: number | null;
timerType: TimerType | null;
endAction: EndAction | null;
current: MaybeNumber; // running countdown
duration: MaybeNumber; // normalised duration of current event
elapsed: MaybeNumber; // elapsed time in current timer
expectedFinish: MaybeNumber; // time we expect timer to finish
finishedAt: MaybeNumber; // only if timer has already finished
playback: Playback;
secondaryTimer: MaybeNumber; // used for roll mode
startedAt: MaybeNumber; // only if timer has already started
};
+31 -17
View File
@@ -11,6 +11,7 @@ export {
SupportedEvent,
} from './definitions/core/OntimeEvent.type.js';
export type { OntimeEntryCommonKeys, OntimeRundown, OntimeRundownEntry } from './definitions/core/Rundown.type.js';
export { TimeStrategy } from './definitions/TimeStrategy.type.js';
export { TimerType } from './definitions/TimerType.type.js';
// ---> Project Data
@@ -21,38 +22,51 @@ export type { Settings } from './definitions/core/Settings.type.js';
// ---> Views
export type { ViewSettings } from './definitions/core/Views.type.js';
export type { TimeFormat } from './definitions/core/TimeFormat.type.js';
// ---> Aliases
export type { Alias } from './definitions/core/Alias.type.js';
// ---> URL Presets
export type { URLPreset } from './definitions/core/UrlPreset.type.js';
// ---> User Fields
export type { UserFields } from './definitions/core/UserFields.type.js';
// ---> Custom Fields
export type {
CustomFields,
CustomField,
CustomFieldLabel,
EventCustomFields,
} from './definitions/core/CustomFields.type.js';
// ---> Integration, Subscription
export type { Subscription } from './definitions/core/Subscription.type.js';
// ---> OSC
export type { OSCSettings, OscSubscription, OscSubscriptionOptions } from './definitions/core/OscSettings.type.js';
// ---> HTTP
export type { HttpSettings, HttpSubscription, HttpSubscriptionOptions } from './definitions/core/HttpSettings.type.js';
export type { OSCSettings, OscSubscription } from './definitions/core/OscSettings.type.js';
export type { HttpSettings, HttpSubscription } from './definitions/core/HttpSettings.type.js';
// SERVER RESPONSES
export type { NetworkInterface, GetInfo } from './api/ontime-controller/BackendResponse.type.js';
export type { GetRundownCached } from './api/rundown-controller/BackendResponse.type.js';
export type {
AuthenticationStatus,
NetworkInterface,
GetInfo,
ProjectFileList,
ProjectFile,
ErrorResponse,
ProjectFileListResponse,
MessageResponse,
} from './api/ontime-controller/BackendResponse.type.js';
export type { RundownCached, NormalisedRundown } from './api/rundown-controller/BackendResponse.type.js';
// SERVER RUNTIME
export { type Log, LogLevel, type LogMessage, LogOrigin } from './definitions/runtime/Logger.type.js';
export { Playback } from './definitions/runtime/Playback.type.js';
export { TimerLifeCycle } from './definitions/core/TimerLifecycle.type.js';
export type { Message, TimerMessage } from './definitions/runtime/MessageControl.type.js';
export type { Message, TimerMessage, MessageState } from './definitions/runtime/MessageControl.type.js';
export type { Loaded } from './definitions/runtime/Playlist.type.js';
export type { Runtime } from './definitions/runtime/Runtime.type.js';
export type { RuntimeStore } from './definitions/runtime/RuntimeStore.type.js';
export type { TimerState } from './definitions/runtime/TimerState.type.js';
// ---> Extra Timer
export { type SimpleTimerState, SimplePlayback, SimpleDirection } from './definitions/runtime/ExtraTimer.type.js';
// CLIENT
// TYPE UTILITIES
export { isOntimeBlock, isOntimeDelay, isOntimeEvent } from './utils/guards.js';
export type { MaybeNumber } from './utils/utils.type.js';
export { isOntimeBlock, isOntimeDelay, isOntimeEvent, isOntimeCycle, isKeyOfType } from './utils/guards.js';
export type { DeepPartial, MaybeNumber, MaybeString } from './utils/utils.type.js';
+11 -3
View File
@@ -1,7 +1,10 @@
import { OntimeRundownEntry } from '../definitions/core/Rundown.type.js';
import { OntimeBlock, OntimeDelay, OntimeEvent, SupportedEvent } from '../definitions/core/OntimeEvent.type.js';
import type { OntimeBlock, OntimeDelay, OntimeEvent } from '../definitions/core/OntimeEvent.type.js';
import { SupportedEvent } from '../definitions/core/OntimeEvent.type.js';
import type { OntimeRundownEntry } from '../definitions/core/Rundown.type.js';
import type { TimerLifeCycleKey } from '../definitions/core/TimerLifecycle.type.js';
import { TimerLifeCycle } from '../definitions/core/TimerLifecycle.type.js';
type MaybeEvent = Partial<OntimeRundownEntry> | null | undefined;
type MaybeEvent = OntimeRundownEntry | Partial<OntimeRundownEntry> | null | undefined;
export function isOntimeEvent(event: MaybeEvent): event is OntimeEvent {
return event?.type === SupportedEvent.Event;
@@ -20,3 +23,8 @@ type AnyKeys<T> = keyof T;
export function isKeyOfType<T extends object>(key: PropertyKey, obj: T): key is AnyKeys<T> {
return key in obj;
}
export function isOntimeCycle(maybeCycle: unknown): maybeCycle is TimerLifeCycleKey {
if (typeof maybeCycle !== 'string') return false;
return Object.values(TimerLifeCycle).includes(maybeCycle as TimerLifeCycle);
}
+5
View File
@@ -1 +1,6 @@
export type MaybeNumber = number | null;
export type MaybeString = string | null;
export type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};