diff --git a/.changeset/selfish-pans-switch.md b/.changeset/selfish-pans-switch.md new file mode 100644 index 00000000..00d2fee5 --- /dev/null +++ b/.changeset/selfish-pans-switch.md @@ -0,0 +1,5 @@ +--- +'@nordeck/matrix-neoboard-widget': minor +--- + +Allows collaborators cursors to be shown in presentation mode if slide editing is enabled diff --git a/src/components/CollaborationBar/CollaborationBar.test.tsx b/src/components/CollaborationBar/CollaborationBar.test.tsx index cc691a66..6b802cb4 100644 --- a/src/components/CollaborationBar/CollaborationBar.test.tsx +++ b/src/components/CollaborationBar/CollaborationBar.test.tsx @@ -37,9 +37,10 @@ beforeEach(() => (widgetApi = mockWidgetApi())); describe('', () => { let Wrapper: ComponentType>; let whiteboardManager: jest.Mocked; + let setPresentationMode: (enable: boolean, enableEdit: boolean) => void; beforeEach(() => { - ({ whiteboardManager } = mockWhiteboardManager()); + ({ whiteboardManager, setPresentationMode } = mockWhiteboardManager()); Wrapper = ({ children }) => ( @@ -103,4 +104,34 @@ describe('', () => { }), ).toBeInTheDocument(); }); + + it('should show cursors in presentation mode if edit mode is enabled', async () => { + setPresentationMode(true, true); + + render(, { wrapper: Wrapper }); + + await userEvent.click( + screen.getByRole('checkbox', { + name: "Show collaborators' cursors", + checked: false, + }), + ); + + expect( + screen.getByRole('checkbox', { + name: "Hide collaborators' cursors", + checked: true, + }), + ).toBeInTheDocument(); + }); + + it('should hide cursors in presentation mode if edit mode is not enabled', async () => { + setPresentationMode(true, false); + + render(, { wrapper: Wrapper }); + + expect( + screen.queryByRole('checkbox', { name: /cursors$/ }), + ).not.toBeInTheDocument(); + }); }); diff --git a/src/components/CollaborationBar/CollaborationBar.tsx b/src/components/CollaborationBar/CollaborationBar.tsx index fe498608..ef784b17 100644 --- a/src/components/CollaborationBar/CollaborationBar.tsx +++ b/src/components/CollaborationBar/CollaborationBar.tsx @@ -15,12 +15,17 @@ */ import { useTranslation } from 'react-i18next'; +import { usePresentationMode } from '../../state'; import { Toolbar } from '../common/Toolbar'; import { Collaborators } from './Collaborators'; import { ShowCollaboratorsCursorsToggle } from './ShowCollaboratorsCursorsToggle'; export function CollaborationBar() { const { t } = useTranslation(); + const { state: presentationState } = usePresentationMode(); + const isEditEnabled = + presentationState.type === 'idle' || presentationState.isEditMode; + const isViewingPresentation = presentationState.type === 'presentation'; const toolbarTitle = t('collaborationBar.title', 'Collaboration'); return ( @@ -29,8 +34,8 @@ export function CollaborationBar() { sx={{ pointerEvents: 'initial' }} data-guided-tour-target="collaborationbar" > - - + {isEditEnabled && } + {!isViewingPresentation && } ); } diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index e893c831..e183f0ae 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -112,10 +112,12 @@ function AnimatedSidebar({ } function ContentArea() { - const { state } = usePresentationMode(); - const isViewingPresentation = state.type === 'presentation'; + const { state: presentationState } = usePresentationMode(); + const isViewingPresentation = presentationState.type === 'presentation'; const isViewingPresentationInEditMode = - isViewingPresentation && state.isEditMode; + isViewingPresentation && presentationState.isEditMode; + const isEditEnabled = + presentationState.type === 'idle' || presentationState.isEditMode; return ( <> @@ -126,12 +128,8 @@ function ContentArea() { justifyContent="end" top={(theme) => theme.spacing(1)} > - {!isViewingPresentation && ( - <> - - - - )} + {!isViewingPresentation && } + {(isEditEnabled || !isViewingPresentation) && } diff --git a/src/components/Whiteboard/WhiteboardHost.tsx b/src/components/Whiteboard/WhiteboardHost.tsx index 816b3a3a..b06e6437 100644 --- a/src/components/Whiteboard/WhiteboardHost.tsx +++ b/src/components/Whiteboard/WhiteboardHost.tsx @@ -113,8 +113,8 @@ export const WhiteboardHostConnected = () => { const { state: presentationState } = usePresentationMode(); const isPresenting = presentationState.type === 'presenting'; const isViewingPresentation = presentationState.type === 'presentation'; - const isViewingPresentationInEditMode = - isViewingPresentation && presentationState.isEditMode; + const isEditEnabled = + presentationState.type === 'idle' || presentationState.isEditMode; if (loading) { return ; @@ -123,10 +123,8 @@ export const WhiteboardHostConnected = () => { return ( diff --git a/src/components/common/Toolbar/ToolbarAvatar.tsx b/src/components/common/Toolbar/ToolbarAvatar.tsx index f28f955a..dcbe33cb 100644 --- a/src/components/common/Toolbar/ToolbarAvatar.tsx +++ b/src/components/common/Toolbar/ToolbarAvatar.tsx @@ -53,6 +53,7 @@ export function ToolbarAvatar({ member, title, children }: ToolbarAvatarProps) { background: theme.palette.background.default, borderRadius: '50%', paddingY: '2px', + minHeight: '34px', '&:hover': { background: theme.palette.background.default, diff --git a/src/lib/testUtils/documentTestUtils.tsx b/src/lib/testUtils/documentTestUtils.tsx index 9a3aeb98..6c4fa1a1 100644 --- a/src/lib/testUtils/documentTestUtils.tsx +++ b/src/lib/testUtils/documentTestUtils.tsx @@ -59,7 +59,7 @@ export function mockWhiteboardManager( whiteboardManager: jest.Mocked; communicationChannel: jest.Mocked; messageSubject: Subject; - setPresentationMode: (enable: boolean) => void; + setPresentationMode: (enable: boolean, enableEdit?: boolean) => void; } { const document = createWhiteboardDocument(); @@ -142,13 +142,18 @@ export function mockWhiteboardManager( whiteboardManager, communicationChannel, messageSubject, - setPresentationMode: (enable) => { + setPresentationMode: (enable, enableEdit) => { messageSubject.next({ senderUserId: '@user-alice', senderSessionId: 'other', type: 'net.nordeck.whiteboard.present_slide', content: { - view: enable ? { isEditMode: false, slideId: 'slide-0' } : undefined, + view: enable + ? { + isEditMode: enableEdit ? enableEdit : false, + slideId: 'slide-0', + } + : undefined, }, }); },