Skip to content

Commit 4cff9e6

Browse files
🐞 fix(chat):Fix uploadthing api callback
1 parent 678418f commit 4cff9e6

File tree

12 files changed

+272
-134
lines changed

12 files changed

+272
-134
lines changed

src/app/(dashboard)/workspaces/[workspaceId]/chats/client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const DashboardClient: React.FC = () => {
3333
});
3434

3535
const { mutate: deleteFile, isPending: isDeletingFile } =
36-
useDeleteWorkspaceFile();
36+
useDeleteWorkspaceFile({ setCurrentlyDeletingFile });
3737

3838
const [DeleteDialog, confirmDelete] = useConfirm(
3939
'删除文档',

src/app/api/uploadthing/core.ts

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import { createUploadthing, type FileRouter } from 'uploadthing/next';
66

77
import { DATABASE_ID, FILES_ID } from '@/common/configs';
88
import { getCurrent } from '@/common/libs/actions/auth.actions';
9-
import { createSessionClient } from '@/common/libs/appwrite';
9+
import { getWorkspaces } from '@/common/libs/actions/workspaces.action';
10+
import { createAdminClient } from '@/common/libs/appwrite';
1011
import { type File } from '@/common/types/files';
1112
// import { PLANS } from '@/config/stripe'
1213
// import { getPineconeClient } from '@/common/libs/pinecone';
@@ -19,10 +20,12 @@ const middleware = async () => {
1920

2021
if (!user) throw new Error('Unauthorized');
2122

23+
const workspaces = await getWorkspaces();
24+
2225
// const subscriptionPlan = await getUserSubscriptionPlan();
2326

2427
// return { subscriptionPlan, userId: user.$id };
25-
return { userId: user.$id };
28+
return { userId: user.$id, workspaceId: workspaces.documents[0].$id };
2629
};
2730

2831
const onUploadComplete = async ({
@@ -39,19 +42,15 @@ const onUploadComplete = async ({
3942
console.log('Upload complete for userId:', metadata.userId);
4043
console.log('file url', file.url);
4144

42-
console.log('debug start');
43-
44-
const { databases } = await createSessionClient();
45-
46-
console.log('databases', databases);
45+
const { databases } = await createAdminClient();
4746

48-
const fileList = await databases.listDocuments<File>(DATABASE_ID, FILES_ID, [
47+
const files = await databases.listDocuments<File>(DATABASE_ID, FILES_ID, [
4948
Query.equal('key', file.key),
5049
]);
5150

52-
console.log('fileList', fileList);
51+
console.log('files', files);
5352

54-
const isFileExist = fileList.documents[0];
53+
const isFileExist = files.documents[0];
5554

5655
console.log('isFileExist', isFileExist);
5756

@@ -64,7 +63,7 @@ const onUploadComplete = async ({
6463
{
6564
key: file.key,
6665
name: file.name,
67-
userId: metadata.userId,
66+
workspaceId: metadata.workspaceId,
6867
url: file.url,
6968
uploadStatus: 'PROCESSING',
7069
}
@@ -109,13 +108,23 @@ const onUploadComplete = async ({
109108
// namespace: createdFile?.id,
110109
// });
111110

112-
await databases.updateDocument(DATABASE_ID, FILES_ID, createdFile.id, {
113-
uploadStatus: 'SUCCESS',
114-
});
111+
await databases.updateDocument(
112+
DATABASE_ID,
113+
FILES_ID,
114+
createdFile.data.$id,
115+
{
116+
uploadStatus: 'SUCCESS',
117+
}
118+
);
115119
} catch (err) {
116-
await databases.updateDocument(DATABASE_ID, FILES_ID, createdFile.id, {
117-
uploadStatus: 'FAILED',
118-
});
120+
await databases.updateDocument(
121+
DATABASE_ID,
122+
FILES_ID,
123+
createdFile.data.$id,
124+
{
125+
uploadStatus: 'FAILED',
126+
}
127+
);
119128
}
120129
};
121130

src/common/api/files/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export { default as useDeleteWorkspaceFile } from './useDeleteWorkspaceFile';
2+
export { default as useGetUploadStatus } from './useGetUploadStatus';
23
export { default as useGetWorkspaceFile } from './useGetWorkspaceFile';
34
export { default as useGetWorkspaceFiles } from './useGetWorkspaceFiles';
4-
export { default as useGetWorkspaceFileWithKey } from './useGetWorkspaceFileWithKey';

src/common/api/files/useDeleteWorkspaceFile.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useMutation, useQueryClient } from '@tanstack/react-query';
22
import { InferRequestType, InferResponseType } from 'hono';
3+
import { Dispatch, SetStateAction } from 'react';
34
import { toast } from 'sonner';
45

56
import client from '@/common/libs/rpc';
@@ -12,7 +13,11 @@ type RequestType = InferRequestType<
1213
(typeof client.api.files)[':fileId']['$delete']
1314
>;
1415

15-
const useDeleteWorkspaceFile = () => {
16+
const useDeleteWorkspaceFile = ({
17+
setCurrentlyDeletingFile,
18+
}: {
19+
setCurrentlyDeletingFile: Dispatch<SetStateAction<string | null>>;
20+
}) => {
1621
const queryClient = useQueryClient();
1722

1823
const mutation = useMutation<ResponseType, Error, RequestType>({
@@ -33,6 +38,9 @@ const useDeleteWorkspaceFile = () => {
3338
queryClient.invalidateQueries({ queryKey: ['files'] });
3439
queryClient.invalidateQueries({ queryKey: ['file', data.$id] });
3540
},
41+
onMutate({ param }) {
42+
setCurrentlyDeletingFile(param.fileId);
43+
},
3644
onError: () => {
3745
toast.error('文档删除失败');
3846
},
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { useQuery } from '@tanstack/react-query';
2+
3+
import client from '@/common/libs/rpc';
4+
5+
interface UseGetUploadStatusProps {
6+
fileId: string;
7+
}
8+
9+
const useGetUploadStatus = ({ fileId }: UseGetUploadStatusProps) => {
10+
const query = useQuery({
11+
queryKey: ['uploadStatus', fileId],
12+
queryFn: async () => {
13+
const response = await client.api.files.uploadStatus[':fileId'].$get({
14+
param: { fileId },
15+
});
16+
17+
if (!response.ok) {
18+
throw new Error('Failed to fetch file');
19+
}
20+
21+
const { data } = await response.json();
22+
23+
return data;
24+
},
25+
refetchInterval: (data) =>
26+
data.state.status === 'success' || data.state.status === 'error'
27+
? false
28+
: 500,
29+
});
30+
31+
return query;
32+
};
33+
34+
export default useGetUploadStatus;

src/common/api/files/useGetWorkspaceFileWithKey.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/common/components/chat/ChatInput.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ const ChatInput: React.FC<ChatInputProps> = ({ isDisabled }) => {
3232
if (e.key === 'Enter' && !e.shiftKey) {
3333
e.preventDefault();
3434

35-
// addMessage();
36-
3735
textareaRef.current?.focus();
3836
}
3937
}}
@@ -45,7 +43,6 @@ const ChatInput: React.FC<ChatInputProps> = ({ isDisabled }) => {
4543
className="absolute bottom-1.5 right-[8px]"
4644
aria-label="send message"
4745
onClick={() => {
48-
// addMessage();
4946
textareaRef.current?.focus();
5047
}}
5148
>

src/common/components/chat/ChatWrapper.tsx

Lines changed: 69 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
'use client';
22

3+
import { ChevronLeft, Loader2, XCircle } from 'lucide-react';
4+
import Link from 'next/link';
5+
6+
import { useGetUploadStatus } from '@/common/api/files';
7+
8+
import ChatInput from './ChatInput';
9+
import { buttonVariants } from '../ui/button';
10+
311
// import { PLANS } from '@/config/stripe'
412
// import { ChatContextProvider } from './ChatContext'
513
// import Messages from './Messages'
@@ -10,88 +18,77 @@ interface ChatWrapperProps {
1018
}
1119

1220
const ChatWrapper: React.FC<ChatWrapperProps> = ({ fileId }) => {
13-
// const { data, isLoading } = trpc.getFileUploadStatus.useQuery(
14-
// {
15-
// fileId,
16-
// },
17-
// {
18-
// refetchInterval: (data) =>
19-
// data?.status === 'SUCCESS' || data?.status === 'FAILED' ? false : 500,
20-
// }
21-
// );
22-
23-
// if (isLoading)
24-
// return (
25-
// <div className="relative flex min-h-full flex-col justify-between gap-2 divide-y divide-zinc-200 bg-zinc-50">
26-
// <div className="mb-28 flex flex-1 flex-col items-center justify-center">
27-
// <div className="flex flex-col items-center gap-2">
28-
// <Loader2 className="h-8 w-8 animate-spin text-blue-500" />
29-
// <h3 className="text-xl font-semibold">载入中...</h3>
30-
// <p className="text-sm text-zinc-500">
31-
// 我们正在准备您的文档
32-
// </p>
33-
// </div>
34-
// </div>
35-
// <ChatInput isDisabled />
36-
// </div>
37-
// );
21+
const { data: status, isLoading } = useGetUploadStatus({ fileId });
3822

39-
// if (data?.status === 'PROCESSING')
40-
// return (
41-
// <div className="relative flex min-h-full flex-col justify-between gap-2 divide-y divide-zinc-200 bg-zinc-50">
42-
// <div className="mb-28 flex flex-1 flex-col items-center justify-center">
43-
// <div className="flex flex-col items-center gap-2">
44-
// <Loader2 className="h-8 w-8 animate-spin text-blue-500" />
45-
// <h3 className="text-xl font-semibold">处里 PDF...</h3>
46-
// <p className="text-sm text-zinc-500">这不会花很长时间。</p>
47-
// </div>
48-
// </div>
49-
// <ChatInput isDisabled />
50-
// </div>
51-
// );
23+
if (isLoading)
24+
return (
25+
<div className="relative flex min-h-full flex-col justify-between gap-2 divide-y divide-zinc-200 bg-zinc-50">
26+
<div className="mb-28 flex flex-1 flex-col items-center justify-center">
27+
<div className="flex flex-col items-center gap-2">
28+
<Loader2 className="h-8 w-8 animate-spin text-blue-500" />
29+
<h3 className="text-xl font-semibold">载入中...</h3>
30+
<p className="text-sm text-zinc-500">我们正在准备您的文档</p>
31+
</div>
32+
</div>
33+
<ChatInput isDisabled />
34+
</div>
35+
);
5236

53-
// if (data?.status === 'FAILED')
54-
// return (
55-
// <div className="relative flex min-h-full flex-col justify-between gap-2 divide-y divide-zinc-200 bg-zinc-50">
56-
// <div className="mb-28 flex flex-1 flex-col items-center justify-center">
57-
// <div className="flex flex-col items-center gap-2">
58-
// <XCircle className="h-8 w-8 text-red-500" />
59-
// <h3 className="text-xl font-semibold">Too many pages in PDF</h3>
60-
// <p className="text-sm text-zinc-500">
61-
// Your{' '}
62-
// <span className="font-medium">
63-
// {isSubscribed ? 'Pro' : 'Free'}
64-
// </span>{' '}
65-
// plan supports up to{' '}
66-
// {isSubscribed
67-
// ? PLANS.find((p) => p.name === 'Pro')?.pagesPerPdf
68-
// : PLANS.find((p) => p.name === 'Free')?.pagesPerPdf}{' '}
69-
// pages per PDF.
70-
// </p>
71-
// <Link
72-
// href="/dashboard"
73-
// className={buttonVariants({
74-
// variant: 'secondary',
75-
// className: 'mt-4',
76-
// })}
77-
// >
78-
// <ChevronLeft className="mr-1.5 h-3 w-3" />
79-
// 返回
80-
// </Link>
81-
// </div>
82-
// </div>
37+
if (status === 'PROCESSING')
38+
return (
39+
<div className="relative flex min-h-full flex-col justify-between gap-2 divide-y divide-zinc-200 bg-zinc-50">
40+
<div className="mb-28 flex flex-1 flex-col items-center justify-center">
41+
<div className="flex flex-col items-center gap-2">
42+
<Loader2 className="h-8 w-8 animate-spin text-blue-500" />
43+
<h3 className="text-xl font-semibold">处里 PDF...</h3>
44+
<p className="text-sm text-zinc-500">这不会花很长时间。</p>
45+
</div>
46+
</div>
47+
<ChatInput isDisabled />
48+
</div>
49+
);
8350

84-
// <ChatInput isDisabled />
85-
// </div>
86-
// );
51+
if (status === 'FAILED')
52+
return (
53+
<div className="relative flex min-h-full flex-col justify-between gap-2 divide-y divide-zinc-200 bg-zinc-50">
54+
<div className="mb-28 flex flex-1 flex-col items-center justify-center">
55+
<div className="flex flex-col items-center gap-2">
56+
<XCircle className="h-8 w-8 text-red-500" />
57+
<h3 className="text-xl font-semibold">Too many pages in PDF</h3>
58+
<p className="text-sm text-zinc-500">
59+
Your{' '}
60+
<span className="font-medium">
61+
{/* {isSubscribed ? 'Pro' : 'Free'} */}
62+
</span>{' '}
63+
plan supports up to{' '}
64+
{/* {isSubscribed
65+
? PLANS.find((p) => p.name === 'Pro')?.pagesPerPdf
66+
: PLANS.find((p) => p.name === 'Free')?.pagesPerPdf}{' '} */}
67+
pages per PDF.
68+
</p>
69+
<Link
70+
href="/dashboard"
71+
className={buttonVariants({
72+
variant: 'secondary',
73+
className: 'mt-4',
74+
})}
75+
>
76+
<ChevronLeft className="mr-1.5 h-3 w-3" />
77+
返回
78+
</Link>
79+
</div>
80+
</div>
81+
<ChatInput isDisabled />
82+
</div>
83+
);
8784

8885
return (
8986
// <ChatContextProvider fileId={fileId}>
9087
<div className="relative flex min-h-full flex-col justify-between gap-2 divide-y divide-zinc-200 bg-zinc-50">
9188
<div className="mb-28 flex flex-1 flex-col justify-between">
9289
{/* <Messages fileId={fileId} /> */}
9390
</div>
94-
{/* <ChatInput /> */}
91+
<ChatInput />
9592
</div>
9693
// </ChatContextProvider>
9794
);

0 commit comments

Comments
 (0)