nicolium: groups migrations

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-02-22 20:08:16 +01:00
parent be44696640
commit fbbcbdce3f
34 changed files with 446 additions and 499 deletions

View File

@@ -1,5 +1,4 @@
import { type InfiniteData, useMutation } from '@tanstack/react-query';
import { GroupMember, GroupRole, PaginatedResponse } from 'pl-api';
import { importEntities } from '@/actions/importer';
import { useClient } from '@/hooks/use-client';
@@ -7,7 +6,9 @@ import { makePaginatedResponseQuery } from '@/queries/utils/make-paginated-respo
import { store } from '@/store';
import { queryClient } from '../client';
import { minifyList } from '../utils/minify-list';
import { minifyAccountList, minifyList } from '../utils/minify-list';
import type { GroupMember, GroupRole, PaginatedResponse } from 'pl-api';
const removeGroupMember = (groupId: string, accountId: string) =>
queryClient.setQueriesData<InfiniteData<PaginatedResponse<MinifiedGroupMember>>>(
@@ -53,6 +54,80 @@ const useKickGroupMemberMutation = (groupId: string, accountId: string) => {
});
};
const useGroupMembershipRequestsQuery = makePaginatedResponseQuery(
(groupId: string) => ['accountsLists', 'groupMembershipRequests', groupId],
(client, [groupId]) =>
client.experimental.groups.getGroupMembershipRequests(groupId).then(minifyAccountList),
);
const useAcceptGroupMembershipRequestMutation = (groupId: string) => {
const client = useClient();
return useMutation({
mutationKey: ['accountsLists', 'groupMembershipRequests', groupId],
mutationFn: (accountId: string) =>
client.experimental.groups.acceptGroupMembershipRequest(groupId, accountId),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ['accountsLists', 'groupMembershipRequests', groupId],
});
queryClient.invalidateQueries({ queryKey: ['accountsLists', 'groupMembers', groupId] });
},
});
};
const useRejectGroupMembershipRequestMutation = (groupId: string) => {
const client = useClient();
return useMutation({
mutationKey: ['accountsLists', 'groupMembershipRequests', groupId],
mutationFn: (accountId: string) =>
client.experimental.groups.rejectGroupMembershipRequest(groupId, accountId),
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ['accountsLists', 'groupMembershipRequests', groupId],
});
queryClient.invalidateQueries({ queryKey: ['accountsLists', 'groupMembers', groupId] });
},
});
};
const usePromoteGroupMemberMutation = (groupId: string) => {
const client = useClient();
return useMutation({
mutationKey: ['accountsLists', 'groupMembers', groupId],
mutationFn: ({ accountId, role }: { accountId: string; role: GroupRole }) =>
client.experimental.groups.promoteGroupUsers(groupId, [accountId], role),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['accountsLists', 'groupMembers', groupId] });
},
});
};
const useDemoteGroupMemberMutation = (groupId: string) => {
const client = useClient();
return useMutation({
mutationKey: ['accountsLists', 'groupMembers', groupId],
mutationFn: ({ accountId, role }: { accountId: string; role: GroupRole }) =>
client.experimental.groups.demoteGroupUsers(groupId, [accountId], role),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['accountsLists', 'groupMembers', groupId] });
},
});
};
type MinifiedGroupMember = ReturnType<typeof minifyGroupMembersList>['items'][0];
export { useGroupMembers, useKickGroupMemberMutation, removeGroupMember, type MinifiedGroupMember };
export {
useGroupMembers,
useKickGroupMemberMutation,
useGroupMembershipRequestsQuery,
useAcceptGroupMembershipRequestMutation,
useRejectGroupMembershipRequestMutation,
usePromoteGroupMemberMutation,
useDemoteGroupMemberMutation,
removeGroupMember,
type MinifiedGroupMember,
};

View File

@@ -0,0 +1,96 @@
import { useMutation, useQuery } from '@tanstack/react-query';
import { batcher } from '@/api/batcher';
import { useClient } from '@/hooks/use-client';
import { useLoggedIn } from '@/hooks/use-logged-in';
import { queryClient } from '../client';
import type { GroupRelationship } from 'pl-api';
const useGroupRelationshipQuery = (groupId?: string) => {
const client = useClient();
const { isLoggedIn } = useLoggedIn();
return useQuery({
queryKey: ['groupRelationships', groupId],
queryFn: () =>
batcher
.groupRelationships(client)
.fetch(groupId!)
.then((data) => data || undefined),
enabled: isLoggedIn && !!groupId,
});
};
const useJoinGroupMutation = (id: string) => {
const client = useClient();
return useMutation({
mutationKey: ['groupRelationships', id, 'join'],
mutationFn: () => client.experimental.groups.joinGroup(id),
onMutate: () => {
let previousRelationship: GroupRelationship | undefined = undefined;
queryClient.setQueryData<GroupRelationship>(['groupRelationships', id], (relationship) => {
previousRelationship = relationship;
if (!relationship) return undefined;
return {
...relationship,
requested: true,
};
});
return previousRelationship;
},
onError: (_, __, previousRelationship) => {
if (previousRelationship) {
queryClient.setQueryData<GroupRelationship>(
['groupRelationships', id],
previousRelationship,
);
}
},
onSuccess: (data) => {
queryClient.setQueryData<GroupRelationship>(['groupRelationships', id], data);
},
});
};
const useLeaveGroupMutation = (id: string) => {
const client = useClient();
return useMutation({
mutationKey: ['groupRelationships', id, 'leave'],
mutationFn: () => client.experimental.groups.leaveGroup(id),
onMutate: () => {
let previousRelationship: GroupRelationship | undefined = undefined;
queryClient.setQueryData<GroupRelationship>(['groupRelationships', id], (relationship) => {
previousRelationship = relationship;
if (!relationship) return undefined;
return {
...relationship,
requested: false,
member: false,
role: undefined,
};
});
return previousRelationship;
},
onError: (_, __, previousRelationship) => {
if (previousRelationship) {
queryClient.setQueryData<GroupRelationship>(
['groupRelationships', id],
previousRelationship,
);
}
},
onSuccess: (data) => {
queryClient.setQueryData<GroupRelationship>(['groupRelationships', id], data);
},
});
};
export { useGroupRelationshipQuery, useJoinGroupMutation, useLeaveGroupMutation };

View File

@@ -0,0 +1,33 @@
import { useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import { useClient } from '@/hooks/use-client';
import { useGroupRelationshipQuery } from './use-group-relationship';
const useGroupQuery = (groupId?: string, withRelationship = true) => {
const client = useClient();
const groupQuery = useQuery({
queryKey: ['groups', groupId],
queryFn: () => client.experimental.groups.getGroup(groupId!),
enabled: !!groupId,
});
const relationshipQuery = useGroupRelationshipQuery(withRelationship ? groupId : undefined);
return useMemo(
() => ({
...groupQuery,
data: groupQuery.data
? {
...groupQuery.data,
relationship: relationshipQuery.data || null,
}
: undefined,
}),
[groupQuery.data, relationshipQuery.data],
);
};
export { useGroupQuery };

View File

@@ -0,0 +1,25 @@
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useClient } from '@/hooks/use-client';
import { useLoggedIn } from '@/hooks/use-logged-in';
const useGroupsQuery = () => {
const client = useClient();
const { isLoggedIn } = useLoggedIn();
const queryClient = useQueryClient();
return useQuery({
queryKey: ['groupLists', 'myGroups'],
queryFn: () =>
client.experimental.groups.getGroups().then((groups) => {
for (const group of groups) {
queryClient.setQueryData(['groups', group.id], group);
}
return groups.map(({ id }) => id);
}),
enabled: isLoggedIn,
});
};
export { useGroupsQuery };

View File

@@ -8,6 +8,7 @@ import type {
AdminAccount,
AdminReport,
BlockedAccount,
Group,
MutedAccount,
PaginatedResponse,
Status,
@@ -70,6 +71,17 @@ const minifyMutedAccountList = (
},
);
const minifyGroupList = (response: PaginatedResponse<Group>): PaginatedResponse<string> =>
minifyList(
response,
(group) => group.id,
(groups) => {
for (const group of groups) {
queryClient.setQueryData(['groups', group.id], group);
}
},
);
const minifyAdminAccount = ({ account, ...adminAccount }: AdminAccount) => {
store.dispatch(importEntities({ accounts: [account] }) as any);
queryClient.setQueryData(['admin', 'accounts', adminAccount.id], adminAccount);
@@ -146,6 +158,7 @@ export {
minifyBlockedAccountList,
minifyMutedAccountList,
minifyStatusList,
minifyGroupList,
minifyAdminAccount,
minifyAdminAccountList,
minifyAdminReport,