Implement Redux state for the new grouped notifications API

This is a big WIP
Renaud Chaput 2024-05-21 01:09:59 +02:00
parent 3939352e92
commit f77394bebd
No known key found for this signature in database
GPG Key ID: BCFC859D49B46990
5 changed files with 187 additions and 0 deletions

View File

@ -0,0 +1,36 @@
import { apiFetchNotifications } from 'mastodon/api/notifications';
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
import type { ApiStatusJSON } from 'mastodon/api_types/statuses';
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
import { importFetchedAccounts, importFetchedStatuses } from './importer';
export const fetchNotifications = createDataLoadingThunk(
'notificationGroups/fetch',
apiFetchNotifications,
(notifications, { dispatch }) => {
const fetchedAccounts: ApiAccountJSON[] = [];
const fetchedStatuses: ApiStatusJSON[] = [];
notifications.forEach((notification) => {
if ('sample_accounts' in notification) {
fetchedAccounts.push(...notification.sample_accounts);
}
// if (notification.type === 'admin.report') {
// fetchedAccounts.push(...notification.report.target_account);
// }
if ('target_status' in notification) {
fetchedStatuses.push(notification.target_status);
}
});
if (fetchedAccounts.length > 0)
dispatch(importFetchedAccounts(fetchedAccounts));
if (fetchedStatuses.length > 0) importFetchedStatuses(fetchedStatuses);
// dispatch(submitMarkers());
},
);

View File

@ -0,0 +1,6 @@
import { apiRequest } from 'mastodon/api';
import type { NotificationGroupJSON } from 'mastodon/api_types/notifications';
export const apiFetchNotifications = () => {
return apiRequest<NotificationGroupJSON[]>('GET', '/v2_alpha/notifications');
};

View File

@ -0,0 +1,60 @@
// See app/serializers/rest/notification_group_serializer.rb
import type { ApiAccountJSON } from './accounts';
import type { ApiStatusJSON } from './statuses';
// See app/model/notification.rb
export type NotificationWithStatusType =
| 'favourite'
| 'reblog'
| 'status'
| 'mention'
| 'poll'
| 'update';
export type NotificationType =
| NotificationWithStatusType
| 'follow'
| 'follow_request'
| 'moderation_warning'
| 'severed_relationships'
| 'admin.sign_up'
| 'admin.report';
export interface BaseNotificationGroupJSON {
group_key: string;
notifications_count: number;
type: NotificationType;
sample_accounts: ApiAccountJSON[];
latest_page_notification_at?: string;
page_min_id?: string;
page_max_id?: string;
}
interface NotificationGroupWithStatusJSON extends BaseNotificationGroupJSON {
type: NotificationWithStatusType;
target_status: ApiStatusJSON;
}
interface ReportNotificationGroupJSON extends BaseNotificationGroupJSON {
type: 'admin.report';
report: unknown;
}
interface ModerationWarningNotificationGroupJSON
extends BaseNotificationGroupJSON {
type: 'moderation_warning';
moderation_warning: unknown;
}
interface AccountRelationshipSeveranceNotificationGroupJSON
extends BaseNotificationGroupJSON {
type: 'severed_relationships';
account_relationship_severance_event: unknown;
}
export type NotificationGroupJSON =
| ReportNotificationGroupJSON
| AccountRelationshipSeveranceNotificationGroupJSON
| NotificationGroupWithStatusJSON
| ModerationWarningNotificationGroupJSON;

View File

@ -0,0 +1,59 @@
import type {
BaseNotificationGroupJSON,
NotificationGroupJSON,
NotificationType,
NotificationWithStatusType,
} from 'mastodon/api_types/notifications';
import type { ApiStatusJSON } from 'mastodon/api_types/statuses';
type BaseNotificationGroup = BaseNotificationGroupJSON;
interface BaseNotificationWithStatus<Type extends NotificationWithStatusType>
extends BaseNotificationGroup {
type: Type;
status: ApiStatusJSON;
}
interface BaseNotification<Type extends NotificationType>
extends BaseNotificationGroup {
type: Type;
}
export type NotificationGroupFavourite =
BaseNotificationWithStatus<'favourite'>;
export type NotificationGroupReblog = BaseNotificationWithStatus<'reblog'>;
export type NotificationGroupStatus = BaseNotificationWithStatus<'status'>;
export type NotificationGroupMention = BaseNotificationWithStatus<'mention'>;
export type NotificationGroupPoll = BaseNotificationWithStatus<'poll'>;
export type NotificationGroupUpdate = BaseNotificationWithStatus<'update'>;
export type NotificationGroupFollow = BaseNotification<'follow'>;
export type NotificationGroupFollowRequest = BaseNotification<'follow_request'>;
export type NotificationGroupAdminSignUp = BaseNotification<'admin.sign_up'>;
// TODO: those two will need special types
export type NotificationGroupModerationWarning =
BaseNotification<'moderation_warning'>;
export type NotificationGroupAdminReport = BaseNotification<'admin.report'>;
export type NotificationGroupSeveredRelationships =
BaseNotification<'severed_relationships'>;
export type NotificationGroup =
| NotificationGroupFavourite
| NotificationGroupReblog
| NotificationGroupStatus
| NotificationGroupMention
| NotificationGroupPoll
| NotificationGroupUpdate
| NotificationGroupFollow
| NotificationGroupFollowRequest
| NotificationGroupModerationWarning
| NotificationGroupSeveredRelationships
| NotificationGroupAdminSignUp
| NotificationGroupAdminReport;
export function createNotificationGroupFromJSON(
groupJson: NotificationGroupJSON,
): NotificationGroup {
// @ts-expect-error -- FIXME: properly convert the special notifications here
return groupJson;
}

View File

@ -0,0 +1,26 @@
import { createReducer } from '@reduxjs/toolkit';
import { fetchNotifications } from 'mastodon/actions/notification_groups';
import { createNotificationGroupFromJSON } from 'mastodon/models/notification_group';
import type { NotificationGroup } from 'mastodon/models/notification_group';
interface NotificationGroupsState {
groups: NotificationGroup[];
unread: number;
}
const initialState: NotificationGroupsState = {
groups: [],
unread: 0,
};
export const notificationGroupsReducer = createReducer(
initialState,
(builder) => {
builder.addCase(fetchNotifications.fulfilled, (state, action) => {
state.groups = action.payload.map((json) =>
createNotificationGroupFromJSON(json),
);
});
},
);