Spaces:
Sleeping
Sleeping
File size: 5,979 Bytes
6337686 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
import { 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 {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle
} from '@/components/ui/dialog'
import { Button } from './ui/button'
import { Input } from './ui/input'
import { ChunkKeys, parseCookies, extraCurlFromCookie, encodeHeadersToCookie, getCookie, setCookie } from '@/lib/utils'
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 [enableTTS, setEnableTTS] = useAtom(voiceAtom)
useEffect(() => {
if (isCopied) {
toast.success('复制成功')
}
}, [isCopied])
if (loc === 'settings') {
return (
<Dialog open onOpenChange={() => setLoc('')} modal>
<DialogContent>
<DialogHeader>
<DialogTitle>设置你的用户信息</DialogTitle>
<DialogDescription>
请使用 Edge 浏览器
<ExternalLink
href="https://www.bing.com/turing/captcha/challenge"
>
打开并登录 Bing
</ExternalLink>
,然后再打开
<ExternalLink href="https://www.bing.com/turing/captcha/challenge">Challenge 接口</ExternalLink>
右键 》检查。打开开发者工具,在网络里面找到 Create 接口 》右键复制》复制为 cURL(bash),粘贴到此处,然后保存。
<div className="h-2" />
图文示例:
<ExternalLink href="https://github.com/weaigc/bingo#如何获取%20BING_HEADER">如何获取 BING_HEADER</ExternalLink>
</DialogDescription>
</DialogHeader>
<div className="flex gap-4">
</div>
<Input
value={curlValue}
placeholder="在此填写用户信息,格式: curl 'https://www.bing.com/turing/captcha/challenge' ..."
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)}
>
<span
className={`${imageOnly ? '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>
<DialogFooter className="items-center">
<Button
variant="secondary"
className="bg-[#c7f3ff] hover:bg-[#fdc7ff]"
onClick={() => {
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
}
const maxAge = 86400 * 30
encodeHeadersToCookie(headerValue).forEach(cookie => document.cookie = `${cookie}; Max-Age=${maxAge}; Path=/; SameSite=None; Secure`)
} else {
[...ChunkKeys, 'BING_COOKIE', 'BING_UA', 'BING_IP'].forEach(key => setCookie(key, ''))
}
setCookie('IMAGE_ONLY', RegExp.$1 === 'cn' || imageOnly ? '1' : '0')
toast.success('保存成功')
setLoc('')
setTimeout(() => {
location.href = './'
}, 2000)
}}
>
保存
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
} else if (loc === 'voice') {
return (
<Dialog open onOpenChange={() => setLoc('')} modal>
<DialogContent>
<DialogHeader>
<DialogTitle>语音设置</DialogTitle>
<DialogDescription>
目前仅支持 PC 端 Edge 及 Chrome 浏览器
</DialogDescription>
</DialogHeader>
<div className="flex gap-2">
启用语音回答
<Switch
checked={enableTTS}
className={`${enableTTS ? 'bg-blue-600' : 'bg-gray-200'} relative inline-flex h-6 w-11 items-center rounded-full`}
onChange={(checked: boolean) => setEnableTTS(checked)}
>
<span
className={`${enableTTS ? 'translate-x-6' : 'translate-x-1'} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</Switch>
</div>
<DialogFooter className="items-center">
<Button
variant="secondary"
onClick={() => {
toast.success('保存成功')
setLoc('')
setTimeout(() => {
location.href = './'
}, 2000)
}}
>
保存
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}
return null
}
|