From 9bfa3e9f8e558e9157e46b30f66d1e6029901982 Mon Sep 17 00:00:00 2001 From: Carlos Valente Date: Mon, 18 Nov 2024 13:40:37 +0100 Subject: [PATCH] feat: implement logo in all views --- .../common/components/view-logo/ViewLogo.tsx | 11 +++++++++ .../features/viewers/backstage/Backstage.scss | 6 +++++ .../features/viewers/backstage/Backstage.tsx | 16 +++++++------ .../src/features/viewers/clock/Clock.scss | 10 +++++++- .../src/features/viewers/clock/Clock.tsx | 7 ++++-- .../features/viewers/countdown/Countdown.scss | 12 ++++++++-- .../features/viewers/countdown/Countdown.tsx | 18 +++++++++++--- .../viewers/minimal-timer/MinimalTimer.scss | 24 ++++++++++++------- .../viewers/minimal-timer/MinimalTimer.tsx | 7 ++++-- .../src/features/viewers/public/Public.scss | 8 ++++++- .../src/features/viewers/public/Public.tsx | 6 +++-- .../features/viewers/studio/StudioClock.scss | 7 ++++++ .../features/viewers/studio/StudioClock.tsx | 13 ++++++---- .../src/features/viewers/timer/Timer.tsx | 4 ++-- .../src/views/timeline/TimelinePage.scss | 9 ++++++- .../src/views/timeline/TimelinePage.tsx | 2 ++ 16 files changed, 124 insertions(+), 36 deletions(-) create mode 100644 apps/client/src/common/components/view-logo/ViewLogo.tsx diff --git a/apps/client/src/common/components/view-logo/ViewLogo.tsx b/apps/client/src/common/components/view-logo/ViewLogo.tsx new file mode 100644 index 000000000..1988d485f --- /dev/null +++ b/apps/client/src/common/components/view-logo/ViewLogo.tsx @@ -0,0 +1,11 @@ +import { projectLogoPath } from '../../api/constants'; + +interface ViewLogoProps { + name: string; + className: string; +} + +export default function ViewLogo(props: ViewLogoProps) { + const { name, className } = props; + return ; +} diff --git a/apps/client/src/features/viewers/backstage/Backstage.scss b/apps/client/src/features/viewers/backstage/Backstage.scss index 62fe19e1e..6b80a5fda 100644 --- a/apps/client/src/features/viewers/backstage/Backstage.scss +++ b/apps/client/src/features/viewers/backstage/Backstage.scss @@ -29,6 +29,12 @@ font-size: clamp(32px, 4.5vw, 64px); font-weight: 600; display: flex; + gap: 1rem; + } + + .logo { + max-width: min(200px, 20vw); + max-height: min(100px, 20vh); } .clock-container { diff --git a/apps/client/src/features/viewers/backstage/Backstage.tsx b/apps/client/src/features/viewers/backstage/Backstage.tsx index b75e10c92..f429e1844 100644 --- a/apps/client/src/features/viewers/backstage/Backstage.tsx +++ b/apps/client/src/features/viewers/backstage/Backstage.tsx @@ -10,6 +10,7 @@ import Schedule from '../../../common/components/schedule/Schedule'; import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext'; import ScheduleNav from '../../../common/components/schedule/ScheduleNav'; import TitleCard from '../../../common/components/title-card/TitleCard'; +import ViewLogo from '../../../common/components/view-logo/ViewLogo'; import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor'; import { useWindowTitle } from '../../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../../common/models/TimeManager.type'; @@ -27,19 +28,19 @@ import './Backstage.scss'; export const MotionTitleCard = motion(TitleCard); interface BackstageProps { - customFields: CustomFields; - isMirrored: boolean; - eventNow: OntimeEvent | null; - eventNext: OntimeEvent | null; - time: ViewExtendedTimer; backstageEvents: OntimeEvent[]; - selectedId: string | null; + customFields: CustomFields; + eventNext: OntimeEvent | null; + eventNow: OntimeEvent | null; general: ProjectData; + isMirrored: boolean; + time: ViewExtendedTimer; + selectedId: string | null; settings: Settings | undefined; } export default function Backstage(props: BackstageProps) { - const { customFields, isMirrored, eventNow, eventNext, time, backstageEvents, selectedId, general, settings } = props; + const { backstageEvents, customFields, eventNext, eventNow, general, time, isMirrored, selectedId, settings } = props; const { getLocalizedString } = useTranslation(); const [blinkClass, setBlinkClass] = useState(false); @@ -81,6 +82,7 @@ export default function Backstage(props: BackstageProps) {
+ {general?.projectLogo && } {general.title}
{getLocalizedString('common.time_now')}
diff --git a/apps/client/src/features/viewers/clock/Clock.scss b/apps/client/src/features/viewers/clock/Clock.scss index 1f44b1cf7..a4905bd38 100644 --- a/apps/client/src/features/viewers/clock/Clock.scss +++ b/apps/client/src/features/viewers/clock/Clock.scss @@ -13,10 +13,18 @@ place-content: center; .clock { - font-family: var(--font-family-bold-override, $timer-bold-font-family) ; + font-family: var(--font-family-bold-override, $timer-bold-font-family); font-size: 20vw; position: relative; color: var(--timer-color-override, $timer-color); letter-spacing: 0.05em; } + + .logo { + position: absolute; + top: 2vw; + left: 2vw; + max-width: min(200px, 20vw); + max-height: min(100px, 20vh); + } } diff --git a/apps/client/src/features/viewers/clock/Clock.tsx b/apps/client/src/features/viewers/clock/Clock.tsx index 82ebe1419..b0a739cdf 100644 --- a/apps/client/src/features/viewers/clock/Clock.tsx +++ b/apps/client/src/features/viewers/clock/Clock.tsx @@ -1,6 +1,7 @@ import { useSearchParams } from 'react-router-dom'; -import { Settings } from 'ontime-types'; +import { ProjectData, Settings } from 'ontime-types'; +import ViewLogo from '../../../common/components/view-logo/ViewLogo'; import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor'; import { useWindowTitle } from '../../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../../common/models/TimeManager.type'; @@ -13,13 +14,14 @@ import { getClockOptions } from './clock.options'; import './Clock.scss'; interface ClockProps { + general: ProjectData; isMirrored: boolean; time: ViewExtendedTimer; settings: Settings | undefined; } export default function Clock(props: ClockProps) { - const { isMirrored, time, settings } = props; + const { general, isMirrored, time, settings } = props; const [searchParams] = useSearchParams(); useWindowTitle('Clock'); @@ -122,6 +124,7 @@ export default function Clock(props: ClockProps) { }} data-testid='clock-view' > + {general?.projectLogo && } + {general?.projectLogo && } {follow === null ? ( diff --git a/apps/client/src/features/viewers/minimal-timer/MinimalTimer.scss b/apps/client/src/features/viewers/minimal-timer/MinimalTimer.scss index 7acb934db..7e2b67959 100644 --- a/apps/client/src/features/viewers/minimal-timer/MinimalTimer.scss +++ b/apps/client/src/features/viewers/minimal-timer/MinimalTimer.scss @@ -21,7 +21,7 @@ .timer { opacity: 1; - font-family: var(--font-family-bold-override, $timer-bold-font-family) ; + font-family: var(--font-family-bold-override, $timer-bold-font-family); font-size: 20vw; position: relative; color: var(--timer-color-override, var(--phase-color)); @@ -43,11 +43,19 @@ /* =================== OVERLAY ===================*/ .end-message { - text-align: center; - font-size: 12vw; - line-height: 0.9em; - font-weight: 600; - color: $timer-finished-color; - padding: 0; - } + text-align: center; + font-size: 12vw; + line-height: 0.9em; + font-weight: 600; + color: $timer-finished-color; + padding: 0; + } + + .logo { + position: absolute; + top: 2vw; + left: 2vw; + max-width: min(200px, 20vw); + max-height: min(100px, 20vh); + } } diff --git a/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx b/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx index b414f316b..633b0aee7 100644 --- a/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx +++ b/apps/client/src/features/viewers/minimal-timer/MinimalTimer.tsx @@ -1,6 +1,7 @@ import { useSearchParams } from 'react-router-dom'; -import { Playback, TimerPhase, TimerType, ViewSettings } from 'ontime-types'; +import { Playback, ProjectData, TimerPhase, TimerType, ViewSettings } from 'ontime-types'; +import ViewLogo from '../../../common/components/view-logo/ViewLogo'; import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor'; import { useWindowTitle } from '../../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../../common/models/TimeManager.type'; @@ -13,13 +14,14 @@ import { MINIMAL_TIMER_OPTIONS } from './minimalTimer.options'; import './MinimalTimer.scss'; interface MinimalTimerProps { + general: ProjectData; isMirrored: boolean; time: ViewExtendedTimer; viewSettings: ViewSettings; } export default function MinimalTimer(props: MinimalTimerProps) { - const { isMirrored, time, viewSettings } = props; + const { general, isMirrored, time, viewSettings } = props; const { getLocalizedString } = useTranslation(); const [searchParams] = useSearchParams(); @@ -158,6 +160,7 @@ export default function MinimalTimer(props: MinimalTimerProps) { }} data-testid='minimal-timer' > + {general?.projectLogo && } {showEndMessage ? (
{viewSettings.endMessage}
diff --git a/apps/client/src/features/viewers/public/Public.scss b/apps/client/src/features/viewers/public/Public.scss index 369692383..04b5ddc5c 100644 --- a/apps/client/src/features/viewers/public/Public.scss +++ b/apps/client/src/features/viewers/public/Public.scss @@ -29,6 +29,12 @@ font-size: clamp(32px, 4.5vw, 64px); font-weight: 600; display: flex; + gap: 1rem; + } + + .logo { + max-width: min(200px, 20vw); + max-height: min(100px, 20vh); } .clock-container { @@ -70,7 +76,7 @@ grid-area: schedule; overflow: hidden; height: 100%; - margin-left: clamp(16px, 5vw, 64px);; + margin-left: clamp(16px, 5vw, 64px); } .schedule-nav-container { diff --git a/apps/client/src/features/viewers/public/Public.tsx b/apps/client/src/features/viewers/public/Public.tsx index 50271db59..f53ddb05a 100644 --- a/apps/client/src/features/viewers/public/Public.tsx +++ b/apps/client/src/features/viewers/public/Public.tsx @@ -7,6 +7,7 @@ import Schedule from '../../../common/components/schedule/Schedule'; import { ScheduleProvider } from '../../../common/components/schedule/ScheduleContext'; import ScheduleNav from '../../../common/components/schedule/ScheduleNav'; import TitleCard from '../../../common/components/title-card/TitleCard'; +import ViewLogo from '../../../common/components/view-logo/ViewLogo'; import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor'; import { useWindowTitle } from '../../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../../common/models/TimeManager.type'; @@ -24,26 +25,26 @@ export const MotionTitleCard = motion(TitleCard); interface BackstageProps { customFields: CustomFields; + general: ProjectData; isMirrored: boolean; publicEventNow: OntimeEvent | null; publicEventNext: OntimeEvent | null; time: ViewExtendedTimer; events: OntimeEvent[]; publicSelectedId: string | null; - general: ProjectData; settings: Settings | undefined; } export default function Public(props: BackstageProps) { const { customFields, + general, isMirrored, publicEventNow, publicEventNext, time, events, publicSelectedId, - general, settings, } = props; @@ -66,6 +67,7 @@ export default function Public(props: BackstageProps) {
+ {general?.projectLogo && } {general.title}
{getLocalizedString('common.time_now')}
diff --git a/apps/client/src/features/viewers/studio/StudioClock.scss b/apps/client/src/features/viewers/studio/StudioClock.scss index 2968e8a5d..7ebe263e9 100644 --- a/apps/client/src/features/viewers/studio/StudioClock.scss +++ b/apps/client/src/features/viewers/studio/StudioClock.scss @@ -204,6 +204,13 @@ $orange-active: #f60; background-color: var(--studio-idle, $red-idle); } } + .logo { + position: absolute; + top: 2vw; + right: 2vw; + max-width: min(200px, 20vw); + max-height: min(100px, 20vh); + } } @media only screen and (max-width: 1200px) { diff --git a/apps/client/src/features/viewers/studio/StudioClock.tsx b/apps/client/src/features/viewers/studio/StudioClock.tsx index 7807d4b98..0c6a85220 100644 --- a/apps/client/src/features/viewers/studio/StudioClock.tsx +++ b/apps/client/src/features/viewers/studio/StudioClock.tsx @@ -1,9 +1,10 @@ import { useSearchParams } from 'react-router-dom'; -import type { MaybeString, OntimeEvent, OntimeRundown, Settings } from 'ontime-types'; +import type { MaybeString, OntimeEvent, OntimeRundown, ProjectData, Settings } from 'ontime-types'; import { Playback } from 'ontime-types'; import { millisToString, removeSeconds, secondsInMillis } from 'ontime-utils'; import { FitText } from '../../../common/components/fit-text/FitText'; +import ViewLogo from '../../../common/components/view-logo/ViewLogo'; import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor'; import { useWindowTitle } from '../../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../../common/models/TimeManager.type'; @@ -16,10 +17,11 @@ import StudioClockSchedule from './StudioClockSchedule'; import './StudioClock.scss'; interface StudioClockProps { - isMirrored: boolean; - eventNext: OntimeEvent | null; - time: ViewExtendedTimer; backstageEvents: OntimeRundown; + eventNext: OntimeEvent | null; + general: ProjectData; + isMirrored: boolean; + time: ViewExtendedTimer; selectedId: MaybeString; nextId: MaybeString; onAir: boolean; @@ -27,7 +29,7 @@ interface StudioClockProps { } export default function StudioClock(props: StudioClockProps) { - const { isMirrored, eventNext, time, backstageEvents, selectedId, nextId, onAir, settings } = props; + const { backstageEvents, eventNext, general, isMirrored, time, selectedId, nextId, onAir, settings } = props; const [searchParams] = useSearchParams(); @@ -65,6 +67,7 @@ export default function StudioClock(props: StudioClockProps) { className={`studio-clock ${isMirrored ? 'mirror' : ''} ${hideRight ? 'hide-right' : ''}`} data-testid='studio-view' > + {general?.projectLogo && }
{hasAmPm &&
{hasAmPm}
} diff --git a/apps/client/src/features/viewers/timer/Timer.tsx b/apps/client/src/features/viewers/timer/Timer.tsx index 0446454b7..d0b82cd22 100644 --- a/apps/client/src/features/viewers/timer/Timer.tsx +++ b/apps/client/src/features/viewers/timer/Timer.tsx @@ -13,10 +13,10 @@ import { ViewSettings, } from 'ontime-types'; -import { projectLogoPath } from '../../../common/api/constants'; import { FitText } from '../../../common/components/fit-text/FitText'; import MultiPartProgressBar from '../../../common/components/multi-part-progress-bar/MultiPartProgressBar'; import TitleCard from '../../../common/components/title-card/TitleCard'; +import ViewLogo from '../../../common/components/view-logo/ViewLogo'; import ViewParamsEditor from '../../../common/components/view-params-editor/ViewParamsEditor'; import { useWindowTitle } from '../../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../../common/models/TimeManager.type'; @@ -172,7 +172,7 @@ export default function Timer(props: TimerProps) { return (
- {general?.projectLogo && } + {general?.projectLogo && }
diff --git a/apps/client/src/views/timeline/TimelinePage.scss b/apps/client/src/views/timeline/TimelinePage.scss index 363e08bf8..f8fe8b6eb 100644 --- a/apps/client/src/views/timeline/TimelinePage.scss +++ b/apps/client/src/views/timeline/TimelinePage.scss @@ -18,10 +18,17 @@ font-size: clamp(32px, 4.5vw, 64px); font-weight: 600; display: flex; - justify-content: space-between; + gap: 1rem; + } + + .logo { + max-width: min(200px, 20vw); + max-height: min(100px, 20vh); } .clock-container { + margin-left: auto; + .label { font-size: clamp(16px, 1.5vw, 24px); font-weight: 600; diff --git a/apps/client/src/views/timeline/TimelinePage.tsx b/apps/client/src/views/timeline/TimelinePage.tsx index ac4b7b87e..90550553b 100644 --- a/apps/client/src/views/timeline/TimelinePage.tsx +++ b/apps/client/src/views/timeline/TimelinePage.tsx @@ -1,6 +1,7 @@ import { useMemo } from 'react'; import { MaybeString, OntimeEvent, ProjectData, Runtime, Settings } from 'ontime-types'; +import ViewLogo from '../../common/components/view-logo/ViewLogo'; import ViewParamsEditor from '../../common/components/view-params-editor/ViewParamsEditor'; import { useWindowTitle } from '../../common/hooks/useWindowTitle'; import { ViewExtendedTimer } from '../../common/models/TimeManager.type'; @@ -74,6 +75,7 @@ export default function TimelinePage(props: TimelinePageProps) {
+ {general?.projectLogo && } {general.title}
{getLocalizedString('common.time_now')}