Skip to content

Commit

Permalink
feat: 增加历史记录
Browse files Browse the repository at this point in the history
  • Loading branch information
weaigc committed Aug 26, 2023
1 parent b78414c commit 46de470
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/app/globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ body {
}

.scroll-button {
bottom: 5rem;
bottom: 4rem;
z-index: 100;

@media (max-width: 767px) {
Expand Down
8 changes: 7 additions & 1 deletion src/components/chat-history.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { useCallback, useEffect, useState } from 'react'
import { useChatHistory, ChatConversation } from '@/lib/hooks/chat-history'
import { IconEdit, IconTrash, IconDownload, IconCheck, IconClose } from './ui/icons'
import { cn, formatDate } from '@/lib/utils'
import { useAtomValue } from 'jotai'
import { historyAtom } from '@/state'
import { debug } from '@/lib/isomorphic'

interface ConversationTheadProps {
conversation: ChatConversation
Expand Down Expand Up @@ -71,8 +74,11 @@ export function ConversationThead({ conversation, onRename, onDelete, onUpdate,
}

export function ChatHistory({ className, onExpaned }: { className?: string, onExpaned: (flag: boolean) => void }) {
const { chatHistory, refreshChats, deleteChat, renameChat, updateMessage, downloadMessage } = useChatHistory()
const historyEnabled = useAtomValue(historyAtom)
const { chatHistory, refreshChats, deleteChat, renameChat, updateMessage, downloadMessage } = useChatHistory(historyEnabled)
useEffect(() => {
debug('historyEnabled', historyEnabled)
if (!historyEnabled) return
refreshChats()
.then(res =>{
if (res?.chats.length > 0) {
Expand Down
47 changes: 41 additions & 6 deletions src/components/settings.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useEffect, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { useAtom } from 'jotai'
import { Switch } from '@headlessui/react'
import { toast } from 'react-hot-toast'
import { hashAtom, voiceAtom } from '@/state'
import { hashAtom, historyAtom, voiceAtom } from '@/state'
import {
Dialog,
DialogContent,
Expand All @@ -17,12 +17,12 @@ import { ChunkKeys, parseCookies, extraCurlFromCookie, encodeHeadersToCookie, ge
import { ExternalLink } from './external-link'
import { useCopyToClipboard } from '@/lib/hooks/use-copy-to-clipboard'


export function Settings() {
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 2000 })
const [loc, setLoc] = useAtom(hashAtom)
const [curlValue, setCurlValue] = useState(extraCurlFromCookie(parseCookies(document.cookie, ChunkKeys)))
const [imageOnly, setImageOnly] = useState(getCookie('IMAGE_ONLY') !== '0')
const [enabledHistory, setHistory] = useAtom(historyAtom)
const [enableTTS, setEnableTTS] = useAtom(voiceAtom)

useEffect(() => {
Expand All @@ -31,6 +31,26 @@ export function Settings() {
}
}, [isCopied])

const handleSwitchImageOnly = useCallback((checked: boolean) => {
let headerValue = curlValue
if (headerValue) {
try {
headerValue = atob(headerValue)
} catch (e) { }
if (!/^\s*curl ['"]https:\/\/(www|cn)\.bing\.com\/turing\/captcha\/challenge['"]/.test(headerValue)) {
toast.error('格式不正确')
return
}
if (RegExp.$1 === 'cn' && checked === false) {
toast.error('你配置的中文域名 cn.bing.com 仅支持画图')
return
}
setImageOnly(checked)
} else {
toast.error('请先配置链接')
}
}, [curlValue])

if (loc === 'settings') {
return (
<Dialog open onOpenChange={() => setLoc('')} modal>
Expand Down Expand Up @@ -61,18 +81,33 @@ export function Settings() {
onChange={e => setCurlValue(e.target.value)}
/>
<div className="flex gap-2">
身份信息仅用于画图(推荐)
<Switch
checked={imageOnly}
className={`${imageOnly ? 'bg-blue-600' : 'bg-gray-200'} relative inline-flex h-6 w-11 items-center rounded-full`}
onChange={(checked: boolean) => setImageOnly(checked)}
onChange={(checked: boolean) => handleSwitchImageOnly(checked)}
>
<span
className={`${imageOnly ? 'translate-x-6' : 'translate-x-1'} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</Switch>
身份信息仅用于画图
</div>

{!imageOnly && (
<div className="flex gap-2">
<Switch
checked={enabledHistory}
className={`${enabledHistory ? 'bg-blue-600' : 'bg-gray-200'} relative inline-flex h-6 w-11 items-center rounded-full`}
onChange={(checked: boolean) => setHistory(checked)}
>
<span
className={`${enabledHistory ? 'translate-x-6' : 'translate-x-1'} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</Switch>
启用历史记录
</div>
)}

<Button variant="ghost" className="bg-[#F5F5F5] hover:bg-[#F2F2F2]" onClick={() => copyToClipboard(btoa(curlValue))}>
转成 BING_HEADER 并复制
</Button>
Expand All @@ -96,7 +131,7 @@ export function Settings() {
} else {
[...ChunkKeys, 'BING_COOKIE', 'BING_UA', 'BING_IP'].forEach(key => setCookie(key, ''))
}
setCookie('IMAGE_ONLY', RegExp.$1 === 'cn' || imageOnly ? '1' : '0')
setCookie('IMAGE_ONLY', RegExp.$1 === 'cn' || imageOnly || !headerValue ? '1' : '0')

toast.success('保存成功')
setLoc('')
Expand Down
20 changes: 10 additions & 10 deletions src/lib/hooks/chat-history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface ChatHistory {
}

const proxyEndpoint = '/api/proxy'
const fetchProxy = (data: any) => {
const fetchProxy = (data: any, showError = true) => {
return fetch(proxyEndpoint, {
method: 'POST',
headers: {
Expand All @@ -31,13 +31,15 @@ const fetchProxy = (data: any) => {
credentials: 'include',
body: JSON.stringify(data),
}).then(res => res.json()).catch(e => {
toast.error('Failed to operation')
if (showError) {
toast.error('Failed to operation')
}
throw e
})
}

export function useChatHistory(botId = 'bing') {
const chatAtom = useMemo(() => chatFamily({ botId: 'bing', page: 'singleton' }), [botId])
export function useChatHistory(historyEnabled: boolean) {
const chatAtom = useMemo(() => chatFamily({ botId: 'bing', page: 'singleton' }), ['bing'])
const [chatState, setChatState] = useAtom(chatAtom)
const [chatHistory, setHistory] = useState<ChatHistory>()

Expand Down Expand Up @@ -157,20 +159,18 @@ export function useChatHistory(botId = 'bing') {
const data = await fetchProxy({
url: 'https://www.bing.com/turing/conversation/chats',
method: 'GET',
}).catch(e => {
console.log(e)
return
})
}, false)
setHistory(data || {})
return data
}, [])

useEffect(() => {
if (chatState.generatingMessageId === '') {
if (!historyEnabled) return
if (chatState.generatingMessageId === '' && [3, 2].includes(chatState.messages.length)) {
debug('refresh history')
refreshChats()
}
}, [chatState.generatingMessageId, chatState.messages?.[1]?.text])
}, [historyEnabled, chatState.generatingMessageId, chatState.messages.length])

return {
chatHistory,
Expand Down
1 change: 1 addition & 0 deletions src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const GreetMessages = [

export const bingConversationStyleAtom = atomWithStorage<BingConversationStyle>('bingConversationStyle', BingConversationStyle.Balanced, undefined, { unstable_getOnInit: true })
export const voiceAtom = atomWithStorage<boolean>('enableTTS', false, undefined, { unstable_getOnInit: true })
export const historyAtom = atomWithStorage<boolean>('enableHistory', false, undefined, { unstable_getOnInit: true })

type Param = { botId: BotId; page: string }

Expand Down

0 comments on commit 46de470

Please sign in to comment.