pl-fe: migrate notifications reducer

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-11-13 01:14:33 +01:00
parent 471e8ef488
commit 36b27a3410
3 changed files with 18 additions and 19 deletions

View file

@ -187,8 +187,8 @@ const expandNotifications = ({ maxId }: Record<string, any> = {}, done: () => an
} }
} }
if (!maxId && notifications.items.size > 0) { if (!maxId && notifications.items.length > 0) {
params.since_id = notifications.items.first()?.page_max_id; params.since_id = notifications.items[0]?.page_max_id;
} }
dispatch(expandNotificationsRequest()); dispatch(expandNotificationsRequest());
@ -257,7 +257,7 @@ const markReadNotifications = () =>
if (!isLoggedIn(getState)) return; if (!isLoggedIn(getState)) return;
const state = getState(); const state = getState();
const topNotificationId = state.notifications.items.first()?.page_max_id; const topNotificationId = state.notifications.items[0]?.page_max_id;
const lastReadId = state.notifications.lastRead; const lastReadId = state.notifications.lastRead;
if (topNotificationId && (lastReadId === -1 || compareId(topNotificationId, lastReadId) > 0)) { if (topNotificationId && (lastReadId === -1 || compareId(topNotificationId, lastReadId) > 0)) {

View file

@ -30,16 +30,14 @@ const messages = defineMessages({
}); });
const getNotifications = createSelector([ const getNotifications = createSelector([
(state: RootState) => state.notifications.items.toArray(), (state: RootState) => state.notifications.items,
(_, topNotification?: string) => topNotification, (_, topNotification?: string) => topNotification,
], (notifications, topNotificationId) => { ], (notifications, topNotificationId) => {
const allNotifications = notifications.map(([_, notification]) => notification).filter(item => item !== null);
if (topNotificationId) { if (topNotificationId) {
const queuedNotificationCount = allNotifications.findIndex((notification) => const queuedNotificationCount = notifications.findIndex((notification) =>
notification.most_recent_notification_id <= topNotificationId, notification.most_recent_notification_id <= topNotificationId,
); );
const displayedNotifications = allNotifications.slice(queuedNotificationCount); const displayedNotifications = notifications.slice(queuedNotificationCount);
return { return {
queuedNotificationCount, queuedNotificationCount,
@ -49,7 +47,7 @@ const getNotifications = createSelector([
return { return {
queuedNotificationCount: 0, queuedNotificationCount: 0,
displayedNotifications: allNotifications, displayedNotifications: notifications,
}; };
}); });

View file

@ -1,4 +1,3 @@
import { OrderedMap as ImmutableOrderedMap } from 'immutable';
import { create } from 'mutative'; import { create } from 'mutative';
import { import {
@ -28,7 +27,7 @@ import type { Notification as BaseNotification, Markers, NotificationGroup, Pagi
import type { AnyAction } from 'redux'; import type { AnyAction } from 'redux';
interface State { interface State {
items: ImmutableOrderedMap<string, NotificationGroup>; items: Array<NotificationGroup>;
hasMore: boolean; hasMore: boolean;
top: boolean; top: boolean;
unread: number; unread: number;
@ -37,7 +36,7 @@ interface State {
} }
const initialState: State = { const initialState: State = {
items: ImmutableOrderedMap(), items: [],
hasMore: true, hasMore: true,
top: false, top: false,
unread: 0, unread: 0,
@ -47,6 +46,9 @@ const initialState: State = {
const parseId = (id: string | number) => parseInt(id as string, 10); const parseId = (id: string | number) => parseInt(id as string, 10);
const filterUnique = (notification: NotificationGroup, index: number, notifications: Array<NotificationGroup>) =>
notifications.findIndex(({ group_key }) => group_key === notification.group_key) === index;
// For sorting the notifications // For sorting the notifications
const comparator = (a: Pick<NotificationGroup, 'most_recent_notification_id'>, b: Pick<NotificationGroup, 'most_recent_notification_id'>) => { const comparator = (a: Pick<NotificationGroup, 'most_recent_notification_id'>, b: Pick<NotificationGroup, 'most_recent_notification_id'>) => {
const parse = (m: Pick<NotificationGroup, 'most_recent_notification_id'>) => parseId(m.most_recent_notification_id); const parse = (m: Pick<NotificationGroup, 'most_recent_notification_id'>) => parseId(m.most_recent_notification_id);
@ -56,7 +58,7 @@ const comparator = (a: Pick<NotificationGroup, 'most_recent_notification_id'>, b
}; };
// Count how many notifications appear after the given ID (for unread count) // Count how many notifications appear after the given ID (for unread count)
const countFuture = (notifications: ImmutableOrderedMap<string, NotificationGroup>, lastId: string | number) => const countFuture = (notifications: Array<NotificationGroup>, lastId: string | number) =>
notifications.reduce((acc, notification) => { notifications.reduce((acc, notification) => {
if (parseId(notification.group_key) > parseId(lastId)) { if (parseId(notification.group_key) > parseId(lastId)) {
return acc + 1; return acc + 1;
@ -70,13 +72,12 @@ const importNotification = (state: State, notification: NotificationGroup) =>
const top = draft.top; const top = draft.top;
if (!top) draft.unread += 1; if (!top) draft.unread += 1;
draft.items = draft.items.set(notification.group_key, notification).sort(comparator); draft.items = [notification, ...draft.items].toSorted(comparator).filter(filterUnique);
}); });
const expandNormalizedNotifications = (state: State, notifications: NotificationGroup[], next: (() => Promise<PaginatedResponse<BaseNotification>>) | null) => const expandNormalizedNotifications = (state: State, notifications: NotificationGroup[], next: (() => Promise<PaginatedResponse<BaseNotification>>) | null) =>
create(state, (draft) => { create(state, (draft) => {
const items = ImmutableOrderedMap(notifications.map(n => [n.group_key, n])); draft.items = [...notifications, ...draft.items].toSorted(comparator).filter(filterUnique);
draft.items = draft.items.merge(items).sort(comparator);
if (!next) draft.hasMore = false; if (!next) draft.hasMore = false;
draft.isLoading = false; draft.isLoading = false;
@ -84,12 +85,12 @@ const expandNormalizedNotifications = (state: State, notifications: Notification
const filterNotifications = (state: State, relationship: Relationship) => const filterNotifications = (state: State, relationship: Relationship) =>
create(state, (draft) => { create(state, (draft) => {
draft.items = draft.items.filterNot(item => item !== null && item.sample_account_ids.includes(relationship.id)); draft.items = draft.items.filter(item => !item.sample_account_ids.includes(relationship.id));
}); });
const filterNotificationIds = (state: State, accountIds: Array<string>, type?: string) => const filterNotificationIds = (state: State, accountIds: Array<string>, type?: string) =>
create(state, (draft) => { create(state, (draft) => {
const helper = (list: ImmutableOrderedMap<string, NotificationGroup>) => list.filterNot(item => item !== null && accountIds.includes(item.sample_account_ids[0]) && (type === undefined || type === item.type)); const helper = (list: Array<NotificationGroup>) => list.filter(item => !(accountIds.includes(item.sample_account_ids[0]) && (type === undefined || type === item.type)));
draft.items = helper(draft.items); draft.items = helper(draft.items);
}); });
@ -134,7 +135,7 @@ const notifications = (state: State = initialState, action: AccountsAction | Any
}); });
case NOTIFICATIONS_FILTER_SET: case NOTIFICATIONS_FILTER_SET:
return create(state, (draft) => { return create(state, (draft) => {
draft.items = ImmutableOrderedMap(); draft.items = [];
draft.hasMore = true; draft.hasMore = true;
}); });
case NOTIFICATIONS_SCROLL_TOP: case NOTIFICATIONS_SCROLL_TOP: