Skip to content

Commit

Permalink
chore: Check screen recording permission (#2623)
Browse files Browse the repository at this point in the history
* chore: add cancel button to screen picker dialog

* add check Screen Recording Permission to IPC

* add Callout when the permission os denied

* filter not available screens
  • Loading branch information
jeanfbrito authored Mar 22, 2023
1 parent 664e0fc commit ef65b07
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 37 deletions.
1 change: 1 addition & 0 deletions src/ipc/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type ChannelToArgsMap = {
'video-call-window/web-contents-id': (webContentsId: number) => void;
'video-call-window/open-screen-picker': () => void;
'video-call-window/screen-sharing-source-responded': (source: string) => void;
'video-call-window/screen-recording-is-permission-granted': () => boolean;
'jitsi-desktop-capturer-get-sources': (
options: Electron.SourcesOptions
) => Electron.DesktopCapturerSource[];
Expand Down
21 changes: 12 additions & 9 deletions src/public/video-call-window.html
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
<!doctype html>
<html>

<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'">
<title>Rocket.Chat</title>
<style>
webview {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: inline-flex !important;
}
webview {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
display: inline-flex !important;
}
</style>
<link rel="stylesheet" href="./icons/rocketchat.css">
</head>

<body>
<body style="background-color: #347d9a">
<div id="root"></div>
<script src="./video-call-window.js"></script>
</body>
</html>

</html>
9 changes: 9 additions & 0 deletions src/videoCallWindow/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ipcMain,
WebContents,
screen,
systemPreferences,
} from 'electron';

import { handle } from '../ipc/main';
Expand All @@ -19,6 +20,14 @@ export const handleDesktopCapturerGetSources = () => {
};

export const startVideoCallWindowHandler = (): void => {
handle(
'video-call-window/screen-recording-is-permission-granted',
async () => {
const permission = systemPreferences.getMediaAccessStatus('screen');
return permission === 'granted';
}
);

handle('video-call-window/open-window', async (_event, url) => {
console.log('[Rocket.Chat Desktop] open-internal-video-chat-window', url);
const validUrl = new URL(url);
Expand Down
112 changes: 84 additions & 28 deletions src/videoCallWindow/screenSharePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Box, Margins } from '@rocket.chat/fuselage';
import {
Box,
Button,
Callout,
Margins,
Scrollable,
} from '@rocket.chat/fuselage';
import {
DesktopCapturer,
DesktopCapturerSource,
Expand All @@ -18,14 +24,32 @@ const desktopCapturer: DesktopCapturer = {
export function ScreenSharePicker() {
const [visible, setVisible] = useState(false);
const [sources, setSources] = useState<DesktopCapturerSource[]>([]);
const [
isScreenRecordingPermissionGranted,
setIsScreenRecordingPermissionGranted,
] = useState(false);

const fetchSources = async (): Promise<void> => {
const sources = await desktopCapturer.getSources({
types: ['window', 'screen'],
});
setSources(sources);
const filteredSources = sources.filter(
(source) => source.thumbnail.isEmpty() === false
);
setSources(filteredSources);
};

useEffect(() => {
const checkScreenRecordingPermission = async () => {
const result = await ipcRenderer.invoke(
'video-call-window/screen-recording-is-permission-granted'
);
setIsScreenRecordingPermissionGranted(result);
};

checkScreenRecordingPermission().catch(console.error);
}, [visible]);

useEffect(() => {
fetchSources();
}, []);
Expand Down Expand Up @@ -62,40 +86,72 @@ export function ScreenSharePicker() {

return (
<Dialog isVisible={visible} onClose={handleClose}>
<Box fontScale='h1' alignSelf='center'>
Select a screen to share
</Box>
<Box
display='flex'
flexWrap='wrap'
alignItems='stretch'
justifyContent='center'
maxSize='x800'
maxWidth='x800'
>
<Margins all='x4' blockEnd='x16'>
{sources.map(({ id, name, thumbnail }) => (
<Source
{!isScreenRecordingPermissionGranted && (
<Box alignSelf='center' display='flex'>
<Callout
title='Screen Recording Permissions Denied'
type='danger'
maxWidth='100%'
>
The screen sharing feature requires screen recording permissions
to be granted. Please grant screen recording permissions in your
system settings and try again.
<br />
Open <b>System Preferences</b> -<b> Security & Privacy</b> -
<b> Screen Recording</b> and check
<b> Rocket.Chat</b>
</Callout>
</Box>
)}
<Box alignSelf='center' display='flex'>
<Box fontScale='h1' alignSelf='left'>
Select a screen to share
</Box>
</Box>
<Scrollable>
<Margins blockStart='x16' blockEnd='x16'>
<Box
display='flex'
flexDirection='column'
onClick={handleScreenSharingSourceClick(id)}
flexWrap='wrap'
alignItems='stretch'
justifyContent='center'
maxSize='x730'
>
<Box
flexGrow={1}
display='flex'
alignItems='center'
justifyContent='center'
>
<Box
is='img'
src={thumbnail.toDataURL()}
alt={name}
style={{ maxWidth: '148px', maxHeight: '148px' }}
/>
</Box>
<Box>{name}</Box>
</Source>
))}
</Margins>
{sources.map(({ id, name, thumbnail }) => (
<Source
display='flex'
flexDirection='column'
onClick={handleScreenSharingSourceClick(id)}
>
<Box
flexGrow={1}
display='flex'
alignItems='center'
justifyContent='center'
>
<Box
is='img'
src={thumbnail.toDataURL()}
alt={name}
style={{ maxWidth: '148px', maxHeight: '148px' }}
/>
</Box>
<Box>{name}</Box>
</Source>
))}
</Box>
</Margins>
</Scrollable>
</Box>
<Box alignSelf='center' display='flex'>
<Button onClick={handleClose}>Cancel</Button>
</Box>
</Dialog>
);
Expand Down

0 comments on commit ef65b07

Please sign in to comment.