ask for media access before record (#172)

This commit is contained in:
an-lee
2024-01-20 10:49:53 +08:00
committed by GitHub
parent 78fc27cb90
commit fe8f14bda7
4 changed files with 60 additions and 3 deletions

View File

@@ -6,6 +6,7 @@ import {
ipcMain,
shell,
dialog,
systemPreferences,
} from "electron";
import path from "path";
import db from "@main/db";
@@ -265,6 +266,25 @@ main.init = () => {
mainWindow.webContents.openDevTools();
});
ipcMain.handle(
"system-preferences-media-access",
async (_event, mediaType: "microphone" | "camera") => {
if (process.platform === "linux") return true;
if (process.platform === "win32")
return systemPreferences.getMediaAccessStatus(mediaType) === "granted";
if (process.platform === "darwin") {
const status = systemPreferences.getMediaAccessStatus(mediaType);
if (status !== "granted") {
const result = await systemPreferences.askForMediaAccess(mediaType);
return result;
} else {
return true;
}
}
}
);
// Shell
ipcMain.handle("shell-open-external", (_event, url) => {
shell.openExternal(url);

View File

@@ -31,6 +31,13 @@ contextBridge.exposeInMainWorld("__ENJOY_APP__", {
},
version,
},
system: {
preferences: {
mediaAccess: (mediaType: "microphone" | "camera") => {
return ipcRenderer.invoke("system-preferences-media-access", mediaType);
},
},
},
providers: {
audible: {
categories: () => {

View File

@@ -1,6 +1,7 @@
import { t } from "i18next";
import { MicIcon } from "lucide-react";
import { useState, useEffect, useRef } from "react";
import { MicIcon, LockIcon } from "lucide-react";
import { useState, useEffect, useRef, useContext } from "react";
import { AppSettingsProviderContext } from "@renderer/context";
import RecordPlugin from "wavesurfer.js/dist/plugins/record";
import WaveSurfer from "wavesurfer.js";
import { cn } from "@renderer/lib/utils";
@@ -16,6 +17,19 @@ export const RecordButton = (props: {
const { className, disabled, onRecordBegin, onRecordEnd } = props;
const [isRecording, setIsRecording] = useState<boolean>(false);
const [duration, setDuration] = useState<number>(0);
const { EnjoyApp } = useContext(AppSettingsProviderContext);
const [access, setAccess] = useState<boolean>(false);
const askForMediaAccess = () => {
EnjoyApp.system.preferences.mediaAccess("microphone").then((access) => {
if (access) {
setAccess(true);
} else {
setAccess(false);
toast.warning(t("noMicrophoneAccess"));
}
});
};
useHotkeys(["command+alt+r", "control+alt+r"], () => {
if (disabled) return;
@@ -41,6 +55,10 @@ export const RecordButton = (props: {
};
}, [isRecording]);
useEffect(() => {
askForMediaAccess();
}, []);
return (
<div
className={cn(
@@ -55,7 +73,11 @@ export const RecordButton = (props: {
)}
onClick={() => {
if (disabled) return;
setIsRecording((isRecording) => !isRecording);
if (access) {
setIsRecording((isRecording) => !isRecording);
} else {
askForMediaAccess();
}
}}
>
{isRecording ? (
@@ -82,6 +104,9 @@ export const RecordButton = (props: {
) : (
<div className="flex items-center justify-center space-x-4 h-10">
<MicIcon className="w-10 h-10" />
{!access && (
<LockIcon className="w-4 h-4 absolute right-3 bottom-4" />
)}
</div>
)}
</div>

View File

@@ -10,6 +10,11 @@ type EnjoyAppType = {
openDevTools: () => Promise<void>;
version: string;
};
system: {
preferences: {
mediaAccess: (mediaType: "microphone") => Promise<boolean>;
};
};
providers: {
audible: {
bestsellers: (params?: {