diff --git a/packages/shared/src/components/cards/highlight/HighlightCardOptions.spec.tsx b/packages/shared/src/components/cards/highlight/HighlightCardOptions.spec.tsx index 921d2e108d0..a08c36c1eab 100644 --- a/packages/shared/src/components/cards/highlight/HighlightCardOptions.spec.tsx +++ b/packages/shared/src/components/cards/highlight/HighlightCardOptions.spec.tsx @@ -7,23 +7,14 @@ import { SidebarSettingsFlags, } from '../../../graphql/settings'; -const mockSubscribe = jest.fn().mockResolvedValue(undefined); -const mockUnsubscribe = jest.fn().mockResolvedValue(undefined); const mockDisplayToast = jest.fn(); const mockUseAuth = jest.fn(); -const mockUseConditionalFeature = jest.fn(); -const mockUseMajorHeadlinesSubscription = jest.fn(); -const mockRouterPush = jest.fn(); const mockUpdateFlag = jest.fn().mockResolvedValue(undefined); const mockUseSettingsContext = jest.fn(); const mockLogEvent = jest.fn(); const mockInvalidateQueries = jest.fn().mockResolvedValue(undefined); const mockUseActiveFeedContext = jest.fn(); -jest.mock('next/router', () => ({ - useRouter: () => ({ push: mockRouterPush }), -})); - jest.mock('@tanstack/react-query', () => ({ ...(jest.requireActual('@tanstack/react-query') as Iterable), useQueryClient: () => ({ invalidateQueries: mockInvalidateQueries }), @@ -45,14 +36,6 @@ jest.mock('../../../contexts/LogContext', () => ({ useLogContext: () => ({ logEvent: mockLogEvent }), })); -jest.mock('../../../hooks/useConditionalFeature', () => ({ - useConditionalFeature: () => mockUseConditionalFeature(), -})); - -jest.mock('../../../hooks/notifications/useMajorHeadlinesSubscription', () => ({ - useMajorHeadlinesSubscription: () => mockUseMajorHeadlinesSubscription(), -})); - jest.mock('../../../hooks/useToastNotification', () => ({ useToastNotification: () => ({ displayToast: mockDisplayToast }), })); @@ -83,13 +66,6 @@ describe('HighlightCardOptions', () => { beforeEach(() => { jest.clearAllMocks(); mockUseAuth.mockReturnValue({ user: { id: '1' } }); - mockUseConditionalFeature.mockReturnValue({ value: true }); - mockUseMajorHeadlinesSubscription.mockReturnValue({ - isSubscribed: false, - isLoading: false, - subscribe: mockSubscribe, - unsubscribe: mockUnsubscribe, - }); mockUseSettingsContext.mockReturnValue({ flags: { highlightsPlacement: HighlightsPlacement.Default }, updateFlag: mockUpdateFlag, @@ -100,16 +76,13 @@ describe('HighlightCardOptions', () => { }); }); - it('should render the options menu with all items when feature is on and user is logged in', () => { + it('should render the placement options when the user is logged in', () => { renderComponent(); expect( screen.getByRole('button', { name: 'Pin to top' }), ).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Disable' })).toBeInTheDocument(); - expect( - screen.getByRole('button', { name: 'Get real-time alerts' }), - ).toBeInTheDocument(); }); it('should not render for guests', () => { @@ -118,17 +91,7 @@ describe('HighlightCardOptions', () => { renderComponent(); expect( - screen.queryByRole('button', { name: 'Get real-time alerts' }), - ).not.toBeInTheDocument(); - }); - - it('should not render when feature is off', () => { - mockUseConditionalFeature.mockReturnValue({ value: false }); - - renderComponent(); - - expect( - screen.queryByRole('button', { name: 'Get real-time alerts' }), + screen.queryByRole('button', { name: 'Pin to top' }), ).not.toBeInTheDocument(); }); @@ -196,65 +159,4 @@ describe('HighlightCardOptions', () => { ); }); }); - - it('should subscribe and show toast with settings action when not subscribed', async () => { - renderComponent(); - - fireEvent.click( - screen.getByRole('button', { name: 'Get real-time alerts' }), - ); - - await waitFor(() => { - expect(mockSubscribe).toHaveBeenCalledWith('feed_card'); - }); - await waitFor(() => { - expect(mockDisplayToast).toHaveBeenCalledWith( - "You'll be the first to know when news breaks.", - expect.objectContaining({ - action: expect.objectContaining({ copy: 'Settings' }), - }), - ); - }); - }); - - it('should navigate to notification settings when toast action is clicked', async () => { - renderComponent(); - - fireEvent.click( - screen.getByRole('button', { name: 'Get real-time alerts' }), - ); - - await waitFor(() => { - expect(mockDisplayToast).toHaveBeenCalled(); - }); - - const toastArgs = mockDisplayToast.mock.calls[0][1]; - toastArgs.action.onClick(); - - expect(mockRouterPush).toHaveBeenCalledWith('/settings/notifications'); - }); - - it('should unsubscribe when subscribed', async () => { - mockUseMajorHeadlinesSubscription.mockReturnValue({ - isSubscribed: true, - isLoading: false, - subscribe: mockSubscribe, - unsubscribe: mockUnsubscribe, - }); - - renderComponent(); - - fireEvent.click( - screen.getByRole('button', { name: 'Turn off real-time alerts' }), - ); - - await waitFor(() => { - expect(mockUnsubscribe).toHaveBeenCalledWith('feed_card'); - }); - await waitFor(() => { - expect(mockDisplayToast).toHaveBeenCalledWith( - 'Real-time alerts turned off.', - ); - }); - }); }); diff --git a/packages/shared/src/components/cards/highlight/HighlightCardOptions.tsx b/packages/shared/src/components/cards/highlight/HighlightCardOptions.tsx index c5a2b3fa942..0f8e49352cb 100644 --- a/packages/shared/src/components/cards/highlight/HighlightCardOptions.tsx +++ b/packages/shared/src/components/cards/highlight/HighlightCardOptions.tsx @@ -1,16 +1,9 @@ import type { ReactElement } from 'react'; -import React, { useMemo, useState } from 'react'; +import React, { useState } from 'react'; import classNames from 'classnames'; -import { useRouter } from 'next/router'; import { useQueryClient } from '@tanstack/react-query'; import { Button, ButtonSize, ButtonVariant } from '../../buttons/Button'; -import { - BellAddIcon, - BellSubscribedIcon, - EyeCancelIcon, - MenuIcon as KebabIcon, - PinIcon, -} from '../../icons'; +import { EyeCancelIcon, MenuIcon as KebabIcon, PinIcon } from '../../icons'; import { MenuIcon } from '../../MenuIcon'; import { DropdownMenu, @@ -18,13 +11,9 @@ import { DropdownMenuOptions, DropdownMenuTrigger, } from '../../dropdown/DropdownMenu'; -import type { MenuItemProps } from '../../dropdown/common'; import { useActiveFeedContext } from '../../../contexts/ActiveFeedContext'; import { useAuthContext } from '../../../contexts/AuthContext'; import { useSettingsContext } from '../../../contexts/SettingsContext'; -import { useMajorHeadlinesSubscription } from '../../../hooks/notifications/useMajorHeadlinesSubscription'; -import { useConditionalFeature } from '../../../hooks/useConditionalFeature'; -import { featureMajorHeadlinesPush } from '../../../lib/featureManagement'; import { useToastNotification } from '../../../hooks/useToastNotification'; import { useLogContext } from '../../../contexts/LogContext'; import { @@ -34,8 +23,6 @@ import { import { LogEvent, Origin } from '../../../lib/log'; import { labels } from '../../../lib'; -const NOTIFICATION_SETTINGS_PATH = '/settings/notifications'; - interface HighlightCardOptionsProps { className?: string; } @@ -43,18 +30,14 @@ interface HighlightCardOptionsProps { const HighlightCardOptionsContent = ({ className, }: HighlightCardOptionsProps): ReactElement => { - const router = useRouter(); const [isPending, setIsPending] = useState(false); const { displayToast } = useToastNotification(); const { logEvent } = useLogContext(); const { flags, updateFlag } = useSettingsContext(); const queryClient = useQueryClient(); const { queryKey: feedQueryKey } = useActiveFeedContext(); - const { isSubscribed, isLoading, subscribe, unsubscribe } = - useMajorHeadlinesSubscription(); - const placement = flags?.highlightsPlacement ?? HighlightsPlacement.Default; - const isPinned = placement === HighlightsPlacement.Pinned; + const isPinned = flags?.highlightsPlacement === HighlightsPlacement.Pinned; const updatePlacement = async (next: HighlightsPlacement) => { if (isPending) { @@ -79,59 +62,6 @@ const HighlightCardOptionsContent = ({ } }; - const toggleSubscription = async () => { - if (isPending || isLoading) { - return; - } - setIsPending(true); - try { - if (isSubscribed) { - await unsubscribe('feed_card'); - displayToast('Real-time alerts turned off.'); - return; - } - await subscribe('feed_card'); - displayToast("You'll be the first to know when news breaks.", { - action: { - copy: 'Settings', - onClick: () => router.push(NOTIFICATION_SETTINGS_PATH), - }, - }); - } finally { - setIsPending(false); - } - }; - - const options = useMemo(() => { - const SubscribeIcon = isSubscribed ? BellSubscribedIcon : BellAddIcon; - return [ - { - label: isPinned ? 'Unpin from top' : 'Pin to top', - icon: , - action: () => - updatePlacement( - isPinned ? HighlightsPlacement.Default : HighlightsPlacement.Pinned, - ), - disabled: isPending, - }, - { - label: 'Disable', - icon: , - action: () => updatePlacement(HighlightsPlacement.Disabled), - disabled: isPending, - }, - { - label: isSubscribed - ? 'Turn off real-time alerts' - : 'Get real-time alerts', - icon: , - action: toggleSubscription, - disabled: isPending || isLoading, - }, - ]; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isPinned, isSubscribed, isPending, isLoading]); - return ( @@ -147,7 +77,27 @@ const HighlightCardOptionsContent = ({ /> - + , + action: () => + updatePlacement( + isPinned + ? HighlightsPlacement.Default + : HighlightsPlacement.Pinned, + ), + disabled: isPending, + }, + { + label: 'Disable', + icon: , + action: () => updatePlacement(HighlightsPlacement.Disabled), + disabled: isPending, + }, + ]} + /> ); @@ -157,13 +107,8 @@ export const HighlightCardOptions = ({ className, }: HighlightCardOptionsProps): ReactElement | null => { const auth = useAuthContext(); - const user = auth?.user; - const { value: isFeatureEnabled } = useConditionalFeature({ - feature: featureMajorHeadlinesPush, - shouldEvaluate: !!user, - }); - if (!isFeatureEnabled || !user) { + if (!auth?.user) { return null; } diff --git a/packages/shared/src/components/highlights/EnableHighlightsAlerts.spec.tsx b/packages/shared/src/components/highlights/EnableHighlightsAlerts.spec.tsx deleted file mode 100644 index 76a28fa3f45..00000000000 --- a/packages/shared/src/components/highlights/EnableHighlightsAlerts.spec.tsx +++ /dev/null @@ -1,189 +0,0 @@ -import React from 'react'; -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; -import { EnableHighlightsAlerts } from './EnableHighlightsAlerts'; -import { LogEvent } from '../../lib/log'; -import { ActionType } from '../../graphql/actions'; - -const mockLogEvent = jest.fn(); -const mockSubscribe = jest.fn().mockResolvedValue(undefined); -const mockCompleteAction = jest.fn().mockResolvedValue(undefined); -const mockCheckHasCompleted = jest.fn(); -const mockDisplayToast = jest.fn(); -const mockUseAuth = jest.fn(); -const mockUseConditionalFeature = jest.fn(); -const mockUseMajorHeadlinesSubscription = jest.fn(); -const mockRouterPush = jest.fn(); -const mockUsePushNotificationContext = jest.fn(); - -jest.mock('next/router', () => ({ - useRouter: () => ({ push: mockRouterPush }), -})); - -jest.mock('../../contexts/PushNotificationContext', () => ({ - usePushNotificationContext: () => mockUsePushNotificationContext(), -})); - -jest.mock('../../contexts/LogContext', () => ({ - useLogContext: () => ({ logEvent: mockLogEvent }), -})); - -jest.mock('../../contexts/AuthContext', () => ({ - useAuthContext: () => mockUseAuth(), -})); - -jest.mock('../../hooks/useActions', () => ({ - useActions: () => ({ - checkHasCompleted: mockCheckHasCompleted, - completeAction: mockCompleteAction, - isActionsFetched: true, - }), -})); - -jest.mock('../../hooks/useConditionalFeature', () => ({ - useConditionalFeature: () => mockUseConditionalFeature(), -})); - -jest.mock('../../hooks/notifications/useMajorHeadlinesSubscription', () => ({ - useMajorHeadlinesSubscription: () => mockUseMajorHeadlinesSubscription(), -})); - -jest.mock('../../hooks/useToastNotification', () => ({ - useToastNotification: () => ({ displayToast: mockDisplayToast }), -})); - -const renderComponent = () => render(); - -describe('EnableHighlightsAlerts', () => { - beforeEach(() => { - jest.clearAllMocks(); - mockUseAuth.mockReturnValue({ user: { id: '1' } }); - mockUseConditionalFeature.mockReturnValue({ value: true }); - mockUseMajorHeadlinesSubscription.mockReturnValue({ - isSubscribed: false, - isLoading: false, - subscribe: mockSubscribe, - unsubscribe: jest.fn(), - }); - mockCheckHasCompleted.mockReturnValue(false); - mockUsePushNotificationContext.mockReturnValue({ isSubscribed: false }); - }); - - it('should render banner when feature is on, user is logged in, not subscribed and not dismissed', () => { - renderComponent(); - - expect(screen.getByText('Never miss a major headline')).toBeInTheDocument(); - expect(screen.getByText('Notify me')).toBeInTheDocument(); - }); - - it('should not render when feature is off', () => { - mockUseConditionalFeature.mockReturnValue({ value: false }); - - renderComponent(); - - expect( - screen.queryByText('Never miss a major headline'), - ).not.toBeInTheDocument(); - }); - - it('should not render for guests', () => { - mockUseAuth.mockReturnValue({ user: undefined }); - - renderComponent(); - - expect( - screen.queryByText('Never miss a major headline'), - ).not.toBeInTheDocument(); - }); - - it('should not render when already subscribed', () => { - mockUseMajorHeadlinesSubscription.mockReturnValue({ - isSubscribed: true, - isLoading: false, - subscribe: mockSubscribe, - unsubscribe: jest.fn(), - }); - - renderComponent(); - - expect( - screen.queryByText('Never miss a major headline'), - ).not.toBeInTheDocument(); - }); - - it('should not render when dismissed', () => { - mockCheckHasCompleted.mockReturnValue(true); - - renderComponent(); - - expect( - screen.queryByText('Never miss a major headline'), - ).not.toBeInTheDocument(); - }); - - it('should log impression on render', () => { - renderComponent(); - - expect(mockLogEvent).toHaveBeenCalledWith({ - event_name: LogEvent.ImpressionMajorHeadlinesAlertsBanner, - extra: JSON.stringify({ origin: 'highlights_page' }), - }); - }); - - it('should subscribe and show toast with settings action on CTA click when push is not yet enabled', async () => { - renderComponent(); - - fireEvent.click(screen.getByText('Notify me')); - - await waitFor(() => { - expect(mockSubscribe).toHaveBeenCalledWith('highlights_page'); - }); - - await waitFor(() => { - expect(mockDisplayToast).toHaveBeenCalledWith( - "You'll be the first to know when news breaks.", - expect.objectContaining({ - action: expect.objectContaining({ copy: 'Settings' }), - }), - ); - }); - - const toastArgs = mockDisplayToast.mock.calls[0][1]; - toastArgs.action.onClick(); - expect(mockRouterPush).toHaveBeenCalledWith('/settings/notifications'); - }); - - it('should show enabled state inline when push was already granted', async () => { - mockUsePushNotificationContext.mockReturnValue({ isSubscribed: true }); - - renderComponent(); - - fireEvent.click(screen.getByText('Notify me')); - - await waitFor(() => { - expect(mockSubscribe).toHaveBeenCalledWith('highlights_page'); - }); - - await waitFor(() => { - expect(screen.getByText("You're in the loop")).toBeInTheDocument(); - }); - - expect(mockDisplayToast).not.toHaveBeenCalled(); - }); - - it('should complete dismiss action and log dismiss on close', async () => { - renderComponent(); - - fireEvent.click(screen.getByRole('button', { name: 'Dismiss' })); - - expect(mockLogEvent).toHaveBeenCalledWith({ - event_name: LogEvent.DismissMajorHeadlinesAlertsBanner, - extra: JSON.stringify({ origin: 'highlights_page' }), - }); - - await waitFor(() => { - expect(mockCompleteAction).toHaveBeenCalledWith( - ActionType.DismissedMajorHeadlinesAlertsBanner, - ); - }); - }); -}); diff --git a/packages/shared/src/components/highlights/EnableHighlightsAlerts.tsx b/packages/shared/src/components/highlights/EnableHighlightsAlerts.tsx deleted file mode 100644 index 4055f226933..00000000000 --- a/packages/shared/src/components/highlights/EnableHighlightsAlerts.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import type { ReactElement } from 'react'; -import React, { useCallback, useState } from 'react'; -import classNames from 'classnames'; -import { useRouter } from 'next/router'; -import { - Button, - ButtonColor, - ButtonSize, - ButtonVariant, -} from '../buttons/Button'; -import CloseButton from '../CloseButton'; -import { - cloudinaryNotificationsBrowser, - cloudinaryNotificationsBrowserEnabled, -} from '../../lib/image'; -import { VIcon } from '../icons'; -import { useAuthContext } from '../../contexts/AuthContext'; -import { useActions } from '../../hooks/useActions'; -import { ActionType } from '../../graphql/actions'; -import { useMajorHeadlinesSubscription } from '../../hooks/notifications/useMajorHeadlinesSubscription'; -import { useConditionalFeature } from '../../hooks/useConditionalFeature'; -import { featureMajorHeadlinesPush } from '../../lib/featureManagement'; -import { useLogContext } from '../../contexts/LogContext'; -import useLogEventOnce from '../../hooks/log/useLogEventOnce'; -import { LogEvent } from '../../lib/log'; -import { useToastNotification } from '../../hooks/useToastNotification'; -import { usePushNotificationContext } from '../../contexts/PushNotificationContext'; - -interface EnableHighlightsAlertsProps { - className?: string; -} - -const ORIGIN = 'highlights_page'; -const NOTIFICATION_SETTINGS_PATH = '/settings/notifications'; - -export const EnableHighlightsAlerts = ({ - className, -}: EnableHighlightsAlertsProps): ReactElement | null => { - const router = useRouter(); - const { user } = useAuthContext(); - const { isSubscribed: isPushEnabled } = usePushNotificationContext(); - const { checkHasCompleted, completeAction, isActionsFetched } = useActions(); - const { logEvent } = useLogContext(); - const { displayToast } = useToastNotification(); - const { isSubscribed, isLoading, subscribe } = - useMajorHeadlinesSubscription(); - const [isPending, setIsPending] = useState(false); - const [acceptedJustNow, setAcceptedJustNow] = useState(false); - - const { value: isFeatureEnabled } = useConditionalFeature({ - feature: featureMajorHeadlinesPush, - shouldEvaluate: !!user, - }); - - const isDismissed = checkHasCompleted( - ActionType.DismissedMajorHeadlinesAlertsBanner, - ); - - const shouldRender = - isFeatureEnabled && - !!user && - isActionsFetched && - !isSubscribed && - !isDismissed; - - useLogEventOnce( - () => ({ - event_name: LogEvent.ImpressionMajorHeadlinesAlertsBanner, - extra: JSON.stringify({ origin: ORIGIN }), - }), - { condition: shouldRender }, - ); - - const handleEnable = useCallback(async () => { - if (isPending || isLoading) { - return; - } - setIsPending(true); - try { - await subscribe(ORIGIN); - if (isPushEnabled) { - setAcceptedJustNow(true); - return; - } - displayToast("You'll be the first to know when news breaks.", { - action: { - copy: 'Settings', - onClick: () => router.push(NOTIFICATION_SETTINGS_PATH), - }, - }); - } finally { - setIsPending(false); - } - }, [isPending, isLoading, subscribe, isPushEnabled, displayToast, router]); - - const handleDismiss = useCallback(() => { - completeAction(ActionType.DismissedMajorHeadlinesAlertsBanner); - logEvent({ - event_name: LogEvent.DismissMajorHeadlinesAlertsBanner, - extra: JSON.stringify({ origin: ORIGIN }), - }); - }, [completeAction, logEvent]); - - if (!shouldRender) { - return null; - } - - return ( -
- - {acceptedJustNow && } - {acceptedJustNow ? "You're in the loop" : 'Never miss a major headline'} - -
-

- {acceptedJustNow ? ( - <> - You can change your{' '} - {' '} - anytime. - - ) : ( - 'Be the first to know when something major happens in the developer world.' - )} -

- -
-
- {!acceptedJustNow && ( - - )} -
- -
- ); -}; - -export default EnableHighlightsAlerts; diff --git a/packages/shared/src/components/highlights/HighlightsPage.tsx b/packages/shared/src/components/highlights/HighlightsPage.tsx index f3616cfaa09..784d9d1cd61 100644 --- a/packages/shared/src/components/highlights/HighlightsPage.tsx +++ b/packages/shared/src/components/highlights/HighlightsPage.tsx @@ -13,7 +13,6 @@ import { import { Tab, TabContainer } from '../tabs/TabContainer'; import { DigestCTA } from './DigestCTA'; import { HighlightItem } from './HighlightItem'; -import { EnableHighlightsAlerts } from './EnableHighlightsAlerts'; const MAJOR_HEADLINES_LABEL = 'Headlines'; const SKELETON_COUNT = 5; @@ -149,7 +148,6 @@ export const HighlightsPage = (): ReactElement => { Happening Now - { const { logEvent } = useLogContext(); @@ -50,17 +47,12 @@ const InAppNotificationsTab = (): ReactElement => { const { isSubscribed, isInitialized, isPushSupported } = usePushNotificationContext(); const { openModal } = useLazyModal(); - const { user } = useAuthContext(); const { notificationSettings: ns, toggleSetting, toggleGroup, getGroupStatus, } = useNotificationSettings(); - const { value: isMajorHeadlinesEnabled } = useConditionalFeature({ - feature: featureMajorHeadlinesPush, - shouldEvaluate: !!user, - }); const onTogglePush = async () => { logEvent({ @@ -125,30 +117,6 @@ const InAppNotificationsTab = (): ReactElement => { } /> - {isMajorHeadlinesEnabled && ( - <> - - - Happening Now - - - - toggleSetting(NotificationType.MajorHeadlineAdded, 'inApp') - } - /> - - - - - )} Activity diff --git a/packages/shared/src/components/notifications/utils.ts b/packages/shared/src/components/notifications/utils.ts index e0ff224a3c5..586d781f5e0 100644 --- a/packages/shared/src/components/notifications/utils.ts +++ b/packages/shared/src/components/notifications/utils.ts @@ -18,7 +18,6 @@ import { AnalyticsIcon, JobIcon, MagicIcon, - MegaphoneIcon, } from '../icons'; import type { NotificationPromptSource } from '../../lib/log'; import { BookmarkReminderIcon } from '../icons/Bookmark/Reminder'; @@ -95,7 +94,6 @@ export enum NotificationType { NewOpportunityMatch = 'new_opportunity_match', WarmIntro = 'warm_intro', ExperienceCompanyEnriched = 'experience_company_enriched', - MajorHeadlineAdded = 'major_headline_added', LiveRoomStarted = 'live_room_started', } @@ -117,7 +115,6 @@ export enum NotificationIconType { Core = 'Core', Analytics = 'Analytics', Opportunity = 'Opportunity', - Megaphone = 'Megaphone', } export const notificationIcon: Record< @@ -141,7 +138,6 @@ export const notificationIcon: Record< [NotificationIconType.Core]: CoreIcon, [NotificationIconType.Analytics]: AnalyticsIcon, [NotificationIconType.Opportunity]: JobIcon, - [NotificationIconType.Megaphone]: MegaphoneIcon, }; export const notificationIconAsPrimary: NotificationIconType[] = [ @@ -167,7 +163,6 @@ export const notificationIconTypeTheme: Record = { [NotificationIconType.Core]: '', [NotificationIconType.Analytics]: 'text-brand-default', [NotificationIconType.Opportunity]: 'text-black', - [NotificationIconType.Megaphone]: 'text-brand-default', }; export const notificationIconStyle: Record< @@ -191,7 +186,6 @@ export const notificationIconStyle: Record< [NotificationIconType.Core]: null, [NotificationIconType.Analytics]: null, [NotificationIconType.Opportunity]: { background: briefButtonBg }, - [NotificationIconType.Megaphone]: null, }; export const notificationTypeTheme: Partial> = @@ -213,7 +207,6 @@ export const notificationTypeTheme: Partial> = [NotificationType.BriefingReady]: 'text-brand-default', [NotificationType.DigestReady]: 'text-brand-default', [NotificationType.UserFollow]: 'text-brand-default', - [NotificationType.MajorHeadlineAdded]: 'text-brand-default', }; export const notificationTypeNotClickable: Partial< diff --git a/packages/shared/src/graphql/actions.ts b/packages/shared/src/graphql/actions.ts index 8415f0da445..999d0ec1513 100644 --- a/packages/shared/src/graphql/actions.ts +++ b/packages/shared/src/graphql/actions.ts @@ -65,7 +65,6 @@ export enum ActionType { DismissBriefCard = 'dismiss_brief_card', DigestUpsell = 'digest_upsell', AskUpsellSearch = 'ask_upsell_search', - DismissedMajorHeadlinesAlertsBanner = 'dismissed_major_headlines_alerts_banner', DismissedNewTabCustomizer = 'dismissed_new_tab_customizer', SeenKeepItOverlay = 'seen_keep_it_overlay', DismissCompanionDemoWidget = 'dismiss_companion_demo_widget', diff --git a/packages/shared/src/hooks/notifications/useMajorHeadlinesSubscription.ts b/packages/shared/src/hooks/notifications/useMajorHeadlinesSubscription.ts deleted file mode 100644 index 611a0d20346..00000000000 --- a/packages/shared/src/hooks/notifications/useMajorHeadlinesSubscription.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { useCallback } from 'react'; -import { NotificationType } from '../../components/notifications/utils'; -import { NotificationPreferenceStatus } from '../../graphql/notifications'; -import useNotificationSettings from './useNotificationSettings'; -import { usePushNotificationMutation } from './usePushNotificationMutation'; -import { usePushNotificationContext } from '../../contexts/PushNotificationContext'; -import { useAuthContext } from '../../contexts/AuthContext'; -import { useLogContext } from '../../contexts/LogContext'; -import { LogEvent, NotificationPromptSource } from '../../lib/log'; - -type MajorHeadlinesOrigin = 'settings' | 'highlights_page' | 'feed_card'; - -type UseMajorHeadlinesSubscriptionResult = { - isSubscribed: boolean; - isPushEnabled: boolean; - isLoading: boolean; - subscribe: (origin: MajorHeadlinesOrigin) => Promise; - unsubscribe: (origin: MajorHeadlinesOrigin) => Promise; -}; - -const ORIGIN_TO_PROMPT_SOURCE: Record< - MajorHeadlinesOrigin, - NotificationPromptSource -> = { - settings: NotificationPromptSource.MajorHeadlinesSettings, - highlights_page: NotificationPromptSource.MajorHeadlinesPage, - feed_card: NotificationPromptSource.MajorHeadlinesCard, -}; - -export const useMajorHeadlinesSubscription = - (): UseMajorHeadlinesSubscriptionResult => { - const { user } = useAuthContext(); - const { logEvent } = useLogContext(); - const { isSubscribed: isPushEnabled } = usePushNotificationContext(); - const { onEnablePush } = usePushNotificationMutation(); - const { - notificationSettings, - isLoadingPreferences, - setNotificationStatusBulk, - } = useNotificationSettings(); - - const settings = - notificationSettings?.[NotificationType.MajorHeadlineAdded]; - const isSubscribed = - settings?.inApp === NotificationPreferenceStatus.Subscribed; - - const subscribe = useCallback( - async (origin: MajorHeadlinesOrigin) => { - if (!user) { - return; - } - - await onEnablePush(ORIGIN_TO_PROMPT_SOURCE[origin]); - - setNotificationStatusBulk([ - { - type: NotificationType.MajorHeadlineAdded, - channel: 'inApp', - status: NotificationPreferenceStatus.Subscribed, - }, - ]); - - logEvent({ - event_name: LogEvent.EnableMajorHeadlinesAlerts, - extra: JSON.stringify({ origin }), - }); - }, - [user, onEnablePush, setNotificationStatusBulk, logEvent], - ); - - const unsubscribe = useCallback( - async (origin: MajorHeadlinesOrigin) => { - if (!user) { - return; - } - - setNotificationStatusBulk([ - { - type: NotificationType.MajorHeadlineAdded, - channel: 'inApp', - status: NotificationPreferenceStatus.Muted, - }, - ]); - - logEvent({ - event_name: LogEvent.DisableMajorHeadlinesAlerts, - extra: JSON.stringify({ origin }), - }); - }, - [user, setNotificationStatusBulk, logEvent], - ); - - return { - isSubscribed, - isPushEnabled, - isLoading: isLoadingPreferences, - subscribe, - unsubscribe, - }; - }; diff --git a/packages/shared/src/lib/featureManagement.ts b/packages/shared/src/lib/featureManagement.ts index 11a2946d5a6..7e401a653bf 100644 --- a/packages/shared/src/lib/featureManagement.ts +++ b/packages/shared/src/lib/featureManagement.ts @@ -33,10 +33,6 @@ export const discussedFeedVersion = new Feature('discussed_feed_version', 2); export const latestFeedVersion = new Feature('latest_feed_version', 2); export const customFeedVersion = new Feature('custom_feed_version', 2); export const featureFeedV2Highlights = new Feature('feed_v2_highlights', false); -export const featureMajorHeadlinesPush = new Feature( - 'major_headlines_push', - false, -); export const featurePostPageHighlights = new Feature( 'post_page_highlights', false, diff --git a/packages/shared/src/lib/log.ts b/packages/shared/src/lib/log.ts index 4ed96ae7058..f9568acd49d 100644 --- a/packages/shared/src/lib/log.ts +++ b/packages/shared/src/lib/log.ts @@ -143,10 +143,6 @@ export enum LogEvent { EnableNotification = 'enable notification', DisableNotification = 'disable notification', ScheduleDigest = 'schedule digest', - EnableMajorHeadlinesAlerts = 'enable major headlines alerts', - DisableMajorHeadlinesAlerts = 'disable major headlines alerts', - ImpressionMajorHeadlinesAlertsBanner = 'impression major headlines alerts banner', - DismissMajorHeadlinesAlertsBanner = 'dismiss major headlines alerts banner', // notifications - end // squads - start ViewSquadInvitation = 'view squad invitation', @@ -678,9 +674,6 @@ export enum NotificationPromptSource { SquadChecklist = 'squad checklist', SourceSubscribe = 'source subscribe', ReadingReminder = 'reading reminder', - MajorHeadlinesSettings = 'major headlines settings', - MajorHeadlinesPage = 'major headlines page', - MajorHeadlinesCard = 'major headlines card', StandupLobby = 'standup lobby', }