Add notifications store trimming

Claire 2024-06-27 14:47:37 +02:00
parent 7109805713
commit 1609fcb44b
3 changed files with 26 additions and 4 deletions

View File

@ -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 }) => {

View File

@ -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(() => {

View File

@ -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<NotificationGroupsState>(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) => {