Migrate everything to pl-api

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak
2024-08-28 20:58:20 +02:00
parent 0ddf6f2768
commit eb231d562e
50 changed files with 610 additions and 466 deletions

View File

@ -1,31 +1,25 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import {
adminAnnouncementSchema,
type AdminAnnouncement as BaseAdminAnnouncement,
type AdminCreateAnnouncementParams,
type AdminUpdateAnnouncementParams,
} from 'pl-api';
import { useClient } from 'pl-fe/hooks';
import { normalizeAnnouncement, AdminAnnouncement } from 'pl-fe/normalizers';
import { queryClient } from 'pl-fe/queries/client';
import { adminAnnouncementSchema, type AdminAnnouncement } from 'pl-fe/schemas';
import { useAnnouncements as useUserAnnouncements } from '../announcements';
interface CreateAnnouncementParams {
content: string;
starts_at?: string | null;
ends_at?: string | null;
all_day?: boolean;
}
interface UpdateAnnouncementParams extends CreateAnnouncementParams {
id: string;
}
const useAnnouncements = () => {
const client = useClient();
const userAnnouncements = useUserAnnouncements();
const getAnnouncements = async () => {
const { json: data } = await client.request<AdminAnnouncement[]>('/api/v1/pleroma/admin/announcements');
const data = await client.admin.announcements.getAnnouncements();
const normalizedData = data.map((announcement) => adminAnnouncementSchema.parse(announcement));
return normalizedData;
return data.items.map(normalizeAnnouncement<BaseAdminAnnouncement>);
};
const result = useQuery<ReadonlyArray<AdminAnnouncement>>({
@ -38,11 +32,9 @@ const useAnnouncements = () => {
mutate: createAnnouncement,
isPending: isCreating,
} = useMutation({
mutationFn: (params: CreateAnnouncementParams) => client.request('/api/v1/pleroma/admin/announcements', {
method: 'POST', body: params,
}),
mutationFn: (params: AdminCreateAnnouncementParams) => client.admin.announcements.createAnnouncement(params),
retry: false,
onSuccess: ({ json: data }) =>
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'announcements'], (prevResult: ReadonlyArray<AdminAnnouncement>) =>
[...prevResult, adminAnnouncementSchema.parse(data)],
),
@ -53,11 +45,10 @@ const useAnnouncements = () => {
mutate: updateAnnouncement,
isPending: isUpdating,
} = useMutation({
mutationFn: ({ id, ...params }: UpdateAnnouncementParams) => client.request(`/api/v1/pleroma/admin/announcements/${id}`, {
method: 'PATCH', body: params,
}),
mutationFn: ({ id, ...params }: AdminUpdateAnnouncementParams & { id: string }) =>
client.admin.announcements.updateAnnouncement(id, params),
retry: false,
onSuccess: ({ json: data }) =>
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'announcements'], (prevResult: ReadonlyArray<AdminAnnouncement>) =>
prevResult.map((announcement) => announcement.id === data.id ? adminAnnouncementSchema.parse(data) : announcement),
),
@ -68,7 +59,7 @@ const useAnnouncements = () => {
mutate: deleteAnnouncement,
isPending: isDeleting,
} = useMutation({
mutationFn: (id: string) => client.request(`/api/v1/pleroma/admin/announcements/${id}`, { method: 'DELETE' }),
mutationFn: (id: string) => client.admin.announcements.deleteAnnouncement(id),
retry: false,
onSuccess: (_, id) =>
queryClient.setQueryData(['admin', 'announcements'], (prevResult: ReadonlyArray<AdminAnnouncement>) =>

View File

@ -2,7 +2,8 @@ import { useMutation, useQuery } from '@tanstack/react-query';
import { useClient } from 'pl-fe/hooks';
import { queryClient } from 'pl-fe/queries/client';
import { domainSchema, type Domain } from 'pl-fe/schemas';
import type { AdminDomain } from 'pl-api';
interface CreateDomainParams {
domain: string;
@ -17,14 +18,9 @@ interface UpdateDomainParams {
const useDomains = () => {
const client = useClient();
const getDomains = async () => {
const { json: data } = await client.request<Domain[]>('/api/v1/pleroma/admin/domains');
const getDomains = () => client.admin.domains.getDomains();
const normalizedData = data.map((domain) => domainSchema.parse(domain));
return normalizedData;
};
const result = useQuery<ReadonlyArray<Domain>>({
const result = useQuery<ReadonlyArray<AdminDomain>>({
queryKey: ['admin', 'domains'],
queryFn: getDomains,
placeholderData: [],
@ -34,13 +30,11 @@ const useDomains = () => {
mutate: createDomain,
isPending: isCreating,
} = useMutation({
mutationFn: (params: CreateDomainParams) => client.request('/api/v1/pleroma/admin/domains', {
method: 'POST', body: params,
}),
mutationFn: (params: CreateDomainParams) => client.admin.domains.createDomain(params),
retry: false,
onSuccess: ({ data }) =>
queryClient.setQueryData(['admin', 'domains'], (prevResult: ReadonlyArray<Domain>) =>
[...prevResult, domainSchema.parse(data)],
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'domains'], (prevResult: ReadonlyArray<AdminDomain>) =>
[...prevResult, data],
),
});
@ -48,13 +42,11 @@ const useDomains = () => {
mutate: updateDomain,
isPending: isUpdating,
} = useMutation({
mutationFn: ({ id, ...params }: UpdateDomainParams) => client.request(`/api/v1/pleroma/admin/domains/${id}`, {
method: 'PATCH', body: params,
}),
mutationFn: ({ id, ...params }: UpdateDomainParams) => client.admin.domains.updateDomain(id, params.public),
retry: false,
onSuccess: ({ json: data }) =>
queryClient.setQueryData(['admin', 'domains'], (prevResult: ReadonlyArray<Domain>) =>
prevResult.map((domain) => domain.id === data.id ? domainSchema.parse(data) : domain),
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'domains'], (prevResult: ReadonlyArray<AdminDomain>) =>
prevResult.map((domain) => domain.id === data.id ? data : domain),
),
});
@ -62,10 +54,10 @@ const useDomains = () => {
mutate: deleteDomain,
isPending: isDeleting,
} = useMutation({
mutationFn: (id: string) => client.request(`/api/v1/pleroma/admin/domains/${id}`, { method: 'DELETE' }),
mutationFn: (id: string) => client.admin.domains.deleteDomain(id),
retry: false,
onSuccess: (_, id) =>
queryClient.setQueryData(['admin', 'domains'], (prevResult: ReadonlyArray<Domain>) =>
queryClient.setQueryData(['admin', 'domains'], (prevResult: ReadonlyArray<AdminDomain>) =>
prevResult.filter(({ id: domainId }) => domainId !== id),
),
});

View File

@ -1,37 +1,25 @@
import { useInfiniteQuery } from '@tanstack/react-query';
import { PaginatedResponse } from 'pl-api';
import { useClient } from 'pl-fe/hooks';
import { moderationLogEntrySchema, type ModerationLogEntry } from 'pl-fe/schemas';
import { flattenPages } from 'pl-fe/utils/queries';
interface ModerationLogResult {
items: ModerationLogEntry[];
total: number;
}
const flattenPages = (pages?: ModerationLogResult[]): ModerationLogEntry[] => (pages || []).map(({ items }) => items).flat();
import type { AdminModerationLogEntry } from 'pl-api';
const useModerationLog = () => {
const client = useClient();
const getModerationLog = async (page: number): Promise<ModerationLogResult> => {
const { json: data } = await client.request<ModerationLogResult>('/api/v1/pleroma/admin/moderation_log', { params: { page } });
const normalizedData = data.items.map((domain) => moderationLogEntrySchema.parse(domain));
return {
items: normalizedData,
total: data.total,
};
};
const getModerationLog = (pageParam?: Pick<PaginatedResponse<AdminModerationLogEntry>, 'next'>): Promise<PaginatedResponse<AdminModerationLogEntry>> =>
(pageParam?.next || client.admin.moderationLog.getModerationLog)();
const queryInfo = useInfiniteQuery({
queryKey: ['admin', 'moderation_log'],
queryFn: ({ pageParam }) => getModerationLog(pageParam),
initialPageParam: 1,
getNextPageParam: (page, allPages) => flattenPages(allPages)!.length >= page.total ? undefined : allPages.length + 1,
initialPageParam: { next: null as (() => Promise<PaginatedResponse<AdminModerationLogEntry>>) | null },
getNextPageParam: (config) => config.next ? config : undefined,
});
const data = flattenPages(queryInfo.data?.pages);
const data = flattenPages(queryInfo.data) || [];
return {
...queryInfo,

View File

@ -2,19 +2,15 @@ import { useMutation, useQuery } from '@tanstack/react-query';
import { useClient } from 'pl-fe/hooks';
import { queryClient } from 'pl-fe/queries/client';
import { relaySchema, type Relay } from 'pl-fe/schemas';
import type { AdminRelay } from 'pl-api';
const useRelays = () => {
const client = useClient();
const getRelays = async () => {
const { json: data } = await client.request<{ relays: Relay[] }>('/api/v1/pleroma/admin/relay');
const getRelays = () => client.admin.relays.getRelays();
const normalizedData = data.relays?.map((relay) => relaySchema.parse(relay));
return normalizedData;
};
const result = useQuery<ReadonlyArray<Relay>>({
const result = useQuery<ReadonlyArray<AdminRelay>>({
queryKey: ['admin', 'relays'],
queryFn: getRelays,
placeholderData: [],
@ -24,14 +20,11 @@ const useRelays = () => {
mutate: followRelay,
isPending: isPendingFollow,
} = useMutation({
mutationFn: (relayUrl: string) => client.request('/api/v1/pleroma/admin/relays', {
method: 'POST',
body: JSON.stringify({ relay_url: relayUrl }),
}),
mutationFn: (relayUrl: string) => client.admin.relays.followRelay(relayUrl),
retry: false,
onSuccess: ({ json: data }) =>
queryClient.setQueryData(['admin', 'relays'], (prevResult: ReadonlyArray<Relay>) =>
[...prevResult, relaySchema.parse(data)],
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'relays'], (prevResult: ReadonlyArray<AdminRelay>) =>
[...prevResult, data],
),
});
@ -39,13 +32,10 @@ const useRelays = () => {
mutate: unfollowRelay,
isPending: isPendingUnfollow,
} = useMutation({
mutationFn: (relayUrl: string) => client.request('/api/v1/pleroma/admin/relays', {
method: 'DELETE',
body: JSON.stringify({ relay_url: relayUrl }),
}),
mutationFn: (relayUrl: string) => client.admin.relays.unfollowRelay(relayUrl),
retry: false,
onSuccess: (_, relayUrl) =>
queryClient.setQueryData(['admin', 'relays'], (prevResult: ReadonlyArray<Relay>) =>
queryClient.setQueryData(['admin', 'relays'], (prevResult: ReadonlyArray<AdminRelay>) =>
prevResult.filter(({ actor }) => actor !== relayUrl),
),
});

View File

@ -2,7 +2,8 @@ import { useMutation, useQuery } from '@tanstack/react-query';
import { useClient } from 'pl-fe/hooks';
import { queryClient } from 'pl-fe/queries/client';
import { adminRuleSchema, type AdminRule } from 'pl-fe/schemas';
import type { AdminRule } from 'pl-api';
interface CreateRuleParams {
priority?: number;
@ -20,12 +21,7 @@ interface UpdateRuleParams {
const useRules = () => {
const client = useClient();
const getRules = async () => {
const { json: data } = await client.request<AdminRule[]>('/api/v1/pleroma/admin/rules');
const normalizedData = data.map((rule) => adminRuleSchema.parse(rule));
return normalizedData;
};
const getRules = () => client.admin.rules.getRules();
const result = useQuery<ReadonlyArray<AdminRule>>({
queryKey: ['admin', 'rules'],
@ -37,13 +33,11 @@ const useRules = () => {
mutate: createRule,
isPending: isCreating,
} = useMutation({
mutationFn: (params: CreateRuleParams) => client.request('/api/v1/pleroma/admin/rules', {
method: 'POST', body: params,
}),
mutationFn: (params: CreateRuleParams) => client.admin.rules.createRule(params),
retry: false,
onSuccess: ({ json: data }) =>
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'rules'], (prevResult: ReadonlyArray<AdminRule>) =>
[...prevResult, adminRuleSchema.parse(data)],
[...prevResult, data],
),
});
@ -51,13 +45,11 @@ const useRules = () => {
mutate: updateRule,
isPending: isUpdating,
} = useMutation({
mutationFn: ({ id, ...params }: UpdateRuleParams) => client.request(`/api/v1/pleroma/admin/rules/${id}`, {
method: 'PATCH', body: params,
}),
mutationFn: ({ id, ...params }: UpdateRuleParams) => client.admin.rules.updateRule(id, params),
retry: false,
onSuccess: ({ json: data }) =>
onSuccess: (data) =>
queryClient.setQueryData(['admin', 'rules'], (prevResult: ReadonlyArray<AdminRule>) =>
prevResult.map((rule) => rule.id === data.id ? adminRuleSchema.parse(data) : rule),
prevResult.map((rule) => rule.id === data.id ? data : rule),
),
});
@ -65,7 +57,7 @@ const useRules = () => {
mutate: deleteRule,
isPending: isDeleting,
} = useMutation({
mutationFn: (id: string) => client.request(`/api/v1/pleroma/admin/rules/${id}`, { method: 'DELETE' }),
mutationFn: (id: string) => client.admin.rules.deleteRule(id),
retry: false,
onSuccess: (_, id) =>
queryClient.setQueryData(['admin', 'rules'], (prevResult: ReadonlyArray<AdminRule>) =>

View File

@ -1,53 +1,45 @@
import { useTransaction } from 'pl-fe/entity-store/hooks';
import { EntityCallbacks } from 'pl-fe/entity-store/hooks/types';
import { useClient, useGetState } from 'pl-fe/hooks';
import { accountIdsToAccts } from 'pl-fe/selectors';
import { useClient } from 'pl-fe/hooks';
import type { Account } from 'pl-fe/normalizers';
const useSuggest = () => {
const client = useClient();
const getState = useGetState();
const { transaction } = useTransaction();
const suggestEffect = (accountIds: string[], suggested: boolean) => {
const suggestEffect = (accountId: string, suggested: boolean) => {
const updater = (account: Account): Account => {
account.is_suggested = suggested;
return account;
};
transaction({
Accounts: accountIds.reduce<Record<string, (account: Account) => Account>>(
(result, id) => ({ ...result, [id]: updater }),
{}),
Accounts: {
[accountId]: updater,
},
});
};
const suggest = async (accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) => {
const accts = accountIdsToAccts(getState(), accountIds);
suggestEffect(accountIds, true);
const suggest = async (accountId: string, callbacks?: EntityCallbacks<void, unknown>) => {
suggestEffect(accountId, true);
try {
await client.request('/api/v1/pleroma/admin/users/suggest', {
method: 'PATCH', body: { nicknames: accts },
});
await client.admin.accounts.suggestUser(accountId);
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
suggestEffect(accountIds, false);
suggestEffect(accountId, false);
}
};
const unsuggest = async (accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) => {
const accts = accountIdsToAccts(getState(), accountIds);
suggestEffect(accountIds, false);
const unsuggest = async (accountId: string, callbacks?: EntityCallbacks<void, unknown>) => {
suggestEffect(accountId, false);
try {
await client.request('/api/v1/pleroma/admin/users/unsuggest', {
method: 'PATCH', body: { nicknames: accts },
});
await client.admin.accounts.unsuggestUser(accountId);
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
suggestEffect(accountIds, true);
suggestEffect(accountId, true);
}
};

View File

@ -1,16 +1,14 @@
import { useTransaction } from 'pl-fe/entity-store/hooks';
import { EntityCallbacks } from 'pl-fe/entity-store/hooks/types';
import { useClient, useGetState } from 'pl-fe/hooks';
import { accountIdsToAccts } from 'pl-fe/selectors';
import { useClient } from 'pl-fe/hooks';
import type { Account } from 'pl-fe/normalizers';
const useVerify = () => {
const client = useClient();
const getState = useGetState();
const { transaction } = useTransaction();
const verifyEffect = (accountIds: string[], verified: boolean) => {
const verifyEffect = (accountId: string, verified: boolean) => {
const updater = (account: Account): Account => {
if (account.__meta.pleroma) {
const tags = account.__meta.pleroma.tags.filter((tag: string) => tag !== 'verified');
@ -24,39 +22,29 @@ const useVerify = () => {
};
transaction({
Accounts: accountIds.reduce<Record<string, (account: Account) => Account>>(
(result, id) => ({ ...result, [id]: updater }),
{}),
Accounts: ({ [accountId]: updater }),
});
};
const verify = async (accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) => {
const accts = accountIdsToAccts(getState(), accountIds);
verifyEffect(accountIds, true);
const verify = async (accountId: string, callbacks?: EntityCallbacks<void, unknown>) => {
verifyEffect(accountId, true);
try {
await client.request('/api/v1/pleroma/admin/users/tag', {
method: 'PUT',
body: { nicknames: accts, tags: ['verified'] },
});
await client.admin.accounts.tagUser(accountId, ['verified']);
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
verifyEffect(accountIds, false);
verifyEffect(accountId, false);
}
};
const unverify = async (accountIds: string[], callbacks?: EntityCallbacks<void, unknown>) => {
const accts = accountIdsToAccts(getState(), accountIds);
verifyEffect(accountIds, false);
const unverify = async (accountId: string, callbacks?: EntityCallbacks<void, unknown>) => {
verifyEffect(accountId, false);
try {
await client.request('/api/v1/pleroma/admin/users/tag', {
method: 'DELETE',
body: { nicknames: accts, tags: ['verified'] },
});
await client.admin.accounts.untagUser(accountId, ['verified']);
callbacks?.onSuccess?.();
} catch (e) {
callbacks?.onError?.(e);
verifyEffect(accountIds, true);
verifyEffect(accountId, true);
}
};

View File

@ -1,7 +1,8 @@
import { instanceSchema } from 'pl-api';
import { __stub } from 'pl-fe/api';
import { buildGroup } from 'pl-fe/jest/factory';
import { renderHook, waitFor } from 'pl-fe/jest/test-helpers';
import { instanceSchema } from 'pl-fe/schemas';
import { useGroups } from './useGroups';