mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-18 05:34:09 +00:00
Feat/132 (#198)
This commit is contained in:
@@ -2,7 +2,7 @@ import { memo } from 'react';
|
||||
import { formatDisplay } from 'common/utils/dateConfig';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import styles from './TimerDisplay.module.scss';
|
||||
import './TimerDisplay.scss';
|
||||
|
||||
const TimerDisplay = ({ time, small, isNegative, hideZeroHours }) => {
|
||||
|
||||
@@ -11,14 +11,9 @@ const TimerDisplay = ({ time, small, isNegative, hideZeroHours }) => {
|
||||
? '-- : -- : --'
|
||||
: formatDisplay(time, hideZeroHours);
|
||||
|
||||
const classes = `${small ? styles.countdownClockSmall : styles.countdownClock}
|
||||
${isNegative ? styles.negative : ''}`;
|
||||
const classes = `timer ${small ? 'timer--small' : ''} ${isNegative ? 'timer--finished' : ''}`;
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
{display}
|
||||
</div>
|
||||
);
|
||||
return <div className={classes}>{display}</div>;
|
||||
};
|
||||
|
||||
export default memo(TimerDisplay);
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
@use '../../../theme/main' as *;
|
||||
|
||||
/* Common */
|
||||
.countdownClock,
|
||||
.countdownClockSmall {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
line-height: 0.9;
|
||||
color: $text-white;
|
||||
}
|
||||
|
||||
/* Viewers */
|
||||
.countdownClock {
|
||||
font-size: 21vw;
|
||||
line-height: 21vw;
|
||||
text-align: center;
|
||||
letter-spacing: 1vw;
|
||||
}
|
||||
|
||||
/* Editor */
|
||||
.countdownClockSmall {
|
||||
font-size: 4em;
|
||||
text-align: center;
|
||||
letter-spacing: 0.1em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.negative {
|
||||
color: $ontime-pink;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
@use '../../../theme/viewerDefs' as *;
|
||||
|
||||
.timer {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
color: var(--timer-color-override, $viewer-color);
|
||||
font-size: 21vw;
|
||||
line-height: 21vw;
|
||||
text-align: center;
|
||||
letter-spacing: 1vw;
|
||||
|
||||
&--small {
|
||||
font-size: 4em;
|
||||
line-height: 0.9;
|
||||
text-align: center;
|
||||
letter-spacing: 0.1em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&--finished {
|
||||
color: $timer-finished-color;
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,8 @@ class ErrorBoundary extends React.Component {
|
||||
});
|
||||
try {
|
||||
this.context.emitError(error.toString());
|
||||
} catch {
|
||||
console.log('Unable to emit error')
|
||||
} catch (e) {
|
||||
console.log('Unable to emit error', error, e )
|
||||
}
|
||||
this.reportContent = `${error} ${info.componentStack}`;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const navigatorConstants = [
|
||||
{ url: '/timer', label: 'Timer' },
|
||||
{ url: '/minimal', label: 'Minimal Timer' },
|
||||
{ url: '/sm', label: 'Backstage' },
|
||||
{ url: '/backstage', label: 'Backstage' },
|
||||
{ url: '/public', label: 'Public' },
|
||||
{ url: '/lower', label: 'Lower Thirds' },
|
||||
{ url: '/pip', label: 'PiP' },
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ import Empty from '../state/Empty';
|
||||
|
||||
import TodayItem from './TodayItem';
|
||||
|
||||
import style from './Paginator.module.scss';
|
||||
import './Paginator.scss';
|
||||
|
||||
export default function Paginator(props) {
|
||||
const {
|
||||
@@ -70,7 +70,7 @@ export default function Paginator(props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={style.entries}>
|
||||
<div className='paginator entries'>
|
||||
{page.map((e) => {
|
||||
if (e.id === selectedId) selectedState = 1;
|
||||
else if (selectedState === 1) selectedState = 2;
|
||||
@@ -0,0 +1,62 @@
|
||||
@use '../../../theme/viewerDefs' as *;
|
||||
|
||||
.paginator.entries {
|
||||
width: 100%;
|
||||
|
||||
.entry-times {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-size: 1.4vw;
|
||||
|
||||
min-width: 10vw;
|
||||
opacity: 0.9;
|
||||
letter-spacing: 0.035em;
|
||||
}
|
||||
|
||||
.entry-title {
|
||||
align-self: center;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.entry {
|
||||
display: flex;
|
||||
font-size: 1.3vw;
|
||||
padding: 0.2vh 1vw;
|
||||
margin-bottom: 1.5vh;
|
||||
border-radius: 3px;
|
||||
|
||||
&--now,
|
||||
&--future {
|
||||
color: var(--color-override, $viewer-color);
|
||||
}
|
||||
|
||||
&--past {
|
||||
font-size: 1.2vw;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&--now {
|
||||
line-height: 5vh;
|
||||
background-color: $now-bg-color;
|
||||
border-bottom: 0.5vh solid;
|
||||
border-bottom-color: var(--accent-color-override, $accent-color);
|
||||
margin-left: -0.5em;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
&--future {
|
||||
background-color: $future-bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.backstage-indicator {
|
||||
color: var(--accent-color-override, $accent-color);
|
||||
margin-left: auto;
|
||||
margin-right: -0.5vw;
|
||||
|
||||
&::before {
|
||||
content: '*';
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
||||
|
||||
import { formatTime } from '../../utils/time';
|
||||
|
||||
import style from './Paginator.module.scss';
|
||||
import './Paginator.scss';
|
||||
|
||||
export default function TodayItem(props) {
|
||||
const { selected, timeStart, timeEnd, title, backstageEvent, colour } = props;
|
||||
@@ -15,16 +15,16 @@ export default function TodayItem(props) {
|
||||
const userColour = colour !== '' ? colour : 'transparent';
|
||||
|
||||
// select styling
|
||||
let selectStyle = style.entryPast;
|
||||
if (selected === 1) selectStyle = style.entryNow;
|
||||
else if (selected === 2) selectStyle = style.entryFuture;
|
||||
let selectStyle = 'entry--past';
|
||||
if (selected === 1) selectStyle = 'entry--now';
|
||||
else if (selected === 2) selectStyle = 'entry--future';
|
||||
return (
|
||||
<div className={selectStyle} style={{ borderLeft: `4px solid ${userColour}` }}>
|
||||
<div className={`${style.entryTimes} ${backstageEvent ? style.backstage : ''}`}>
|
||||
<div className={`entry ${selectStyle}`} style={{ borderLeft: `4px solid ${userColour}` }}>
|
||||
<div className='entry-times'>
|
||||
{`${start} · ${end}`}
|
||||
</div>
|
||||
<div className={style.entryTitle}>{title}</div>
|
||||
{backstageEvent && <div className={style.backstageInd} />}
|
||||
<div className='entry-title'>{title}</div>
|
||||
{backstageEvent && <div className='backstage-indicator' />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './TitleSide.scss';
|
||||
|
||||
export default function TitleSide(props) {
|
||||
const { type, label, title, subtitle, presenter } = props;
|
||||
|
||||
const isNext = type === 'next';
|
||||
|
||||
return (
|
||||
<div className='title-side'>
|
||||
<div className='label'>{label}</div>
|
||||
<div className={isNext ? 'title next' : 'title now'}>{title}</div>
|
||||
<div className={isNext ? 'presenter next' : 'presenter now'}>{presenter}</div>
|
||||
<div className={isNext ? 'subtitle next' : 'subtitle now'}>{subtitle}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
TitleSide.propTypes = {
|
||||
type: PropTypes.oneOf(['now', 'next']),
|
||||
label: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
subtitle: PropTypes.string,
|
||||
presenter: PropTypes.string,
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
@use '../../../theme/viewerDefs' as *;
|
||||
|
||||
.title-side {
|
||||
.label {
|
||||
font-size: 1.3vw;
|
||||
color: var(--accent-color-override, $accent-color);
|
||||
}
|
||||
|
||||
.title,
|
||||
.subtitle,
|
||||
.presenter {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: $title-color;
|
||||
font-weight: 600;
|
||||
|
||||
&.now {
|
||||
font-size: 2.5vw;
|
||||
}
|
||||
|
||||
&.next {
|
||||
font-size: 2vw;
|
||||
}
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: $subtitle-color;
|
||||
&.now {
|
||||
font-size: 1.2vw;
|
||||
margin-top: -1vh;
|
||||
}
|
||||
|
||||
&.next {
|
||||
font-size: 1.1vw;
|
||||
margin-top: -0.8vh;
|
||||
}
|
||||
}
|
||||
|
||||
.presenter {
|
||||
font-weight: 400;
|
||||
color: $subtitle-color;
|
||||
|
||||
&.now {
|
||||
font-size: 2vw;
|
||||
}
|
||||
|
||||
&.next {
|
||||
font-size: 1.5vw;
|
||||
}
|
||||
}
|
||||
|
||||
.title:after,
|
||||
.subtitle:after,
|
||||
.presenter:after {
|
||||
content: '\200b';
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
@use '../../../theme/main' as *;
|
||||
|
||||
.entries {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.entryTimes {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-size: 1.4vw;
|
||||
|
||||
min-width: 10vw;
|
||||
opacity: 0.9;
|
||||
letter-spacing: 0.035em;
|
||||
}
|
||||
|
||||
.entryTitle {
|
||||
align-self: center;
|
||||
@include ellipsis;
|
||||
}
|
||||
|
||||
.entryPast,
|
||||
.entryNow,
|
||||
.entryFuture {
|
||||
display: flex;
|
||||
font-size: 1.3vw;
|
||||
padding: 0.2vh 1vw;
|
||||
margin-bottom: 1.5vh;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.entryPast {
|
||||
font-size: 1.2vw;
|
||||
}
|
||||
|
||||
.entryPast > .entryTitle {
|
||||
color: $text-gray-disabled;
|
||||
}
|
||||
|
||||
.entryNow,
|
||||
.entryFuture {
|
||||
color: $text-white;
|
||||
}
|
||||
|
||||
.entryFuture {
|
||||
background-color: $bg-gray-950;
|
||||
}
|
||||
|
||||
.entryNow {
|
||||
line-height: 5vh;
|
||||
background-color: $bg-gray-900;
|
||||
border-bottom: 0.5vh solid $ontime-pink;
|
||||
margin-left: -0.5em;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.backstageInd {
|
||||
color: $ontime-pink;
|
||||
margin-left: auto;
|
||||
margin-right: -0.5vw;
|
||||
}
|
||||
|
||||
.backstageInd::before {
|
||||
content: '*';
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import style from './TitleSide.module.scss';
|
||||
|
||||
export default function TitleSide(props) {
|
||||
const { type, label, title, subtitle, presenter } = props;
|
||||
|
||||
const titleStyle = type === 'next' ? style.nextTitle : style.nowTitle;
|
||||
const subStyle = type === 'next' ? style.nextSubtitle : style.nowSubtitle;
|
||||
const presStyle = type === 'next' ? style.nextPresenter : style.nowPresenter;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={style.label}>{label}</div>
|
||||
<div className={titleStyle}>{title}</div>
|
||||
<div className={presStyle}>{presenter}</div>
|
||||
<div className={subStyle}>{subtitle}</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
TitleSide.propTypes = {
|
||||
type: PropTypes.oneOf(['now', 'next']),
|
||||
label: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
subtitle: PropTypes.string,
|
||||
presenter: PropTypes.string,
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
@use '../../../theme/main' as *;
|
||||
|
||||
.label {
|
||||
@include card-label;
|
||||
}
|
||||
|
||||
.nowTitle,
|
||||
.nextTitle {
|
||||
@include card-title;
|
||||
}
|
||||
|
||||
.nowSubtitle,
|
||||
.nowPresenter,
|
||||
.nextSubtitle,
|
||||
.nextPresenter {
|
||||
color: $subtitle-gray;
|
||||
}
|
||||
|
||||
.nowTitle {
|
||||
font-size: 2.5vw;
|
||||
}
|
||||
|
||||
.nowPresenter {
|
||||
font-size: 2vw;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.nowSubtitle {
|
||||
font-size: 1.2vw;
|
||||
margin-top: -1vh;
|
||||
}
|
||||
|
||||
.nextTitle {
|
||||
font-size: 2vw;
|
||||
}
|
||||
|
||||
.nextSubtitle {
|
||||
margin-top: -0.8vh;
|
||||
font-size: 1.1vw;
|
||||
}
|
||||
|
||||
.nextPresenter {
|
||||
font-weight: 400;
|
||||
font-size: 1.5vw;
|
||||
}
|
||||
|
||||
.nowTitle:after,
|
||||
.nowSubtitle:after,
|
||||
.nowPresenter:after,
|
||||
.nextTitle:after,
|
||||
.nextSubtitle:after,
|
||||
.nextPresenter:after {
|
||||
content: '\200b';
|
||||
}
|
||||
Reference in New Issue
Block a user