From 1609fcb44b19e9ed2d4698ae1156d40e46cba844 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 27 Jun 2024 14:47:37 +0200 Subject: [PATCH] Add notifications store trimming --- .../mastodon/actions/notification_groups.ts | 4 ++++ .../features/notifications_v2/index.tsx | 8 ++++---- .../mastodon/reducers/notifications_groups.ts | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/actions/notification_groups.ts b/app/javascript/mastodon/actions/notification_groups.ts index 9a1b5158fa..4cfc05f8d8 100644 --- a/app/javascript/mastodon/actions/notification_groups.ts +++ b/app/javascript/mastodon/actions/notification_groups.ts @@ -113,6 +113,10 @@ export const processNewNotificationForGroups = createAppAsyncThunk( export const loadPending = createAction('notificationGroups/loadPending'); +export const updateScrollPosition = createAction<{ top: boolean }>( + 'notificationGroups/updateScrollPosition', +); + export const setNotificationsFilter = createAppAsyncThunk( 'notifications/filter/set', ({ filterType }: { filterType: string }, { dispatch }) => { diff --git a/app/javascript/mastodon/features/notifications_v2/index.tsx b/app/javascript/mastodon/features/notifications_v2/index.tsx index e497f26f66..0750a53e3c 100644 --- a/app/javascript/mastodon/features/notifications_v2/index.tsx +++ b/app/javascript/mastodon/features/notifications_v2/index.tsx @@ -13,6 +13,7 @@ import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg? import { fetchNotifications, fetchNotificationsGap, + updateScrollPosition, loadPending, } from 'mastodon/actions/notification_groups'; import { compareId } from 'mastodon/compare_id'; @@ -37,7 +38,6 @@ import type { RootState } from 'mastodon/store'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { submitMarkers } from '../../actions/markers'; import { - scrollTopNotifications, // mountNotifications, // unmountNotifications, markNotificationsAsRead, @@ -146,7 +146,7 @@ export const Notifications: React.FC<{ return () => { // dispatch(unmountNotifications()); - // dispatch(scrollTopNotifications(false)); + // dispatch(updateScrollPosition({ top: false })); }; }, [dispatch]); @@ -171,11 +171,11 @@ export const Notifications: React.FC<{ }, [dispatch]); const handleScrollToTop = useDebouncedCallback(() => { - dispatch(scrollTopNotifications(true)); + dispatch(updateScrollPosition({ top: true })); }, 100); const handleScroll = useDebouncedCallback(() => { - dispatch(scrollTopNotifications(false)); + dispatch(updateScrollPosition({ top: false })); }, 100); useEffect(() => { diff --git a/app/javascript/mastodon/reducers/notifications_groups.ts b/app/javascript/mastodon/reducers/notifications_groups.ts index 78bfda831e..4b6af8f934 100644 --- a/app/javascript/mastodon/reducers/notifications_groups.ts +++ b/app/javascript/mastodon/reducers/notifications_groups.ts @@ -13,6 +13,7 @@ import { fetchNotificationsGap, processNewNotificationForGroups, loadPending, + updateScrollPosition, } from 'mastodon/actions/notification_groups'; import { disconnectTimeline, @@ -28,6 +29,8 @@ import { } from 'mastodon/models/notification_group'; import type { NotificationGroup } from 'mastodon/models/notification_group'; +const NOTIFICATIONS_TRIM_LIMIT = 50; + export interface NotificationGap { type: 'gap'; maxId?: string; @@ -37,12 +40,14 @@ export interface NotificationGap { interface NotificationGroupsState { groups: (NotificationGroup | NotificationGap)[]; pendingGroups: (NotificationGroup | NotificationGap)[]; + scrolledToTop: boolean; isLoading: boolean; } const initialState: NotificationGroupsState = { groups: [], pendingGroups: [], // holds pending groups in slow mode + scrolledToTop: false, isLoading: false, }; @@ -220,6 +225,13 @@ function processNewNotification( } } +function trimNotifications(state: NotificationGroupsState) { + // TODO: is there more to it? + if (state.scrolledToTop) { + state.groups.splice(NOTIFICATIONS_TRIM_LIMIT); + } +} + export const notificationsGroupsReducer = createReducer(initialState, (builder) => { builder @@ -315,6 +327,7 @@ export const notificationsGroupsReducer = usePendingItems ? state.pendingGroups : state.groups, notification, ); + trimNotifications(state); }) .addCase(disconnectTimeline, (state, action) => { if (action.payload.timeline === 'home') { @@ -368,12 +381,17 @@ export const notificationsGroupsReducer = } } } + trimNotifications(state); }); // Then build the consolidated list and clear pending groups state.groups = state.pendingGroups.concat(state.groups); state.pendingGroups = []; }) + .addCase(updateScrollPosition, (state, action) => { + state.scrolledToTop = action.payload.top; + trimNotifications(state); + }) .addMatcher( isAnyOf(authorizeFollowRequestSuccess, rejectFollowRequestSuccess), (state, action) => {