usePermissions Composable
Reactive browser permission checking with request functionality
Code
import { ref, watch, onMounted } from 'vue';
type PermissionName = 'camera' | 'microphone' | 'notifications' | 'geolocation' | 'clipboard-read' | 'clipboard-write';
type PermissionStatus = 'granted' | 'denied' | 'prompt' | 'unsupported';
export function usePermissions(permissionName: PermissionName) {
const status = ref<PermissionStatus>('unsupported');
const isGranted = ref(false);
const isDenied = ref(false);
const isPrompt = ref(false);
// Update derived states
const updateDerivedStates = () => {
isGranted.value = status.value === 'granted';
isDenied.value = status.value === 'denied';
isPrompt.value = status.value === 'prompt';
};
// Check permission status
const checkPermission = __TOKEN_52__ () => {
try {
__TOKEN_54__ (!navigator.permissions) {
status.value = 'unsupported';
updateDerivedStates();
return;
}
const permissionStatus = await navigator.permissions.query({
name: permissionName as PermissionName
});
// Update initial status
status.value = permissionStatus.state as PermissionStatus;
updateDerivedStates();
// Listen for status changes
permissionStatus.addEventListener('change', () => {
status.value = permissionStatus.state as PermissionStatus;
updateDerivedStates();
});
} __TOKEN_58__ (error) {
console.error('Failed to check permission:', error);
status.value = 'unsupported';
updateDerivedStates();
}
};
// Request permission (for permissions that require direct request)
const requestPermission = __TOKEN_60__ (): Promise<boolean> => {
try {
switch (permissionName) {
case 'camera':
await navigator.mediaDevices.getUserMedia({ video: true });
break;
case 'microphone':
await navigator.mediaDevices.getUserMedia({ audio: true });
break;
case 'notifications':
await Notification.requestPermission();
break;
case 'geolocation':
await new __TOKEN_80__((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject);
});
break;
default:
break;
}
// Re-check status after request
await checkPermission();
return isGranted.value;
} __TOKEN_69__ (error) {
console.error('Failed to request permission:', error);
await checkPermission();
return false;
}
};
// Initial check
onMounted(() => {
checkPermission();
});
// Watch for status changes
watch(status, updateDerivedStates);
return {
status,
isGranted,
isDenied,
isPrompt,
checkPermission,
requestPermission
};
}
// Usage example
// const { isGranted, requestPermission } = usePermissions('notifications');
// const enableNotifications = async () => {
// const granted = await requestPermission();
// if (granted) {
// new Notification('Notifications enabled!');
// }
// };