[Glitch] Reload notifications when accepted notifications are merged (streaming only)
Port 53c183f899
to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
shrike
parent
99ffae7d44
commit
bfd01110d8
|
@ -138,8 +138,18 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
|
|||
|
||||
export const loadPending = createAction('notificationGroups/loadPending');
|
||||
|
||||
export const updateScrollPosition = createAction<{ top: boolean }>(
|
||||
export const updateScrollPosition = createAppAsyncThunk(
|
||||
'notificationGroups/updateScrollPosition',
|
||||
({ top }: { top: boolean }, { dispatch, getState }) => {
|
||||
if (
|
||||
top &&
|
||||
getState().notificationGroups.mergedNotifications === 'needs-reload'
|
||||
) {
|
||||
void dispatch(fetchNotifications());
|
||||
}
|
||||
|
||||
return { top };
|
||||
},
|
||||
);
|
||||
|
||||
export const setNotificationsFilter = createAppAsyncThunk(
|
||||
|
@ -165,5 +175,34 @@ export const markNotificationsAsRead = createAction(
|
|||
'notificationGroups/markAsRead',
|
||||
);
|
||||
|
||||
export const mountNotifications = createAction('notificationGroups/mount');
|
||||
export const mountNotifications = createAppAsyncThunk(
|
||||
'notificationGroups/mount',
|
||||
(_, { dispatch, getState }) => {
|
||||
const state = getState();
|
||||
|
||||
if (
|
||||
state.notificationGroups.mounted === 0 &&
|
||||
state.notificationGroups.mergedNotifications === 'needs-reload'
|
||||
) {
|
||||
void dispatch(fetchNotifications());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export const unmountNotifications = createAction('notificationGroups/unmount');
|
||||
|
||||
export const refreshStaleNotificationGroups = createAppAsyncThunk<{
|
||||
deferredRefresh: boolean;
|
||||
}>('notificationGroups/refreshStale', (_, { dispatch, getState }) => {
|
||||
const state = getState();
|
||||
|
||||
if (
|
||||
state.notificationGroups.scrolledToTop ||
|
||||
!state.notificationGroups.mounted
|
||||
) {
|
||||
void dispatch(fetchNotifications());
|
||||
return { deferredRefresh: false };
|
||||
}
|
||||
|
||||
return { deferredRefresh: true };
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
deleteAnnouncement,
|
||||
} from './announcements';
|
||||
import { updateConversations } from './conversations';
|
||||
import { processNewNotificationForGroups } from './notification_groups';
|
||||
import { processNewNotificationForGroups, refreshStaleNotificationGroups } from './notification_groups';
|
||||
import { updateNotifications, expandNotifications } from './notifications';
|
||||
import { updateStatus } from './statuses';
|
||||
import {
|
||||
|
@ -108,6 +108,14 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'notifications_merged':
|
||||
const state = getState();
|
||||
if (state.notifications.top || !state.notifications.mounted)
|
||||
dispatch(expandNotifications({ forceLoad: true, maxId: undefined }));
|
||||
if(state.settings.getIn(['notifications', 'groupingBeta'], false)) {
|
||||
dispatch(refreshStaleNotificationGroups());
|
||||
}
|
||||
break;
|
||||
case 'conversation':
|
||||
// @ts-expect-error
|
||||
dispatch(updateConversations(JSON.parse(data.payload)));
|
||||
|
|
|
@ -81,7 +81,11 @@ export const Notifications: React.FC<{
|
|||
|
||||
const anyPendingNotification = useAppSelector(selectAnyPendingNotification);
|
||||
|
||||
const isUnread = unreadNotificationsCount > 0;
|
||||
const needsReload = useAppSelector(
|
||||
(state) => state.notificationGroups.mergedNotifications === 'needs-reload',
|
||||
);
|
||||
|
||||
const isUnread = unreadNotificationsCount > 0 || needsReload;
|
||||
|
||||
const canMarkAsRead =
|
||||
useAppSelector(selectSettingsNotificationsShowUnread) &&
|
||||
|
@ -118,11 +122,11 @@ export const Notifications: React.FC<{
|
|||
|
||||
// Keep track of mounted components for unread notification handling
|
||||
useEffect(() => {
|
||||
dispatch(mountNotifications());
|
||||
void dispatch(mountNotifications());
|
||||
|
||||
return () => {
|
||||
dispatch(unmountNotifications());
|
||||
dispatch(updateScrollPosition({ top: false }));
|
||||
void dispatch(updateScrollPosition({ top: false }));
|
||||
};
|
||||
}, [dispatch]);
|
||||
|
||||
|
@ -147,11 +151,11 @@ export const Notifications: React.FC<{
|
|||
}, [dispatch]);
|
||||
|
||||
const handleScrollToTop = useDebouncedCallback(() => {
|
||||
dispatch(updateScrollPosition({ top: true }));
|
||||
void dispatch(updateScrollPosition({ top: true }));
|
||||
}, 100);
|
||||
|
||||
const handleScroll = useDebouncedCallback(() => {
|
||||
dispatch(updateScrollPosition({ top: false }));
|
||||
void dispatch(updateScrollPosition({ top: false }));
|
||||
}, 100);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
markNotificationsAsRead,
|
||||
mountNotifications,
|
||||
unmountNotifications,
|
||||
refreshStaleNotificationGroups,
|
||||
} from 'flavours/glitch/actions/notification_groups';
|
||||
import {
|
||||
disconnectTimeline,
|
||||
|
@ -51,6 +52,7 @@ interface NotificationGroupsState {
|
|||
readMarkerId: string;
|
||||
mounted: number;
|
||||
isTabVisible: boolean;
|
||||
mergedNotifications: 'ok' | 'pending' | 'needs-reload';
|
||||
}
|
||||
|
||||
const initialState: NotificationGroupsState = {
|
||||
|
@ -58,6 +60,8 @@ const initialState: NotificationGroupsState = {
|
|||
pendingGroups: [], // holds pending groups in slow mode
|
||||
scrolledToTop: false,
|
||||
isLoading: false,
|
||||
// this is used to track whether we need to refresh notifications after accepting requests
|
||||
mergedNotifications: 'ok',
|
||||
// The following properties are used to track unread notifications
|
||||
lastReadId: '0', // used internally for unread notifications
|
||||
readMarkerId: '0', // user-facing and updated when focus changes
|
||||
|
@ -301,6 +305,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
|
|||
json.type === 'gap' ? json : createNotificationGroupFromJSON(json),
|
||||
);
|
||||
state.isLoading = false;
|
||||
state.mergedNotifications = 'ok';
|
||||
updateLastReadId(state);
|
||||
})
|
||||
.addCase(fetchNotificationsGap.fulfilled, (state, action) => {
|
||||
|
@ -455,7 +460,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
|
|||
state.groups = state.pendingGroups.concat(state.groups);
|
||||
state.pendingGroups = [];
|
||||
})
|
||||
.addCase(updateScrollPosition, (state, action) => {
|
||||
.addCase(updateScrollPosition.fulfilled, (state, action) => {
|
||||
state.scrolledToTop = action.payload.top;
|
||||
updateLastReadId(state);
|
||||
trimNotifications(state);
|
||||
|
@ -482,7 +487,7 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
|
|||
action.payload.markers.notifications.last_read_id;
|
||||
}
|
||||
})
|
||||
.addCase(mountNotifications, (state) => {
|
||||
.addCase(mountNotifications.fulfilled, (state) => {
|
||||
state.mounted += 1;
|
||||
commitLastReadId(state);
|
||||
updateLastReadId(state);
|
||||
|
@ -498,6 +503,10 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
|
|||
.addCase(unfocusApp, (state) => {
|
||||
state.isTabVisible = false;
|
||||
})
|
||||
.addCase(refreshStaleNotificationGroups.fulfilled, (state, action) => {
|
||||
if (action.payload.deferredRefresh)
|
||||
state.mergedNotifications = 'needs-reload';
|
||||
})
|
||||
.addMatcher(
|
||||
isAnyOf(authorizeFollowRequestSuccess, rejectFollowRequestSuccess),
|
||||
(state, action) => {
|
||||
|
|
Loading…
Reference in New Issue