mirror of https://github.com/mastodon/mastodon.git
Add notifications store trimming
parent
7109805713
commit
1609fcb44b
|
@ -113,6 +113,10 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
|
||||||
|
|
||||||
export const loadPending = createAction('notificationGroups/loadPending');
|
export const loadPending = createAction('notificationGroups/loadPending');
|
||||||
|
|
||||||
|
export const updateScrollPosition = createAction<{ top: boolean }>(
|
||||||
|
'notificationGroups/updateScrollPosition',
|
||||||
|
);
|
||||||
|
|
||||||
export const setNotificationsFilter = createAppAsyncThunk(
|
export const setNotificationsFilter = createAppAsyncThunk(
|
||||||
'notifications/filter/set',
|
'notifications/filter/set',
|
||||||
({ filterType }: { filterType: string }, { dispatch }) => {
|
({ filterType }: { filterType: string }, { dispatch }) => {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg?
|
||||||
import {
|
import {
|
||||||
fetchNotifications,
|
fetchNotifications,
|
||||||
fetchNotificationsGap,
|
fetchNotificationsGap,
|
||||||
|
updateScrollPosition,
|
||||||
loadPending,
|
loadPending,
|
||||||
} from 'mastodon/actions/notification_groups';
|
} from 'mastodon/actions/notification_groups';
|
||||||
import { compareId } from 'mastodon/compare_id';
|
import { compareId } from 'mastodon/compare_id';
|
||||||
|
@ -37,7 +38,6 @@ import type { RootState } from 'mastodon/store';
|
||||||
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
|
||||||
import { submitMarkers } from '../../actions/markers';
|
import { submitMarkers } from '../../actions/markers';
|
||||||
import {
|
import {
|
||||||
scrollTopNotifications,
|
|
||||||
// mountNotifications,
|
// mountNotifications,
|
||||||
// unmountNotifications,
|
// unmountNotifications,
|
||||||
markNotificationsAsRead,
|
markNotificationsAsRead,
|
||||||
|
@ -146,7 +146,7 @@ export const Notifications: React.FC<{
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
// dispatch(unmountNotifications());
|
// dispatch(unmountNotifications());
|
||||||
// dispatch(scrollTopNotifications(false));
|
// dispatch(updateScrollPosition({ top: false }));
|
||||||
};
|
};
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
|
@ -171,11 +171,11 @@ export const Notifications: React.FC<{
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
const handleScrollToTop = useDebouncedCallback(() => {
|
const handleScrollToTop = useDebouncedCallback(() => {
|
||||||
dispatch(scrollTopNotifications(true));
|
dispatch(updateScrollPosition({ top: true }));
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
const handleScroll = useDebouncedCallback(() => {
|
const handleScroll = useDebouncedCallback(() => {
|
||||||
dispatch(scrollTopNotifications(false));
|
dispatch(updateScrollPosition({ top: false }));
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import {
|
||||||
fetchNotificationsGap,
|
fetchNotificationsGap,
|
||||||
processNewNotificationForGroups,
|
processNewNotificationForGroups,
|
||||||
loadPending,
|
loadPending,
|
||||||
|
updateScrollPosition,
|
||||||
} from 'mastodon/actions/notification_groups';
|
} from 'mastodon/actions/notification_groups';
|
||||||
import {
|
import {
|
||||||
disconnectTimeline,
|
disconnectTimeline,
|
||||||
|
@ -28,6 +29,8 @@ import {
|
||||||
} from 'mastodon/models/notification_group';
|
} from 'mastodon/models/notification_group';
|
||||||
import type { NotificationGroup } from 'mastodon/models/notification_group';
|
import type { NotificationGroup } from 'mastodon/models/notification_group';
|
||||||
|
|
||||||
|
const NOTIFICATIONS_TRIM_LIMIT = 50;
|
||||||
|
|
||||||
export interface NotificationGap {
|
export interface NotificationGap {
|
||||||
type: 'gap';
|
type: 'gap';
|
||||||
maxId?: string;
|
maxId?: string;
|
||||||
|
@ -37,12 +40,14 @@ export interface NotificationGap {
|
||||||
interface NotificationGroupsState {
|
interface NotificationGroupsState {
|
||||||
groups: (NotificationGroup | NotificationGap)[];
|
groups: (NotificationGroup | NotificationGap)[];
|
||||||
pendingGroups: (NotificationGroup | NotificationGap)[];
|
pendingGroups: (NotificationGroup | NotificationGap)[];
|
||||||
|
scrolledToTop: boolean;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: NotificationGroupsState = {
|
const initialState: NotificationGroupsState = {
|
||||||
groups: [],
|
groups: [],
|
||||||
pendingGroups: [], // holds pending groups in slow mode
|
pendingGroups: [], // holds pending groups in slow mode
|
||||||
|
scrolledToTop: false,
|
||||||
isLoading: 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 =
|
export const notificationsGroupsReducer =
|
||||||
createReducer<NotificationGroupsState>(initialState, (builder) => {
|
createReducer<NotificationGroupsState>(initialState, (builder) => {
|
||||||
builder
|
builder
|
||||||
|
@ -315,6 +327,7 @@ export const notificationsGroupsReducer =
|
||||||
usePendingItems ? state.pendingGroups : state.groups,
|
usePendingItems ? state.pendingGroups : state.groups,
|
||||||
notification,
|
notification,
|
||||||
);
|
);
|
||||||
|
trimNotifications(state);
|
||||||
})
|
})
|
||||||
.addCase(disconnectTimeline, (state, action) => {
|
.addCase(disconnectTimeline, (state, action) => {
|
||||||
if (action.payload.timeline === 'home') {
|
if (action.payload.timeline === 'home') {
|
||||||
|
@ -368,12 +381,17 @@ export const notificationsGroupsReducer =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
trimNotifications(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then build the consolidated list and clear pending groups
|
// Then build the consolidated list and clear pending groups
|
||||||
state.groups = state.pendingGroups.concat(state.groups);
|
state.groups = state.pendingGroups.concat(state.groups);
|
||||||
state.pendingGroups = [];
|
state.pendingGroups = [];
|
||||||
})
|
})
|
||||||
|
.addCase(updateScrollPosition, (state, action) => {
|
||||||
|
state.scrolledToTop = action.payload.top;
|
||||||
|
trimNotifications(state);
|
||||||
|
})
|
||||||
.addMatcher(
|
.addMatcher(
|
||||||
isAnyOf(authorizeFollowRequestSuccess, rejectFollowRequestSuccess),
|
isAnyOf(authorizeFollowRequestSuccess, rejectFollowRequestSuccess),
|
||||||
(state, action) => {
|
(state, action) => {
|
||||||
|
|
Loading…
Reference in New Issue