Merge remote-tracking branch 'origin/master' into v3

This commit is contained in:
Carlos Valente
2024-01-05 21:55:16 +01:00
15 changed files with 161 additions and 74 deletions
+13 -1
View File
@@ -44,7 +44,8 @@ jobs:
- name: Docker Setup Buildx - name: Docker Setup Buildx
uses: docker/setup-buildx-action@v2.5.0 uses: docker/setup-buildx-action@v2.5.0
- name: Build and push Docker images - name: Build and push stable release
if: github.event.release.prerelease == false
uses: docker/build-push-action@v4.0.0 uses: docker/build-push-action@v4.0.0
with: with:
context: . context: .
@@ -54,3 +55,14 @@ jobs:
push: true push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:latest tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:latest
- name: Build and push pre-release
if: github.event.release.prerelease == true
uses: docker/build-push-action@v4.0.0
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
# Push is a shorthand for --output=type=registry
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/ontime:${{ env.RELEASE_VERSION }} , ${{ secrets.DOCKERHUB_USERNAME }}/ontime:nightly
+1
View File
@@ -40,6 +40,7 @@
"build:local": "cross-env NODE_ENV=local vite build", "build:local": "cross-env NODE_ENV=local vite build",
"build:electron": "cross-env NODE_ENV=local vite build", "build:electron": "cross-env NODE_ENV=local vite build",
"build:docker": "vite build", "build:docker": "vite build",
"build:localdocker": "cross-env NODE_ENV=local vite build",
"lint": "eslint . --quiet", "lint": "eslint . --quiet",
"lint-staged": "eslint", "lint-staged": "eslint",
"test": "vitest", "test": "vitest",
@@ -14,24 +14,26 @@ interface TimeInputProps {
time?: number; time?: number;
delay?: number; delay?: number;
placeholder: string; placeholder: string;
validationHandler: (entry: TimeEntryField, val: number) => boolean;
previousEnd?: number; previousEnd?: number;
warning?: string;
className?: string; className?: string;
} }
function ButtonInitial(name: TimeEntryField) {
if (name === 'timeStart') return 'S';
if (name === 'timeEnd') return 'E';
if (name === 'durationOverride') return 'D';
return '';
}
function ButtonTooltip(name: TimeEntryField, tooltip?: string) {
if (name === 'timeStart') return `Start${tooltip ? `: ${tooltip}` : ''}`;
if (name === 'timeEnd') return `End${tooltip ? `: ${tooltip}` : ''}`;
if (name === 'durationOverride') return `Duration${tooltip ? `: ${tooltip}` : ''}`;
return '';
}
export default function TimeInput(props: TimeInputProps) { export default function TimeInput(props: TimeInputProps) {
const { const { id, name, submitHandler, time = 0, delay = 0, placeholder, previousEnd = 0, className } = props;
id,
name,
submitHandler,
time = 0,
delay = 0,
placeholder,
validationHandler,
previousEnd = 0,
className = '',
} = props;
const { emitError } = useEmitLog(); const { emitError } = useEmitLog();
const inputRef = useRef<HTMLInputElement | null>(null); const inputRef = useRef<HTMLInputElement | null>(null);
const [value, setValue] = useState<string>(''); const [value, setValue] = useState<string>('');
@@ -87,15 +89,12 @@ export default function TimeInput(props: TimeInputProps) {
// check if time is different from before // check if time is different from before
if (newValMillis === time) return false; if (newValMillis === time) return false;
// validate with parent
if (!validationHandler(name, newValMillis)) return false;
// update entry // update entry
submitHandler(name, newValMillis); submitHandler(name, newValMillis);
return true; return true;
}, },
[name, previousEnd, submitHandler, time, validationHandler], [name, previousEnd, submitHandler, time],
); );
/** /**
@@ -153,8 +152,19 @@ export default function TimeInput(props: TimeInputProps) {
resetValue(); resetValue();
}, [resetValue, time]); }, [resetValue, time]);
const isDelayed = delay !== 0;
const inputClasses = cx([style.timeInput, isDelayed ? style.delayed : null]);
const buttonClasses = cx([style.inputButton, isDelayed ? style.delayed : null]);
const timeInputClass = className ? className : style.timeInput; const timeInputClass = className ? className : style.timeInput;
const TooltipLabel = useMemo(() => {
return ButtonTooltip(name, '');
}, [name]);
const ButtonText = useMemo(() => {
return ButtonInitial(name);
}, [name]);
return ( return (
<Input <Input
size='sm' size='sm'
@@ -1,4 +1,4 @@
import { memo, useState } from 'react'; import { memo } from 'react';
import { Select, Switch } from '@chakra-ui/react'; import { Select, Switch } from '@chakra-ui/react';
import { EndAction, OntimeEvent, TimerType } from 'ontime-types'; import { EndAction, OntimeEvent, TimerType } from 'ontime-types';
import { calculateDuration, millisToString } from 'ontime-utils'; import { calculateDuration, millisToString } from 'ontime-utils';
@@ -8,7 +8,6 @@ import TimeInputWithButton from '../../../common/components/input/time-input/Tim
import { useEventAction } from '../../../common/hooks/useEventAction'; import { useEventAction } from '../../../common/hooks/useEventAction';
import { millisToDelayString } from '../../../common/utils/dateConfig'; import { millisToDelayString } from '../../../common/utils/dateConfig';
import { cx } from '../../../common/utils/styleUtils'; import { cx } from '../../../common/utils/styleUtils';
import { TimeEntryField, validateEntry } from '../../../common/utils/timesManager';
import style from '../EventEditor.module.scss'; import style from '../EventEditor.module.scss';
@@ -41,13 +40,6 @@ const EventEditorTimes = (props: EventEditorTimesProps) => {
props; props;
const { updateEvent } = useEventAction(); const { updateEvent } = useEventAction();
const [warning, setWarnings] = useState({ start: '', end: '', duration: '' });
const timerValidationHandler = (entry: TimeEntryField, val: number) => {
const valid = validateEntry(entry, val, timeStart, timeEnd);
setWarnings((prev) => ({ ...prev, ...valid.warnings }));
return valid.value;
};
const handleSubmit = (field: TimeActions, value: number | string | boolean) => { const handleSubmit = (field: TimeActions, value: number | string | boolean) => {
const newEventData: Partial<OntimeEvent> = { id: eventId }; const newEventData: Partial<OntimeEvent> = { id: eventId };
@@ -99,11 +91,9 @@ const EventEditorTimes = (props: EventEditorTimesProps) => {
id='timeStart' id='timeStart'
name='timeStart' name='timeStart'
submitHandler={handleSubmit} submitHandler={handleSubmit}
validationHandler={timerValidationHandler}
time={timeStart} time={timeStart}
delay={delay} delay={delay}
placeholder='Start' placeholder='Start'
warning={warning.start}
/> />
<label className={inputTimeLabels} htmlFor='timeEnd'> <label className={inputTimeLabels} htmlFor='timeEnd'>
{endLabel} {endLabel}
@@ -112,11 +102,9 @@ const EventEditorTimes = (props: EventEditorTimesProps) => {
id='timeEnd' id='timeEnd'
name='timeEnd' name='timeEnd'
submitHandler={handleSubmit} submitHandler={handleSubmit}
validationHandler={timerValidationHandler}
time={timeEnd} time={timeEnd}
delay={delay} delay={delay}
placeholder='End' placeholder='End'
warning={warning.end}
/> />
<label className={style.inputLabel} htmlFor='durationOverride'> <label className={style.inputLabel} htmlFor='durationOverride'>
Duration Duration
@@ -125,10 +113,8 @@ const EventEditorTimes = (props: EventEditorTimesProps) => {
id='durationOverride' id='durationOverride'
name='durationOverride' name='durationOverride'
submitHandler={handleSubmit} submitHandler={handleSubmit}
validationHandler={timerValidationHandler}
time={duration} time={duration}
placeholder='Duration' placeholder='Duration'
warning={warning.duration}
/> />
<span className={style.spacer} /> <span className={style.spacer} />
<label className={`${style.inputLabel} ${style.publicToggle}`}> <label className={`${style.inputLabel} ${style.publicToggle}`}>
@@ -215,7 +215,9 @@ export default function Rundown(props: RundownProps) {
if (index === 0) { if (index === 0) {
eventIndex = 0; eventIndex = 0;
} }
let isFirstEvent = false;
if (entry.type === SupportedEvent.Event) { if (entry.type === SupportedEvent.Event) {
isFirstEvent = eventIndex === 0;
eventIndex++; eventIndex++;
previousEnd = thisEnd; previousEnd = thisEnd;
thisEnd = entry.timeEnd; thisEnd = entry.timeEnd;
@@ -237,6 +239,7 @@ export default function Rundown(props: RundownProps) {
<RundownEntry <RundownEntry
type={entry.type} type={entry.type}
isPast={isPast} isPast={isPast}
isFirstEvent={isFirstEvent}
data={entry} data={entry}
selected={isSelected} selected={isSelected}
hasCursor={hasCursor} hasCursor={hasCursor}
@@ -20,6 +20,7 @@ export type EventItemActions = 'set-cursor' | 'event' | 'delay' | 'block' | 'del
interface RundownEntryProps { interface RundownEntryProps {
type: SupportedEvent; type: SupportedEvent;
isPast: boolean; isPast: boolean;
isFirstEvent: boolean;
data: OntimeRundownEntry; data: OntimeRundownEntry;
selected: boolean; selected: boolean;
hasCursor: boolean; hasCursor: boolean;
@@ -32,8 +33,19 @@ interface RundownEntryProps {
} }
export default function RundownEntry(props: RundownEntryProps) { export default function RundownEntry(props: RundownEntryProps) {
const { isPast, data, selected, hasCursor, next, previousEnd, previousEventId, playback, isRolling, disableEdit } = const {
props; isPast,
data,
selected,
hasCursor,
next,
previousEnd,
previousEventId,
playback,
isRolling,
disableEdit,
isFirstEvent,
} = props;
const { emitError } = useEmitLog(); const { emitError } = useEmitLog();
const { addEvent, updateEvent, deleteEvent, swapEvents } = useEventAction(); const { addEvent, updateEvent, deleteEvent, swapEvents } = useEventAction();
@@ -160,6 +172,7 @@ export default function RundownEntry(props: RundownEntryProps) {
isRolling={isRolling} isRolling={isRolling}
actionHandler={actionHandler} actionHandler={actionHandler}
disableEdit={disableEdit} disableEdit={disableEdit}
isFirstEvent={isFirstEvent}
/> />
); );
} else if (data.type === SupportedEvent.Block) { } else if (data.type === SupportedEvent.Block) {
@@ -10,11 +10,11 @@ $skip-opacity: 0.1;
display: grid; display: grid;
grid-template-areas: grid-template-areas:
"binder ... ... ..." 'binder ... ... ...'
"binder pb-actions times actions" 'binder pb-actions times actions'
"binder pb-actions title next" 'binder pb-actions title next-ind'
"binder pb-actions estatus estatus" 'binder pb-actions estatus estatus'
"binder ... ... ..."; 'binder ... ... ...';
grid-template-columns: $block-binder-width auto 1fr auto; grid-template-columns: $block-binder-width auto 1fr auto;
grid-template-rows: 0.25rem 2.25rem 2.25rem 2.25rem 0.25rem; grid-template-rows: 0.25rem 2.25rem 2.25rem 2.25rem 0.25rem;
@@ -53,8 +53,18 @@ $skip-opacity: 0.1;
outline: 1px solid $block-cursor-color; outline: 1px solid $block-cursor-color;
} }
/* we stop the eventActions from having opacity to fix issue with dropdown drawing order */
&.past:not(.skip) { &.past:not(.skip) {
opacity: 0.6; .delayNote,
.statusElements,
.eventTitle,
.eventNote,
.eventTimers,
.eventStatus,
.playbackActions,
.binder {
opacity: 0.4;
}
} }
&.skip { &.skip {
@@ -160,8 +170,8 @@ $skip-opacity: 0.1;
grid-area: estatus; grid-area: estatus;
display: grid; display: grid;
grid-template-areas: grid-template-areas:
"notes status" 'notes status'
"progb progb"; 'progb progb';
gap: 2px; gap: 2px;
grid-template-rows: auto 0.25rem; grid-template-rows: auto 0.25rem;
align-items: center; align-items: center;
@@ -180,9 +190,8 @@ $skip-opacity: 0.1;
overflow-y: hidden; overflow-y: hidden;
} }
.nextTag { .nextTag {
grid-area: next; grid-area: next-ind;
font-size: 1rem; font-size: 1rem;
color: $orange-500; color: $orange-500;
letter-spacing: 0.03px; letter-spacing: 0.03px;
@@ -190,6 +199,35 @@ $skip-opacity: 0.1;
text-align: right; text-align: right;
} }
.indicators {
grid-area: next-ind;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 0.5rem;
.indicator {
background-color: $gray-1250;
margin: 0.4rem;
margin-right: 0;
border-radius: 0.7rem;
width: 0.7rem;
height: 0.7rem;
}
.indicator.delay {
background-color: $ontime-delay;
}
.indicator.overlap {
background-color: $gray-600;
}
.indicator.spacing {
background-color: $gray-600;
}
.indicator.nextDay {
background-color: $gray-600;
}
}
.eventStatus { .eventStatus {
grid-area: status; grid-area: status;
display: flex; display: flex;
@@ -198,7 +236,6 @@ $skip-opacity: 0.1;
gap: 0.5rem; gap: 0.5rem;
color: var(--status-color-override, $gray-500); color: var(--status-color-override, $gray-500);
.statusIcon { .statusIcon {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
@@ -50,6 +50,7 @@ interface EventBlockProps {
}, },
) => void; ) => void;
disableEdit: boolean; disableEdit: boolean;
isFirstEvent: boolean;
} }
export default function EventBlock(props: EventBlockProps) { export default function EventBlock(props: EventBlockProps) {
@@ -76,6 +77,7 @@ export default function EventBlock(props: EventBlockProps) {
isRolling, isRolling,
actionHandler, actionHandler,
disableEdit, disableEdit,
isFirstEvent,
} = props; } = props;
const { selectedEventId, setSelectedEventId, clearSelectedEventId } = useEventIdSwapping(); const { selectedEventId, setSelectedEventId, clearSelectedEventId } = useEventIdSwapping();
const moveCursorTo = useAppMode((state) => state.setCursor); const moveCursorTo = useAppMode((state) => state.setCursor);
@@ -210,6 +212,7 @@ export default function EventBlock(props: EventBlockProps) {
isRolling={isRolling} isRolling={isRolling}
actionHandler={actionHandler} actionHandler={actionHandler}
disableEdit={disableEdit} disableEdit={disableEdit}
isFirstEvent={isFirstEvent}
/> />
)} )}
</div> </div>
@@ -11,9 +11,11 @@ import { IoPlaySkipForward } from '@react-icons/all-files/io5/IoPlaySkipForward'
import { IoStop } from '@react-icons/all-files/io5/IoStop'; import { IoStop } from '@react-icons/all-files/io5/IoStop';
import { IoTime } from '@react-icons/all-files/io5/IoTime'; import { IoTime } from '@react-icons/all-files/io5/IoTime';
import { EndAction, Playback, TimerType } from 'ontime-types'; import { EndAction, Playback, TimerType } from 'ontime-types';
import { millisToString } from 'ontime-utils';
import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn'; import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn';
import { useAppMode } from '../../../common/stores/appModeStore'; import { useAppMode } from '../../../common/stores/appModeStore';
import { millisToDelayString } from '../../../common/utils/dateConfig';
import { tooltipDelayMid } from '../../../ontimeConfig'; import { tooltipDelayMid } from '../../../ontimeConfig';
import EditableBlockTitle from '../common/EditableBlockTitle'; import EditableBlockTitle from '../common/EditableBlockTitle';
import { EventItemActions } from '../RundownEntry'; import { EventItemActions } from '../RundownEntry';
@@ -53,6 +55,7 @@ interface EventBlockInnerProps {
isRolling: boolean; isRolling: boolean;
actionHandler: (action: EventItemActions, payload?: any) => void; actionHandler: (action: EventItemActions, payload?: any) => void;
disableEdit: boolean; disableEdit: boolean;
isFirstEvent: boolean;
} }
const EventBlockInner = (props: EventBlockInnerProps) => { const EventBlockInner = (props: EventBlockInnerProps) => {
@@ -76,6 +79,7 @@ const EventBlockInner = (props: EventBlockInnerProps) => {
isRolling, isRolling,
actionHandler, actionHandler,
disableEdit, disableEdit,
isFirstEvent,
} = props; } = props;
const [renderInner, setRenderInner] = useState(false); const [renderInner, setRenderInner] = useState(false);
@@ -103,6 +107,19 @@ const EventBlockInner = (props: EventBlockInnerProps) => {
playBtnStyles._hover = {}; playBtnStyles._hover = {};
} }
const delayedStart = Math.max(0, timeStart + delay);
const newTime = millisToString(delayedStart);
const delayTime = delay !== 0 ? millisToDelayString(delay) : null;
const overlap = previousEnd - timeStart;
const overlapTime = !isFirstEvent
? overlap > 0
? `Overlapping ${millisToDelayString(overlap)}`
: overlap < 0
? `Spacing ${millisToDelayString(overlap)}`
: null
: null;
return !renderInner ? null : ( return !renderInner ? null : (
<> <>
<EventBlockTimers <EventBlockTimers
@@ -114,10 +131,36 @@ const EventBlockInner = (props: EventBlockInnerProps) => {
previousEnd={previousEnd} previousEnd={previousEnd}
/> />
<EditableBlockTitle title={title} eventId={eventId} placeholder='Event title' className={style.eventTitle} /> <EditableBlockTitle title={title} eventId={eventId} placeholder='Event title' className={style.eventTitle} />
{next && ( {next ? (
<Tooltip label='Next event' {...tooltipProps}> <Tooltip label='Next event' {...tooltipProps}>
<span className={style.nextTag}>UP NEXT</span> <span className={style.nextTag}>UP NEXT</span>
</Tooltip> </Tooltip>
) : (
<span className={style.indicators}>
<Tooltip
label={
delayTime && (
<div>
{delayTime}
<br />
New Time: {newTime}
</div>
)
}
>
<div className={`${style.indicator} ${delayTime ? style.delay : ''}`} />
</Tooltip>
<Tooltip label={overlapTime}>
<div
className={`${style.indicator} ${
overlap > 0 ? style.overlap : overlap < 0 && overlapTime !== null ? style.spacing : ''
}`}
/>
</Tooltip>
<Tooltip label='Start time is later than end'>
<div className={`${style.indicator} ${timeStart > timeEnd ? style.nextDay : ''}`} />
</Tooltip>
</span>
)} )}
<EventBlockPlayback <EventBlockPlayback
eventId={eventId} eventId={eventId}
@@ -1,11 +1,10 @@
import { memo, useCallback, useState } from 'react'; import { memo } from 'react';
import { OntimeEvent } from 'ontime-types'; import { OntimeEvent } from 'ontime-types';
import { calculateDuration, millisToString } from 'ontime-utils'; import { calculateDuration, millisToString } from 'ontime-utils';
import TimeInputWithButton from '../../../../common/components/input/time-input/TimeInputWithButton'; import TimeInputWithButton from '../../../../common/components/input/time-input/TimeInputWithButton';
import { useEventAction } from '../../../../common/hooks/useEventAction'; import { useEventAction } from '../../../../common/hooks/useEventAction';
import { millisToDelayString } from '../../../../common/utils/dateConfig'; import { millisToDelayString } from '../../../../common/utils/dateConfig';
import { TimeEntryField, validateEntry } from '../../../../common/utils/timesManager';
import style from '../EventBlock.module.scss'; import style from '../EventBlock.module.scss';
@@ -24,8 +23,6 @@ const EventBlockTimers = (props: EventBlockTimerProps) => {
const { eventId, timeStart, timeEnd, duration, delay, previousEnd } = props; const { eventId, timeStart, timeEnd, duration, delay, previousEnd } = props;
const { updateEvent } = useEventAction(); const { updateEvent } = useEventAction();
const [warning, setWarnings] = useState({ start: '', end: '', duration: '' });
const handleSubmit = (field: TimeActions, value: number) => { const handleSubmit = (field: TimeActions, value: number) => {
const newEventData: Partial<OntimeEvent> = { id: eventId }; const newEventData: Partial<OntimeEvent> = { id: eventId };
switch (field) { switch (field) {
@@ -49,21 +46,6 @@ const EventBlockTimers = (props: EventBlockTimerProps) => {
updateEvent(newEventData); updateEvent(newEventData);
}; };
/**
* @description Validates a time input against its pair
* @param {string} entry - field to validate: timeStart, timeEnd, durationOverride
* @param {number} val - field value
* @return {boolean}
*/
const handleValidation = useCallback(
(field: TimeEntryField, value: number) => {
const valid = validateEntry(field, value, timeStart, timeEnd);
setWarnings((prev) => ({ ...prev, ...valid.warnings }));
return valid.value;
},
[timeEnd, timeStart],
);
const delayedStart = Math.max(0, timeStart + delay); const delayedStart = Math.max(0, timeStart + delay);
const newTime = millisToString(delayedStart); const newTime = millisToString(delayedStart);
const delayTime = delay !== 0 ? millisToDelayString(delay) : null; const delayTime = delay !== 0 ? millisToDelayString(delay) : null;
@@ -73,32 +55,26 @@ const EventBlockTimers = (props: EventBlockTimerProps) => {
<TimeInputWithButton <TimeInputWithButton
name='timeStart' name='timeStart'
submitHandler={handleSubmit} submitHandler={handleSubmit}
validationHandler={handleValidation}
time={timeStart} time={timeStart}
delay={delay} delay={delay}
placeholder='Start' placeholder='Start'
previousEnd={previousEnd} previousEnd={previousEnd}
warning={warning.start}
/> />
<TimeInputWithButton <TimeInputWithButton
name='timeEnd' name='timeEnd'
submitHandler={handleSubmit} submitHandler={handleSubmit}
validationHandler={handleValidation}
time={timeEnd} time={timeEnd}
delay={delay} delay={delay}
placeholder='End' placeholder='End'
previousEnd={previousEnd} previousEnd={previousEnd}
warning={warning.end}
/> />
<TimeInputWithButton <TimeInputWithButton
name='durationOverride' name='durationOverride'
submitHandler={handleSubmit} submitHandler={handleSubmit}
validationHandler={handleValidation}
time={duration} time={duration}
delay={0} delay={0}
placeholder='Duration' placeholder='Duration'
previousEnd={previousEnd} previousEnd={previousEnd}
warning={warning.duration}
/> />
{delayTime && ( {delayTime && (
<div className={style.delayNote}> <div className={style.delayNote}>
@@ -3,7 +3,6 @@ import { TranslationObject } from './en';
export const langIt: TranslationObject = { export const langIt: TranslationObject = {
'common.end_time': 'Ora di Fine', 'common.end_time': 'Ora di Fine',
'common.expected_finish': 'Fine Prevista', 'common.expected_finish': 'Fine Prevista',
'common.minutes': 'min',
'common.now': 'Adesso', 'common.now': 'Adesso',
'common.next': 'Prossimo', 'common.next': 'Prossimo',
'common.public_message': 'Messaggio pubblico', 'common.public_message': 'Messaggio pubblico',
+1
View File
@@ -52,6 +52,7 @@
"build:electron": "pnpm prebuild && esbuild src/app.ts --log-level=error --platform=node --format=cjs --bundle --minify --outfile=dist/index.cjs", "build:electron": "pnpm prebuild && esbuild src/app.ts --log-level=error --platform=node --format=cjs --bundle --minify --outfile=dist/index.cjs",
"build:local": "pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --bundle --minify --outfile=dist/index.cjs", "build:local": "pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --bundle --minify --outfile=dist/index.cjs",
"build:docker": "pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --minify --bundle --outfile=dist/docker.cjs", "build:docker": "pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --minify --bundle --outfile=dist/docker.cjs",
"build:localdocker": "NODE_ENV=local pnpm prebuild && esbuild src/index.ts --log-level=error --platform=node --format=cjs --minify --bundle --outfile=dist/docker.cjs",
"build:debug": "pnpm prebuild && esbuild src/app.ts --platform=node --format=cjs --bundle --outfile=dist/index.cjs", "build:debug": "pnpm prebuild && esbuild src/app.ts --platform=node --format=cjs --bundle --outfile=dist/index.cjs",
"lint": "eslint . --quiet", "lint": "eslint . --quiet",
"lint-staged": "eslint", "lint-staged": "eslint",
+1 -1
View File
@@ -3,7 +3,7 @@ version: "3"
services: services:
ontime: ontime:
container_name: ontime container_name: ontime
image: getontime/ontime:beta_v2 image: getontime/ontime:latest
ports: ports:
- "4001:4001/tcp" - "4001:4001/tcp"
- "8888:8888/udp" - "8888:8888/udp"
+2
View File
@@ -30,6 +30,8 @@
"build": "turbo run build", "build": "turbo run build",
"build:local": "turbo run build:local", "build:local": "turbo run build:local",
"build:electron": "turbo run build:electron", "build:electron": "turbo run build:electron",
"build:docker": "turbo run build:docker",
"build:localdocker": "turbo run build:localdocker",
"dist-win": "turbo run dist-win", "dist-win": "turbo run dist-win",
"dist-mac": "turbo run dist-mac", "dist-mac": "turbo run dist-mac",
"dist-linux": "turbo run dist-linux", "dist-linux": "turbo run dist-linux",
+1
View File
@@ -26,6 +26,7 @@
"build:local": {}, "build:local": {},
"build:electron": {}, "build:electron": {},
"build:docker": {}, "build:docker": {},
"build:localdocker": {},
"e2e": { "e2e": {
"dependsOn": ["^build"] "dependsOn": ["^build"]
}, },