mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-16 04:43:35 +00:00
Feat/162 (#187)
* feat(key): add user options to minimal timer * feat(key): register minimal timer in settings * feat(key): version bump
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import NavLogo from '../../../common/components/nav/NavLogo';
|
||||
@@ -8,26 +9,127 @@ import style from './MinimalTimer.module.scss';
|
||||
|
||||
export default function MinimalTimer(props) {
|
||||
const { pres, time } = props;
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
// Set window title
|
||||
useEffect(() => {
|
||||
document.title = 'ontime - Minimal Timer';
|
||||
}, []);
|
||||
document.title = 'ontime - Minimal Timer';
|
||||
|
||||
// get config from url: key, text, font, size, hidenav, hideovertime
|
||||
// eg. http://localhost:3000/minimal?key=f00&text=fff
|
||||
// Check for user options
|
||||
const userOptions = {};
|
||||
|
||||
// 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}`;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
userOptions.size = size;
|
||||
}
|
||||
|
||||
// alignX: flex justification
|
||||
// start | center | end
|
||||
const alignX = searchParams.get('alignx');
|
||||
if (alignX) {
|
||||
if (alignX === 'start' || alignX === 'center' || alignX === 'end') {
|
||||
userOptions.justifyContent = alignX;
|
||||
}
|
||||
}
|
||||
|
||||
// alignX: flex alignment
|
||||
// start | center | end
|
||||
const alignY = searchParams.get('aligny');
|
||||
if (alignY) {
|
||||
if (alignY === 'start' || alignY === 'center' || alignY === 'end') {
|
||||
userOptions.alignItems = alignY;
|
||||
}
|
||||
}
|
||||
|
||||
// offsetX: position in pixels
|
||||
// Should be a number 0 - 1920
|
||||
const offsetX = searchParams.get('offsetx');
|
||||
if (offsetX) {
|
||||
const pixels = Number(offsetX);
|
||||
if (!isNaN(pixels)) {
|
||||
userOptions.left = `${pixels}px`;
|
||||
}
|
||||
}
|
||||
|
||||
// offsetX: position in pixels
|
||||
// Should be a number 0 - 1920
|
||||
const offsetY = searchParams.get('offsety');
|
||||
if (offsetY) {
|
||||
const pixels = Number(offsetY);
|
||||
if (!isNaN(pixels)) {
|
||||
userOptions.top = `${pixels}px`;
|
||||
}
|
||||
}
|
||||
|
||||
const hideNav = searchParams.get('hidenav');
|
||||
if (hideNav) {
|
||||
userOptions.hideNav = hideNav;
|
||||
}
|
||||
|
||||
const hideOvertime = searchParams.get('hideovertime');
|
||||
if (hideOvertime) {
|
||||
userOptions.hideOvertime = hideOvertime;
|
||||
}
|
||||
|
||||
const hideMessagesOverlay = searchParams.get('hidemessages');
|
||||
if (hideMessagesOverlay) {
|
||||
userOptions.hideMessagesOverlay = hideMessagesOverlay;
|
||||
}
|
||||
|
||||
const showOverlay = pres.text !== '' && pres.visible;
|
||||
const isPlaying = time.playstate !== 'pause';
|
||||
const timer = formatDisplay(time.running, true);
|
||||
const clean = timer.replace('/:/g', '');
|
||||
const finishedStyle = userOptions?.hideOvertime ? style.container : style.containerFinished;
|
||||
|
||||
return (
|
||||
<div className={time.finished ? style.containerFinished : style.container}>
|
||||
<div className={showOverlay ? style.messageOverlayActive : style.messageOverlay}>
|
||||
<div className={style.message}>{pres.text}</div>
|
||||
</div>
|
||||
<NavLogo />
|
||||
<div
|
||||
className={time.finished ? finishedStyle : style.container}
|
||||
style={{
|
||||
backgroundColor: userOptions.keyColour,
|
||||
color: userOptions.textColour,
|
||||
justifyContent: userOptions.justifyContent,
|
||||
alignItems: userOptions.alignItems,
|
||||
}}
|
||||
data-testid='minimal-timer'
|
||||
>
|
||||
{!hideMessagesOverlay && (
|
||||
<div className={showOverlay ? style.messageOverlayActive : style.messageOverlay}>
|
||||
<div className={style.message}>{pres.text}</div>
|
||||
</div>
|
||||
)}
|
||||
{!userOptions?.hideNav && <NavLogo />}
|
||||
<div
|
||||
style={{ fontSize: `${89 / (clean.length - 1)}vw` }}
|
||||
className={isPlaying ? style.timer : style.timerPaused}
|
||||
style={{
|
||||
fontSize: `${(89 / (clean.length - 1)) * userOptions.size}vw`,
|
||||
fontFamily: userOptions.font,
|
||||
top: userOptions.top,
|
||||
left: userOptions.left,
|
||||
}}
|
||||
>
|
||||
{time.isNegative ? `-${timer}` : timer}
|
||||
</div>
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
background: $bg-black;
|
||||
height: 100vh;
|
||||
color: $title-white;
|
||||
display: grid;
|
||||
place-content: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1vw;
|
||||
border: 1vw solid $bg-black;
|
||||
border: 1vw solid transparent;
|
||||
}
|
||||
|
||||
.containerFinished {
|
||||
@@ -21,6 +22,7 @@
|
||||
.timerPaused {
|
||||
font-family: "Arial Black", sans-serif;
|
||||
font-size: 20vw;
|
||||
position: relative;
|
||||
color: inherit;
|
||||
opacity: 1;
|
||||
transition: 0.5s;
|
||||
|
||||
Reference in New Issue
Block a user