diff --git a/apps/client/src/common/components/client-modal/RenameClientModal.tsx b/apps/client/src/common/components/client-modal/RenameClientModal.tsx
index 4dbf95ea4..dc6e03625 100644
--- a/apps/client/src/common/components/client-modal/RenameClientModal.tsx
+++ b/apps/client/src/common/components/client-modal/RenameClientModal.tsx
@@ -1,17 +1,9 @@
import { useState } from 'react';
-import {
- Button,
- Input,
- Modal,
- ModalBody,
- ModalCloseButton,
- ModalContent,
- ModalFooter,
- ModalHeader,
- ModalOverlay,
-} from '@chakra-ui/react';
+import Button from '../../../common/components/buttons/Button';
import { setClientRemote } from '../../hooks/useSocket';
+import Dialog from '../dialog/Dialog';
+import Input from '../input/input/Input';
interface RenameClientModalProps {
id: string;
@@ -20,8 +12,7 @@ interface RenameClientModalProps {
onClose: () => void;
}
-export function RenameClientModal(props: RenameClientModalProps) {
- const { id, name: currentName = '', isOpen, onClose } = props;
+export function RenameClientModal({ id, name: currentName = '', isOpen, onClose }: RenameClientModalProps) {
const [name, setName] = useState(currentName);
const { setClientName } = setClientRemote;
@@ -36,29 +27,24 @@ export function RenameClientModal(props: RenameClientModalProps) {
const canSubmit = name !== currentName && name !== '';
return (
-
-
-
- Rename: {currentName}
-
-
- setName(event.target.value)}
- />
-
-
-
-
-
+ >
+ }
+ />
);
}
diff --git a/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss b/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss
index a2f9808aa..613d8c298 100644
--- a/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss
+++ b/apps/client/src/common/components/navigation-menu/NavigationMenu.module.scss
@@ -1,107 +1,68 @@
-@use '../../../theme/mixins' as *;
-
-$menu-hover-bg: $gray-1350;
-$menu-focus-bg: $gray-1300;
-
-$button-size: 3rem;
-
-.fadeable {
- opacity: 1;
-
- transition-property: opacity;
- transition-duration: 0.3s;
-
- &.hidden {
- opacity: 0;
- pointer-events: none;
- }
-}
-
-.lockIcon {
- font-size: 1.5rem;
- color: $active-indicator;
- padding: 0.5em;
-
- position: fixed;
- left: 0;
- top: 0;
- z-index: 12;
-}
-
-.buttonContainer {
- display: flex;
- flex-direction: column;
- row-gap: 1rem;
- padding: 0.5em;
-
- position: fixed;
- left: 0;
- top: 0;
- z-index: 12;
-}
-
-.navButton {
- font-size: 1.5rem;
- height: $button-size;
- width: $button-size;;
-}
-
-.link {
- @include action-link;
- padding: 0.75rem 1.5rem;
- gap: 0.5rem;
- width: 100%;
- cursor: pointer;
-
- &:hover {
- background-color: $menu-hover-bg;
- }
-
- &:active {
- background-color: $border-color-ondark;
- }
-
- &:focus {
- outline: none;
- background-color: $menu-focus-bg;
- border-left: 2px solid $action-text-color;
- }
-
- &.current {
- background-color: $menu-hover-bg;
- border-left: 4px solid $action-text-color;
- }
-}
-
-.linkIcon {
- margin-left: auto;
- @include rotate-fourty-five;
-}
-
.separator {
border-color: $border-color-ondark;
}
-.sectionHeader {
- font-size: calc(1rem - 2px);
- margin-left: 1rem;
- color: $gray-700;
+.backdrop {
+ position: fixed;
+ inset: 0;
+ z-index: $zindex-backdrop;
+ background-color: $backdrop-color;
+ transition: opacity 300ms cubic-bezier(0.45, 1.005, 0, 1.005);
+
+ &[data-starting-style],
+ &[data-ending-style] {
+ opacity: 0;
+ }
}
-.bottom {
- margin-top: auto;
- margin-bottom: 1rem;
-}
+.drawer {
+ box-sizing: border-box;
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ z-index: $zindex-dialog;
+
+ width: 22rem;
+ height: 100vh;
-.interfaces {
- padding: 0.5rem 1rem;
display: flex;
- flex-wrap: wrap;
- gap: 0.5rem;
+ flex-direction: column;
+ padding-block: 1rem;
+
+ background-color: $gray-1250;
+ color: $ui-white;
+ border-right: 1px solid $gray-1200;
+
+ &[data-open] {
+ transform: translateX(0%);
+ transition: transform 300ms cubic-bezier(0.45, 1.005, 0, 1.005);
+ }
+
+ &[data-starting-style],
+ &[data-ending-style] {
+ transform: translateX(-100%);
+ transition: transform 500ms cubic-bezier(0.45, 1.005, 0, 1.005);
+ }
+
+ // take the whole screen in mobile devices
+ @media (max-width: $min-tablet) {
+ width: 100vw;
+ }
}
-.goIcon {
- @include rotate-fourty-five;
- margin-left: 0.25rem;
- margin-bottom: 0.25rem;
+.header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 3.5rem;
+ padding-inline: 1.5rem;
+
+ font-weight: 600;
+ font-size: 1.25rem;
+}
+
+.body {
+ flex: 1;
+ overflow-y: auto;
}
diff --git a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx
index 914cd7b74..233ccb618 100644
--- a/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx
+++ b/apps/client/src/common/components/navigation-menu/NavigationMenu.tsx
@@ -1,29 +1,20 @@
-import { memo, PropsWithChildren } from 'react';
-import { createPortal } from 'react-dom';
-import { IoArrowUp, IoContract, IoExpand, IoLockClosedOutline, IoSwapVertical } from 'react-icons/io5';
-import { Link, useLocation } from 'react-router-dom';
-import {
- Drawer,
- DrawerBody,
- DrawerCloseButton,
- DrawerContent,
- DrawerHeader,
- DrawerOverlay,
- useDisclosure,
-} from '@chakra-ui/react';
-import { useFullscreen } from '@mantine/hooks';
+import { memo } from 'react';
+import { IoClose, IoContract, IoExpand, IoLockClosedOutline, IoSwapVertical } from 'react-icons/io5';
+import { useLocation } from 'react-router-dom';
+import { Dialog } from '@base-ui-components/react/dialog';
+import { useDisclosure, useFullscreen } from '@mantine/hooks';
import { isLocalhost } from '../../../externals';
import { navigatorConstants } from '../../../viewerConfig';
-import { useElectronEvent } from '../../hooks/useElectronEvent';
-import useInfo from '../../hooks-query/useInfo';
import { useClientStore } from '../../stores/clientStore';
import { useViewOptionsStore } from '../../stores/viewOptions';
-import { isKeyEnter } from '../../utils/keyEvent';
-import { handleLinks, linkToOtherHost, openLink } from '../../utils/linkUtils';
-import { cx } from '../../utils/styleUtils';
+import IconButton from '../buttons/IconButton';
import { RenameClientModal } from '../client-modal/RenameClientModal';
-import CopyTag from '../copy-tag/CopyTag';
+
+import ClientLink from './client-link/ClientLink';
+import EditorNavigation from './editor-navigation/EditorNavigation';
+import NavigationMenuItem from './navigation-menu-item/NavigationMenuItem';
+import OtherAddresses from './other-addresses/OtherAddresses';
import style from './NavigationMenu.module.scss';
@@ -32,74 +23,49 @@ interface NavigationMenuProps {
onClose: () => void;
}
-function NavigationMenu(props: NavigationMenuProps) {
- const { isOpen, onClose } = props;
-
+export default memo(NavigationMenu);
+function NavigationMenu({ isOpen, onClose }: NavigationMenuProps) {
const id = useClientStore((store) => store.id);
const name = useClientStore((store) => store.name);
- const { isOpen: isOpenRename, onOpen: onRenameOpen, onClose: onCloseRename } = useDisclosure();
+ const [isRenameOpen, handlers] = useDisclosure(false);
const { fullscreen, toggle } = useFullscreen();
const { mirror, toggleMirror } = useViewOptionsStore();
const location = useLocation();
- return createPortal(
-
+
+ {isLocalhost && (
+
+
+
+ )}
+
+
+
);
}
-
-interface OtherAddressesProps {
- currentLocation: string;
-}
-
-function OtherAddresses(props: OtherAddressesProps) {
- const { currentLocation } = props;
- const { data } = useInfo();
-
- // there is no point showing this if we only have one interface
- if (data.networkInterfaces.length < 2) {
- return null;
- }
-
- return (
-
-
Accessible on external networks
-
- {data?.networkInterfaces?.map((nif) => {
- if (nif.name === 'localhost') {
- return null;
- }
-
- const address = linkToOtherHost(nif.address, currentLocation);
-
- return (
- openLink(address)}
- label='Copy IP or navigate to address'
- >
- {nif.address}
-
- );
- })}
-
-
- );
-}
-
-interface ClientLinkProps {
- current: boolean;
- to: string;
-}
-
-function ClientLink(props: PropsWithChildren) {
- const { current, to, children } = props;
- const { isElectron } = useElectronEvent();
-
- const classes = cx([style.link, current && style.current]);
-
- if (isElectron) {
- return (
- handleLinks(event, to)}>
- {children}
-
-
- );
- }
-
- return (
-
- {children}
-
- );
-}
-
-export default memo(NavigationMenu);
diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx
index 4490c5a81..652fe03d2 100644
--- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx
+++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx
@@ -2,10 +2,10 @@ import { memo } from 'react';
import { useDisclosure } from '@chakra-ui/react';
import { useHotkeys } from '@mantine/hooks';
-import FloatingNavigation from './FloatingNavigation';
+import FloatingNavigation from './floating-navigation/FloatingNavigation';
+import ViewLockedIcon from './view-locked-icon/ViewLockedIcon';
import NavigationMenu from './NavigationMenu';
import useViewEditor from './useViewEditor';
-import ViewLockedIcon from './ViewLockedIcon';
interface ViewNavigationMenuProps {
isLockable?: boolean;
diff --git a/apps/client/src/common/components/navigation-menu/client-link/ClientLink.module.scss b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.module.scss
new file mode 100644
index 000000000..431a04308
--- /dev/null
+++ b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.module.scss
@@ -0,0 +1,4 @@
+.linkIcon {
+ margin-left: auto;
+ @include rotate-fourty-five;
+}
diff --git a/apps/client/src/common/components/navigation-menu/client-link/ClientLink.tsx b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.tsx
new file mode 100644
index 000000000..1d7e507d1
--- /dev/null
+++ b/apps/client/src/common/components/navigation-menu/client-link/ClientLink.tsx
@@ -0,0 +1,34 @@
+import { PropsWithChildren } from 'react';
+import { IoArrowUp } from 'react-icons/io5';
+import { useNavigate } from 'react-router-dom';
+
+import { useElectronEvent } from '../../../hooks/useElectronEvent';
+import { handleLinks } from '../../../utils/linkUtils';
+import NavigationMenuItem from '../navigation-menu-item/NavigationMenuItem';
+
+import style from './ClientLink.module.scss';
+
+interface ClientLinkProps {
+ current: boolean;
+ to: string;
+}
+
+export default function ClientLink({ current, to, children }: PropsWithChildren) {
+ const { isElectron } = useElectronEvent();
+ const navigate = useNavigate();
+
+ if (isElectron) {
+ return (
+ handleLinks(to)}>
+ {children}
+
+
+ );
+ }
+
+ return (
+ navigate(`/${to}`)}>
+ {children}
+
+ );
+}
diff --git a/apps/client/src/common/components/navigation-menu/editor-navigation/EditorNavigation.tsx b/apps/client/src/common/components/navigation-menu/editor-navigation/EditorNavigation.tsx
new file mode 100644
index 000000000..0d94221c5
--- /dev/null
+++ b/apps/client/src/common/components/navigation-menu/editor-navigation/EditorNavigation.tsx
@@ -0,0 +1,38 @@
+import { IoLockClosedOutline } from 'react-icons/io5';
+import { useNavigate } from 'react-router-dom';
+import { useViewportSize } from '@mantine/hooks';
+
+import NavigationMenuItem from '../navigation-menu-item/NavigationMenuItem';
+
+export default function EditorNavigation() {
+ const { width } = useViewportSize();
+ const navigate = useNavigate();
+
+ if (width > 1440) {
+ return (
+ navigate('/editor')}>
+
+ Editor
+
+ );
+ }
+
+ return (
+ <>
+ navigate('/timercontrol')}>
+
+ Timer Controls
+
+
+ navigate('/messagecontrol')}>
+
+ Message Controls
+
+
+ navigate('/rundown')}>
+
+ Rundown
+
+ >
+ );
+}
diff --git a/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.module.scss b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.module.scss
new file mode 100644
index 000000000..ea5279118
--- /dev/null
+++ b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.module.scss
@@ -0,0 +1,23 @@
+.fadeable {
+ opacity: 1;
+
+ transition-property: opacity;
+ transition-duration: 0.3s;
+
+ &.hidden {
+ opacity: 0;
+ pointer-events: none;
+ }
+}
+
+.buttonContainer {
+ display: flex;
+ flex-direction: column;
+ row-gap: 1rem;
+ padding: 0.5em;
+
+ position: fixed;
+ left: 0;
+ top: 0;
+ z-index: $zindex-nav;
+}
diff --git a/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx
similarity index 53%
rename from apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx
rename to apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx
index a38454344..0301bdd16 100644
--- a/apps/client/src/common/components/navigation-menu/FloatingNavigation.tsx
+++ b/apps/client/src/common/components/navigation-menu/floating-navigation/FloatingNavigation.tsx
@@ -1,26 +1,28 @@
import { IoApps } from 'react-icons/io5';
import { IoSettingsOutline } from 'react-icons/io5';
-import { useFadeOutOnInactivity } from '../../hooks/useFadeOutOnInactivity';
-import { cx } from '../../utils/styleUtils';
-import IconButton from '../buttons/IconButton';
+import { useFadeOutOnInactivity } from '../../../hooks/useFadeOutOnInactivity';
+import { cx } from '../../../utils/styleUtils';
+import IconButton from '../../buttons/IconButton';
-import style from './NavigationMenu.module.scss';
+import style from './FloatingNavigation.module.scss';
interface FloatingNavigationProps {
toggleMenu: () => void;
toggleSettings: () => void;
}
-export default function FloatingNavigation(props: FloatingNavigationProps) {
- const { toggleMenu, toggleSettings } = props;
- const isButtonShown = useFadeOutOnInactivity();
+export default function FloatingNavigation({ toggleMenu, toggleSettings }: FloatingNavigationProps) {
+ const isButtonShown = useFadeOutOnInactivity(true);
return (
-
+
void;
+}
+
+export default function NavigationMenuItem({
+ active,
+ className,
+ children,
+ onClick,
+}: PropsWithChildren) {
+ return (
+ {
+ isKeyEnter(event) && onClick();
+ }}
+ >
+ {children}
+
+ );
+}
diff --git a/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.module.scss b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.module.scss
new file mode 100644
index 000000000..50ca4ee8c
--- /dev/null
+++ b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.module.scss
@@ -0,0 +1,18 @@
+.header {
+ font-size: calc(1rem - 2px);
+ margin-left: 1rem;
+ color: $gray-700;
+}
+
+.interfaces {
+ padding: 0.5rem 1rem;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+
+.goIcon {
+ @include rotate-fourty-five;
+ margin-left: 0.25rem;
+ margin-bottom: 0.25rem;
+}
diff --git a/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.tsx b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.tsx
new file mode 100644
index 000000000..d4a47191f
--- /dev/null
+++ b/apps/client/src/common/components/navigation-menu/other-addresses/OtherAddresses.tsx
@@ -0,0 +1,46 @@
+import { IoArrowUp } from 'react-icons/io5';
+
+import useInfo from '../../../hooks-query/useInfo';
+import { linkToOtherHost, openLink } from '../../../utils/linkUtils';
+import CopyTag from '../../copy-tag/CopyTag';
+
+import style from './OtherAddresses.module.scss';
+
+interface OtherAddressesProps {
+ currentLocation: string;
+}
+
+export default function OtherAddresses({ currentLocation }: OtherAddressesProps) {
+ const { data } = useInfo();
+
+ // there is no point showing this if we only have one interface
+ if (data.networkInterfaces.length < 2) {
+ return null;
+ }
+
+ return (
+ <>
+ Accessible on external networks
+
+ {data?.networkInterfaces?.map((nif) => {
+ if (nif.name === 'localhost') {
+ return null;
+ }
+
+ const address = linkToOtherHost(nif.address, currentLocation);
+
+ return (
+ openLink(address)}
+ label='Copy IP or navigate to address'
+ >
+ {nif.address}
+
+ );
+ })}
+
+ >
+ );
+}
diff --git a/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.module.scss b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.module.scss
new file mode 100644
index 000000000..5995cbb4d
--- /dev/null
+++ b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.module.scss
@@ -0,0 +1,22 @@
+.fadeable {
+ opacity: 1;
+
+ transition-property: opacity;
+ transition-duration: 0.3s;
+
+ &.hidden {
+ opacity: 0;
+ pointer-events: none;
+ }
+}
+
+.lockIcon {
+ font-size: 1.5rem;
+ color: $active-indicator;
+ padding: 0.5em;
+
+ position: fixed;
+ left: 0;
+ top: 0;
+ z-index: $zindex-nav;
+}
diff --git a/apps/client/src/common/components/navigation-menu/ViewLockedIcon.tsx b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.tsx
similarity index 63%
rename from apps/client/src/common/components/navigation-menu/ViewLockedIcon.tsx
rename to apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.tsx
index 3afe50cad..3dfac5561 100644
--- a/apps/client/src/common/components/navigation-menu/ViewLockedIcon.tsx
+++ b/apps/client/src/common/components/navigation-menu/view-locked-icon/ViewLockedIcon.tsx
@@ -1,9 +1,9 @@
import { IoLockClosedOutline } from 'react-icons/io5';
-import { useFadeOutOnInactivity } from '../../hooks/useFadeOutOnInactivity';
-import { cx } from '../../utils/styleUtils';
+import { useFadeOutOnInactivity } from '../../../hooks/useFadeOutOnInactivity';
+import { cx } from '../../../utils/styleUtils';
-import style from './NavigationMenu.module.scss';
+import style from './ViewLockedIcon.module.scss';
export default function ViewLockedIcon() {
const isLockIconShown = useFadeOutOnInactivity();
diff --git a/apps/client/src/common/utils/linkUtils.ts b/apps/client/src/common/utils/linkUtils.ts
index 98f0aec32..db2b0707c 100644
--- a/apps/client/src/common/utils/linkUtils.ts
+++ b/apps/client/src/common/utils/linkUtils.ts
@@ -20,13 +20,13 @@ export function openLink(url: string) {
* serverUrl and baseURI are used for testing
*/
export function handleLinks(
- event: MouseEvent,
location: string,
+ event?: MouseEvent,
externalServerUrl: string = serverURL,
externalBaseURI: string = baseURI,
) {
// we handle the link manually
- event.preventDefault();
+ event?.preventDefault();
const destination = new URL(externalServerUrl);
destination.pathname = externalBaseURI ? `${externalBaseURI}/${location}` : location;
diff --git a/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx b/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx
index 4e1209a3c..db7553550 100644
--- a/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx
+++ b/apps/client/src/features/app-settings/panel/feature-settings-panel/UrlPresetsForm.tsx
@@ -198,7 +198,7 @@ export default function UrlPresetsForm() {
handleLinks(event, preset.alias)}
+ clickHandler={(event) => handleLinks(preset.alias, event)}
tooltip='Test preset'
aria-label='Test preset'
variant='ontime-ghosted'
diff --git a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx
index c0979bebd..45724679c 100644
--- a/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx
+++ b/apps/client/src/features/app-settings/panel/network-panel/NetworkLogExport.tsx
@@ -10,7 +10,7 @@ import style from './NetworkLogExport.module.scss';
export default function LogExport() {
const extract = (event: MouseEvent) => {
- handleLinks(event, 'log');
+ handleLinks('log', event);
};
return (
diff --git a/apps/client/src/features/control/message/MessageControlExport.jsx b/apps/client/src/features/control/message/MessageControlExport.jsx
index 0dd7b036a..9f5fbf117 100644
--- a/apps/client/src/features/control/message/MessageControlExport.jsx
+++ b/apps/client/src/features/control/message/MessageControlExport.jsx
@@ -15,7 +15,7 @@ const MessageControlExport = () => {
return (
- {!isExtracted &&
handleLinks(event, 'messagecontrol')} />}
+ {!isExtracted && handleLinks('messagecontrol', event)} />}
diff --git a/apps/client/src/features/control/message/TimerPreview.tsx b/apps/client/src/features/control/message/TimerPreview.tsx
index 3a3db72f5..1ba9636b3 100644
--- a/apps/client/src/features/control/message/TimerPreview.tsx
+++ b/apps/client/src/features/control/message/TimerPreview.tsx
@@ -49,7 +49,7 @@ export default function TimerPreview() {
return (
-
handleLinks(event, 'timer')} />
+ handleLinks('timer', event)} />
{
const isExtracted = window.location.pathname.includes('/timercontrol');
return (
- {!isExtracted &&
handleLinks(event, 'timercontrol')} />}
+ {!isExtracted && handleLinks('timercontrol', event)} />}
diff --git a/apps/client/src/features/rundown/RundownExport.tsx b/apps/client/src/features/rundown/RundownExport.tsx
index 3298fcab9..145f0ca43 100644
--- a/apps/client/src/features/rundown/RundownExport.tsx
+++ b/apps/client/src/features/rundown/RundownExport.tsx
@@ -28,7 +28,7 @@ function RundownExport() {
- {!isExtracted && handleLinks(event, 'rundown')} />}
+ {!isExtracted && handleLinks('rundown', event)} />}
diff --git a/apps/client/src/theme/_mixins.scss b/apps/client/src/theme/_mixins.scss
index 94d8fea27..4998a6bbd 100644
--- a/apps/client/src/theme/_mixins.scss
+++ b/apps/client/src/theme/_mixins.scss
@@ -2,20 +2,6 @@
//////////////////////////////////// general app elements
-@mixin action-link {
- color: $action-text-color;
- display: flex;
- align-items: center;
- cursor: pointer;
- transition-property: color;
- transition-duration: $transition-time-action;
- white-space: nowrap;
-
- &:hover {
- color: $ontime-color;
- }
-}
-
@mixin ellipsis-text {
white-space: nowrap;
overflow: hidden;
diff --git a/apps/client/src/viewerConfig.ts b/apps/client/src/viewerConfig.ts
index 475e7c552..f45600ecc 100644
--- a/apps/client/src/viewerConfig.ts
+++ b/apps/client/src/viewerConfig.ts
@@ -1,7 +1,5 @@
export const navigatorConstants = [
{ url: 'timer', label: 'Timer' },
- { url: 'minimal', label: 'Minimal Timer' },
- { url: 'clock', label: 'Wall Clock' },
{ url: 'backstage', label: 'Backstage' },
{ url: 'timeline', label: 'Timeline (beta)' },
{ url: 'lower', label: 'Lower Thirds' },
diff --git a/e2e/tests/001-smoke-tests.spec.ts b/e2e/tests/001-smoke-tests.spec.ts
index 2dff5e4a1..2c3a4f027 100644
--- a/e2e/tests/001-smoke-tests.spec.ts
+++ b/e2e/tests/001-smoke-tests.spec.ts
@@ -33,18 +33,6 @@ test.describe('pages routes are available', () => {
await expect(page).toHaveTitle(/ontime/);
});
- test('clock', async ({ page }) => {
- await page.goto('http://localhost:4001/timer');
-
- await expect(page).toHaveTitle(/ontime/);
- });
-
- test('minimal', async ({ page }) => {
- await page.goto('http://localhost:4001/minimal');
-
- await expect(page).toHaveTitle(/ontime/);
- });
-
test('backstage', async ({ page }) => {
await page.goto('http://localhost:4001/backstage');
diff --git a/e2e/tests/002-view-navigation.spec.ts b/e2e/tests/002-view-navigation.spec.ts
index 20e918d84..ba269b2ec 100644
--- a/e2e/tests/002-view-navigation.spec.ts
+++ b/e2e/tests/002-view-navigation.spec.ts
@@ -6,37 +6,23 @@ test.describe('test view navigation feature', () => {
await expect(page.locator('data-testid=timer-view')).toBeVisible();
});
- test('Minimal', async ({ page }) => {
- await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Minimal Timer' }).click();
- await expect(page.locator('data-testid=minimal-timer')).toBeVisible();
- await expect(page).toHaveURL('http://localhost:4001/minimal');
- });
-
- test('Wall Clock', async ({ page }) => {
- await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Wall Clock', exact: true }).click();
- await expect(page.locator('data-testid=clock-view')).toBeVisible();
- await expect(page).toHaveURL('http://localhost:4001/clock');
- });
-
test('Timeline', async ({ page }) => {
await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Timeline' }).click();
+ await page.getByRole('button', { name: 'Timeline' }).click();
page.locator('data-testid=timeline-view');
await expect(page).toHaveURL('http://localhost:4001/timeline');
});
test('Backstage', async ({ page }) => {
await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Backstage' }).click();
+ await page.getByRole('button', { name: 'Backstage' }).click();
page.locator('data-testid=backstage-view');
await expect(page).toHaveURL('http://localhost:4001/backstage');
});
test('Lower Thirds', async ({ page }) => {
await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Lower Thirds' }).click();
+ await page.getByRole('button', { name: 'Lower Thirds' }).click();
await expect(page).toHaveURL('http://localhost:4001/lower');
const errorBoundary = page.locator('data-testid=error-container');
await expect(errorBoundary).toHaveCount(0);
@@ -44,28 +30,28 @@ test.describe('test view navigation feature', () => {
test('Studio Clock', async ({ page }) => {
await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Studio Clock' }).click();
+ await page.getByRole('button', { name: 'Studio Clock' }).click();
page.locator('data-testid=studio-view');
await expect(page).toHaveURL('http://localhost:4001/studio');
});
test('Countdown', async ({ page }) => {
await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Countdown' }).click();
+ await page.getByRole('button', { name: 'Countdown' }).click();
page.locator('data-testid=countdown-view');
await expect(page).toHaveURL('http://localhost:4001/countdown');
});
test('Project Info', async ({ page }) => {
await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Project Info' }).click();
+ await page.getByRole('button', { name: 'Project Info' }).click();
page.locator('data-testid=project-view');
await expect(page).toHaveURL('http://localhost:4001/info');
});
test('Timer', async ({ page }) => {
await openNavigationMenu(page);
- await page.getByRole('link', { name: 'Timer', exact: true }).click();
+ await page.getByRole('button', { name: 'Timer', exact: true }).click();
page.locator('data-testid=timer-view');
await expect(page).toHaveURL('http://localhost:4001/timer');
});