add poster
This commit is contained in:
45
package-lock.json
generated
45
package-lock.json
generated
@@ -16,6 +16,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.1.8",
|
"@radix-ui/react-tooltip": "^1.1.8",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"katex": "^0.16.21",
|
"katex": "^0.16.21",
|
||||||
"lucide-react": "^0.263.1",
|
"lucide-react": "^0.263.1",
|
||||||
"openai": "^4.83.0",
|
"openai": "^4.83.0",
|
||||||
@@ -2111,6 +2112,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/base64-arraybuffer": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/base64-js": {
|
"node_modules/base64-js": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
@@ -2478,6 +2487,14 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/css-line-break": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||||
|
"dependencies": {
|
||||||
|
"utrie": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cssesc": {
|
"node_modules/cssesc": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||||
@@ -3241,6 +3258,18 @@
|
|||||||
"url": "https://opencollective.com/unified"
|
"url": "https://opencollective.com/unified"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/html2canvas": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
|
||||||
|
"dependencies": {
|
||||||
|
"css-line-break": "^2.1.0",
|
||||||
|
"text-segmentation": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/human-signals": {
|
"node_modules/human-signals": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
|
||||||
@@ -5845,6 +5874,14 @@
|
|||||||
"tailwindcss": ">=3.0.0 || insiders"
|
"tailwindcss": ">=3.0.0 || insiders"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/text-segmentation": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||||
|
"dependencies": {
|
||||||
|
"utrie": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/thenify": {
|
"node_modules/thenify": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
||||||
@@ -6118,6 +6155,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/utrie": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"base64-arraybuffer": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vfile": {
|
"node_modules/vfile": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/vfile/-/vfile-6.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/vfile/-/vfile-6.0.3.tgz",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.1.8",
|
"@radix-ui/react-tooltip": "^1.1.8",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
"html2canvas": "^1.4.1",
|
||||||
"katex": "^0.16.21",
|
"katex": "^0.16.21",
|
||||||
"lucide-react": "^0.263.1",
|
"lucide-react": "^0.263.1",
|
||||||
"openai": "^4.83.0",
|
"openai": "^4.83.0",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
import { Send, Menu, MoreHorizontal, UserPlus, UserMinus, Users2, Users, MoreVertical, Mic, MicOff } from 'lucide-react';
|
import { Send, Menu, MoreHorizontal, UserPlus, UserMinus, Users2, Users, MoreVertical, Share2, Mic, MicOff } from 'lucide-react';
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
@@ -25,6 +25,8 @@ import ReactMarkdown from 'react-markdown';
|
|||||||
import remarkGfm from 'remark-gfm'
|
import remarkGfm from 'remark-gfm'
|
||||||
import remarkMath from 'remark-math'
|
import remarkMath from 'remark-math'
|
||||||
import rehypeKatex from 'rehype-katex'
|
import rehypeKatex from 'rehype-katex'
|
||||||
|
import html2canvas from 'html2canvas';
|
||||||
|
import { SharePoster } from '@/components/SharePoster';
|
||||||
|
|
||||||
// 使用本地头像数据,避免外部依赖
|
// 使用本地头像数据,避免外部依赖
|
||||||
const getAvatarData = (name: string) => {
|
const getAvatarData = (name: string) => {
|
||||||
@@ -349,6 +351,16 @@ const ChatUI = () => {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// 添加对聊天区域的引用
|
||||||
|
const chatAreaRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
// 更新分享函数
|
||||||
|
const [showPoster, setShowPoster] = useState(false);
|
||||||
|
|
||||||
|
const handleShareChat = () => {
|
||||||
|
setShowPoster(true);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<KaTeXStyle />
|
<KaTeXStyle />
|
||||||
@@ -437,7 +449,7 @@ const ChatUI = () => {
|
|||||||
{/* Main Chat Area */}
|
{/* Main Chat Area */}
|
||||||
<div className="flex-1 overflow-hidden">
|
<div className="flex-1 overflow-hidden">
|
||||||
<ScrollArea className="h-full p-4">
|
<ScrollArea className="h-full p-4">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4" ref={chatAreaRef}>
|
||||||
{messages.map((message) => (
|
{messages.map((message) => (
|
||||||
<div key={message.id}
|
<div key={message.id}
|
||||||
className={`flex items-start gap-2 ${message.sender.name === "我" ? "justify-end" : ""}`}>
|
className={`flex items-start gap-2 ${message.sender.name === "我" ? "justify-end" : ""}`}>
|
||||||
@@ -520,6 +532,23 @@ const ChatUI = () => {
|
|||||||
{/* Input Area */}
|
{/* Input Area */}
|
||||||
<div className="bg-white border-t pb-[calc(0.75rem+env(safe-area-inset-bottom))] pt-3 px-4">
|
<div className="bg-white border-t pb-[calc(0.75rem+env(safe-area-inset-bottom))] pt-3 px-4">
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={handleShareChat}
|
||||||
|
className="px-3"
|
||||||
|
>
|
||||||
|
<Share2 className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>分享聊天记录</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
<Input
|
<Input
|
||||||
placeholder="输入消息..."
|
placeholder="输入消息..."
|
||||||
className="flex-1"
|
className="flex-1"
|
||||||
@@ -615,6 +644,13 @@ const ChatUI = () => {
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 添加 SharePoster 组件 */}
|
||||||
|
<SharePoster
|
||||||
|
isOpen={showPoster}
|
||||||
|
onClose={() => setShowPoster(false)}
|
||||||
|
chatAreaRef={chatAreaRef}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user