Skip to content

Commit

Permalink
add view parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-Arc committed Jan 8, 2025
1 parent c2d8e40 commit f88ee6b
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { hideTimerSeconds } from '../../../common/components/view-params-editor/constants';
import { ViewOption } from '../../../common/components/view-params-editor/types';

export const MINIMAL_TIMER_OPTIONS: ViewOption[] = [
export const POPOUT_TIMER_OPTIONS: ViewOption[] = [
{ section: 'Timer Options' },
hideTimerSeconds,
{ section: 'Element visibility' },
Expand Down Expand Up @@ -58,34 +58,4 @@ export const MINIMAL_TIMER_OPTIONS: ViewOption[] = [
type: 'number',
placeholder: '1 (default)',
},
{
id: 'alignx',
title: 'Align Horizontal',
description: 'Moves the horizontally in page to start = left | center | end = right',
type: 'option',
values: { start: 'Start', center: 'Center', end: 'End' },
defaultValue: 'center',
},
{
id: 'offsetx',
title: 'Offset Horizontal',
description: 'Offsets the timer horizontal position by a given amount in pixels',
type: 'number',
placeholder: '0 (default)',
},
{
id: 'aligny',
title: 'Align Vertical',
description: 'Moves the vertically in page to start = left | center | end = right',
type: 'option',
values: { start: 'Start', center: 'Center', end: 'End' },
defaultValue: 'center',
},
{
id: 'offsety',
title: 'Offset Vertical',
description: 'Offsets the timer vertical position by a given amount in pixels',
type: 'number',
placeholder: '0 (default)',
},
];
16 changes: 14 additions & 2 deletions apps/client/src/features/viewers/pop-out-clock/PopOutTimer.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@use '../../../theme/viewerDefs' as *;

.minimal-timer {
.popput-timer {
margin: 0;
box-sizing: border-box; /* reset */
overflow: hidden;
Expand All @@ -19,10 +19,14 @@
transition: $viewer-transition-time;
}

.mirror {
transform: rotate(180deg);
}

.timer {
opacity: 1;
font-family: var(--font-family-bold-override, $timer-bold-font-family);
font-size: 15vw;
font-size: 20vw;
position: relative;
color: var(--timer-color-override, var(--phase-color));
transition: $viewer-transition-time;
Expand Down Expand Up @@ -50,4 +54,12 @@
color: $timer-finished-color;
padding: 0;
}

.logo {
position: absolute;
top: 2vw;
left: 2vw;
max-width: min(200px, 20vw);
max-height: min(100px, 20vh);
}
}
134 changes: 128 additions & 6 deletions apps/client/src/features/viewers/pop-out-clock/PopOutTimer.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,152 @@
import { useCallback, useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Button } from '@chakra-ui/react';
import { Playback, ProjectData, TimerPhase, TimerType, ViewSettings } from 'ontime-types';

import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor';
import { useWindowTitle } from '../../../common/hooks/useWindowTitle';
import { ViewExtendedTimer } from '../../../common/models/TimeManager.type';
import { OverridableOptions } from '../../../common/models/View.types';
import { useTranslation } from '../../../translation/TranslationProvider';
import { getFormattedTimer, getTimerByType } from '../common/viewUtils';
import { getFormattedTimer, getTimerByType, isStringBoolean } from '../common/viewUtils';

import { POPOUT_TIMER_OPTIONS } from './PopOutTimer.options';

import './PopOutTimer.scss';

interface PopTimerProps {
general: ProjectData;
isMirrored: boolean;
time: ViewExtendedTimer;
viewSettings: ViewSettings;
}

export default function PopOutClock(props: PopTimerProps) {
const { time } = props;
const [pipElement, setPipElement] = useState<{ timer: HTMLDivElement; pipWindow: Window } | false>(false);
const { general, isMirrored, time, viewSettings } = props;

Check failure on line 25 in apps/client/src/features/viewers/pop-out-clock/PopOutTimer.tsx

View workflow job for this annotation

GitHub Actions / unit-test

'general' is assigned a value but never used. Allowed unused vars must match /^_/u
const [pipElement, setPipElement] = useState<
{ timer: HTMLDivElement; pipWindow: Window; background: HTMLDivElement } | false
>(false);
const [searchParams] = useSearchParams();

const { getLocalizedString } = useTranslation();

useWindowTitle('Popout Timer');

const stageTimer = getTimerByType(false, time);
const display = getFormattedTimer(stageTimer, time.timerType, getLocalizedString('common.minutes'), {
removeSeconds: false,
removeLeadingZero: true,
});

// TODO: this should be tied to the params
// USER OPTIONS
const userOptions: OverridableOptions = {
size: 1,
};

// key: string
// Should be a hex string '#00FF00' with key colour
const key = searchParams.get('key');
if (key) {
userOptions.keyColour = `#${key}`;
}

// textColour: string
// Should be a hex string '#ffffff'
const textColour = searchParams.get('text');
if (textColour) {
userOptions.textColour = `#${textColour}`;
}

// textBackground: string
// Should be a hex string '#ffffff'
const textBackground = searchParams.get('textbg');
if (textBackground) {
userOptions.textBackground = `#${textBackground}`;
}

// font: string
// Should be a string with a font name 'arial'
const font = searchParams.get('font');
if (font) {
userOptions.font = font;
}

// size: multiplier
// Should be a number 0.0-n
const size = searchParams.get('size');
if (size !== null && typeof size !== 'undefined') {
if (!Number.isNaN(Number(size))) {
userOptions.size = Number(size);
}
}
const stageTimerCharacters = display.replace('/:/g', '').length;
const timerFontSize = (89 / (stageTimerCharacters - 1)) * (userOptions.size || 1);

const hideOvertime = searchParams.get('hideovertime');
userOptions.hideOvertime = isStringBoolean(hideOvertime);

const hideEndMessage = searchParams.get('hideendmessage');
userOptions.hideEndMessage = isStringBoolean(hideEndMessage);

const hideTimerSeconds = searchParams.get('hideTimerSeconds');
userOptions.hideTimerSeconds = isStringBoolean(hideTimerSeconds);

const showLeadingZeros = searchParams.get('showLeadingZeros');
userOptions.removeLeadingZeros = !isStringBoolean(showLeadingZeros);

const timerIsTimeOfDay = time.timerType === TimerType.Clock;

const isPlaying = time.playback !== Playback.Pause;

const shouldShowModifiers = time.timerType === TimerType.CountDown || time.countToEnd;
const finished = time.phase === TimerPhase.Overtime;
const showEndMessage = shouldShowModifiers && finished && viewSettings.endMessage && !hideEndMessage;
const showFinished =
shouldShowModifiers && finished && !userOptions?.hideOvertime && (shouldShowModifiers || showEndMessage);

const showProgress = time.playback !== Playback.Stop;
const showWarning = shouldShowModifiers && time.phase === TimerPhase.Warning;
const showDanger = shouldShowModifiers && time.phase === TimerPhase.Danger;

let timerColor = viewSettings.normalColor;
if (!timerIsTimeOfDay && showProgress && showWarning) timerColor = viewSettings.warningColor;
if (!timerIsTimeOfDay && showProgress && showDanger) timerColor = viewSettings.dangerColor;

useEffect(() => {
if (pipElement) {
pipElement.timer.innerText = display;
}
}, [display, pipElement]);

useEffect(() => {
if (pipElement) {
pipElement.background.classList.toggle('mirror', isMirrored);
if (userOptions.keyColour) pipElement.background.style.setProperty('background-color', userOptions.keyColour);

pipElement.timer.classList.toggle('timer--paused', !isPlaying);
pipElement.timer.classList.toggle('timer--finished', !showFinished);
if (userOptions.textColour) pipElement.timer.style.setProperty('color', userOptions.textColour);
if (userOptions.textBackground)
pipElement.timer.style.setProperty('background-color', userOptions.textBackground);
if (userOptions.font) pipElement.timer.style.setProperty('font-family', userOptions.font);
pipElement.timer.style.setProperty('font-size', `${timerFontSize}vw`);
pipElement.timer.style.setProperty('--phase-color', timerColor);
}
}, [
isMirrored,
isPlaying,
pipElement,
showFinished,
timerColor,
timerFontSize,
userOptions.font,
userOptions.justifyContent,
userOptions.keyColour,
userOptions.textBackground,
userOptions.textColour,
]);

const closePip = useCallback(() => {
if (pipElement) {
pipElement.pipWindow.close();
Expand All @@ -52,7 +170,9 @@ export default function PopOutClock(props: PopTimerProps) {

// create the backgoind element
const background = document.createElement('div');
background.classList.add('minimal-timer');
background.classList.add('popout-timer');
background.classList.toggle('mirror', isMirrored);

pipWindow.document.body.append(background);

// create the timer element
Expand All @@ -62,7 +182,7 @@ export default function PopOutClock(props: PopTimerProps) {

pipWindow.document.title = 'ONTIME'; //TODO: trying to hide or change the title bar

setPipElement({ timer, pipWindow });
setPipElement({ timer, pipWindow, background });

//clear state when the pip is closed
pipWindow.addEventListener(
Expand All @@ -73,7 +193,7 @@ export default function PopOutClock(props: PopTimerProps) {
{ once: true },
);
});
}, []);
}, [isMirrored]);

return (
<div>
Expand All @@ -84,6 +204,8 @@ export default function PopOutClock(props: PopTimerProps) {
<br></br>
<br></br>
<br></br>
<ViewParamsEditor viewOptions={POPOUT_TIMER_OPTIONS} />

<Button isDisabled={pipElement != false} variant='ontime-filled' onClick={openPip}>
Open
</Button>
Expand Down

0 comments on commit f88ee6b

Please sign in to comment.