1import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
2import { PermissionStatus } from 'unimodules-permissions-interface';
3
4import {
5  NativeNotificationPermissionsRequest,
6  NotificationPermissionsStatus,
7} from './NotificationPermissions.types';
8import { NotificationPermissionsModule } from './NotificationPermissionsModule.types';
9
10function convertPermissionStatus(
11  status?: NotificationPermission | 'prompt'
12): NotificationPermissionsStatus {
13  switch (status) {
14    case 'granted':
15      return {
16        status: PermissionStatus.GRANTED,
17        expires: 'never',
18        canAskAgain: false,
19        granted: true,
20      };
21    case 'denied':
22      return {
23        status: PermissionStatus.DENIED,
24        expires: 'never',
25        canAskAgain: false,
26        granted: false,
27      };
28    default:
29      return {
30        status: PermissionStatus.UNDETERMINED,
31        expires: 'never',
32        canAskAgain: true,
33        granted: false,
34      };
35  }
36}
37
38async function resolvePermissionAsync({
39  shouldAsk,
40}: {
41  shouldAsk: boolean;
42}): Promise<NotificationPermissionsStatus> {
43  if (!canUseDOM) {
44    return convertPermissionStatus('denied');
45  }
46
47  const { Notification = {} } = window as any;
48  if (typeof Notification.requestPermission !== 'undefined') {
49    let status = Notification.permission;
50    if (shouldAsk) {
51      status = await Notification.requestPermission();
52    }
53    return convertPermissionStatus(status);
54  } else if (typeof navigator !== 'undefined' && navigator?.permissions?.query) {
55    // TODO(Bacon): Support `push` in the future when it's stable.
56    const query = await navigator.permissions.query({ name: 'notifications' });
57    return convertPermissionStatus(query.state);
58  }
59  // Platforms like iOS Safari don't support Notifications so return denied.
60  return convertPermissionStatus('denied');
61}
62
63export default {
64  addListener: () => {},
65  removeListeners: () => {},
66  async getPermissionsAsync(): Promise<NotificationPermissionsStatus> {
67    return resolvePermissionAsync({ shouldAsk: false });
68  },
69  async requestPermissionsAsync(
70    request: NativeNotificationPermissionsRequest
71  ): Promise<NotificationPermissionsStatus> {
72    return resolvePermissionAsync({ shouldAsk: true });
73  },
74} as NotificationPermissionsModule;
75