mirror of https://github.com/usememos/memos
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { create } from "@bufbuild/protobuf";
|
|
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
import { attachmentServiceClient } from "@/connect";
|
|
import {
|
|
type Attachment,
|
|
BatchDeleteAttachmentsRequestSchema,
|
|
type ListAttachmentsRequest,
|
|
ListAttachmentsRequestSchema,
|
|
} from "@/types/proto/api/v1/attachment_service_pb";
|
|
|
|
// Query keys factory
|
|
export const attachmentKeys = {
|
|
all: ["attachments"] as const,
|
|
lists: () => [...attachmentKeys.all, "list"] as const,
|
|
list: (filters?: Partial<ListAttachmentsRequest>) => [...attachmentKeys.lists(), filters] as const,
|
|
details: () => [...attachmentKeys.all, "detail"] as const,
|
|
detail: (name: string) => [...attachmentKeys.details(), name] as const,
|
|
};
|
|
|
|
// Hook to fetch attachments
|
|
export function useAttachments() {
|
|
return useQuery({
|
|
queryKey: attachmentKeys.lists(),
|
|
queryFn: async () => {
|
|
const { attachments } = await attachmentServiceClient.listAttachments(create(ListAttachmentsRequestSchema, {}));
|
|
return attachments;
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useInfiniteAttachments(request: Partial<ListAttachmentsRequest> = {}, options?: { enabled?: boolean }) {
|
|
return useInfiniteQuery({
|
|
queryKey: attachmentKeys.list(request),
|
|
queryFn: async ({ pageParam }) => {
|
|
const response = await attachmentServiceClient.listAttachments(
|
|
create(ListAttachmentsRequestSchema, {
|
|
...request,
|
|
pageToken: pageParam || "",
|
|
} as Record<string, unknown>),
|
|
);
|
|
return response;
|
|
},
|
|
initialPageParam: "",
|
|
getNextPageParam: (lastPage) => lastPage.nextPageToken || undefined,
|
|
staleTime: 1000 * 60,
|
|
gcTime: 1000 * 60 * 5,
|
|
enabled: options?.enabled ?? true,
|
|
});
|
|
}
|
|
|
|
// Hook to create/upload attachment
|
|
export function useCreateAttachment() {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: async (attachment: Attachment) => {
|
|
const result = await attachmentServiceClient.createAttachment({ attachment });
|
|
return result;
|
|
},
|
|
onSuccess: () => {
|
|
// Invalidate attachments list
|
|
queryClient.invalidateQueries({ queryKey: attachmentKeys.lists() });
|
|
},
|
|
});
|
|
}
|
|
|
|
// Hook to delete attachment
|
|
export function useDeleteAttachment() {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: async (name: string) => {
|
|
await attachmentServiceClient.deleteAttachment({ name });
|
|
return name;
|
|
},
|
|
onSuccess: (name) => {
|
|
// Remove from cache
|
|
queryClient.removeQueries({ queryKey: attachmentKeys.detail(name) });
|
|
// Invalidate lists
|
|
queryClient.invalidateQueries({ queryKey: attachmentKeys.lists() });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useBatchDeleteAttachments() {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: async (names: string[]) => {
|
|
await attachmentServiceClient.batchDeleteAttachments(create(BatchDeleteAttachmentsRequestSchema, { names }));
|
|
return names;
|
|
},
|
|
onSuccess: (names) => {
|
|
for (const name of names) {
|
|
queryClient.removeQueries({ queryKey: attachmentKeys.detail(name) });
|
|
}
|
|
queryClient.invalidateQueries({ queryKey: attachmentKeys.lists() });
|
|
},
|
|
});
|
|
}
|