diff --git a/apps/client/src/common/hooks/useSocket.ts b/apps/client/src/common/hooks/useSocket.ts index 30862c92e..49df2b066 100644 --- a/apps/client/src/common/hooks/useSocket.ts +++ b/apps/client/src/common/hooks/useSocket.ts @@ -51,8 +51,11 @@ export const setMessage = { timerText: (payload: string) => sendSocket('message', { timer: { text: payload } }), timerVisible: (payload: boolean) => sendSocket('message', { timer: { visible: payload } }), secondaryMessage: (payload: string) => sendSocket('message', { secondary: payload }), - timerBlink: (payload: boolean) => sendSocket('message', { timer: { blink: payload } }), - timerBlackout: (payload: boolean) => sendSocket('message', { timer: { blackout: payload } }), + // blink and blackout are mutually exclusive stage states, so turning one on turns the other off + timerBlink: (payload: boolean) => + sendSocket('message', payload ? { timer: { blink: true, blackout: false } } : { timer: { blink: false } }), + timerBlackout: (payload: boolean) => + sendSocket('message', payload ? { timer: { blackout: true, blink: false } } : { timer: { blackout: false } }), timerSecondarySource: (payload: TimerMessage['secondarySource']) => sendSocket('message', { timer: { secondarySource: payload } }), /** returns the stage to a plain timer, keeping whatever the operator has typed */ diff --git a/apps/client/src/features/control/message/MessageControl.module.scss b/apps/client/src/features/control/message/MessageControl.module.scss index 427b13344..9561340a5 100644 --- a/apps/client/src/features/control/message/MessageControl.module.scss +++ b/apps/client/src/features/control/message/MessageControl.module.scss @@ -1,8 +1,18 @@ -/* the screen state buttons belong with the preview they act on, not with the message inputs */ +/* the screen state buttons belong with the preview they act on, not with the message inputs. + buttons sit in a column to the right of the stage by default; once the container narrows + too far for that (e.g. an extracted window resized narrow), they drop into a row below it */ .screenGroup { flex: 1 1 auto; min-height: 0; - display: flex; - flex-direction: column; - gap: $element-inner-spacing; + display: grid; + grid-template-columns: 1fr auto; + grid-template-rows: 1fr; + gap: $element-spacing; +} + +@container (max-width: 22rem) { + .screenGroup { + grid-template-columns: 1fr; + grid-template-rows: 1fr auto; + } } diff --git a/apps/client/src/features/control/message/ScreenControl.module.scss b/apps/client/src/features/control/message/ScreenControl.module.scss index 43b722d2b..fae239d69 100644 --- a/apps/client/src/features/control/message/ScreenControl.module.scss +++ b/apps/client/src/features/control/message/ScreenControl.module.scss @@ -1,6 +1,16 @@ .screenControl { display: grid; - grid-auto-flow: column; - grid-auto-columns: 1fr; + grid-auto-flow: row; gap: $element-spacing; + align-self: center; + width: 8rem; +} + +@container (max-width: 22rem) { + .screenControl { + grid-auto-flow: column; + grid-auto-columns: 1fr; + align-self: stretch; + width: 100%; + } } diff --git a/apps/client/src/features/control/message/TimerPreview.module.scss b/apps/client/src/features/control/message/TimerPreview.module.scss index 002a8ec3e..898ae4785 100644 --- a/apps/client/src/features/control/message/TimerPreview.module.scss +++ b/apps/client/src/features/control/message/TimerPreview.module.scss @@ -1,6 +1,6 @@ /* the stage is the only elastic element in the panel, the controls below it keep their size */ .stage { - flex: 1 1 auto; + min-width: 0; min-height: 3rem; position: relative; /* a query container so that the embedded timer scales to the preview, not to the viewport */