From fe5756225c3c52c53820be5b721491d592103013 Mon Sep 17 00:00:00 2001 From: M-ZubairAhmed Date: Wed, 27 Nov 2024 06:32:23 +0000 Subject: [PATCH] [MM-61066] Add support for disabled notifications in desktop (#28739) --- .../notification_permission_bar/index.tsx | 3 + .../use_desktop_notification_permission.ts | 52 ++++++++++++++ .../section_notice/section_notice_button.tsx | 1 + .../src/components/section_notice/types.ts | 1 + .../index.test.tsx | 21 ++++++ .../index.tsx | 9 +++ ...rmission_desktop_denied_section_notice.tsx | 71 +++++++++++++++++++ .../index.test.tsx | 21 ++++++ .../index.tsx | 6 +- webapp/channels/src/i18n/en.json | 6 ++ 10 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 webapp/channels/src/components/common/hooks/use_desktop_notification_permission.ts create mode 100644 webapp/channels/src/components/user_settings/notifications/desktop_and_mobile_notification_setting/notification_permission_section_notice/notification_permission_desktop_denied_section_notice.tsx diff --git a/webapp/channels/src/components/announcement_bar/notification_permission_bar/index.tsx b/webapp/channels/src/components/announcement_bar/notification_permission_bar/index.tsx index a94c4fd4d2..17304e6f0b 100644 --- a/webapp/channels/src/components/announcement_bar/notification_permission_bar/index.tsx +++ b/webapp/channels/src/components/announcement_bar/notification_permission_bar/index.tsx @@ -8,6 +8,7 @@ import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; import NotificationPermissionNeverGrantedBar from 'components/announcement_bar/notification_permission_bar/notification_permission_never_granted_bar'; import NotificationPermissionUnsupportedBar from 'components/announcement_bar/notification_permission_bar/notification_permission_unsupported_bar'; +import {useDesktopAppNotificationPermission} from 'components/common/hooks/use_desktop_notification_permission'; import { isNotificationAPISupported, @@ -19,6 +20,8 @@ import { export default function NotificationPermissionBar() { const isLoggedIn = Boolean(useSelector(getCurrentUserId)); + useDesktopAppNotificationPermission(); + if (!isLoggedIn) { return null; } diff --git a/webapp/channels/src/components/common/hooks/use_desktop_notification_permission.ts b/webapp/channels/src/components/common/hooks/use_desktop_notification_permission.ts new file mode 100644 index 0000000000..68c707079b --- /dev/null +++ b/webapp/channels/src/components/common/hooks/use_desktop_notification_permission.ts @@ -0,0 +1,52 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {useCallback, useEffect, useState} from 'react'; + +import type {NotificationPermissionNeverGranted} from 'utils/notifications'; +import {isNotificationAPISupported} from 'utils/notifications'; +import {isDesktopApp} from 'utils/user_agent'; + +export type DesktopNotificationPermission = Exclude | undefined; + +// We store the permission state globally here to avoid calling requestPermission() multiple times +let desktopNotificationPermissionGlobalState: DesktopNotificationPermission | undefined; + +// This is used to request notification permission for desktop app +// it also returns the permission state. We use this as a workaround for bug with Electron - https://github.com/electron/electron/issues/11221 +// tl;dr Electron always show 'granted' when queries for Notification.permission, hence this workaround +export function useDesktopAppNotificationPermission(): [DesktopNotificationPermission, () => Promise] { + const [desktopNotificationPermission, setDesktopNotificationPermission] = useState(undefined); + + const isDesktop = isDesktopApp(); + const isSupported = isNotificationAPISupported(); + + const requestDesktopNotificationPermission = useCallback(async () => { + // Based on Electron's notification permission it will have following states + // - allowed - No further action needed + // - denied permanently - No further action needed + // - denied (temporary) - In this case, electron notification permission dialog is shown with requestPermission() + const permission = await Notification.requestPermission(); + + // Update the global state + desktopNotificationPermissionGlobalState = permission as DesktopNotificationPermission; + + // Update the local state + setDesktopNotificationPermission(permission as DesktopNotificationPermission); + + return permission; + }, []); + + useEffect(() => { + if (!isDesktop || !isSupported) { + setDesktopNotificationPermission(undefined); + } else if (desktopNotificationPermissionGlobalState === undefined) { + // We are in initial state, we need to request permission now + requestDesktopNotificationPermission(); + } else if (desktopNotificationPermissionGlobalState !== undefined) { + setDesktopNotificationPermission(desktopNotificationPermissionGlobalState); + } + }, [isDesktop, isSupported, requestDesktopNotificationPermission]); + + return [desktopNotificationPermission, requestDesktopNotificationPermission]; +} diff --git a/webapp/channels/src/components/section_notice/section_notice_button.tsx b/webapp/channels/src/components/section_notice/section_notice_button.tsx index c68a0c77fc..56f8a9286c 100644 --- a/webapp/channels/src/components/section_notice/section_notice_button.tsx +++ b/webapp/channels/src/components/section_notice/section_notice_button.tsx @@ -21,6 +21,7 @@ const SectionNoticeButton = ({