Skip to content

Commit

Permalink
feat(Output): support flipping, dynamic font size
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarpl committed Jan 22, 2024
1 parent ddfa7c6 commit 8e0c03e
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 14 deletions.
6 changes: 3 additions & 3 deletions packages/apps/backend/src/data-stores/OutputSettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ export class OutputSettingsStore {
// _id: '',

// TODO: load these from persistent store upon startup?
fontSize: 10,
fontSize: 7,

mirrorHorizontally: false,
mirrorVertically: false,

focusPosition: 'center',
showFocusPosition: false,

marginHorizontal: 5,
marginVertical: 5,
marginHorizontal: 1,
marginVertical: 1,

activeRundownPlaylistId: null,
})
Expand Down
8 changes: 8 additions & 0 deletions packages/apps/client/src/PrompterStyles.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@

font-size: var(--prompter-font-size-base);
line-height: var(--prompter-line-height);

/* These are needed to maintain compatibility with Prose-mirror's text layout */
word-wrap: break-word;
white-space: pre-wrap;
white-space: break-spaces;
-webkit-font-variant-ligatures: none;
font-variant-ligatures: none;
font-feature-settings: 'liga' 0;
}

.Prompter p {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const CurrentRundown = observer((): React.JSX.Element => {
</Button>
</p>
<SystemStatusAlertBars />
<ul className={classes.SegmentLineList}>
<ul className={classes.SegmentLineList} role="tree">
{openRundown.segmentsInOrder.map((segment) => (
<li key={segment.id} data-segment-id={segment.id} className={classes.SegmentContainer}>
<li key={segment.id} data-segment-id={segment.id} className={classes.SegmentContainer} role="tree">
<Segment segment={segment} />
</li>
))}
Expand Down
10 changes: 7 additions & 3 deletions packages/apps/client/src/components/CurrentRundown/Segment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@ const Segment = observer(({ segment }: { segment: UISegment }): React.JSX.Elemen
return lineId === RootAppStore.uiStore.selectedLineId
}

function onClick(e: React.MouseEvent<HTMLLIElement>) {
function onFocus(e: React.FocusEvent<HTMLLIElement>) {
const lineId = e.currentTarget.dataset['lineId'] as UILineId
RootAppStore.uiStore.setSelectedLineId(lineId)
}

return (
<>
<div className={classes.SegmentIdentifier}>{segment.name}</div>
<div className={classes.SegmentIdentifier} role="heading">
{segment.name}
</div>
<ul className={classes.LineContainer}>
{segment.linesInOrder.map((line) => (
<li
key={line.id}
className={isSelected(line.id) ? classes.LineSelected : classes.Line}
onClickCapture={onClick}
onFocus={onFocus}
data-line-id={line.id}
tabIndex={0}
role="treeitem"
>
<Line line={line} />
</li>
Expand Down
10 changes: 10 additions & 0 deletions packages/apps/client/src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,13 @@ $theme-colors: (
--color-dark-1: #{$dark-1};
--color-dark-2: #{$dark-2};
}

/* Remove outline for non-keyboard :focus */
*:focus:not(:focus-visible) {
outline: none;
}

/* Optional: Customize .focus-visible */
:focus-visible {
outline: $primary solid 2px;
}
3 changes: 1 addition & 2 deletions packages/apps/client/src/stores/RundownStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ export class RundownStore {
sendRundownToOutput = (id: RundownPlaylistId) => {
if (!this.outputSettings) return
// TODO: This really shouldn't require the entire outputSettings object to be available first
this.connection.outputSettings.update(null, {
...this.outputSettings,
this.connection.outputSettings.patch(null, {
activeRundownPlaylistId: id,
})
}
Expand Down
8 changes: 8 additions & 0 deletions packages/apps/client/src/views/Output/Output.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.Output {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
overflow: auto;
}
26 changes: 22 additions & 4 deletions packages/apps/client/src/views/Output/Output.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useRef } from 'react'
import React, { useCallback, useEffect, useMemo, useRef } from 'react'
import { observer } from 'mobx-react-lite'
import { RootAppStore } from 'src/stores/RootAppStore.ts'

Expand All @@ -8,7 +8,10 @@ import { Helmet } from 'react-helmet-async'
import { getCurrentTime } from 'src/lib/getCurrentTime'
import { useQueryParam } from 'src/lib/useQueryParam'

import classes from './Output.module.scss'

const Output = observer(function Output(): React.ReactElement {
const rootEl = useRef<HTMLDivElement>(null)
const speed = useRef(0)

const isPrimary = useQueryParam('primary') !== null
Expand All @@ -26,7 +29,7 @@ const Output = observer(function Output(): React.ReactElement {

// don't do this, it's just for testing:
const interval = setInterval(() => {
window.scrollBy(0, speed.current)
rootEl.current?.scrollBy(0, speed.current)
}, 1000 / 60)

return () => {
Expand Down Expand Up @@ -139,19 +142,34 @@ const Output = observer(function Output(): React.ReactElement {
*/

const fontSize = RootAppStore.outputSettingsStore.outputSettings.fontSize
const scaleVertical = RootAppStore.outputSettingsStore.outputSettings.mirrorVertically ? '-1' : '1'
const scaleHorizontal = RootAppStore.outputSettingsStore.outputSettings.mirrorHorizontally ? '-1' : '1'

const styleVariables = useMemo(
() =>
({
'--prompter-font-size-base': `${fontSize}vw`,
transform: `scale(${scaleHorizontal}, ${scaleVertical})`,
} as React.CSSProperties),
[fontSize, scaleVertical, scaleHorizontal]
)

const className = `Prompter ${classes.Output}`

if (!rundown) {
return (
<>
{GLOBAL_SETTINGS}
<div className="Prompter"></div>
<div className={className}></div>
</>
)
}

return (
<>
{GLOBAL_SETTINGS}
<div className="Prompter">
<div className={className} style={styleVariables} ref={rootEl}>
<h1>{rundown.name}</h1>
{rundown.segmentsInOrder.map((segment) => (
<Segment key={segment.id} segment={segment} />
Expand Down

0 comments on commit 8e0c03e

Please sign in to comment.