Skip to content

Commit

Permalink
feat: implement mark as unread for individual notifications (#62)
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Setch <adam.setch@outlook.com>
  • Loading branch information
setchy authored Sep 19, 2024
1 parent a95c647 commit 550589d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 25 deletions.
67 changes: 45 additions & 22 deletions src/components/NotificationRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const NotificationRow: FC<INotificationRow> = ({
isAnimated = false,
isRead = false,
}: INotificationRow) => {
const { markNotificationsRead, settings } = useContext(AppContext);
const { markNotificationsRead, markNotificationsUnread, settings } =
useContext(AppContext);
const [animateExit, setAnimateExit] = useState(false);
const [showAsRead, setShowAsRead] = useState(false);

Expand Down Expand Up @@ -121,27 +122,49 @@ export const NotificationRow: FC<INotificationRow> = ({
</div>
</div>

{!animateExit && !isRead && notification.unread && (
<Flex alignItems="center">
<Tooltip content="Mark as read" position="left">
<IconButton
label="Mark as read"
title="Mark as read"
icon={(iconProps) => (
<HipchatMediaAttachmentCountIcon {...iconProps} size="small" />
)}
shape="circle"
spacing="compact"
appearance="subtle"
onClick={() => {
setAnimateExit(!settings.delayNotificationState);
setShowAsRead(settings.delayNotificationState);
markNotificationsRead([notification]);
}}
/>
</Tooltip>
</Flex>
)}
{!animateExit &&
(notification.unread ? (
<Flex alignItems="center">
<Tooltip content="Mark as read" position="left">
<IconButton
label="Mark as read"
title="Mark as read"
icon={(iconProps) => (
<HipchatMediaAttachmentCountIcon
{...iconProps}
size="small"
/>
)}
shape="circle"
spacing="compact"
appearance="subtle"
onClick={() => {
setAnimateExit(!settings.delayNotificationState);
setShowAsRead(settings.delayNotificationState);
markNotificationsRead([notification]);
}}
/>
</Tooltip>
</Flex>
) : (
<Flex alignItems="center">
<Tooltip content="Mark as unread" position="left">
<IconButton
label="Mark as unread"
title="Mark as unread"
icon={() => null}
shape="circle"
spacing="compact"
appearance="subtle"
onClick={() => {
markNotificationsUnread([notification]);
notification.unread = true;
notification.readState = 'unread';
}}
/>
</Tooltip>
</Flex>
))}
</div>
);
};
12 changes: 10 additions & 2 deletions src/context/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ interface AppContextState {
markNotificationsRead: (
notifications: AtlassifyNotification[],
) => Promise<void>;
markNotificationUnread: (
notification: AtlassifyNotification,
markNotificationsUnread: (
notifications: AtlassifyNotification[],
) => Promise<void>;

settings: SettingsState;
Expand All @@ -120,6 +120,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
status,
globalError,
markNotificationsRead,
markNotificationsUnread,
} = useNotifications();

useEffect(() => {
Expand Down Expand Up @@ -257,6 +258,12 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
[auth, settings, markNotificationsRead],
);

const markNotificationsUnreadWithAccounts = useCallback(
async (notifications: AtlassifyNotification[]) =>
await markNotificationsUnread({ auth, settings }, notifications),
[auth, settings, markNotificationsUnread],
);

return (
<AppContext.Provider
value={{
Expand All @@ -272,6 +279,7 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
fetchNotifications: fetchNotificationsWithAccounts,

markNotificationsRead: markNotificationsReadWithAccounts,
markNotificationsUnread: markNotificationsUnreadWithAccounts,

settings,
clearFilters,
Expand Down
43 changes: 42 additions & 1 deletion src/hooks/useNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import type {
AtlassifyState,
Status,
} from '../types';
import { markNotificationsAsRead } from '../utils/api/client';
import {
markNotificationsAsRead,
markNotificationsAsUnread,
} from '../utils/api/client';
import { triggerNativeNotifications } from '../utils/notifications/native';
import {
getAllNotifications,
Expand All @@ -24,6 +27,10 @@ interface NotificationsState {
state: AtlassifyState,
notifications: AtlassifyNotification[],
) => Promise<void>;
markNotificationsUnread: (
state: AtlassifyState,
notifications: AtlassifyNotification[],
) => Promise<void>;
status: Status;
globalError: AtlassifyError;
}
Expand Down Expand Up @@ -116,6 +123,39 @@ export const useNotifications = (): NotificationsState => {
[notifications],
);

const markNotificationsUnread = useCallback(
async (
_state: AtlassifyState,
unreadNotifications: AtlassifyNotification[],
) => {
setStatus('loading');

const account = unreadNotifications[0].account;
const notificationIDs = unreadNotifications.map(
(notification) => notification.id,
);

try {
await markNotificationsAsUnread(account, notificationIDs);

// FIXME
// const updatedNotifications = unreadNotifications.map((notification) => {
// notification.unread = true;
// notification.readState = 'unread';
// return notification;
// });

// setNotifications(updatedNotifications);
// setTrayIconColor(updatedNotifications);
} catch (err) {
log.error('Error occurred while marking notifications as read', err);
}

setStatus('success');
},
[notifications],
);

return {
status,
globalError,
Expand All @@ -124,5 +164,6 @@ export const useNotifications = (): NotificationsState => {
removeAccountNotifications,
fetchNotifications,
markNotificationsRead,
markNotificationsUnread,
};
};

0 comments on commit 550589d

Please sign in to comment.