diff --git a/src/components/NotificationRow.tsx b/src/components/NotificationRow.tsx index 9d802f0fd..e5d211c0c 100644 --- a/src/components/NotificationRow.tsx +++ b/src/components/NotificationRow.tsx @@ -23,10 +23,12 @@ import { NotificationHeader } from './notification/NotificationHeader'; interface INotificationRow { notification: Notification; + isRead?: boolean; } export const NotificationRow: FC = ({ notification, + isRead = false, }: INotificationRow) => { const { settings, @@ -56,6 +58,7 @@ export const NotificationRow: FC = ({ removeNotificationFromState, settings, ]); + const unsubscribeFromThread = (event: MouseEvent) => { // Don't trigger onClick of parent element. event.stopPropagation(); @@ -88,6 +91,7 @@ export const NotificationRow: FC = ({ animateExit && 'translate-x-full opacity-0 transition duration-[350ms] ease-in-out', showAsRead && Opacity.READ, + isRead && Opacity.READ, )} >
{ it('should mark a repo as read', () => { render( - + , ); @@ -71,7 +73,9 @@ describe('components/Repository.tsx', () => { it('should mark a repo as done', () => { render( - + , ); diff --git a/src/components/RepositoryNotifications.tsx b/src/components/RepositoryNotifications.tsx index c0d49d267..a7f1e9973 100644 --- a/src/components/RepositoryNotifications.tsx +++ b/src/components/RepositoryNotifications.tsx @@ -5,13 +5,7 @@ import { MarkGithubIcon, ReadIcon, } from '@primer/octicons-react'; -import { - type FC, - type MouseEvent, - useCallback, - useContext, - useState, -} from 'react'; +import { type FC, type MouseEvent, useContext, useState } from 'react'; import { AppContext } from '../context/App'; import { Opacity, Size } from '../types'; import type { Notification } from '../typesGitHub'; @@ -31,22 +25,15 @@ export const RepositoryNotifications: FC = ({ repoName, repoNotifications, }) => { - const { markRepoNotificationsRead, markRepoNotificationsDone } = + const { settings, markRepoNotificationsRead, markRepoNotificationsDone } = useContext(AppContext); - - const markRepoAsRead = useCallback(() => { - markRepoNotificationsRead(repoNotifications[0]); - }, [repoNotifications, markRepoNotificationsRead]); - - const markRepoAsDone = useCallback(() => { - markRepoNotificationsDone(repoNotifications[0]); - }, [repoNotifications, markRepoNotificationsDone]); - - const avatarUrl = repoNotifications[0].repository.owner.avatar_url; - + const [animateExit, setAnimateExit] = useState(false); + const [showAsRead, setShowAsRead] = useState(false); const [showRepositoryNotifications, setShowRepositoryNotifications] = useState(true); + const avatarUrl = repoNotifications[0].repository.owner.avatar_url; + const toggleRepositoryNotifications = () => { setShowRepositoryNotifications(!showRepositoryNotifications); }; @@ -68,7 +55,9 @@ export const RepositoryNotifications: FC = ({
= ({ title="Mark Repository as Done" icon={CheckIcon} size={Size.MEDIUM} - onClick={markRepoAsDone} + onClick={(event: MouseEvent) => { + // Don't trigger onClick of parent element. + event.stopPropagation(); + setAnimateExit(!settings.delayNotificationState); + setShowAsRead(settings.delayNotificationState); + markRepoNotificationsDone(repoNotifications[0]); + }} /> ) => { + // Don't trigger onClick of parent element. + event.stopPropagation(); + setAnimateExit(!settings.delayNotificationState); + setShowAsRead(settings.delayNotificationState); + markRepoNotificationsRead(repoNotifications[0]); + }} /> = ({ {showRepositoryNotifications && repoNotifications.map((notification) => ( - + ))} ); diff --git a/src/hooks/useNotifications.ts b/src/hooks/useNotifications.ts index 2b4b604c4..ece638730 100644 --- a/src/hooks/useNotifications.ts +++ b/src/hooks/useNotifications.ts @@ -154,7 +154,7 @@ export const useNotifications = (): NotificationsState => { ); const markRepoNotificationsRead = useCallback( - async (_state: GitifyState, notification: Notification) => { + async (state: GitifyState, notification: Notification) => { setStatus('loading'); const repoSlug = notification.repository.full_name; @@ -166,7 +166,9 @@ export const useNotifications = (): NotificationsState => { hostname, notification.account.token, ); + const updatedNotifications = removeNotifications( + state.settings, notification, notifications, ); @@ -209,6 +211,7 @@ export const useNotifications = (): NotificationsState => { } const updatedNotifications = removeNotifications( + state.settings, notification, notifications, ); diff --git a/src/utils/remove-notifications.test.ts b/src/utils/remove-notifications.test.ts index 9ed87a90c..98d476de8 100644 --- a/src/utils/remove-notifications.test.ts +++ b/src/utils/remove-notifications.test.ts @@ -2,6 +2,7 @@ import { mockAccountNotifications, mockSingleAccountNotifications, } from '../__mocks__/notifications-mocks'; +import { mockSettings } from '../__mocks__/state-mocks'; import { mockSingleNotification } from './api/__mocks__/response-mocks'; import { removeNotifications } from './remove-notifications'; @@ -10,6 +11,7 @@ describe('utils/remove-notifications.ts', () => { expect(mockSingleAccountNotifications[0].notifications.length).toBe(1); const result = removeNotifications( + mockSettings, mockSingleNotification, mockSingleAccountNotifications, ); @@ -22,6 +24,7 @@ describe('utils/remove-notifications.ts', () => { expect(mockAccountNotifications[1].notifications.length).toBe(2); const result = removeNotifications( + mockSettings, mockSingleNotification, mockAccountNotifications, ); @@ -29,4 +32,16 @@ describe('utils/remove-notifications.ts', () => { expect(result[0].notifications.length).toBe(0); expect(result[1].notifications.length).toBe(2); }); + + it('should skip notification removal if delay state enabled', () => { + expect(mockSingleAccountNotifications[0].notifications.length).toBe(1); + + const result = removeNotifications( + { ...mockSettings, delayNotificationState: true }, + mockSingleNotification, + mockSingleAccountNotifications, + ); + + expect(result[0].notifications.length).toBe(1); + }); }); diff --git a/src/utils/remove-notifications.ts b/src/utils/remove-notifications.ts index ee819ebf3..507d46fa0 100644 --- a/src/utils/remove-notifications.ts +++ b/src/utils/remove-notifications.ts @@ -1,11 +1,16 @@ -import type { AccountNotifications } from '../types'; +import type { AccountNotifications, SettingsState } from '../types'; import type { Notification } from '../typesGitHub'; import { getAccountUUID } from './auth/utils'; export function removeNotifications( + settings: SettingsState, notification: Notification, notifications: AccountNotifications[], ): AccountNotifications[] { + if (settings.delayNotificationState) { + return notifications; + } + const repoSlug = notification.repository.full_name; const accountIndex = notifications.findIndex(