diff --git a/app/javascript/mastodon/features/notifications_v2/index.tsx b/app/javascript/mastodon/features/notifications_v2/index.tsx
index 7feefe6358..471649d989 100644
--- a/app/javascript/mastodon/features/notifications_v2/index.tsx
+++ b/app/javascript/mastodon/features/notifications_v2/index.tsx
@@ -19,6 +19,7 @@ import { Icon } from 'mastodon/components/icon';
import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator';
import { useIdentity } from 'mastodon/identity_context';
import type { NotificationGap } from 'mastodon/reducers/notifications_groups';
+import { selectUnreadNotificationsGroupsCount } from 'mastodon/selectors/notifications';
import {
selectNeedsNotificationPermission,
selectSettingsNotificationsExcludedTypes,
@@ -35,8 +36,8 @@ import {
expandNotifications,
scrollTopNotifications,
loadPending,
- mountNotifications,
- unmountNotifications,
+ // mountNotifications,
+ // unmountNotifications,
markNotificationsAsRead,
} from '../../actions/notifications';
import Column from '../../components/column';
@@ -81,52 +82,35 @@ const getNotifications = createSelector(
);
// const mapStateToProps = (state) => ({
-// isUnread:
-// state.getIn(['notifications', 'unread']) > 0 ||
-// state.getIn(['notifications', 'pendingItems']).size > 0,
// numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList())
// .size,
-// canMarkAsRead:
-// state.getIn(['settings', 'notifications', 'showUnread']) &&
-// state.getIn(['notifications', 'readMarkerId']) !== '0' &&
-// getNotifications(state).some(
-// (item) =>
-// item !== null &&
-// compareId(
-// item.get('id'),
-// state.getIn(['notifications', 'readMarkerId']),
-// ) > 0,
-// ),
// });
export const Notifications: React.FC<{
columnId?: string;
- isUnread?: boolean;
multiColumn?: boolean;
numPending: number;
-}> = ({ isUnread, columnId, multiColumn, numPending }) => {
+}> = ({ columnId, multiColumn, numPending }) => {
const intl = useIntl();
const notifications = useAppSelector(getNotifications);
const dispatch = useAppDispatch();
const isLoading = useAppSelector((s) => s.notificationsGroups.isLoading);
const hasMore = useAppSelector((s) => s.notificationsGroups.hasMore);
- const readMarkerId = useAppSelector(
- (s) => s.notificationsGroups.readMarkerId,
- );
+
const lastReadId = useAppSelector((s) =>
- selectSettingsNotificationsShowUnread(s)
- ? s.notificationsGroups.readMarkerId
- : '0',
+ selectSettingsNotificationsShowUnread(s) ? s.markers.notifications : '0',
);
- const canMarkAsRead = useAppSelector(
- (s) =>
- selectSettingsNotificationsShowUnread(s) &&
- s.notificationsGroups.readMarkerId !== '0' &&
- notifications.some(
- (item) =>
- item.type !== 'gap' && compareId(item.group_key, readMarkerId) > 0,
- ),
+
+ const unreadNotificationsCount = useAppSelector(
+ selectUnreadNotificationsGroupsCount,
);
+
+ const isUnread = unreadNotificationsCount > 0;
+
+ const canMarkAsRead =
+ useAppSelector(selectSettingsNotificationsShowUnread) &&
+ unreadNotificationsCount > 0;
+
const needsNotificationPermission = useAppSelector(
selectNeedsNotificationPermission,
);
@@ -157,14 +141,14 @@ export const Notifications: React.FC<{
}, []);
useEffect(() => {
- dispatch(mountNotifications());
+ // dispatch(mountNotifications());
// FIXME: remove once this becomes the main implementation
void dispatch(fetchNotifications());
return () => {
- dispatch(unmountNotifications());
- dispatch(scrollTopNotifications(false));
+ // dispatch(unmountNotifications());
+ // dispatch(scrollTopNotifications(false));
};
}, [dispatch]);
@@ -282,7 +266,9 @@ export const Notifications: React.FC<{
onMoveUp={handleMoveUp}
onMoveDown={handleMoveDown}
unread={
- lastReadId !== '0' && compareId(item.group_key, lastReadId) > 0
+ lastReadId !== '0' &&
+ !!item.page_max_id &&
+ compareId(item.page_max_id, lastReadId) > 0
}
/>
),
diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx
index ff90eef359..13f1b4f083 100644
--- a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx
+++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx
@@ -34,6 +34,7 @@ import { NavigationPortal } from 'mastodon/components/navigation_portal';
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
import { timelinePreview, trendsEnabled } from 'mastodon/initial_state';
import { transientSingleColumn } from 'mastodon/is_mobile';
+import { selectUnreadNotificationsGroupsCount } from 'mastodon/selectors/notifications';
import ColumnLink from './column_link';
import DisabledAccountBanner from './disabled_account_banner';
@@ -62,14 +63,27 @@ const NotificationsLink = () => {
const count = useSelector(state => state.getIn(['notifications', 'unread']));
const intl = useIntl();
+ const newCount = useSelector(selectUnreadNotificationsGroupsCount);
+
return (
- }
- activeIcon={}
- text={intl.formatMessage(messages.notifications)}
- />
+ <>
+ }
+ activeIcon={}
+ text={intl.formatMessage(messages.notifications)}
+ />
+ }
+ activeIcon={}
+ text={"New Notifications"}
+ />
+ >
);
};
diff --git a/app/javascript/mastodon/reducers/notifications_groups.ts b/app/javascript/mastodon/reducers/notifications_groups.ts
index a9b73ff046..aa869bf9b5 100644
--- a/app/javascript/mastodon/reducers/notifications_groups.ts
+++ b/app/javascript/mastodon/reducers/notifications_groups.ts
@@ -31,18 +31,14 @@ export interface NotificationGap {
interface NotificationGroupsState {
groups: (NotificationGroup | NotificationGap)[];
- unread: number;
isLoading: boolean;
hasMore: boolean;
- readMarkerId: string;
}
const initialState: NotificationGroupsState = {
groups: [],
- unread: 0,
isLoading: false,
hasMore: false,
- readMarkerId: '0',
};
function removeNotificationsForAccounts(
@@ -172,7 +168,6 @@ export const notificationsGroupsReducer =
})
.addCase(clearNotifications.pending, (state) => {
state.groups = [];
- state.unread = 0;
state.hasMore = false;
})
.addCase(blockAccountSuccess, (state, action) => {
diff --git a/app/javascript/mastodon/selectors/notifications.ts b/app/javascript/mastodon/selectors/notifications.ts
new file mode 100644
index 0000000000..ced25fcafb
--- /dev/null
+++ b/app/javascript/mastodon/selectors/notifications.ts
@@ -0,0 +1,19 @@
+import { createSelector } from '@reduxjs/toolkit';
+
+import { compareId } from 'mastodon/compare_id';
+import type { RootState } from 'mastodon/store';
+
+export const selectUnreadNotificationsGroupsCount = createSelector(
+ [
+ (s: RootState) => s.markers.notifications,
+ (s: RootState) => s.notificationsGroups.groups,
+ ],
+ (notificationMarker, groups) => {
+ return groups.filter(
+ (group) =>
+ group.type !== 'gap' &&
+ group.page_max_id &&
+ compareId(group.page_max_id, notificationMarker) > 0,
+ ).length;
+ },
+);