From 832c0609400ff87c74318fabaf3a01dab1fcf1e7 Mon Sep 17 00:00:00 2001 From: Carlos Valente <34649812+cpvalente@users.noreply.github.com> Date: Fri, 30 Dec 2022 11:41:03 +0100 Subject: [PATCH] v2: views (#278) * config(sentry): instrumentation only in production * chore: upgrade deps * refactor: simplify and convert to ts * refactor: composition and styles * chore: remove deprecated deps * ux: close menu on click outside * style: small tweaks and clarifications * refactor: retire PiP view * ux: small tweaks * style: cleanup deprecated styles * chore: remove unused * refactor: remove usages of deprecated fields and improve null timer presentation * refactor: improve composition of countdown * style: cleanup overridable styles * ux: show event overtime status * style: correct logic in paused timers --- client/package.json | 64 +- client/src/AppRouter.tsx | 3 - .../components/countdown/TimerDisplay.jsx | 26 - .../components/countdown/TimerDisplay.scss | 22 - .../errorBoundary/ErrorBoundary.module.scss | 8 +- .../myProgressBar/MyProgressBar.jsx | 31 - .../myProgressBar/MyProgressBar.module.scss | 24 - .../navigation-menu/NavigationMenu.tsx | 9 +- .../components/paginator/Paginator.scss | 66 - .../common/components/paginator/Paginator.tsx | 102 - .../common/components/paginator/TodayItem.tsx | 37 - .../components/progress-bar/ProgressBar.scss | 23 + .../components/progress-bar/ProgressBar.tsx | 25 + .../protectRoute/ProtectRoute.module.scss | 14 +- .../common/components/schedule/Schedule.scss | 71 + .../common/components/schedule/Schedule.tsx | 58 + .../components/schedule/ScheduleContext.tsx | 72 + .../components/schedule/ScheduleItem.tsx | 45 + .../components/schedule/ScheduleNav.tsx | 24 + client/src/common/components/state/Empty.tsx | 2 +- .../timer-display/TimerDisplay.scss | 21 + .../components/timer-display/TimerDisplay.tsx | 34 + .../components/title-card/TitleCard.scss | 61 +- .../components/title-card/TitleCard.tsx | 13 +- .../components/title-side/TitleSide.jsx | 26 - .../components/title-side/TitleSide.scss | 61 - .../upload-modal/UploadModal.module.scss | 6 +- .../hooks/__tests__/useClickOutside.test.ts | 46 + client/src/common/hooks/useClickOutside.ts | 26 + client/src/common/models/TimeManager.type.ts | 15 + client/src/common/models/TimeManaget.type.ts | 11 - client/src/common/utils/dateConfig.js | 2 +- client/src/common/utils/eventsManager.ts | 20 +- .../src/features/FeatureWrapper.module.scss | 6 +- .../control/message/MessageControl.tsx | 4 +- .../control/playback/PlaybackTimer.tsx | 6 +- client/src/features/menu/MenuBar.module.scss | 4 +- .../EventBlockProgressBar.module.scss | 7 +- .../quick-add-block/QuickAddBlock.module.scss | 2 +- client/src/features/viewers/ViewWrapper.jsx | 15 +- .../features/viewers/backstage/Backstage.jsx | 169 - .../features/viewers/backstage/Backstage.scss | 215 +- .../features/viewers/backstage/Backstage.tsx | 176 + client/src/features/viewers/clock/Clock.scss | 23 +- client/src/features/viewers/clock/Clock.tsx | 2 +- .../features/viewers/countdown/Countdown.scss | 139 +- .../{Countdown.jsx => Countdown.tsx} | 108 +- .../viewers/countdown/CountdownSelect.tsx | 46 + .../viewers/countdown/countdown.helpers.js | 68 - .../viewers/countdown/countdown.helpers.ts | 69 + .../viewers/minimal-timer/MinimalTimer.scss | 34 +- .../viewers/minimal-timer/MinimalTimer.tsx | 24 +- .../viewers/picture-in-picture/Pip.jsx | 137 - .../viewers/picture-in-picture/Pip.scss | 136 - client/src/features/viewers/public/Public.jsx | 144 - .../src/features/viewers/public/Public.scss | 206 +- client/src/features/viewers/public/Public.tsx | 135 + .../features/viewers/studio/StudioClock.jsx | 35 +- .../features/viewers/studio/StudioClock.scss | 10 + client/src/features/viewers/timer/Timer.scss | 98 +- .../viewers/timer/{Timer.jsx => Timer.tsx} | 129 +- client/src/index.tsx | 2 +- client/src/theme/_mixins.scss | 2 +- client/src/theme/_v2Styles.scss | 5 +- client/src/theme/_viewerDefs.scss | 41 +- client/src/theme/_viewers.scss | 189 - client/src/theme/_viewers_mixins.scss | 189 - client/src/theme/ontimeTooltip.ts | 8 +- client/src/viewerConfig.ts | 1 - client/yarn.lock | 3103 +++++++++-------- server/src/external/styles/override.css | 16 +- 71 files changed, 3114 insertions(+), 3657 deletions(-) delete mode 100644 client/src/common/components/countdown/TimerDisplay.jsx delete mode 100644 client/src/common/components/countdown/TimerDisplay.scss delete mode 100644 client/src/common/components/myProgressBar/MyProgressBar.jsx delete mode 100644 client/src/common/components/myProgressBar/MyProgressBar.module.scss delete mode 100644 client/src/common/components/paginator/Paginator.scss delete mode 100644 client/src/common/components/paginator/Paginator.tsx delete mode 100644 client/src/common/components/paginator/TodayItem.tsx create mode 100644 client/src/common/components/progress-bar/ProgressBar.scss create mode 100644 client/src/common/components/progress-bar/ProgressBar.tsx create mode 100644 client/src/common/components/schedule/Schedule.scss create mode 100644 client/src/common/components/schedule/Schedule.tsx create mode 100644 client/src/common/components/schedule/ScheduleContext.tsx create mode 100644 client/src/common/components/schedule/ScheduleItem.tsx create mode 100644 client/src/common/components/schedule/ScheduleNav.tsx create mode 100644 client/src/common/components/timer-display/TimerDisplay.scss create mode 100644 client/src/common/components/timer-display/TimerDisplay.tsx delete mode 100644 client/src/common/components/title-side/TitleSide.jsx delete mode 100644 client/src/common/components/title-side/TitleSide.scss create mode 100644 client/src/common/hooks/__tests__/useClickOutside.test.ts create mode 100644 client/src/common/hooks/useClickOutside.ts create mode 100644 client/src/common/models/TimeManager.type.ts delete mode 100644 client/src/common/models/TimeManaget.type.ts delete mode 100644 client/src/features/viewers/backstage/Backstage.jsx create mode 100644 client/src/features/viewers/backstage/Backstage.tsx rename client/src/features/viewers/countdown/{Countdown.jsx => Countdown.tsx} (66%) create mode 100644 client/src/features/viewers/countdown/CountdownSelect.tsx delete mode 100644 client/src/features/viewers/countdown/countdown.helpers.js create mode 100644 client/src/features/viewers/countdown/countdown.helpers.ts delete mode 100644 client/src/features/viewers/picture-in-picture/Pip.jsx delete mode 100644 client/src/features/viewers/picture-in-picture/Pip.scss delete mode 100644 client/src/features/viewers/public/Public.jsx create mode 100644 client/src/features/viewers/public/Public.tsx rename client/src/features/viewers/timer/{Timer.jsx => Timer.tsx} (55%) delete mode 100644 client/src/theme/_viewers.scss delete mode 100644 client/src/theme/_viewers_mixins.scss diff --git a/client/package.json b/client/package.json index f7e504174..5144e1cdd 100644 --- a/client/package.json +++ b/client/package.json @@ -3,29 +3,29 @@ "version": "1.9.7", "private": true, "dependencies": { - "@chakra-ui/react": "^2.4.1", - "@dnd-kit/core": "^6.0.5", + "@chakra-ui/react": "^2.4.5", + "@dnd-kit/core": "^6.0.6", "@dnd-kit/sortable": "^7.0.1", - "@dnd-kit/utilities": "^3.2.0", + "@dnd-kit/utilities": "^3.2.1", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", "@react-icons/all-files": "^4.1.0", - "@sentry/react": "^7.24.1", + "@sentry/react": "^7.28.1", "@sentry/tracing": "^7.24.1", "@tanstack/react-query": "^4.18.0", "@tanstack/react-query-devtools": "^4.18.0", - "autosize": "^5.0.1", + "autosize": "^5.0.2", "axios": "^1.2.0", "color": "^4.2.3", "csv-stringify": "^6.2.3", - "framer-motion": "^7.5.3", + "framer-motion": "^8.0.2", "jotai": "^1.10.0", "luxon": "^3.1.0", - "react": "^18.1.0", + "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", - "react-dom": "^18.1.0", + "react-dom": "^18.2.0", "react-fast-compare": "^3.2.0", - "react-qr-code": "^2.0.5", + "react-qr-code": "^2.0.11", "react-router-dom": "^6.3.0", "react-table": "^7.7.0", "socket.io-client": "^4.5.4", @@ -53,40 +53,38 @@ ] }, "devDependencies": { - "@sentry/vite-plugin": "^0.2.4", + "@sentry/vite-plugin": "^0.3.0", "@tanstack/eslint-plugin-query": "^4.15.1", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.1.1", - "@testing-library/react-hooks": "^8.0.0", "@testing-library/user-event": "^14.1.1", "@types/color": "^3.0.3", - "@types/node": "^18.7.16", - "@types/react": "^18.0.21", - "@types/react-beautiful-dnd": "^13.1.2", - "@types/react-dom": "^18.0.6", - "@typescript-eslint/eslint-plugin": "^5.37.0", - "@typescript-eslint/parser": "^5.37.0", - "@vitejs/plugin-react": "^2.2.0", + "@types/node": "^18.11.18", + "@types/react": "^18.0.26", + "@types/react-beautiful-dnd": "^13.1.3", + "@types/react-dom": "^18.0.10", + "@typescript-eslint/eslint-plugin": "^5.47.1", + "@typescript-eslint/parser": "^5.47.1", + "@vitejs/plugin-react": "^3.0.0", "eslint": "^8.25.0", "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^27.0.4", - "eslint-plugin-react": "^7.31.8", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-simple-import-sort": "^7.0.0", - "eslint-plugin-testing-library": "^5.6.4", - "jsdom": "^20.0.0", - "prettier": "^2.7.1", + "eslint-plugin-simple-import-sort": "^8.0.0", + "eslint-plugin-testing-library": "^5.9.1", + "jsdom": "^20.0.3", + "prettier": "^2.8.1", "prop-types": "^15.8.1", - "react-test-renderer": "^18.1.0", - "sass": "^1.51.0", - "stylelint": "^14.9.1", - "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard-scss": "^4.0.0", + "sass": "^1.57.1", + "stylelint": "^14.16.0", + "stylelint-config-prettier": "^9.0.4", + "stylelint-config-standard-scss": "^6.1.0", "typescript": "^4.8.3", - "vite": "^3.2.4", - "vite-plugin-svgr": "^2.2.2", - "vite-tsconfig-paths": "^3.6.0", - "vitest": "^0.25.3" + "vite": "^4.0.3", + "vite-plugin-svgr": "^2.4.0", + "vite-tsconfig-paths": "^4.0.3", + "vitest": "^0.26.2" }, "resolutions": { "**/@types/react": "18.0.21" diff --git a/client/src/AppRouter.tsx b/client/src/AppRouter.tsx index 140abca37..f87cfe14d 100644 --- a/client/src/AppRouter.tsx +++ b/client/src/AppRouter.tsx @@ -15,7 +15,6 @@ const Countdown = lazy(() => import('features/viewers/countdown/Countdown')); const Backstage = lazy(() => import('features/viewers/backstage/Backstage')); const Public = lazy(() => import('features/viewers/public/Public')); const Lower = lazy(() => import('features/viewers/lower-thirds/LowerWrapper')); -const Pip = lazy(() => import('features/viewers/picture-in-picture/Pip')); const StudioClock = lazy(() => import('features/viewers/studio/StudioClock')); const STimer = withSocket(TimerView); @@ -25,7 +24,6 @@ const SCountdown = withSocket(Countdown); const SBackstage = withSocket(Backstage); const SPublic = withSocket(Public); const SLowerThird = withSocket(Lower); -const SPip = withSocket(Pip); const SStudio = withSocket(StudioClock); const FeatureWrapper = lazy(() => import('features/FeatureWrapper')); @@ -70,7 +68,6 @@ export default function AppRouter() { } /> } /> - } /> } /> {/*/!* Lower cannot have fallback *!/*/} } /> diff --git a/client/src/common/components/countdown/TimerDisplay.jsx b/client/src/common/components/countdown/TimerDisplay.jsx deleted file mode 100644 index 8fa4b428a..000000000 --- a/client/src/common/components/countdown/TimerDisplay.jsx +++ /dev/null @@ -1,26 +0,0 @@ -import { memo } from 'react'; -import { formatDisplay } from 'common/utils/dateConfig'; -import PropTypes from 'prop-types'; - -import './TimerDisplay.scss'; - -const TimerDisplay = ({ time, small, isNegative, hideZeroHours }) => { - - const display = - (time === null || typeof time === 'undefined' || isNaN(time)) - ? '-- : -- : --' - : formatDisplay(time, hideZeroHours); - - const classes = `timer ${small ? 'timer--small' : ''} ${isNegative ? 'timer--finished' : ''}`; - - return
{display}
; -}; - -export default memo(TimerDisplay); - -TimerDisplay.propTypes = { - time: PropTypes.number, - small: PropTypes.bool, - isNegative: PropTypes.bool, - hideZeroHours: PropTypes.bool, -}; diff --git a/client/src/common/components/countdown/TimerDisplay.scss b/client/src/common/components/countdown/TimerDisplay.scss deleted file mode 100644 index fd3739c02..000000000 --- a/client/src/common/components/countdown/TimerDisplay.scss +++ /dev/null @@ -1,22 +0,0 @@ -@use '../../../theme/viewerDefs' as *; - -.timer { - font-family: var(--font-family-override, $ontime-font-family); - color: var(--timer-color-override, $viewer-color); - font-size: 21vw; - line-height: 21vw; - text-align: center; - letter-spacing: 1vw; - - &--small { - font-size: 3.75em; - line-height: 0.9; - text-align: center; - letter-spacing: 0.1em; - font-weight: 600; - } - - &--finished { - color: $timer-finished-color; - } -} diff --git a/client/src/common/components/errorBoundary/ErrorBoundary.module.scss b/client/src/common/components/errorBoundary/ErrorBoundary.module.scss index afde83608..71182baf6 100644 --- a/client/src/common/components/errorBoundary/ErrorBoundary.module.scss +++ b/client/src/common/components/errorBoundary/ErrorBoundary.module.scss @@ -1,4 +1,4 @@ -@use '../../../theme/main' as *; +@use '../../../theme/v2Styles' as *; .errorContainer { width: 100%; @@ -9,17 +9,17 @@ color: white; .error { - color: $ontime-pink; + color: $error-red; font-weight: 600; } .report { - text-decoration: underline $ontime-pink; + text-decoration: underline $error-red; cursor: pointer; } .report:hover { - color: $ontime-pink; + color: $error-red; } .report:active { diff --git a/client/src/common/components/myProgressBar/MyProgressBar.jsx b/client/src/common/components/myProgressBar/MyProgressBar.jsx deleted file mode 100644 index fd9141a78..000000000 --- a/client/src/common/components/myProgressBar/MyProgressBar.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import { clamp } from 'common/utils/math'; -import PropTypes from 'prop-types'; - -import styles from './MyProgressBar.module.scss'; - -export default function MyProgressBar(props) { - const { now, complete, showElapsed } = props; - - let percentComplete = showElapsed ? 0 : 100; - - if (now != null && complete != null) { - percentComplete = showElapsed - ? clamp(100 - (now * 100) / complete, 0, 100) - : clamp((now * 100) / complete, 0, 100); - } - - return ( -
-
-
- ); -} - -MyProgressBar.propTypes = { - now: PropTypes.number, - complete: PropTypes.number, - showElapsed: PropTypes.bool, -} diff --git a/client/src/common/components/myProgressBar/MyProgressBar.module.scss b/client/src/common/components/myProgressBar/MyProgressBar.module.scss deleted file mode 100644 index deef4b350..000000000 --- a/client/src/common/components/myProgressBar/MyProgressBar.module.scss +++ /dev/null @@ -1,24 +0,0 @@ -@use '../../../theme/main' as *; - -.progress, -.progressCountdown { - height: 2vh; - border-radius: 4px; -} - -.progress { - background-color: $bg-gray-900; -} - -.progressCountdown { - background-color: $ontime-pink; -} - -.progressBar { - width: 100%; - height: 2vh; - background-color: $title-white; - border-radius: 4px; - transition: 1s linear; - transition-property: width; -} diff --git a/client/src/common/components/navigation-menu/NavigationMenu.tsx b/client/src/common/components/navigation-menu/NavigationMenu.tsx index b74fcaebb..bb67c069f 100644 --- a/client/src/common/components/navigation-menu/NavigationMenu.tsx +++ b/client/src/common/components/navigation-menu/NavigationMenu.tsx @@ -1,4 +1,4 @@ -import { KeyboardEvent, useEffect, useState } from 'react'; +import { KeyboardEvent, useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { Link, useLocation } from 'react-router-dom'; import { IoApps } from '@react-icons/all-files/io5/IoApps'; @@ -10,6 +10,7 @@ import { useAtom } from 'jotai'; import { navigatorConstants } from '../../../viewerConfig'; import { mirrorViewersAtom } from '../../atoms/ViewerSettings'; +import useClickOutside from '../../hooks/useClickOutside'; import useFullscreen from '../../hooks/useFullscreen'; import { useKeyDown } from '../../hooks/useKeyDown'; @@ -22,6 +23,8 @@ export default function NavigationMenu() { const [isMirrored, setMirrored] = useAtom(mirrorViewersAtom); const [showButton, setShowButton] = useState(false); const [showMenu, setShowMenu] = useState(false); + const menuRef = useRef(null); + useClickOutside(menuRef, () => setShowMenu(false)); const toggleMenu = () => setShowMenu((prev) => !prev); useKeyDown(toggleMenu, ' '); @@ -49,7 +52,7 @@ export default function NavigationMenu() { const handleMirror = () => setMirrored((prev) => !prev); return createPortal( -