Mostly migrate pl-fe notifications to notification groups
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import omit from 'lodash.omit';
|
||||
import pick from 'lodash.pick';
|
||||
import * as v from 'valibot';
|
||||
|
||||
import {
|
||||
@ -110,7 +111,7 @@ import {
|
||||
MuteAccountParams,
|
||||
UpdateFilterParams,
|
||||
} from './params/filtering';
|
||||
import { GetGroupedNotificationsParams } from './params/grouped-notifications';
|
||||
import { GetGroupedNotificationsParams, GetUnreadNotificationGroupCountParams } from './params/grouped-notifications';
|
||||
import {
|
||||
CreateGroupParams,
|
||||
GetGroupBlocksParams,
|
||||
@ -193,6 +194,7 @@ import request, { getNextLink, getPrevLink, type RequestBody, RequestMeta } from
|
||||
import { buildFullPath } from './utils/url';
|
||||
|
||||
import type {
|
||||
Account,
|
||||
AdminAccount,
|
||||
AdminAnnouncement,
|
||||
AdminModerationLogEntry,
|
||||
@ -299,6 +301,28 @@ class PlApiClient {
|
||||
};
|
||||
};
|
||||
|
||||
#paginatedSingleGet = async <T>(input: URL | RequestInfo, body: RequestBody, schema: v.BaseSchema<any, T, v.BaseIssue<unknown>>): Promise<PaginatedSingleResponse<T>> => {
|
||||
const getMore = (input: string | null) => input ? async () => {
|
||||
const response = await this.request(input);
|
||||
|
||||
return {
|
||||
previous: getMore(getPrevLink(response)),
|
||||
next: getMore(getNextLink(response)),
|
||||
items: v.parse(schema, response.json),
|
||||
partial: response.status === 206,
|
||||
};
|
||||
} : null;
|
||||
|
||||
const response = await this.request(input, body);
|
||||
|
||||
return {
|
||||
previous: getMore(getPrevLink(response)),
|
||||
next: getMore(getNextLink(response)),
|
||||
items: v.parse(schema, response.json),
|
||||
partial: response.status === 206,
|
||||
};
|
||||
};
|
||||
|
||||
#paginatedPleromaAccounts = async (params: {
|
||||
query?: string;
|
||||
filters?: string;
|
||||
@ -398,11 +422,16 @@ class PlApiClient {
|
||||
}
|
||||
|
||||
const groupedNotificationsResults: GroupedNotificationsResults = {
|
||||
accounts: items.map(({ account }) => account),
|
||||
statuses: items.reduce<Array<Status>>((statuses, notification) => {
|
||||
if ('status' in notification) statuses.push(notification.status);
|
||||
accounts: Object.values(items.reduce<Record<string, Account>>((accounts, notification) => {
|
||||
accounts[notification.account.id] = notification.account;
|
||||
if ('target' in notification) accounts[notification.target.id] = notification.target;
|
||||
|
||||
return accounts;
|
||||
}, {})),
|
||||
statuses: Object.values(items.reduce<Record<string, Status>>((statuses, notification) => {
|
||||
if ('status' in notification) statuses[notification.status.id] = notification.status;
|
||||
return statuses;
|
||||
}, []),
|
||||
}, {})),
|
||||
notification_groups: notificationGroups,
|
||||
};
|
||||
|
||||
@ -2767,11 +2796,66 @@ class PlApiClient {
|
||||
};
|
||||
|
||||
public readonly groupedNotifications = {
|
||||
getGroupedNotifications: async (params: GetGroupedNotificationsParams) => {
|
||||
getGroupedNotifications: async (params: GetGroupedNotificationsParams, meta?: RequestMeta) => {
|
||||
if (this.features.groupedNotifications) {
|
||||
return this.#paginatedGet('/api/v2/notifications', { params }, groupedNotificationsResultsSchema);
|
||||
return this.#paginatedSingleGet('/api/v2/notifications', { ...meta, params }, groupedNotificationsResultsSchema);
|
||||
} else {
|
||||
return this.#groupNotifications(await this.notifications.getNotifications(), params);
|
||||
const response = await this.notifications.getNotifications(
|
||||
pick(params, ['max_id', 'since_id', 'limit', 'min_id', 'types', 'exclude_types', 'account_id', 'include_filtered']),
|
||||
);
|
||||
|
||||
return this.#groupNotifications(response, params);
|
||||
}
|
||||
},
|
||||
|
||||
getNotificationGroup: async (groupKey: string) => {
|
||||
if (this.features.groupedNotifications) {
|
||||
const response = await this.request(`/api/v2/notifications/${groupKey}`);
|
||||
|
||||
return v.parse(groupedNotificationsResultsSchema, response.json);
|
||||
} else {
|
||||
const response = await this.request(`/api/v1/notifications/${groupKey}`);
|
||||
|
||||
return this.#groupNotifications({
|
||||
previous: null,
|
||||
next: null,
|
||||
items: [response.json],
|
||||
partial: false,
|
||||
}).items;
|
||||
}
|
||||
},
|
||||
|
||||
dismissNotificationGroup: async (groupKey: string) => {
|
||||
if (this.features.groupedNotifications) {
|
||||
const response = await this.request(`/api/v2/notifications/${groupKey}/dismiss`, { method: 'POST' });
|
||||
|
||||
return response.json as {};
|
||||
} else {
|
||||
return this.notifications.dismissNotification(groupKey);
|
||||
}
|
||||
},
|
||||
|
||||
getNotificationGroupAccounts: async (groupKey: string) => {
|
||||
if (this.features.groupedNotifications) {
|
||||
const response = await this.request(`/api/v2/notifications/${groupKey}/accounts`);
|
||||
|
||||
return v.parse(filteredArray(accountSchema), response.json);
|
||||
} else {
|
||||
return (await (this.groupedNotifications.getNotificationGroup(groupKey))).accounts;
|
||||
}
|
||||
},
|
||||
|
||||
getUnreadNotificationGroupCount: async (params: GetUnreadNotificationGroupCountParams) => {
|
||||
if (this.features.groupedNotifications) {
|
||||
const response = await this.request('/api/v2/notifications/unread_count', { params });
|
||||
|
||||
return v.parse(v.object({
|
||||
count: v.number(),
|
||||
}), response.json);
|
||||
} else {
|
||||
return this.notifications.getUnreadNotificationCount(
|
||||
pick(params || {}, ['max_id', 'since_id', 'limit', 'min_id', 'types', 'exclude_types', 'account_id']),
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@ -38,9 +38,16 @@ const accountNotificationGroupSchema = v.object({
|
||||
type: v.picklist(['follow', 'follow_request', 'admin.sign_up', 'bite']),
|
||||
});
|
||||
|
||||
const mentionNotificationGroupSchema = v.object({
|
||||
...baseNotificationGroupSchema.entries,
|
||||
type: v.literal('mention'),
|
||||
subtype: v.fallback(v.nullable(v.picklist(['reply'])), null),
|
||||
status_id: v.string(),
|
||||
});
|
||||
|
||||
const statusNotificationGroupSchema = v.object({
|
||||
...baseNotificationGroupSchema.entries,
|
||||
type: v.picklist(['status', 'mention', 'reblog', 'favourite', 'poll', 'update', 'event_reminder']),
|
||||
type: v.picklist(['status', 'reblog', 'favourite', 'poll', 'update', 'event_reminder']),
|
||||
status_id: v.string(),
|
||||
});
|
||||
|
||||
@ -105,6 +112,7 @@ const notificationGroupSchema: v.BaseSchema<any, NotificationGroup, v.BaseIssue<
|
||||
})),
|
||||
v.variant('type', [
|
||||
accountNotificationGroupSchema,
|
||||
mentionNotificationGroupSchema,
|
||||
statusNotificationGroupSchema,
|
||||
reportNotificationGroupSchema,
|
||||
severedRelationshipNotificationGroupSchema,
|
||||
@ -117,6 +125,7 @@ const notificationGroupSchema: v.BaseSchema<any, NotificationGroup, v.BaseIssue<
|
||||
|
||||
type NotificationGroup = v.InferOutput<
|
||||
| typeof accountNotificationGroupSchema
|
||||
| typeof mentionNotificationGroupSchema
|
||||
| typeof statusNotificationGroupSchema
|
||||
| typeof reportNotificationGroupSchema
|
||||
| typeof severedRelationshipNotificationGroupSchema
|
||||
|
||||
@ -41,6 +41,7 @@ export * from './filter';
|
||||
export * from './group';
|
||||
export * from './group-member';
|
||||
export * from './group-relationship';
|
||||
export * from './grouped-notifications-results';
|
||||
export * from './instance';
|
||||
export * from './interaction-policy';
|
||||
export * from './interaction-request';
|
||||
|
||||
@ -15,4 +15,17 @@ interface GetGroupedNotificationsParams extends PaginationParams {
|
||||
include_filtered?: boolean;
|
||||
}
|
||||
|
||||
export type { GetGroupedNotificationsParams };
|
||||
interface GetUnreadNotificationGroupCountParams {
|
||||
/** Maximum number of results to return. Defaults to 100 notifications. Max 1000 notifications. */
|
||||
limit?: number;
|
||||
/** Types of notifications that should count towards unread notifications. */
|
||||
types?: Array<string>;
|
||||
/** Types of notifications that should not count towards unread notifications. */
|
||||
exclude_types?: Array<string>;
|
||||
/** Only count unread notifications received from the specified account. */
|
||||
account_id?: string;
|
||||
/** Restrict which notification types can be grouped. Use this if there are notification types for which your client does not support grouping. If omitted, the server will group notifications of all types it supports (currently, `favourite`, `follow` and `reblog`). If you do not want any notification grouping, use GET /api/v1/notifications/unread_count instead. */
|
||||
grouped_types?: Array<string>;
|
||||
}
|
||||
|
||||
export type { GetGroupedNotificationsParams, GetUnreadNotificationGroupCountParams };
|
||||
|
||||
@ -4,6 +4,7 @@ export * from './apps';
|
||||
export * from './chats';
|
||||
export * from './events';
|
||||
export * from './filtering';
|
||||
export * from './grouped-notifications';
|
||||
export * from './groups';
|
||||
export * from './instance';
|
||||
export * from './interaction-requests';
|
||||
|
||||
Reference in New Issue
Block a user