diff --git a/packages/frontend/apps/electron/src/main/recording/feature.ts b/packages/frontend/apps/electron/src/main/recording/feature.ts index 856624b33..d967c9293 100644 --- a/packages/frontend/apps/electron/src/main/recording/feature.ts +++ b/packages/frontend/apps/electron/src/main/recording/feature.ts @@ -780,6 +780,13 @@ export const checkMeetingPermissions = () => { ) as Record<(typeof mediaTypes)[number], boolean>; }; +export const askForMeetingPermission = async (type: 'microphone') => { + if (!isMacOS()) { + return false; + } + return systemPreferences.askForMediaAccess(type); +}; + export const checkCanRecordMeeting = () => { const features = checkMeetingPermissions(); return ( diff --git a/packages/frontend/apps/electron/src/main/recording/index.ts b/packages/frontend/apps/electron/src/main/recording/index.ts index a057e9381..3a9893525 100644 --- a/packages/frontend/apps/electron/src/main/recording/index.ts +++ b/packages/frontend/apps/electron/src/main/recording/index.ts @@ -9,6 +9,7 @@ import { shell } from 'electron'; import { isMacOS } from '../../shared/utils'; import type { NamespaceHandlers } from '../type'; import { + askForMeetingPermission, checkMeetingPermissions, checkRecordingAvailable, disableRecordingFeature, @@ -76,6 +77,9 @@ export const recordingHandlers = { checkMeetingPermissions: async () => { return checkMeetingPermissions(); }, + askForMeetingPermission: async (_, type: 'microphone') => { + return askForMeetingPermission(type); + }, showRecordingPermissionSetting: async (_, type: 'screen' | 'microphone') => { const urlMap = { screen: 'Privacy_ScreenCapture', diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx index 33528d606..f7fbe821a 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/meetings/index.tsx @@ -210,7 +210,13 @@ export const MeetingsSettings = () => { const handleOpenMicrophoneRecordingPermissionSetting = useAsyncCallback(async () => { - await meetingSettingsService.showRecordingPermissionSetting('microphone'); + const result = + await meetingSettingsService.askForMeetingPermission('microphone'); + if (!result) { + await meetingSettingsService.showRecordingPermissionSetting( + 'microphone' + ); + } }, [meetingSettingsService]); const handleOpenSavedRecordings = useAsyncCallback(async () => { diff --git a/packages/frontend/core/src/modules/media/services/meeting-settings.ts b/packages/frontend/core/src/modules/media/services/meeting-settings.ts index 490e0cbd7..dacd4dc8a 100644 --- a/packages/frontend/core/src/modules/media/services/meeting-settings.ts +++ b/packages/frontend/core/src/modules/media/services/meeting-settings.ts @@ -114,6 +114,12 @@ export class MeetingSettingsService extends Service { ); } + async askForMeetingPermission(type: 'microphone') { + return this.desktopApiService?.handler.recording.askForMeetingPermission( + type + ); + } + setRecordingMode = (mode: MeetingSettingsSchema['recordingMode']) => { const currentMode = this.settings.recordingMode;