Skip to content

Commit

Permalink
feat: update pdf sharing in prebuilt
Browse files Browse the repository at this point in the history
  • Loading branch information
amar-1995 authored Oct 4, 2023
1 parent efd57db commit f4ffa20
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 166 deletions.
4 changes: 2 additions & 2 deletions packages/react-sdk/src/utils/commons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export default function usePrevious<T>(state: T): T | undefined {
return ref.current;
}

const chromiumBasedBrowsers = ['chrome', 'brave', 'opera', 'edge'];
const chromiumBasedBrowsers = ['blink'];

export const isChromiumBased = chromiumBasedBrowsers.some(
(value: string) => parsedUserAgent.getBrowser()?.name?.toLowerCase() === value,
(value: string) => parsedUserAgent.getEngine()?.name?.toLowerCase() === value,
);

export const pdfIframeURL = 'https://pdf-annotation.100ms.live/generic/web/viewer.html';
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,18 @@ export const useUrlToEmbed = () => {
return useHMSStore(selectAppData(APP_DATA.embedConfig))?.url;
};

export const usePDFAnnotator = () => {
return useHMSStore(selectAppData(APP_DATA.pdfConfig))?.state;
export const usePDFConfig = () => {
return useHMSStore(selectAppData(APP_DATA.pdfConfig));
};

export const useResetPDFConfig = () => {
const [, setPDFConfig] = useSetAppDataByKey(APP_DATA.pdfConfig);
return useCallback(() => setPDFConfig(), [setPDFConfig]);
};

export const useResetEmbedConfig = () => {
const [, setEmbedConfig] = useSetAppDataByKey(APP_DATA.embedConfig);
return () => setEmbedConfig();
};
export const usePinnedTrack = () => {
const pinnedTrackId = useHMSStore(selectAppData(APP_DATA.pinnedTrackId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const SubmitPDF = ({ pdfFile, onOpenChange }) => {
type="submit"
onClick={() => {
if (pdfFile) {
setPDFConfig({ state: true, file: pdfFile });
setPDFConfig(pdfFile);
onOpenChange(false);
}
}}
Expand Down
107 changes: 47 additions & 60 deletions packages/roomkit-react/src/Prebuilt/layouts/EmbedView.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
selectPeers,
selectPeerScreenSharing,
throwErrorHandler,
useHMSStore,
useScreenShare,
} from '@100mslive/react-sdk';
import React, { useEffect, useMemo } from 'react';
import { selectAppData, selectPeers, selectPeerScreenSharing, useEmbedShare, useHMSStore } from '@100mslive/react-sdk';
import { SecondaryTiles } from '../components/SecondaryTiles';
import { ToastManager } from '../components/Toast/ToastManager';
import { ProminenceLayout } from '../components/VideoLayouts/ProminenceLayout';
import { Box } from '../../Layout';
import { useSetAppDataByKey } from '../components/AppData/useUISettings';
import { useResetEmbedConfig, useSetAppDataByKey } from '../components/AppData/useUISettings';
import { APP_DATA } from '../common/constants';

export const EmbedView = () => {
return (
<EmbebScreenShareView>
<EmbedScreenShareView>
<EmbedComponent />
</EmbebScreenShareView>
</EmbedScreenShareView>
);
};

export const EmbebScreenShareView = ({ children }) => {
export const EmbedScreenShareView = ({ children }) => {
const peers = useHMSStore(selectPeers);

const peerPresenting = useHMSStore(selectPeerScreenSharing);
Expand All @@ -44,62 +39,54 @@ export const EmbebScreenShareView = ({ children }) => {
</ProminenceLayout.Root>
);
};

/**
* EmbedView is responsible for rendering the iframe and managing the screen sharing functionality.
*/
const EmbedComponent = () => {
const { amIScreenSharing, toggleScreenShare } = useScreenShare(throwErrorHandler);
const [embedConfig, setEmbedConfig] = useSetAppDataByKey(APP_DATA.embedConfig);
const [wasScreenShared, setWasScreenShared] = useState(false);
// to handle - https://github.com/facebook/react/issues/24502
const screenShareAttemptInProgress = useRef(false);
const src = embedConfig.url;
const iframeRef = useRef();

const resetEmbedConfig = useCallback(() => {
if (src) {
setEmbedConfig({ url: '' });
}
}, [src, setEmbedConfig]);
const embedConfig = useHMSStore(selectAppData(APP_DATA.embedConfig));
const resetConfig = useResetEmbedConfig();

useEffect(() => {
if (embedConfig.shareScreen && !amIScreenSharing && !wasScreenShared && !screenShareAttemptInProgress.current) {
screenShareAttemptInProgress.current = true;
// start screenshare on load for others in the room to see
toggleScreenShare({
forceCurrentTab: true,
cropElement: iframeRef.current,
})
.then(() => {
setWasScreenShared(true);
})
.catch(resetEmbedConfig)
.finally(() => {
screenShareAttemptInProgress.current = false;
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// need to send resetConfig to clear configuration, if stop screenshare occurs.
const { iframeRef, startEmbedShare, isEmbedShareInProgress } = useEmbedShare(resetConfig);

useEffect(() => {
// reset embed when screenshare is closed from anywhere
if (wasScreenShared && !amIScreenSharing) {
resetEmbedConfig();
}
return () => {
// close screenshare when this component is being unmounted
if (wasScreenShared && amIScreenSharing) {
resetEmbedConfig();
toggleScreenShare(); // stop
(async () => {
if (embedConfig && !isEmbedShareInProgress) {
try {
await startEmbedShare(embedConfig);
} catch (err) {
resetConfig();
ToastManager.addToast({
title: `Error while sharing embed url ${err.message || ''}`,
variant: 'error',
});
}
}
};
}, [wasScreenShared, amIScreenSharing, resetEmbedConfig, toggleScreenShare]);
})();
}, [isEmbedShareInProgress, embedConfig, startEmbedShare, resetConfig]);

return (
<Box ref={iframeRef} css={{ size: '100%' }}>
<Box
css={{
mx: '$8',
flex: '3 1 0',
'@lg': {
flex: '2 1 0',
display: 'flex',
alignItems: 'center',
},
}}
>
<iframe
src={src}
title={src}
style={{ width: '100%', height: '100%', border: 0 }}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture fullscreen"
title="Embed View"
ref={iframeRef}
style={{
width: '100%',
height: '100%',
border: 0,
borderRadius: '0.75rem',
}}
allow="autoplay; clipboard-write;"
referrerPolicy="no-referrer"
/>
</Box>
Expand Down
148 changes: 49 additions & 99 deletions packages/roomkit-react/src/Prebuilt/layouts/PDFView.jsx
Original file line number Diff line number Diff line change
@@ -1,111 +1,61 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { throwErrorHandler, useScreenShare } from '@100mslive/react-sdk';
import React, { useEffect } from 'react';
import { usePDFShare } from '@100mslive/react-sdk';
import { ToastManager } from '../components/Toast/ToastManager';
import { Box } from '../../Layout';
import { ThemeTypes, useTheme } from '../../Theme';
import { EmbebScreenShareView } from './EmbedView';
import { useSetAppDataByKey } from '../components/AppData/useUISettings';
import { APP_DATA, isChrome } from '../common/constants';
import { EmbedScreenShareView } from './EmbedView';
import { usePDFConfig, useResetPDFConfig } from '../components/AppData/useUISettings';

/**
* PDFView is responsible for rendering the PDF iframe and managing the screen sharing functionality.
*/
export const PDFView = () => {
return (
<EmbebScreenShareView>
<PDFEmbedComponent />
</EmbebScreenShareView>
);
};
const pdfConfig = usePDFConfig();
const resetConfig = useResetPDFConfig();

export const PDFEmbedComponent = () => {
const ref = useRef();
const themeType = useTheme().themeType;
const [isPDFLoaded, setIsPDFLoaded] = useState(false);
let pdfJSURL = process.env.REACT_APP_PDFJS_IFRAME_URL;
const { amIScreenSharing, toggleScreenShare } = useScreenShare(throwErrorHandler);
const [pdfConfig, setPDFConfig] = useSetAppDataByKey(APP_DATA.pdfConfig);
if (pdfConfig.url && !pdfConfig.file) {
pdfJSURL = pdfJSURL + '?file=' + encodeURIComponent(pdfConfig.url);
}
const [wasScreenShared, setWasScreenShared] = useState(false);
// to handle - https://github.com/facebook/react/issues/24502
const screenShareAttemptInProgress = useRef(false);
const iframeRef = useRef();
// need to send resetConfig to clear configuration, if stop screenshare occurs.
const { iframeRef, startPDFShare, isPDFShareInProgress } = usePDFShare(resetConfig);

const resetEmbedConfig = useCallback(() => {
setPDFConfig({ state: false });
}, [setPDFConfig]);
useEffect(() => {
if (isPDFLoaded && ref.current) {
ref.current.contentWindow.postMessage(
{
theme: themeType === ThemeTypes.dark ? 2 : 1,
},
'*',
);
}
}, [isPDFLoaded, themeType]);
useEffect(() => {
if (!amIScreenSharing && !wasScreenShared && !screenShareAttemptInProgress.current) {
screenShareAttemptInProgress.current = true;
// start screenshare on load for others in the room to see
toggleScreenShare({
forceCurrentTab: isChrome,
cropElement: iframeRef.current,
preferCurrentTab: isChrome,
})
.then(() => {
setWasScreenShared(true);
})
.catch(resetEmbedConfig)
.finally(() => {
screenShareAttemptInProgress.current = false;
(async () => {
try {
if (!isPDFShareInProgress && pdfConfig) {
await startPDFShare(pdfConfig);
}
} catch (err) {
resetConfig();
ToastManager.addToast({
title: `Error while sharing annotator ${err.message || ''}`,
variant: 'error',
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
// reset embed when screenshare is closed from anywhere
if (wasScreenShared && !amIScreenSharing) {
resetEmbedConfig();
}
return () => {
// close screenshare when this component is being unmounted
if (wasScreenShared && amIScreenSharing) {
resetEmbedConfig();
toggleScreenShare(); // stop
}
};
}, [wasScreenShared, amIScreenSharing, resetEmbedConfig, toggleScreenShare]);

})();
}, [isPDFShareInProgress, pdfConfig, resetConfig, startPDFShare]);
return (
<Box ref={iframeRef} css={{ size: '100%' }}>
<iframe
src={pdfJSURL}
title="PDF Annotator"
ref={ref}
style={{
width: '100%',
height: '100%',
border: 0,
borderRadius: '0.75rem',
}}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture fullscreen"
referrerPolicy="no-referrer"
onLoad={() => {
if (ref.current && pdfConfig.file) {
// setting theme dark -> 2 and light -> 1
requestAnimationFrame(() => {
ref.current.contentWindow.postMessage(
{
file: pdfConfig.file,
theme: themeType === ThemeTypes.dark ? 2 : 1,
},
'*',
);
setIsPDFLoaded(true);
}, 1000);
}
<EmbedScreenShareView>
<Box
css={{
mx: '$8',
flex: '3 1 0',
'@lg': {
flex: '2 1 0',
display: 'flex',
alignItems: 'center',
},
}}
/>
</Box>
>
<iframe
title="Embed View"
ref={iframeRef}
style={{
width: '100%',
height: '100%',
border: 0,
borderRadius: '0.75rem',
}}
allow="autoplay; clipboard-write;"
referrerPolicy="no-referrer"
/>
</Box>
</EmbedScreenShareView>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import SidePane from './SidePane';
import { WaitingView } from './WaitingView';
// import { useWhiteboardMetadata } from '../plugins/whiteboard';
import {
usePDFAnnotator,
usePDFConfig,
useUrlToEmbed,
useWaitingViewerRole,
// @ts-ignore: No implicit Any
Expand All @@ -45,7 +45,7 @@ export const VideoStreamingSection = ({
const hmsActions = useHMSActions();
const waitingViewerRole = useWaitingViewerRole();
const urlToIframe = useUrlToEmbed();
const pdfAnnotatorActive = usePDFAnnotator();
const pdfAnnotatorActive = usePDFConfig();

useEffect(() => {
if (!isConnected) {
Expand Down

0 comments on commit f4ffa20

Please sign in to comment.