Compare commits

..

19 Commits

Author SHA1 Message Date
e647d1791d 增加了 gpt-4-1106-preview, gpt-4-32k-0314 2023-11-19 00:21:44 +08:00
a7c76596de no message 2023-09-27 09:52:35 +08:00
ef4dbda961 复制携带标题 2023-08-30 11:15:07 +08:00
3b0fcbfb64 历史记录详情-更多操作按钮修改 2023-08-29 10:47:55 +08:00
c8f13dff8c 历史记录详情-更多操作按钮修改 2023-08-29 10:26:42 +08:00
7e3254bc81 分享历史记录页面-添加隐藏工具栏按钮 2023-08-24 17:32:26 +08:00
adf6af0824 分享历史记录页面-添加隐藏工具栏按钮 2023-08-24 17:24:41 +08:00
ede810f51b 样式修改 2023-08-24 16:18:03 +08:00
df8d2bb3d0 样式修改 2023-08-24 15:59:07 +08:00
b844f82c50 分享详情页修改 2023-08-24 15:18:19 +08:00
a494c0ed16 iframe域名调整 2023-08-24 14:44:59 +08:00
337a3f2d6e iframe域名调整 2023-08-24 14:43:25 +08:00
589cd6c49c 对话框顶部边距设置 2023-08-24 14:40:07 +08:00
fe55fae1f7 页面优化 2023-08-24 14:19:39 +08:00
44409b2bba 样式修改 2023-08-23 17:20:27 +08:00
a2c90214ad 历史记录页修改 2023-08-23 17:13:21 +08:00
3f8a11e1e0 pnpm-系统信息同步 2023-08-21 12:14:31 +08:00
5f061ddf14 pnpm-取消置顶 2023-08-21 10:34:05 +08:00
cf4fedbee2 pnpm提交-排序修正 2023-08-18 18:49:36 +08:00
22 changed files with 434 additions and 173 deletions

View File

@@ -14,5 +14,7 @@ import Conversation from './main/Conversation'
<Conversation client:only />
</div>
</main>
<Send client:load />
<div id='infoSend'>
<Send client:load />
</div>
</main>

View File

@@ -5,12 +5,14 @@ import { conversationMapSortList } from '@/stores/conversation'
import ConversationSidebarItem from './ConversationSidebarItem'
import ConversationSidebarAdd from './ConversationSidebarAdd'
import { addConversation } from '@/stores/conversation'
import { showConversationEditModal } from '@/stores/ui'
import ChatList from '../../pages/chat/datalist'
export default () => {
const { t } = useI18n()
const $conversationMapSortList = useStore(conversationMapSortList)
//设置副标题数字
//设置副标题数字
const setNameNum = (setName: string, numList: any) => {
let list = conversationMapSortList.get()
let title = ''
@@ -21,10 +23,9 @@ export default () => {
let num = seachText[0].match(/\(\d+\)/g) || 'null'
if (num !== 'null') {
count = Math.max(count, Number(num[0].replace('(', '').replace(')', '')))
console.log(count, Number(num[0].replace('(', '').replace(')', '')))
}
})
title =count?`${setName}(${count + 1})`:`${setName}`
title = count ? `${setName}(${count + 1})` : `${setName}${numList.length > 0 ? '(1)' : ''}`
return title
}
@@ -36,45 +37,50 @@ export default () => {
}
}
onMount(() => {
setTimeout(() => {
let itemList = conversationMapSortList.get()
let setName = JSON.parse(sessionStorage.getItem('dialogueName') as any)||'未命名对话'
let numList: number[] = []
itemList.map((res, i) => {
if (checkName(res.name, setName.name)) numList.push(i)
})
// onMount(() => {
// return
// setTimeout(() => {
// let itemList = conversationMapSortList.get()
// let setName = JSON.parse(sessionStorage.getItem('dialogueName') as any) || '未命名对话'
// let numList: number[] = []
// itemList.map((res, i) => {
// if (checkName(res.name, setName.name)) numList.push(i)
// })
if(setName.switch){
addConversation({name:setNameNum(setName.name, numList)})
setName.switch=false
sessionStorage.setItem('dialogueName',JSON.stringify({name:setName.name,switch:false}))
}
}, 1000)
})
// if (setName.switch) {
// addConversation({ name: setNameNum(setName.name, numList), systemInfo: setName.systemInfo })
// showConversationEditModal.set(true)
// setName.switch = false
// sessionStorage.setItem('dialogueName', JSON.stringify({ name: setName.name, switch: false }))
// }
// }, 1000)
// })
return (
<div class="h-full flex flex-col bg-sidebar">
<header class="h-14 fi justify-between px-4 text-xs uppercase">
<p class="px-2">{t('conversations.title')}</p>
<div class="fi gap-1">
{/* <Button
<div style={{height:'100vh'}}>
<div class="h-full flex flex-col bg-sidebar" style={{height:'50%',overflow:'auto'}}>
<header class="h-14 fi justify-between px-4 text-xs uppercase">
<p class="px-2">{t('conversations.title')}</p>
<div class="fi gap-1">
{/* <Button
icon="i-carbon-search"
onClick={() => {}}
size="sm"
/> */}
<ConversationSidebarAdd />
</div>
</header>
<div class="flex-1 overflow-auto">
<div class="px-2">
<For each={$conversationMapSortList()}>
{instance => (
<ConversationSidebarItem instance={instance} />
)}
</For>
<ConversationSidebarAdd />
</div>
</header>
<div class="flex-1 overflow-auto">
<div class="px-2">
<For each={$conversationMapSortList()}>
{instance => (
<ConversationSidebarItem instance={instance} />
)}
</For>
</div>
</div>
</div>
<ChatList></ChatList>
</div>
)
}

View File

@@ -3,6 +3,7 @@ import { currentConversationId, deleteConversationById } from '@/stores/conversa
import { showConversationSidebar } from '@/stores/ui'
import { useI18n } from '@/hooks'
import type { Conversation } from '@/types/conversation'
import { chatShow } from '@/pages/chat/ts/store'
interface Props {
instance: Omit<Conversation, 'messages'> & {
@@ -16,6 +17,15 @@ export default ({ instance }: Props) => {
const isTouchDevice = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
const handleClick = () => {
chatShow.set(false)
let infoHeader = document.getElementById("infoHeader");
let infoSend = document.getElementById("infoSend");
let mtBox = document.getElementsByClassName('flex-1 mt-14 flex flex-col overflow-hidden')[0]
if (!chatShow.get()) {
infoHeader.style.display = "flex";
infoSend.style.display = "block";
mtBox.style.marginTop = '3.5rem';
}
currentConversationId.set(instance.id)
showConversationSidebar.set(false)
}
@@ -36,7 +46,7 @@ export default ({ instance }: Props) => {
<div class="fcc w-8 h-8 rounded-full text-xl shrink-0">
{instance.icon ? instance.icon : <div class="text-base i-carbon-chat" />}
</div>
<div class="flex-1 truncate text-sm">{ instance.name || t('conversations.untitled') }</div>
<div class="flex-1 truncate text-sm">{instance.name || t('conversations.untitled')}</div>
<div class={isTouchDevice ? '' : 'hidden group-hover:block'}>
<div
class="inline-flex p-2 items-center gap-1 rounded-md hv-base"

View File

@@ -16,7 +16,9 @@ export default () => {
})
})
return (
<header onDblClick={scrollController().scrollToTop} class="shrink-0 absolute top-0 left-0 right-0 fi justify-between border-b border-base h-14 px-4">
<header onDblClick={scrollController().scrollToTop}
id='infoHeader'
class="shrink-0 absolute top-0 left-0 right-0 fi justify-between border-b border-base h-14 px-4">
<div class="fi overflow-hidden">
<div
class="fcc p-2 rounded-md text-xl hv-foreground md:hidden"

View File

@@ -1,4 +1,4 @@
import { Match, Switch, createEffect,onMount } from 'solid-js'
import { Match, Switch, createEffect, Show } from 'solid-js'
import { useStore } from '@nanostores/solid'
import { conversationMap, currentConversationId } from '@/stores/conversation'
import { conversationMessagesMap } from '@/stores/messages'
@@ -10,6 +10,8 @@ import Welcome from './Welcome'
import Continuous from './Continuous'
import Single from './Single'
import Image from './Image'
import { chatShow } from '@/pages/chat/ts/store'
import Iframe from '@/pages/chat/components/iframe'
export default () => {
const { t } = useI18n()
@@ -33,7 +35,7 @@ export default () => {
createEffect(() => {
const conversation = currentConversation()
const currentDomain = window.location.hostname;
const contentDomain = currentDomain=='gtering.com'?'Gtering.com':'Ansnid.Com';
const contentDomain = currentDomain == 'gtering.com' ? 'Gtering.com' : 'Ansnid.Com';
document.title = conversation ? `${(conversation.name || t('conversations.untitled'))} - ` + contentDomain : contentDomain
const link = document.querySelector("link[rel~='icon']") as HTMLLinkElement
@@ -43,34 +45,45 @@ export default () => {
}
})
let chat: any = null
chat = useStore(chatShow)
return (
<Switch
fallback={(
<Welcome />
)}
>
<Match when={$currentConversationId() && !currentConversationMessages().length}>
<ConversationEmpty conversation={currentConversation()} />
</Match>
<Match when={currentBot()?.type === 'chat_continuous'}>
<Continuous
conversationId={$currentConversationId()}
messages={currentConversationMessages}
/>
</Match>
<Match when={currentBot()?.type === 'chat_single'}>
<Single
conversationId={$currentConversationId()}
messages={currentConversationMessages}
/>
</Match>
<Match when={currentBot()?.type === 'image_generation'}>
<Image
// conversationId={$currentConversationId()}
messages={currentConversationMessages}
// fetching={isLoading() || !isStreaming()}
/>
</Match>
</Switch>
<>
<Show when={!chat()}>
<Switch
fallback={(
<Welcome />
)}
>
<Match when={$currentConversationId() && !currentConversationMessages().length}>
<ConversationEmpty conversation={currentConversation()} />
</Match>
<Match when={currentBot()?.type === 'chat_continuous'}>
<Continuous
conversationId={$currentConversationId()}
messages={currentConversationMessages}
/>
</Match>
<Match when={currentBot()?.type === 'chat_single'}>
<Single
conversationId={$currentConversationId()}
messages={currentConversationMessages}
/>
</Match>
<Match when={currentBot()?.type === 'image_generation'}>
<Image
// conversationId={$currentConversationId()}
messages={currentConversationMessages}
// fetching={isLoading() || !isStreaming()}
/>
</Match>
</Switch>
</Show>
<Show when={chat()}>
<Iframe></Iframe>
</Show>
</>
)
}

View File

@@ -3,28 +3,24 @@ import { For } from 'solid-js'
import MessageItem from './../main/MessageItem'
import Banner from './banner'
import './style.css'
import { createEffect, createSignal, useEffect,onMount } from 'solid-js'
import { createEffect, createSignal, useEffect, onMount,sg } from 'solid-js'
import { fetchData } from '../../http/api'
export default () => {
const currentDomain = window.location.hostname;
const contentDomain = currentDomain=='gtering.com'?'Gtering.com':'Ansnid.Com';
const contentDomain = currentDomain == 'gtering.com' ? 'Gtering.com' : 'Ansnid.Com';
const [views, setViews] = createSignal(0)
const [url, setUrl] = createSignal('')
const [title, setTitle] = createSignal(contentDomain)
const [items, setItems] = createSignal([])
// localStorage.setItem('theme', 'light');
document.documentElement.classList.toggle('dark', false)
const [views, setViews] = createSignal(0)
const [url, setUrl] = createSignal('')
const [title, setTitle] = createSignal(contentDomain)
const [items, setItems] = createSignal([])
// localStorage.setItem('theme', 'light');
document.documentElement.classList.toggle('dark', false)
onMount(() => {
fetchData(null, function(data){
fetchData(null, function (data) {
setViews(data.data.views);
setUrl(data.data.url);
@@ -32,14 +28,16 @@ export default () => {
setTitle(data.data.title);
document.title = data.data.title ? `${(data.data.title || t('conversations.untitled'))} - ` + contentDomain : contentDomain
}, "/chatgptApi/conversations?url="+encodeURIComponent(window.location.href))
}, "/chatgptApi/conversations?url=" + encodeURIComponent(window.location.href))
}, []);
let [moreBox,setMoreBox]= createSignal(false)
return (
<div class="flex flex-col h-full">
<div style="text-align: center; padding: 0.75rem;">
{title}
{title}
</div>
<div class="scroll-list relative flex flex-col h-full overflow-y-scroll">
<For each={items()}>
@@ -53,7 +51,16 @@ export default () => {
)}
</For>
</div>
<Banner views={views} url={url} />
<div class={[moreBox()?'more-show-box more-hid-box flex-end':'more-hid-box flex-end'].join()} onClick={()=>setMoreBox(!moreBox())}>
<div class='more-btn'>
<Banner views={views} url={url} title={title}/>
<div class='icon'>
<div class='icon-r'></div>
<div class='icon-r mg-l-3'></div>
<div class='icon-r mg-l-3'></div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -1,4 +1,5 @@
export default function Banner({ views, url }: { views: number }) {
import './style.css'
export default function Banner({ views, url ,title}: { views: number }) {
const copyToClipboard = (text) => {
var tempInput = document.createElement("input");
@@ -17,7 +18,7 @@ export default function Banner({ views, url }: { views: number }) {
return (
<div
className="z-10 fixed bottom-10 inset-x-0 mx-auto max-w-fit rounded-lg px-3 py-2 bg-white border border-gray-100 shadow-md flex justify-between space-x-2 items-center"
className="z-10 pos-a more-box mx-auto max-w-fit rounded-lg px-3 py-2 bg-white border border-gray-100 shadow-md flex justify-between space-x-2 items-center"
initial={{ opacity: 0, y: 100 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 100 }}
@@ -43,7 +44,7 @@ export default function Banner({ views, url }: { views: number }) {
<button
onClick={() =>
copyToClipboard(url())
copyToClipboard(`${title()} ${url()}`)
}
className="p-2 flex flex-col space-y-1 items-center rounded-md w-12 hover:bg-gray-100 active:bg-gray-200 transition-all"
>

View File

@@ -15,3 +15,61 @@
.ansnidshare .ansnid_copy{
/* margin: 0px !important;*/
}
.more-btn{
--un-shadow: var(--un-shadow-inset) 0 4px 6px -1px var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 2px 4px -2px var(--un-shadow-color, rgba(0,0,0,0.1));
box-shadow: var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow);
width:2.5rem;
height:2.5rem;
border-radius:50%;
display: flex;
justify-content: center;
align-items: center;
background:#fff;
border:1px solid rgba(0,0,0,0.1);
margin-right:0.3125rem;
}
.more-btn .icon{
width:1.5rem;
display: flex;
align-items: center;
justify-content: center;
}
.more-btn .icon .icon-r{
width:5px;
height:5px;
border-radius:50%;
background: rgba(0,0,0,0.5);
}
.mg-l-3{
margin-left:3px;
}
.pos-a{
position: absolute;
}
.more-box{
right:3.5rem;
}
.more-hid-box{
position: fixed;
bottom:2rem;
right:0.05rem;
z-index:66;
overflow: hidden;
width:3.1rem;
height:5.1rem;
display: flex;
align-items: center;
transition: width linear 0.2s;
}
.more-show-box{
width:24.1rem;
}
.flex-end{
display: flex;
align-items: center;
flex-direction:row-reverse;
}

View File

@@ -1,7 +1,8 @@
import type { JSXElement } from 'solid-js'
import '../../pages/chat/css/list.css'
interface Props {
direction: 'left' | 'right'
direction: 'left' | 'right' | 'none'
class?: string
children: JSXElement
}
@@ -10,6 +11,7 @@ export default (props: Props) => {
const containerBaseClass = {
left: 'w-[260px] h-100dvh border-r',
right: 'w-[300px] h-100dvh border-l',
none:'w-100'
}[props.direction]
return (

View File

@@ -5,7 +5,7 @@ interface Data {}
interface ResponseData {
code: number;
message: string;
data: Array;
data: any;
url: string;
}

View File

@@ -3,17 +3,22 @@ import ConversationSidebarItem from './listItem'
import { createStore } from "solid-js/store";
import '../css/list.css'
import { fetchData } from '../../../http/api'
import { addConversation } from '@/stores/conversation'
import { showConversationEditModal } from '@/stores/ui'
import { conversationMapSortList } from '@/stores/conversation'
import { chatShow, uniqid } from '../ts/store';
import { showConversationSidebar } from '@/stores/ui'
import { useStore } from '@nanostores/solid'
export default () => {
// dataItemLists.set([{id:'1'},{id:'2'},{id:'3'},{id:'4'},{id:'5'},{id:'6'}])
const [list, setList] = createStore({
data: [{ id: '1', Topping: false }, { id: '2', Topping: false }, { id: '3', Topping: false }, { id: '4', Topping: false }, { id: '5', Topping: false }, { id: '6', Topping: false }]
data: [{ title: '' }]
})
type errorObj={
show:boolean,
message:string
type errorObj = {
show: boolean,
message: string
}
let [errorShow, setErrorShow] = createSignal({
@@ -25,18 +30,23 @@ export default () => {
fetchData({}, function (data) {
if (data.code === 200) {
setList('data', () => [...data.data])
} else {
// setErrorFun(data.message)
}
}, '/chat/api', 'GET');
}
//标题
let dialogueName = ''
//新建对话框
const newlyAdded = () => {
window.open(`${location.protocol}//${location.host}`)
let dialogue = {
systemmessage: '',
title: ''
}
// //新建对话框
// const newlyAdded = () => {
// window.open(`${location.protocol}//${location.host}`)
// }
//删除记录
let deleteItem = { key: null, e: null }
const handleDelete = (e: MouseEvent, key: string) => {
@@ -64,25 +74,65 @@ export default () => {
let [pop, setPop] = createSignal(false)
let [popType, setPopType] = createSignal('open')
const popShow = (type: string, e: any, key: number, name: string = '未命名对话') => {
const popShow = (type: string, e: any, key: number, dialogueObj: any = {}) => {
setPopType(type)
if (type == 'delete') {
deleteItem['key'] = key as any
deleteItem['e'] = e
}
if (type === 'open') dialogueName = name
if (type === 'open') dialogue = dialogueObj
setPop(!pop())
}
//设置副标题数字
const setNameNum = (setName: string, numList: any) => {
let list = conversationMapSortList.get()
let title = ''
let count = 0
numList.map((res: number) => {
let regex1 = new RegExp("" + setName + '\\(\\d+\\)', 'g')
let seachText = list[res].name.match(regex1) || 'null'
let num = seachText[0].match(/\(\d+\)/g) || 'null'
if (num !== 'null') {
count = Math.max(count, Number(num[0].replace('(', '').replace(')', '')))
}
})
title = count ? `${setName}(${count + 1})` : `${setName}${numList.length > 0 ? '(1)' : ''}`
return title
}
//查重
const checkName = (name: string, setName: string) => {
let setNameReg = new RegExp(setName, 'g')
if (setNameReg.test(name) && name.replace(/\(\d+\)/g, '') === setName) {
return true
}
}
//确认按钮
const determineBtn = () => {
if (popType() === 'open') {
sessionStorage.setItem('dialogueName', JSON.stringify({ name: dialogueName, switch: true }))
if (isMobile()) {
location.pathname = '/'
} else {
newlyAdded()
sessionStorage.setItem('dialogueName', JSON.stringify({ name: dialogue.title, switch: true, systemInfo: dialogue.systemmessage }))
// if (isMobile()) {
// location.pathname = '/'
// } else {
// newlyAdded()
let itemList = conversationMapSortList.get()
let setName = JSON.parse(sessionStorage.getItem('dialogueName') as any) || '未命名对话'
let numList: number[] = []
itemList.map((res, i) => {
if (checkName(res.name, setName.name)) numList.push(i)
})
if (setName.switch) {
addConversation({ name: setNameNum(setName.name, numList), systemInfo: setName.systemInfo })
showConversationEditModal.set(true)
setName.switch = false
sessionStorage.setItem('dialogueName', JSON.stringify({ name: setName.name, switch: false }))
}
chatShow.set(false)
setDataInfo()
// }
} else if (popType() === 'delete') {
handleDelete(deleteItem['e'] as any, deleteItem['key'] as any)
}
@@ -90,36 +140,66 @@ export default () => {
}
//显示错误提示
const setErrorFun=(message:string)=>{
setErrorShow({
message,
show:true
})
// const setErrorFun = (message: string) => {
// // console.log(message)
// setErrorShow({
// message,
// show: true
// })
// }
//查看记录内容
const chatWatch = (id: string = '') => {
chatShow.set(true)
showConversationSidebar.set(false)
uniqid.set(id)
setDataInfo()
}
const unId = useStore(uniqid)
//设置切换显示内容
const setDataInfo = () => {
let infoSend = document.getElementById("infoSend");
let infoHeader = document.getElementById("infoHeader");
let mtBox = document.getElementsByClassName('flex-1 mt-14 flex flex-col overflow-hidden')[0]
if (chatShow.get()) {
infoSend.style.display = "none";
if (!isMobile()) {
infoHeader.style.display = "none";
mtBox.style.marginTop = 0;
}
} else {
infoSend.style.display = "flex";
if (!isMobile()) {
infoHeader.style.display = "flex";
mtBox.style.marginTop = '3.5rem';
}
}
}
//提示弹窗
const ErrorState = () => (
<div class='tps-error-box'>
<div class="max-w-base h-full flex items-end flex-col justify-between gap-8 sm:(flex-row items-center) py-4 text-error text-sm" style="padding: 1rem;">
<div class="flex-1 w-full">
<div class="fi gap-0.5 mb-1">
<span i-carbon-warning />
<span class="font-semibold">{errorShow().message}</span>
</div>
</div>
<div class="border border-error px-2 py-1 rounded-md hv-base hover:bg-white" onClick={() => { setErrorShow({ show: false, message: errorShow().message }) }} >
Dismiss
</div>
</div>
</div>
)
// const ErrorState = () => (
// <div class='tps-error-box'>
// <div class="max-w-base h-full flex items-end flex-col justify-between gap-8 sm:(flex-row items-center) py-4 text-error text-sm" style="padding: 1rem;">
// <div class="flex-1 w-full">
// <div class="fi gap-0.5 mb-1">
// <span i-carbon-warning />
// <span class="font-semibold">{errorShow().message}</span>
// </div>
// </div>
// <div class="border border-error px-2 py-1 rounded-md hv-base hover:bg-white" onClick={() => { setErrorShow({ show: false, message: errorShow().message }) }} >
// Dismiss
// </div>
// </div>
// </div>
// )
onMount(() => {
getList()
})
return (
<div class="h-full flex flex-col bg-sidebar max-w-350 min-w-260">
<div class="h-full flex flex-col bg-sidebar">
<Show when={pop()}>
<div class='pop center-f'>
<div class='center-f text-box'>
@@ -140,14 +220,20 @@ export default () => {
</div>
</div>
</Show>
<Show when={errorShow().show}>
{/* <Show when={errorShow().show}>
<ErrorState />
</Show>
<div class="flex-1 overflow-auto">
<div class="px-2">
</Show> */}
<div class="overflow-auto px-2">
<div style={{ width: '100%' }}>
<For each={list.data}>
{(instance, i) => (
<ConversationSidebarItem popShow={popShow} setErrorFun={setErrorFun} instanceData={{ ...instance }} infoList={list.data} key={i as any} setList={setList} />
<Show when={instance.title}>
<div class={[instance.uniqid == unId()?'click-bg':''].join()}>
<ConversationSidebarItem
clickInfo={instance.uniqid == unId()}
chatWatch={chatWatch} popShow={popShow} instanceData={{ ...instance }} infoList={list.data} key={i as any} setList={setList} />
</div>
</Show>
)}
</For>
</div>

View File

@@ -0,0 +1,26 @@
import { keys } from 'idb-keyval'
import '../css/list.css'
import { createSignal, Switch, Match } from 'solid-js'
import { uniqid } from '@/pages/chat/ts/store'
import { useStore } from '@nanostores/solid'
interface Props {
}
export default () => {
let id: any = ''
id = useStore(uniqid) as any
return (
<Switch>
<Match when={id()}>
<div style={{ width: '100%', height: '100%' }} id='iframe'>
<iframe src={`/share/?id=${id()}`} style={{ width: '100%', height: '100%' }}></iframe>
</div>
</Match>
<Match when={!id()}>
<div></div>
</Match>
</Switch>
)
}

View File

@@ -1,6 +1,6 @@
import { keys } from 'idb-keyval'
import '../css/list.css'
import { createSignal } from 'solid-js'
import { createSignal,splitProps } from 'solid-js'
import { fetchData } from '../../../http/api'
type dataList = {
@@ -8,47 +8,52 @@ type dataList = {
}
interface Props {
instanceData: Omit<dataList, 'messages'> & {},
instanceData: {
title?:string,
istop?:number,
uniqid?:string
},
key: any,
setList: Function,
infoList: any,
popShow: Function,
setErrorFun:Function
chatWatch:Function,
clickInfo:any
}
export default ({ instanceData, key, setList, infoList, popShow,setErrorFun }: Props) => {
export default ({ instanceData, key, setList, infoList, popShow,chatWatch,clickInfo }: Props,props:any) => {
//设置数据
const instanceItem = instanceData
let instance = instanceItem || { id: '', name: '' }
let instance = instanceItem || { id: '', name: '',uniqid:'' }
const isTouchDevice = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
const handleClick = () => {
// console.log(dataList)
}
//获取置顶数据
//置顶数据排序
const getToppingItem = (arr: any) => {
let toppingArr: { id: string, istop: boolean }[] = []
let copyArr: any[]=[]
arr.map((res: { istop: boolean; id: string }, i: number) => {
if (res.istop) {
toppingArr.push(arr.splice(i, 1)[0] as { istop: boolean; id: string })
copyArr.push(arr[i])
}else{
toppingArr.push(arr[i])
}
})
return toppingArr
// console.log([...copyArr,...toppingArr])
return [...copyArr,...toppingArr]
}
//设置置顶
//设置数据置顶
const setItemTop = (uniqid: string, item: any) => {
return new Promise((res, rej) => {
fetchData({ uniqid }, function (data) {
if (data.code === 200) {
item.istop = item.istop ? 0 : 1
} else {
setErrorFun(data.message)
// setErrorFun(data.message)
}
res(null)
}, '/chat/top', 'GET');
}, !item.istop?'/chat/top':'/chat/cancelTop', 'POST');
})
}
@@ -58,7 +63,7 @@ export default ({ instanceData, key, setList, infoList, popShow,setErrorFun }: P
let item = arr[key]
setItemTop(item.uniqid, item).then(res=>{
let toppindItem = getToppingItem(arr)
setList('data', (list: null[]) => [...toppindItem, ...arr])
setList('data', (list: null[]) => [...toppindItem])
})
e.stopPropagation()
}
@@ -66,9 +71,11 @@ export default ({ instanceData, key, setList, infoList, popShow,setErrorFun }: P
return (
<div
class={[
clickInfo?
'group fi h-10 my-0.5 px-2 gap-2 hv-base rounded-md click-bg' :
'group fi h-10 my-0.5 px-2 gap-2 hv-base rounded-md'
].join(' ')}
onClick={handleClick}
onClick={()=>chatWatch(instance.uniqid)}
>
<div class="fcc w-8 h-8 rounded-full text-xl shrink-0">
<div class="text-base i-carbon-chat" />
@@ -78,7 +85,7 @@ export default ({ instanceData, key, setList, infoList, popShow,setErrorFun }: P
<div class={[isTouchDevice ? '' : 'hidden group-hover:block'].join('')}>
<div
class="inline-flex p-2 items-center gap-1 rounded-md hv-base"
onClick={() => popShow('open', null, null, instance.title)}
onClick={(e) => {popShow('open', null, null, instance);e.stopPropagation()}}
>
<div class='add-new-icon'></div>
</div>
@@ -89,14 +96,14 @@ export default ({ instanceData, key, setList, infoList, popShow,setErrorFun }: P
class="inline-flex p-2 items-center gap-1 rounded-md hv-base"
onClick={e => setDataTop(e, key())}
>
<div class='list-top-icon'></div>
<div class={[instance.istop === 1 ?'list-top-icon-b':'list-top-icon'].join('')}></div>
</div>
</div>
<div class={isTouchDevice ? '' : 'hidden group-hover:block'}>
<div
class="inline-flex p-2 items-center gap-1 rounded-md hv-base"
onClick={e => popShow('delete', e, key())}
onClick={e => {popShow('delete', e, key());e.stopPropagation()}}
>
<div class="i-carbon-close" />
</div>

View File

@@ -17,6 +17,13 @@
background-position: center;
background-size: 1rem 1rem;
}
.list-top-icon-b {
width: 1rem;
height: 1rem;
background: url('../img/posTopB.svg') no-repeat;
background-position: center;
background-size: 1rem 1rem;
}
.add-new-icon {
width: 1rem;
@@ -90,4 +97,22 @@
height:10rem;
background:rgba(246, 246, 246, 1);
width:100%;
}
.chat-list-title{
font-size:0.75rem;
line-height:1rem;
height:3.5rem;
text-transform:uppercase;
padding:0 1rem;
display: flex;
align-items: center;
}
.top-bor{
border-top:1px solid #e9ecef;
}
.click-bg{
background: rgba(243, 243, 243, 1) !important;
border-radius: 0.375rem;
}

View File

@@ -1,21 +0,0 @@
---
import Layout from '@/layouts/Layout.astro'
import Main from '@/components/Main.astro'
import ConversationSidebar from './components/dataList'
import ModalsLayer from '@/components/ModalsLayer'
import Sidebar from '@/components/ui/Sidebar'
import BuildStores from '@/components/client-only/BuildStores'
import './css/list.css'
---
<Layout title="Ansnid">
<div class="h-100vh w-screen flex">
<Sidebar direction="left" class='w-100'>
<ConversationSidebar client:only="solid-js" />
</Sidebar>
<!-- <Main /> -->
</div>
<!-- <ModalsLayer client:only />
<BuildStores client:only /> -->
</Layout>

View File

@@ -0,0 +1,23 @@
import ConversationSidebar from './components/dataList'
import Sidebar from '@/components/ui/Sidebar'
import './css/list.css'
export default () => {
return (
<div class='top-bor' style={{height:'50%',overflow:'auto'}}>
<div class='chat-list-title'>
</div>
<div class="flex">
<Sidebar direction="none" class=''>
<ConversationSidebar />
</Sidebar>
</div>
{/* <ModalsLayer />
<BuildStores/> */}
</div>
)
}

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1692866656055" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3806" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M221 592c-44.183 0-80-35.817-80-80s35.817-80 80-80 80 35.817 80 80-35.817 80-80 80z m291 0c-44.183 0-80-35.817-80-80s35.817-80 80-80 80 35.817 80 80-35.817 80-80 80z m291 0c-44.183 0-80-35.817-80-80s35.817-80 80-80 80 35.817 80 80-35.817 80-80 80z" fill="#000000" p-id="3807"></path></svg>

After

Width:  |  Height:  |  Size: 622 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1692354575685" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2366" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M43.072 974.72l380.864-301.952 151.936 161.6c0 0 63.424 17.28 67.328-30.72l-3.904-163.584 225.088-259.648 98.048-5.696c0 0 76.928-15.488 21.184-82.752l-275.072-276.928c0 0-74.944-9.6-69.248 59.584l0 75.008L383.552 367.104 225.856 376.64c0 0-57.728 19.2-36.608 69.248l148.16 146.176L43.072 974.72 43.072 974.72z" fill="#2c2c2c" p-id="2367"></path></svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@@ -0,0 +1,3 @@
import { atom } from 'nanostores';
export const chatShow=atom(false)
export const uniqid=atom('')

View File

@@ -6,6 +6,7 @@ import Settings from '@/components/settings/SettingsSidebar'
import ModalsLayer from '@/components/ModalsLayer'
import Sidebar from '@/components/ui/Sidebar'
import BuildStores from '@/components/client-only/BuildStores'
---
<Layout title="Ansnid">

View File

@@ -42,12 +42,18 @@ const providerOpenAI = () => {
type: 'select',
options: [
{ value: 'gpt-3.5-turbo', label: 'gpt-3.5-turbo' },
{ value: 'gpt-3.5-turbo-16k', label: 'gpt-3.5-turbo-16k' },
{ value: 'gpt-4', label: 'gpt-4' },
{ value: 'gpt-4-0314', label: 'gpt-4-0314' },
{ value: 'gpt-4-0613', label: 'gpt-4-0613' },
{ value: 'gpt-4-1106-preview', label: 'gpt-4-1106-preview' },
{ value: 'gpt-4-32k', label: 'gpt-4-32k' },
{ value: 'gpt-4-32k-0314', label: 'gpt-4-32k-0314' },
{ value: 'gpt-4-32k-0613', label: 'gpt-4-32k-0613' },
{ value: 'gpt-3.5-turbo-0301', label: 'gpt-3.5-turbo-0301' },
{ value: 'gpt-3.5-turbo-0613', label: 'gpt-3.5-turbo-0613' },
{ value: 'gpt-3.5-turbo-1106', label: 'gpt-3.5-turbo-1106' },
{ value: 'gpt-3.5-turbo-16k', label: 'gpt-3.5-turbo-16k' },
{ value: 'gpt-3.5-turbo-16k-0613', label: 'gpt-3.5-turbo-16k-0613' },
],
default: 'gpt-3.5-turbo',
},

View File

@@ -55,6 +55,7 @@ export const rebuildConversationStore = async() => {
}
export const addConversation = action(conversationMap, 'addConversation', (map, instance?: Partial<Conversation>) => {
console.log(conversationMap,instance)
const instanceId = instance?.id || `id_${Date.now()}`
const conversation: Conversation = {
id: instanceId,
@@ -62,6 +63,7 @@ export const addConversation = action(conversationMap, 'addConversation', (map,
name: instance?.name || '',
icon: instance?.icon || '',
lastUseTime: Date.now(),
systemInfo:instance?.systemInfo
}
map.setKey(instanceId, conversation)
db.setItem(instanceId, conversation)