From 74d88e80d513689d3bf788e1c6b2f4e7f6fe94e8 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Mon, 28 Nov 2022 15:27:17 +0100 Subject: [PATCH] Calls: Show notification when missing access to camera or mic (#2157) --- src/global/actions/apiUpdaters/calls.ts | 3 +- src/global/actions/ui/calls.ts | 48 ++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/global/actions/apiUpdaters/calls.ts b/src/global/actions/apiUpdaters/calls.ts index 8e2a60c2e..edc455d10 100644 --- a/src/global/actions/apiUpdaters/calls.ts +++ b/src/global/actions/apiUpdaters/calls.ts @@ -6,7 +6,7 @@ import { updateChat } from '../../reducers'; import { ARE_CALLS_SUPPORTED } from '../../../util/environment'; import { notifyAboutCall } from '../../../util/notifications'; import { selectPhoneCallUser } from '../../selectors/calls'; -import { initializeSoundsForSafari } from '../ui/calls'; +import { checkNavigatorUserMediaPermissions, initializeSoundsForSafari } from '../ui/calls'; import { onTickEnd } from '../../../util/schedulers'; addActionHandler('apiUpdate', (global, actions, update) => { @@ -96,6 +96,7 @@ addActionHandler('apiUpdate', (global, actions, update) => { }); void initializeSoundsForSafari(); + void checkNavigatorUserMediaPermissions(call.isVideo); return { ...global, phoneCall: call, diff --git a/src/global/actions/ui/calls.ts b/src/global/actions/ui/calls.ts index 06468967a..b22372849 100644 --- a/src/global/actions/ui/calls.ts +++ b/src/global/actions/ui/calls.ts @@ -1,4 +1,6 @@ -import { addActionHandler, getGlobal, setGlobal } from '../../index'; +import { + addActionHandler, getActions, getGlobal, setGlobal, +} from '../../index'; import { selectActiveGroupCall, selectChatGroupCall, selectGroupCall } from '../../selectors/calls'; import { callApi } from '../../../api/gramjs'; import { selectChat, selectUser } from '../../selectors'; @@ -217,6 +219,8 @@ addActionHandler('joinGroupCall', async (global, actions, payload) => { createAudioElement(); await initializeSoundsForSafari(); + void checkNavigatorUserMediaPermissions(true); + const { groupCalls: { activeGroupCallId } } = global; let groupCall = id ? selectGroupCall(global, id) : selectChatGroupCall(global, chatId); @@ -319,6 +323,7 @@ addActionHandler('requestCall', async (global, actions, payload) => { } await initializeSoundsForSafari(); + void checkNavigatorUserMediaPermissions(isVideo); setGlobal({ ...getGlobal(), @@ -365,3 +370,44 @@ export function removeGroupCallAudioElement() { audioContext = undefined; audioElement = undefined; } + +// This method is used instead of a navigator.permissions.query to determine permission to use a microphone, +// because Firefox does not have support for 'microphone' and 'camera' permissions +// https://github.com/mozilla/standards-positions/issues/19#issuecomment-370158947 +export function checkNavigatorUserMediaPermissions(isVideo?: boolean) { + if (isVideo) { + navigator.mediaDevices.getUserMedia({ video: true }) + .then((stream) => { + if (stream.getVideoTracks().length === 0) { + getActions().showNotification({ + message: langProvider.getTranslation('Call.Camera.Error'), + }); + } else { + checkMicrophonePermission(); + } + }) + .catch(() => { + getActions().showNotification({ + message: langProvider.getTranslation('Call.Camera.Error'), + }); + }); + } else { + checkMicrophonePermission(); + } +} + +function checkMicrophonePermission() { + navigator.mediaDevices.getUserMedia({ audio: true }) + .then((stream) => { + if (stream.getAudioTracks().length === 0) { + getActions().showNotification({ + message: langProvider.getTranslation('RequestAcces.Error.HaveNotAccess.Call'), + }); + } + }) + .catch(() => { + getActions().showNotification({ + message: langProvider.getTranslation('RequestAcces.Error.HaveNotAccess.Call'), + }); + }); +}