1
This commit is contained in:
@@ -35,11 +35,11 @@ interface IProps<T> {
|
||||
}
|
||||
|
||||
export const gradients = [
|
||||
'bg-amber-500',
|
||||
'bg-orange-600',
|
||||
'bg-teal-500',
|
||||
'bg-purple-600',
|
||||
'bg-blue-700'
|
||||
'bg-[#FF9B25]',
|
||||
'bg-[#04BCD2]',
|
||||
'bg-[#2586FF]',
|
||||
'bg-[#D855D3]',
|
||||
'bg-[#C04B51]'
|
||||
]
|
||||
|
||||
// 'bg-slate-600',
|
||||
@@ -61,7 +61,7 @@ export const gradients = [
|
||||
// 'bg-pink-600',
|
||||
// 'bg-rose-600'
|
||||
export function TitleIconBg({ id, className = '', children = <SkillIcon /> }) {
|
||||
return <div className={cname(`rounded-sm flex justify-center items-center ${gradients[parseInt(id + '', 16) % gradients.length]}`, className)}>{children}</div>
|
||||
return <div className={cname(`flex justify-center items-center cursor-pointer ${gradients[parseInt(id + '', 16) % gradients.length]}`, className)} style={{borderRadius:"7px"}}>{children}</div>
|
||||
}
|
||||
|
||||
export default function CardComponent<T>({
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { useMessageStore } from "./messageStore";
|
||||
import GuideQuestions from "./GuideQuestions";
|
||||
import { ClearIcon } from "@/components/bs-icons/clear";
|
||||
import duihua_send from "../../../assets/chat/duihua-send.png";
|
||||
|
||||
export default function ChatInput({ clear, form, questions, inputForm, wsUrl, onBeforSend }) {
|
||||
const { toast } = useToast()
|
||||
@@ -230,8 +231,8 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on
|
||||
// setInputEmpty(textarea.value.trim() === '')
|
||||
}
|
||||
|
||||
return <div className="absolute bottom-0 w-full pt-1 bg-[#fff] dark:bg-[#1B1B1B]">
|
||||
<div className={`relative ${clear && 'pl-9'}`}>
|
||||
return <div className="absolute bottom-0 w-full bg-[#fff] dark:bg-[#000000]">
|
||||
<div className={`relative`}>
|
||||
{/* form */}
|
||||
{
|
||||
formShow && <div className="relative">
|
||||
@@ -248,14 +249,14 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on
|
||||
onClick={handleClickGuideWord}
|
||||
/>
|
||||
{/* clear */}
|
||||
<div className="flex absolute left-0 top-4 z-10">
|
||||
{/* <div className="flex absolute left-0 top-4 z-10">
|
||||
{
|
||||
clear && <div
|
||||
className={`w-6 h-6 rounded-sm hover:bg-gray-200 cursor-pointer flex justify-center items-center `}
|
||||
onClick={() => { !inputLock.locked && destory() }}
|
||||
><ClearIcon className={!showWhenLocked && inputLock.locked ? 'text-gray-400' : 'text-gray-950'} ></ClearIcon></div>
|
||||
}
|
||||
</div>
|
||||
</div> */}
|
||||
{/* form */}
|
||||
<div className="flex absolute left-3 top-4 z-10">
|
||||
{
|
||||
@@ -266,30 +267,36 @@ export default function ChatInput({ clear, form, questions, inputForm, wsUrl, on
|
||||
}
|
||||
</div>
|
||||
{/* send */}
|
||||
<div className="flex gap-2 absolute right-3 top-4 z-10">
|
||||
<div className="flex gap-2 absolute right-[2.5%] z-10">
|
||||
<div
|
||||
id="bs-send-btn"
|
||||
className="w-6 h-6 rounded-sm hover:bg-gray-200 cursor-pointer flex justify-center items-center"
|
||||
className="w-[68px] h-[40px] bg-[#FFD54C] cursor-pointer flex justify-center items-center"
|
||||
onClick={() => { !inputLock.locked && handleSendClick() }}
|
||||
><SendIcon className={inputLock.locked ? 'text-gray-400' : 'text-gray-950'}></SendIcon></div>
|
||||
style={{borderRadius:"20px"}}
|
||||
>
|
||||
{/* <SendIcon className={inputLock.locked ? 'text-gray-400' : 'text-gray-950'}></SendIcon> */}
|
||||
<img src={duihua_send} className="w-[20px]" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
{/* question */}
|
||||
<Textarea
|
||||
<textarea
|
||||
id="bs-send-input"
|
||||
ref={inputRef}
|
||||
rows={1}
|
||||
style={{ height: 56 }}
|
||||
style={{ height: 34 }}
|
||||
disabled={inputLock.locked}
|
||||
onInput={handleTextAreaHeight}
|
||||
placeholder={inputLock.locked ? inputLock.reason : t('chat.inputPlaceholder')}
|
||||
className={"resize-none py-4 pr-10 text-md min-h-6 max-h-[200px] scrollbar-hide dark:bg-[#2A2B2E] text-gray-800" + (form && ' pl-10')}
|
||||
// className={"resize-none py-4 pr-10 text-md min-h-6 max-h-[200px] scrollbar-hide dark:bg-[#2A2B2E] text-gray-800" + (form && ' pl-10')}
|
||||
className="questionTextarea w-full resize-none border-none bg-transparent outline-none max-h-[160px]"
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === "Enter" && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
!inputLock.locked && handleSendClick()
|
||||
}
|
||||
}}
|
||||
></Textarea>
|
||||
></textarea>
|
||||
<p className="w-[100%] text-center text-[#666666]">内容由AI生成,仅供参考</p>
|
||||
</div>
|
||||
<p className="text-center text-sm pt-2 pb-4 text-gray-400">{appConfig.dialogTips}</p>
|
||||
</div>
|
||||
|
||||
@@ -27,13 +27,13 @@ export default function GuideQuestions({ locked, chatId, questions, onClick }) {
|
||||
if (locked || !words.length) return null
|
||||
|
||||
if (showGuideQuestion) return <div className="relative">
|
||||
<div className="absolute left-0 bottom-0">
|
||||
<p className="text-gray-950 text-sm mb-2 bg-[rgba(255,255,255,0.8)] rounded-md w-fit px-2 py-1">{t('chat.recommendationQuestions')}</p>
|
||||
<div className="absolute left-[14px] bottom-0">
|
||||
<p className="text-[#fff] mb-[10px] bg-[]">推荐问题</p>
|
||||
{
|
||||
words.map((question, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="w-fit bg-[#d4dffa] border-2 border-gray-50 shadow-md text-gray-600 rounded-md mb-1 px-4 py-1 text-sm cursor-pointer"
|
||||
className="w-fit bg-[#52430c] shadow-md text-[#fff] rounded-md mb-1 px-4 py-1 text-sm cursor-pointer"
|
||||
onClick={() => {
|
||||
setShowGuideQuestion(false)
|
||||
onClick(question)
|
||||
|
||||
@@ -80,7 +80,7 @@ export default function MessageBs({ data, onUnlike = () => { }, onSource }: { da
|
||||
return <div className="flex w-full py-1">
|
||||
<div className="w-fit max-w-[90%]">
|
||||
{data.sender && <p className="text-gray-600 text-xs mb-2">{data.sender}</p>}
|
||||
<div className="min-h-8 px-6 py-4 rounded-2xl bg-[#F5F6F8] dark:bg-[#313336]">
|
||||
<div className="ml-[14px] min-h-8 px-6 py-4 rounded-2xl bg-[#13110D] dark:bg-[#13110D] text-[#fff]">
|
||||
<div className="flex gap-2">
|
||||
<div className="w-6 h-6 min-w-6 flex justify-center items-center rounded-full" style={{ background: avatarColor }} ><AvatarIcon /></div>
|
||||
{data.message.toString() ?
|
||||
|
||||
@@ -27,7 +27,7 @@ export default function MessageUser({ useName, data }: { data: ChatMessageType }
|
||||
return <div className="flex justify-end w-full py-1">
|
||||
<div className="w-fit min-h-8 max-w-[90%]">
|
||||
{useName && <p className="text-gray-600 text-xs mb-2 text-right">{useName}</p>}
|
||||
<div className="rounded-2xl px-6 py-4 bg-[#EEF2FF] dark:bg-[#333A48]">
|
||||
<div className="mr-[14px] rounded-2xl px-6 py-4 bg-[#EEF2FF] dark:bg-[#333A48]">
|
||||
<div className="flex gap-2 ">
|
||||
<div className="text-[#0D1638] dark:text-[#CFD5E8] text-sm break-all whitespace-break-spaces">{msg}</div>
|
||||
<div className="w-6 h-6 min-w-6"><img src="/user.png" alt="" /></div>
|
||||
@@ -36,7 +36,7 @@ export default function MessageUser({ useName, data }: { data: ChatMessageType }
|
||||
{/* 附加信息 */}
|
||||
{
|
||||
// 数组类型的 data通常是文件上传消息,不展示附加按钮
|
||||
!Array.isArray(data.message.data) && <div className="flex justify-between mt-2">
|
||||
!Array.isArray(data.message.data) && <div className="flex justify-between mt-2 mr-[14px]">
|
||||
<span></span>
|
||||
<div className="flex gap-2 text-gray-400 cursor-pointer self-end">
|
||||
{!running && <Pencil2Icon className="hover:text-gray-500" onClick={() => handleResend(false)} />}
|
||||
|
||||
@@ -12,6 +12,13 @@ import {
|
||||
} from "../../bs-ui/sheet";
|
||||
import CardComponent from "../cardComponent";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SpotlightCard } from "@lobehub/ui";
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
import robot from "../../../assets/robot.png";
|
||||
import robot2 from "../../../assets/robot2.png";
|
||||
import robot3 from "../../../assets/robot3.png";
|
||||
import zidingyi1 from "../../../assets/npc/zidingyi1.png";
|
||||
import zidingyi2 from "../../../assets/npc/zidingyi2.png";
|
||||
|
||||
export default function SkillSheet({ select, children, onSelect }) {
|
||||
const [keyword, setKeyword] = useState("");
|
||||
@@ -24,7 +31,6 @@ export default function SkillSheet({ select, children, onSelect }) {
|
||||
return res;
|
||||
})
|
||||
);
|
||||
|
||||
const handleSearch = (e) => {
|
||||
const { value } = e.target;
|
||||
setKeyword(value);
|
||||
@@ -37,12 +43,73 @@ export default function SkillSheet({ select, children, onSelect }) {
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
||||
const render = (item: any) => (
|
||||
<Flexbox align={'flex-start'} className={`selectNpcFlexbox`}>
|
||||
{/* <Avatar size={24} src={item.favicon} style={{ flex: 'none' }} /> */}
|
||||
{/* <Flexbox>
|
||||
<div style={{ fontSize: 15, fontWeight: 600 }}>{item.name}</div>
|
||||
<div style={{ opacity: 0.6 }}>{item.name}</div>
|
||||
</Flexbox> */}
|
||||
{/* <Card key={item.id} className="w-[300px] overflow-hidden cursor-pointer" onClick={() => onSelect(item)}>
|
||||
<CardHeader>
|
||||
<CardTitle className=" flex items-center gap-2">
|
||||
<div className={"rounded-full w-[30px] h-[30px] " + gradients[parseInt(item.id, 16) % gradients.length]}></div>
|
||||
<span>{item.name}</span>
|
||||
</CardTitle>
|
||||
<CardDescription className="">{item.description}</CardDescription>
|
||||
</CardHeader>
|
||||
</Card> */}
|
||||
<div className="npcInfoItemBg">
|
||||
<span>
|
||||
<span>
|
||||
<div>
|
||||
{/* <img src={robot} className="w-[160px]" alt=""/> */}
|
||||
{(item.id == "06b1d374-ba97-46e6-8782-c56dec8dcc17" || item.id == "ed8e21f6-9757-43d0-b076-8c6e81bb0580") && <img src={robot2} className="w-[160px]" alt=""/>}
|
||||
{item.id == "ca214b41-2b73-4585-b172-bf1e546cf6ec" && <img src={robot3} className="w-[160px]" alt=""/>}
|
||||
{(item.id != "06b1d374-ba97-46e6-8782-c56dec8dcc17" && item.id != "ed8e21f6-9757-43d0-b076-8c6e81bb0580" && item.id != "ca214b41-2b73-4585-b172-bf1e546cf6ec") && <img src={robot} className="w-[160px]" alt=""/>}
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
{(item.id == "06b1d374-ba97-46e6-8782-c56dec8dcc17" || item.id == "ed8e21f6-9757-43d0-b076-8c6e81bb0580") && <img src={robot2} className="w-[42px]" alt=""/>}
|
||||
{item.id == "ca214b41-2b73-4585-b172-bf1e546cf6ec" && <img src={robot3} className="w-[42px]" alt=""/>}
|
||||
{(item.id != "06b1d374-ba97-46e6-8782-c56dec8dcc17" && item.id != "ed8e21f6-9757-43d0-b076-8c6e81bb0580" && item.id != "ca214b41-2b73-4585-b172-bf1e546cf6ec") && <img src={robot} className="w-[42px]" alt=""/>}
|
||||
{/* <img src={robot} className="w-[42px]" alt=""/> */}
|
||||
<div>
|
||||
<p>{item.name}</p>
|
||||
<div>
|
||||
{/* <div>绘画类</div>
|
||||
<div>绘画类</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-[10px] test-[13px]">{item.description}</p>
|
||||
<div className="flex justify-end mb-[14px] mr-[14px] mt-[14px]">
|
||||
{select.some((_) => _.id === item.id) ? (
|
||||
<Button size="sm" className="h-6 bg-[#FFD025]" disabled>
|
||||
{t("build.added")}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
size="sm"
|
||||
className="h-6 bg-[#FFD025]"
|
||||
onClick={() => onSelect(item)}
|
||||
>
|
||||
{t("build.add")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</Flexbox>
|
||||
);
|
||||
|
||||
return (
|
||||
<Sheet>
|
||||
<SheetTrigger asChild>{children}</SheetTrigger>
|
||||
<SheetContent className="bg-gray-100 sm:min-w-[966px]">
|
||||
<SheetContent className="bg-[#1A1A1A] sm:min-w-[966px]">
|
||||
<div className="flex h-full" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="w-fit p-6">
|
||||
<div className="w-[270px] p-6">
|
||||
<SheetTitle>{t("build.addSkill")}</SheetTitle>
|
||||
<SearchInput
|
||||
value={keyword}
|
||||
@@ -50,47 +117,47 @@ export default function SkillSheet({ select, children, onSelect }) {
|
||||
className="my-6"
|
||||
onChange={handleSearch}
|
||||
/>
|
||||
<Button className="w-full" onClick={toCreateFlow}>
|
||||
{/* <Button className="w-full" onClick={toCreateFlow}>
|
||||
{t("build.createSkill")}
|
||||
</Button>
|
||||
</Button> */}
|
||||
<div className="w-[244px] h-[34px] flex items-center justify-center bg-[#FFD025] text-[#000] cursor-pointer" style={{borderRadius:"34px"}} onClick={toCreateFlow}>{t("build.createSkill")}</div>
|
||||
</div>
|
||||
<div className="flex h-full min-w-[696px] flex-1 flex-wrap content-start gap-1.5 overflow-y-auto bg-[#fff] p-5 pt-12 scrollbar-hide">
|
||||
<div className="min-w-[696px] overflow-y-auto bg-[#000000] scrollbar-hide skillSheet">
|
||||
{onlineFlows[0] ? (
|
||||
onlineFlows.map((flow, i) => (
|
||||
<CardComponent
|
||||
key={i}
|
||||
id={i + 1}
|
||||
data={flow}
|
||||
title={flow.name}
|
||||
description={flow.description}
|
||||
type="sheet"
|
||||
footer={
|
||||
<div className="flex justify-end">
|
||||
{select.some((_) => _.id === flow.id) ? (
|
||||
<Button size="sm" className="h-6" disabled>
|
||||
{t("build.added")}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
size="sm"
|
||||
className="h-6"
|
||||
onClick={() => onSelect(flow)}
|
||||
>
|
||||
{t("build.add")}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
))
|
||||
// onlineFlows.map((flow, i) => (
|
||||
// <CardComponent
|
||||
// key={i}
|
||||
// id={i + 1}
|
||||
// data={flow}
|
||||
// title={flow.name}
|
||||
// description={flow.description}
|
||||
// type="sheet"
|
||||
// footer={
|
||||
// <div className="flex justify-end">
|
||||
// {select.some((_) => _.id === flow.id) ? (
|
||||
// <Button size="sm" className="h-6" disabled>
|
||||
// {t("build.added")}
|
||||
// </Button>
|
||||
// ) : (
|
||||
// <Button
|
||||
// size="sm"
|
||||
// className="h-6"
|
||||
// onClick={() => onSelect(flow)}
|
||||
// >
|
||||
// {t("build.add")}
|
||||
// </Button>
|
||||
// )}
|
||||
// </div>
|
||||
// }
|
||||
// />
|
||||
// ))
|
||||
<SpotlightCard items={onlineFlows} renderItem={render} className="mt-[14px] skillSheetSpotlightCard"/>
|
||||
) : (
|
||||
<div className="flex w-full flex-col items-center justify-center pt-40">
|
||||
<p className="mb-3 text-sm text-muted-foreground">
|
||||
<p className="mb-3 text-sm text-[#fff]">
|
||||
{t("build.empty")}
|
||||
</p>
|
||||
<Button className="w-[200px]" onClick={toCreateFlow}>
|
||||
{t("build.createSkill")}
|
||||
</Button>
|
||||
<div className="w-[200px] h-[34px] flex items-center justify-center bg-[#FFD025] text-[#000] cursor-pointer" style={{borderRadius:"34px"}} onClick={toCreateFlow}>{t("build.createSkill")}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,10 @@ import { useTranslation } from "react-i18next";
|
||||
import { PersonIcon, StarFilledIcon } from "@radix-ui/react-icons";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Button } from "@/components/bs-ui/button";
|
||||
import sousuo from "../../../assets/npc/sousuo.png";
|
||||
import gongjuAdd from "../../../assets/npc/gongjuAdd.png";
|
||||
import gongjuIcon from "../../../assets/npc/gongjuIcon.png";
|
||||
import gongjuIcon1 from "../../../assets/npc/gongjuIcon1.png";
|
||||
|
||||
export default function ToolsSheet({ select, onSelect, children }) {
|
||||
const { t } = useTranslation()
|
||||
@@ -34,35 +38,48 @@ export default function ToolsSheet({ select, onSelect, children }) {
|
||||
<SheetTrigger asChild>
|
||||
{children}
|
||||
</SheetTrigger>
|
||||
<SheetContent className="w-[1000px] sm:max-w-[1000px] bg-gray-100">
|
||||
<SheetContent className="w-[1000px] sm:max-w-[1000px] bg-[#121212]">
|
||||
<div className="flex h-full" onClick={e => e.stopPropagation()}>
|
||||
<div className="w-fit p-6">
|
||||
<SheetTitle>{t('build.addTool')}</SheetTitle>
|
||||
<SearchInput placeholder={t('build.search')} className="mt-6" onChange={(e) => setKeyword(e.target.value)} />
|
||||
<Button
|
||||
<div className="relative mt-[14px]">
|
||||
<img src={sousuo} className="absolute w-[14px] left-[14px] top-[10px]" alt="" />
|
||||
<input placeholder="搜索"
|
||||
className="w-[237px] h-[34px] bg-[#1A1A1A] text-[#fff] pl-[40px]"
|
||||
style={{borderRadius:"17px",outline:"none"}}
|
||||
onChange={(e) => setKeyword(e.target.value)} type="text" />
|
||||
</div>
|
||||
{/* <SearchInput placeholder={t('build.search')} className="mt-6" onChange={(e) => setKeyword(e.target.value)} /> */}
|
||||
{/* <Button
|
||||
className="mt-4 w-full"
|
||||
onClick={() => window.open("/build/tools")}
|
||||
>
|
||||
{t('create')}{t("tools.createCustomTool")}
|
||||
</Button>
|
||||
</Button> */}
|
||||
<div className="w-[237px] h-[27px] bg-[#FFD025] mt-[14px] flex justify-center items-center border-radius-14 cursor-pointer" onClick={() => window.open("/build/tools")}>
|
||||
<img src={gongjuAdd} className="w-[14px]" alt="" />
|
||||
<span className="text-[#333333] ml-[12px]">自定义工具</span>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<div
|
||||
className={`flex items-center gap-2 px-4 py-2 rounded-md cursor-pointer hover:bg-muted-foreground/10 transition-all duration-200 ${type === 'default' && 'bg-muted-foreground/10'}`}
|
||||
className={`flex items-center gap-2 px-4 py-2 rounded-md cursor-pointer hover:bg-muted-foreground/10 transition-all duration-200 ${type === 'default' && 'bg-[#2A271D] text-[#FFD54C]'}`}
|
||||
onClick={() => setType('default')}
|
||||
>
|
||||
<PersonIcon />
|
||||
<span>{t('tools.builtinTools')}</span>
|
||||
{/* <PersonIcon /> */}
|
||||
{type === "default" ? <img src={gongjuIcon1} className="w-[14px]" alt="" /> : <img src={gongjuIcon} className="w-[14px]" alt="" />}
|
||||
<span className="ml-[8px] text-[#999999]">内置工具</span>
|
||||
</div>
|
||||
<div
|
||||
className={`flex items-center gap-2 px-4 py-2 rounded-md cursor-pointer hover:bg-muted-foreground/10 transition-all duration-200 mt-1 ${type === 'custom' && 'bg-muted-foreground/10'}`}
|
||||
className={`flex items-center gap-2 px-4 py-2 rounded-md cursor-pointer hover:bg-muted-foreground/10 transition-all duration-200 mt-1 ${type === 'custom' && 'bg-[#2A271D] text-[#FFD54C]'}`}
|
||||
onClick={() => setType('custom')}
|
||||
>
|
||||
<StarFilledIcon />
|
||||
<span>{t('tools.customTools')}</span>
|
||||
{type === "custom" ? <img src={gongjuIcon1} className="w-[14px]" alt="" /> : <img src={gongjuIcon} className="w-[14px]" alt="" />}
|
||||
{/* <StarFilledIcon /> */}
|
||||
<span className="ml-[8px] text-[#999999]">自定义工具</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 bg-[#fff] p-5 pt-12 h-full overflow-auto scrollbar-hide">
|
||||
<div className="flex-1 bg-[#121212] p-5 pt-12 h-full overflow-auto scrollbar-hide">
|
||||
<Accordion type="single" collapsible className="w-full">
|
||||
{
|
||||
options.length ? options.map(el => (
|
||||
|
||||
Reference in New Issue
Block a user