diff --git a/client/src/App.css b/client/src/App.css
index 27b6f4c02..d49c3757f 100644
--- a/client/src/App.css
+++ b/client/src/App.css
@@ -8,4 +8,4 @@
overflow: hidden;
background-color: rgba(0, 0, 0, 0);
height: 100vh;
-}
+}
\ No newline at end of file
diff --git a/client/src/assets/images/empty.svg b/client/src/assets/images/empty.svg
new file mode 100644
index 000000000..913948ced
--- /dev/null
+++ b/client/src/assets/images/empty.svg
@@ -0,0 +1,21 @@
+
diff --git a/client/src/common/components/buttons/SettingsIconBtn.jsx b/client/src/common/components/buttons/SettingsIconBtn.jsx
new file mode 100644
index 000000000..738aab8b3
--- /dev/null
+++ b/client/src/common/components/buttons/SettingsIconBtn.jsx
@@ -0,0 +1,14 @@
+import { IconButton } from '@chakra-ui/button';
+import { FiSettings } from 'react-icons/fi';
+
+export default function SettingsIconBtn(props) {
+ return (
+ }
+ isRound
+ variant='outline'
+ onClick={props.clickHandler}
+ />
+ );
+}
diff --git a/client/src/common/components/myProgressBar/MyProgressBar.jsx b/client/src/common/components/myProgressBar/MyProgressBar.jsx
index 840af36e0..df76f5108 100644
--- a/client/src/common/components/myProgressBar/MyProgressBar.jsx
+++ b/client/src/common/components/myProgressBar/MyProgressBar.jsx
@@ -2,8 +2,11 @@ import { clamp } from '../../../app/utils';
import styles from './MyProgressBar.module.css';
export default function MyProgressBar(props) {
- const { now, complete } = props;
- const percentComplete = clamp((now * 100) / complete - 1, 0, 100);
+ const { now, complete, showElapsed } = props;
+ const percentComplete = showElapsed
+ ? clamp((100 - (now * 100) / complete - 1), 0, 100)
+ : clamp((now * 100) / complete - 1, 0, 100)
+
return (
diff --git a/client/src/common/input/EditableTimer.module.css b/client/src/common/input/EditableTimer.module.css
index e38fb9cde..4ce165612 100644
--- a/client/src/common/input/EditableTimer.module.css
+++ b/client/src/common/input/EditableTimer.module.css
@@ -13,7 +13,7 @@
}
.delayedEditable {
- border: 1px solid #d69e2e88;
+ border: 1px solid #d69e2e55;
}
.delayValue {
@@ -22,6 +22,5 @@
padding: 0.3em 0;
text-align: center;
align-self: flex-start;
- border: 1px solid #d69e2e88;
- background-color: #d69e2e22;
+ background-color: #d69e2e55;
}
diff --git a/client/src/common/state/Empty.jsx b/client/src/common/state/Empty.jsx
new file mode 100644
index 000000000..f76965d63
--- /dev/null
+++ b/client/src/common/state/Empty.jsx
@@ -0,0 +1,12 @@
+import { ReactComponent as Emptyimage } from '../../assets/images/empty.svg';
+import style from './Empty.module.css';
+
+export default function Empty(props) {
+ const { text } = props;
+ return (
+
+
+ {text}
+
+ );
+}
diff --git a/client/src/common/state/Empty.module.css b/client/src/common/state/Empty.module.css
new file mode 100644
index 000000000..1d66c890a
--- /dev/null
+++ b/client/src/common/state/Empty.module.css
@@ -0,0 +1,16 @@
+.emptyContainer {
+ text-align: center;
+ color: rgba(0, 0, 0, 0.17);
+ font-weight: 600;
+ font-size: 2em;
+ width: 100%;
+}
+.empty {
+ width: 100%;
+ margin: auto 0;
+ opacity: 0.3;
+}
+
+.text {
+ text-align: center;
+}
diff --git a/client/src/features/control/MessageControl.jsx b/client/src/features/control/MessageControl.jsx
index 602e57ae6..615543808 100644
--- a/client/src/features/control/MessageControl.jsx
+++ b/client/src/features/control/MessageControl.jsx
@@ -89,8 +89,8 @@ export default function MessageControl() {
placeholder='only the presenter screens see this'
className={style.inline}
>
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
- Event List
-
-
-
-
-
-
-
+
+
+
+ Event List
+
+
+
+
+
+
-
-
-
- Preview Displays
-
-
-
-
-
+
+
+ Preview Displays
+
+
+
+
-
-
-
- Display Messages
-
-
-
-
-
-
-
+
+
+ Display Messages
+
+
+
+
+
+
-
-
-
- Time Control
-
-
-
-
-
+
+
+ Time Control
+
+
+
+
-
-
+
+
+
-
}
- isRound
- variant='outline'
- onClick={onOpen}
- />
-
-
-
-
-
-
-
-
-
-
+ />
+
+
+
+
+
+
+
+
>
);
}
diff --git a/client/src/features/editors/Editor.module.css b/client/src/features/editors/Editor.module.css
index 0462d6261..1b606b809 100644
--- a/client/src/features/editors/Editor.module.css
+++ b/client/src/features/editors/Editor.module.css
@@ -1,12 +1,71 @@
.mainContainer {
background: linear-gradient(90deg, #202020 0%, #121212 100%);
width: 100%;
+ height: 100%;
margin: auto;
- height: 95vh;
color: #fffd;
+ padding: 2vh;
+
+ display: grid;
+ grid-template-rows: 1fr 1fr 1fr;
+ grid-template-columns: 1fr 25vw 25vw 5vw;
+ grid-template-areas:
+ 'even mess play sett'
+ 'even prev prev sett'
+ 'even prev prev sett';
+ gap: 2vh;
}
-.editor {
+/* 2/3 window, hide previews */
+@media (max-width: 1250px) and (min-height: 700px) {
+ .mainContainer {
+ grid-template-rows: 1fr 1fr;
+ grid-template-columns: 1fr 1fr 1fr;
+ grid-template-areas:
+ 'even play sett'
+ 'even mess sett';
+ }
+
+ .preview {
+ visibility: hidden;
+ }
+}
+
+/* 1/3 window, show control only */
+@media (max-width: 750px) and (min-height: 500px) {
+ .mainContainer {
+ grid-template-rows: auto 1fr;
+ grid-template-columns: 100%;
+ grid-template-areas:
+ 'mess'
+ 'play';
+ }
+
+ .editor,
+ .preview,
+ .settings {
+ visibility: hidden;
+ }
+}
+
+/* 1/3 corner window, playback only */
+@media (max-width: 900px) and (max-height: 500px) {
+ .mainContainer {
+ grid-template-rows: 1fr;
+ grid-template-columns: 1fr;
+ grid-template-areas: 'play';
+ }
+
+ .editor,
+ .messages,
+ .preview,
+ .settings {
+ visibility: hidden;
+ }
+}
+
+.mainContainer > div {
+ border-radius: 0.5em;
height: 100%;
margin-top: 1.5vh;
background-color: rgba(255, 255, 255, 0.13);
@@ -16,6 +75,26 @@
flex-direction: column;
}
+.editor {
+ grid-area: even;
+}
+
+.preview {
+ grid-area: prev;
+}
+
+.messages {
+ grid-area: mess;
+}
+
+.playback {
+ grid-area: play;
+}
+
+.settings {
+ grid-area: sett;
+}
+
.content {
padding-top: 1.5em;
}
@@ -32,3 +111,25 @@
display: flex;
justify-content: flex-end;
}
+
+/* width */
+::-webkit-scrollbar {
+ width: 0.5em;
+}
+
+/* Track */
+::-webkit-scrollbar-track {
+ background: rgba(255, 255, 255, 0.01);
+ border-radius: 4px;
+}
+
+/* Handle */
+::-webkit-scrollbar-thumb {
+ background: rgba(255, 255, 255, 0.15);
+ border-radius: 4px;
+}
+
+/* Handle on hover */
+::-webkit-scrollbar-thumb:hover {
+ background: rgba(255, 255, 255, 0.35);
+}
diff --git a/client/src/features/editors/list/Block.module.css b/client/src/features/editors/list/Block.module.css
index 93c0740eb..1fc7d4737 100644
--- a/client/src/features/editors/list/Block.module.css
+++ b/client/src/features/editors/list/Block.module.css
@@ -17,7 +17,6 @@
padding: 0.2em 1em;
box-sizing: border-box;
display: flex;
- margin: auto;
gap: 1em;
}
@@ -68,10 +67,8 @@
background-color: rgba(255, 255, 255, 0.36);
background: linear-gradient(
180deg,
- #4bffabcc 0%,
- #227c52aa 09%,
- #4bffab11 10%,
- #4bffab11 89%,
+ #00000000 10%,
+ #4bffab10 89%,
#227c52aa 90%,
#4bffabcc 100%
);
diff --git a/client/src/features/editors/list/EventList.jsx b/client/src/features/editors/list/EventList.jsx
index 9f507d8f9..11be77df4 100644
--- a/client/src/features/editors/list/EventList.jsx
+++ b/client/src/features/editors/list/EventList.jsx
@@ -4,6 +4,8 @@ import BlockBlock from './BlockBlock';
import EventBlock from './EventBlock';
import { useEffect, useState } from 'react';
import { useSocket } from '../../../app/context/socketContext';
+import Empty from '../../../common/state/Empty';
+
export default function EventList(props) {
const { events, eventsHandler } = props;
@@ -28,6 +30,12 @@ export default function EventList(props) {
};
}, [socket]);
+ if (events.length < 1) {
+ return (
+
+ );
+ }
+
console.log('EventList: events in event list', events);
let cumulativeDelay = 0;
let eventCount = -1;
diff --git a/client/src/features/editors/list/List.module.css b/client/src/features/editors/list/List.module.css
index a8c20abd2..0cee5f3de 100644
--- a/client/src/features/editors/list/List.module.css
+++ b/client/src/features/editors/list/List.module.css
@@ -7,4 +7,11 @@
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 4px;
padding: 8px;
+ overflow-y: scroll;
+ height: 71vh;
+}
+
+.empty {
+ opacity: 0.3;
+ align-self: center;
}
diff --git a/client/src/features/menu/EventListMenu.jsx b/client/src/features/menu/EventListMenu.jsx
index b28fba79f..aab5270f1 100644
--- a/client/src/features/menu/EventListMenu.jsx
+++ b/client/src/features/menu/EventListMenu.jsx
@@ -16,7 +16,12 @@ export default function EventListMenu(props) {
size: 'sm',
variant: 'outline',
colorScheme: 'whiteAlpha',
- backgroundColor: '#ffffff05'
+ backgroundColor: '#ffffff05',
+ };
+
+ const menuStyle = {
+ color: 'initial',
+ backgroundColor: 'rgba(255,255,255,0.67)',
};
const addHandler = () => {
@@ -25,16 +30,14 @@ export default function EventListMenu(props) {
return (
-
diff --git a/client/src/features/viewers/ViewWrapper.jsx b/client/src/features/viewers/ViewWrapper.jsx
index 96034b1df..32c7ce525 100644
--- a/client/src/features/viewers/ViewWrapper.jsx
+++ b/client/src/features/viewers/ViewWrapper.jsx
@@ -115,7 +115,10 @@ const withSocket = (Component) => {
// Filter events only to pass down
useEffect(() => {
if (eventsData == null) return;
- const e = eventsData.filter((d) => d.type === 'event');
+
+ // filter just events with title
+ const e = eventsData.filter((d) => d.type === 'event' && d.title !== '');
+
setEvents(e);
}, [eventsData]);
diff --git a/client/src/features/viewers/backstage/Paginator.jsx b/client/src/features/viewers/backstage/Paginator.jsx
index 395b8aeab..4f707b61e 100644
--- a/client/src/features/viewers/backstage/Paginator.jsx
+++ b/client/src/features/viewers/backstage/Paginator.jsx
@@ -5,7 +5,7 @@ import { useInterval } from '../../../app/hooks/useInterval';
export default function Paginator(props) {
const { events, selectedId } = props;
- const LIMIT_PER_PAGE = 3;
+ const LIMIT_PER_PAGE = 7;
const SCROLL_TIME = 5000;
const SCROLL_PAST = false;
const [numEvents, setNumEvents] = useState(0);
@@ -49,14 +49,16 @@ export default function Paginator(props) {
return (
<>
-
- {[...Array(pages)].map((p, i) => (
-
- ))}
-
+ {pages > 1 && (
+
+ {[...Array(pages)].map((p, i) => (
+
+ ))}
+
+ )}
{page.map((e) => {
diff --git a/client/src/features/viewers/backstage/Paginator.module.css b/client/src/features/viewers/backstage/Paginator.module.css
index 3e2f9380d..9a23ae659 100644
--- a/client/src/features/viewers/backstage/Paginator.module.css
+++ b/client/src/features/viewers/backstage/Paginator.module.css
@@ -2,7 +2,6 @@
display: flex;
flex-direction: column;
gap: 1.5vh;
- padding-top: 2vh;
}
.navItem,
diff --git a/client/src/features/viewers/backstage/StageManager.module.css b/client/src/features/viewers/backstage/StageManager.module.css
index 2e6a790f3..93e18faa7 100644
--- a/client/src/features/viewers/backstage/StageManager.module.css
+++ b/client/src/features/viewers/backstage/StageManager.module.css
@@ -41,6 +41,17 @@
/* =================== TITLES ===================*/
+.infoContainer > div {
+ overflow:hidden;
+}
+
+.nextContainer > div,
+.nowContainer > div {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
.nowContainer,
.nextContainer,
.todayContainer {
@@ -157,8 +168,10 @@
.entryStart,
.entryEnd {
font-size: 1.5vw;
+ min-width: 3.5vw;
}
+
.entryTitle {
align-self: center;
}
@@ -183,7 +196,7 @@
.entryNow {
font-size: 1.3vw;
color: #fff;
- line-height: 7vh;
+ line-height: 4vh;
background-color: rgba(255, 255, 255, 0.09);
border-bottom: 0.5vh solid #ff7597aa;
margin-left: -0.5vw;
@@ -212,6 +225,7 @@
.infoMessages {
grid-area: binf;
font-size: 1.5vw;
+ line-height: 2vw;
white-space: pre-line;
}
diff --git a/client/src/features/viewers/backstage/TodayItem.jsx b/client/src/features/viewers/backstage/TodayItem.jsx
index 23b808d50..939a11ce5 100644
--- a/client/src/features/viewers/backstage/TodayItem.jsx
+++ b/client/src/features/viewers/backstage/TodayItem.jsx
@@ -4,8 +4,8 @@ export default function TodayItem(props) {
const { selected, timeStart, timeEnd, title } = props;
// Format timers
- const start = timeStart ? stringFromMillis(timeStart, false) : '';
- const end = timeEnd ? stringFromMillis(timeEnd, false) : '';
+ const start = stringFromMillis(timeStart, false) || '';
+ const end = stringFromMillis(timeEnd, false) || '';
// select styling
let selectStyle = style.entryPast;
diff --git a/client/src/features/viewers/lower/Lower.module.css b/client/src/features/viewers/lower/Lower.module.css
index 51898e9cd..708bc40b0 100644
--- a/client/src/features/viewers/lower/Lower.module.css
+++ b/client/src/features/viewers/lower/Lower.module.css
@@ -1,8 +1,12 @@
.lowerThird {
+ margin: 0;
+ box-sizing: border-box; /* reset */
+ overflow: hidden;
+ width: 100%; /* restrict the page width to viewport */
+ height: 100%;
+
color: #fffffa;
font-size: 4vh;
- width: 100%;
- height: 100%;
}
.lowerContainer {
@@ -36,6 +40,13 @@
position: relative;
}
+.titleContainer,
+.subtitleContainer {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
.titleDecor,
.subDecor {
grid-area: decor;
diff --git a/client/src/features/viewers/presenter/PresenterView.jsx b/client/src/features/viewers/presenter/PresenterView.jsx
index 77ed48a29..ba8e966d0 100644
--- a/client/src/features/viewers/presenter/PresenterView.jsx
+++ b/client/src/features/viewers/presenter/PresenterView.jsx
@@ -41,6 +41,7 @@ export default function PresenterView(props) {
)}
diff --git a/client/src/features/viewers/presenter/PresenterView.module.css b/client/src/features/viewers/presenter/PresenterView.module.css
index dbc6a2f44..033d6a2b6 100644
--- a/client/src/features/viewers/presenter/PresenterView.module.css
+++ b/client/src/features/viewers/presenter/PresenterView.module.css
@@ -1,3 +1,5 @@
+@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;800&display=swap');
+
.container__gray,
.container__grayFinished {
margin: 0;
@@ -55,9 +57,18 @@
grid-area: next;
}
+.title,
+.subtitle,
+.presenter {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
.title {
color: #ddd;
font-size: 2.5vw;
+ flex: 1;
}
.subtitle,
@@ -147,6 +158,7 @@
}
.clock {
+ font-family: 'Open Sans', sans-serif;
font-size: 4vw;
letter-spacing: 0.4vw;
color: #ddd;
diff --git a/client/src/features/viewers/viewers.css b/client/src/features/viewers/viewers.css
deleted file mode 100644
index 820096bed..000000000
--- a/client/src/features/viewers/viewers.css
+++ /dev/null
@@ -1,41 +0,0 @@
-@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;800&display=swap');
-
-.presenter {
- font-size: 1vh;
- height: 100%;
- color: #ffffff;
- display: flex;
- flex-direction: column;
- padding-left: 4vh;
-}
-
-.presentationTitle {
- font-size: 5vw;
- text-align: left;
-}
-
-.presentationSub {
- font-size: 3vw;
- text-align: left;
-}
-
-.userMessage {
- font-size: 10vw;
- text-align: center;
-}
-
-.hidden {
- display: none;
-}
-
-.extra {
- width: 100%;
- position: absolute;
- bottom: 3vh;
- left: 0;
-
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-around;
-}