mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-05-30 20:09:29 +02:00
Merge pull request #388 from webees/fix/macos-permission-grant-feedback
fix: improve macOS permission grant feedback
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@
|
||||
|
||||
### Maintenance
|
||||
|
||||
- chore: versiom bump
|
||||
- chore: version bump
|
||||
- chore: update flake.nix for v0.24.3 [skip ci] (#383)
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,17 @@
|
||||
"core:window:allow-minimize",
|
||||
"core:window:allow-toggle-maximize",
|
||||
"opener:default",
|
||||
{
|
||||
"identifier": "opener:allow-open-url",
|
||||
"allow": [
|
||||
{
|
||||
"url": "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"
|
||||
},
|
||||
{
|
||||
"url": "x-apple.systempreferences:com.apple.preference.security?Privacy_Camera"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fs:default",
|
||||
"shell:allow-execute",
|
||||
"shell:allow-kill",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { writeText as writeClipboardText } from "@tauri-apps/plugin-clipboard-manager";
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
import Color from "color";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -368,19 +369,36 @@ export function SettingsDialog({
|
||||
async (permissionType: PermissionType) => {
|
||||
setRequestingPermission(permissionType);
|
||||
try {
|
||||
await requestPermission(permissionType);
|
||||
showSuccessToast(
|
||||
t("settings.permissions.accessRequested", {
|
||||
permission: getPermissionDisplayName(permissionType),
|
||||
}),
|
||||
const granted = await requestPermission(permissionType);
|
||||
if (granted) {
|
||||
showSuccessToast(
|
||||
permissionType === "microphone"
|
||||
? t("permissionDialog.grantedToastMicrophone")
|
||||
: t("permissionDialog.grantedToastCamera"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await openUrl(
|
||||
`x-apple.systempreferences:com.apple.preference.security?${
|
||||
permissionType === "microphone"
|
||||
? "Privacy_Microphone"
|
||||
: "Privacy_Camera"
|
||||
}`,
|
||||
);
|
||||
showErrorToast(
|
||||
permissionType === "microphone"
|
||||
? t("permissionDialog.stillNotGrantedMicrophone")
|
||||
: t("permissionDialog.stillNotGrantedCamera"),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Failed to request permission:", error);
|
||||
showErrorToast(t("permissionDialog.requestFailed"));
|
||||
} finally {
|
||||
setRequestingPermission(null);
|
||||
}
|
||||
},
|
||||
[getPermissionDisplayName, requestPermission, t],
|
||||
[requestPermission, t],
|
||||
);
|
||||
|
||||
const handleSave = useCallback(async () => {
|
||||
|
||||
@@ -21,7 +21,7 @@ const loadMacOSPermissions = async () => {
|
||||
export type PermissionType = "microphone" | "camera";
|
||||
|
||||
interface UsePermissionsReturn {
|
||||
requestPermission: (type: PermissionType) => Promise<void>;
|
||||
requestPermission: (type: PermissionType) => Promise<boolean>;
|
||||
isMicrophoneAccessGranted: boolean;
|
||||
isCameraAccessGranted: boolean;
|
||||
isInitialized: boolean;
|
||||
@@ -68,51 +68,44 @@ export function usePermissions(): UsePermissionsReturn {
|
||||
|
||||
// Request permission
|
||||
const requestPermission = useCallback(
|
||||
async (type: PermissionType): Promise<void> => {
|
||||
if (!currentPlatform || currentPlatform !== "macos") return;
|
||||
async (type: PermissionType): Promise<boolean> => {
|
||||
// Non-macOS platforms do not require this permission gate.
|
||||
if (!currentPlatform || currentPlatform !== "macos") return true;
|
||||
|
||||
// macOS - use the permissions API
|
||||
try {
|
||||
const permissions = await loadMacOSPermissions();
|
||||
if (!permissions) return;
|
||||
if (!permissions) return false;
|
||||
|
||||
const readPermission = async () => {
|
||||
const granted =
|
||||
type === "microphone"
|
||||
? await permissions.checkMicrophonePermission()
|
||||
: await permissions.checkCameraPermission();
|
||||
if (type === "microphone") {
|
||||
setIsMicrophoneAccessGranted(granted);
|
||||
} else {
|
||||
setIsCameraAccessGranted(granted);
|
||||
}
|
||||
return granted;
|
||||
};
|
||||
|
||||
if (type === "microphone") {
|
||||
await permissions.requestMicrophonePermission();
|
||||
|
||||
// Poll for permission status change
|
||||
const pollMicPermission = async () => {
|
||||
const granted = await permissions.checkMicrophonePermission();
|
||||
setIsMicrophoneAccessGranted(granted);
|
||||
|
||||
if (!granted) {
|
||||
setTimeout(() => {
|
||||
void pollMicPermission();
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
await pollMicPermission();
|
||||
}
|
||||
|
||||
if (type === "camera") {
|
||||
} else {
|
||||
await permissions.requestCameraPermission();
|
||||
|
||||
// Poll for permission status change
|
||||
const pollCamPermission = async () => {
|
||||
const granted = await permissions.checkCameraPermission();
|
||||
setIsCameraAccessGranted(granted);
|
||||
|
||||
if (!granted) {
|
||||
setTimeout(() => {
|
||||
void pollCamPermission();
|
||||
}, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
await pollCamPermission();
|
||||
}
|
||||
|
||||
for (let attempt = 0; attempt < 8; attempt += 1) {
|
||||
const granted = await readPermission();
|
||||
if (granted) return true;
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
return readPermission();
|
||||
} catch (error) {
|
||||
console.error(`Failed to request ${type} permission on macOS:`, error);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[currentPlatform],
|
||||
|
||||
Reference in New Issue
Block a user