import '@picocss/pico' import { useEffect, useState } from 'react' import { defaultConfig, getUserConfig, isUsingApiKey, isUsingCustomModel, isUsingMultiModeModel, ModelMode, Models, setUserConfig, ThemeMode, TriggerMode, } from '../config/index.mjs' import { Tab, TabList, TabPanel, Tabs } from 'react-tabs' import 'react-tabs/style/react-tabs.css' import './styles.scss' import { MarkGithubIcon } from '@primer/octicons-react' import Browser from 'webextension-polyfill' import PropTypes from 'prop-types' import { config as toolsConfig } from '../content-script/selection-tools' import wechatpay from './donation/wechatpay.jpg' import bugmeacoffee from './donation/bugmeacoffee.png' import { useWindowTheme } from '../hooks/use-window-theme.mjs' import { languageList } from '../config/language.mjs' import { isSafari } from '../utils/index.mjs' function GeneralPart({ config, updateConfig }) { const [balance, setBalance] = useState(null) const getBalance = async () => { const response = await fetch('https://api.openai.com/dashboard/billing/credit_grants', { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${config.apiKey}`, }, }) if (response.ok) setBalance((await response.json()).total_available.toFixed(2)) } return ( <>
) } GeneralPart.propTypes = { config: PropTypes.object.isRequired, updateConfig: PropTypes.func.isRequired, } function AdvancedPart({ config, updateConfig }) { return ( <>
) } AdvancedPart.propTypes = { config: PropTypes.object.isRequired, updateConfig: PropTypes.func.isRequired, } function SelectionTools({ config, updateConfig }) { return ( <> {config.selectionTools.map((key) => ( ))} ) } SelectionTools.propTypes = { config: PropTypes.object.isRequired, updateConfig: PropTypes.func.isRequired, } function SiteAdapters({ config, updateConfig }) { return ( <> {config.siteAdapters.map((key) => ( ))} ) } SiteAdapters.propTypes = { config: PropTypes.object.isRequired, updateConfig: PropTypes.func.isRequired, } function Donation() { return (
buymeacoffee
<> Wechat Pay wechatpay
) } // eslint-disable-next-line react/prop-types function Footer({ currentVersion, latestVersion }) { return (
Current Version: {currentVersion}{' '} {currentVersion === latestVersion ? ( '(Latest)' ) : ( <> (Latest:{' '} {latestVersion} ) )}
Help | Changelog
) } function Popup() { const [config, setConfig] = useState(defaultConfig) const [currentVersion, setCurrentVersion] = useState('') const [latestVersion, setLatestVersion] = useState('') const theme = useWindowTheme() const updateConfig = (value) => { setConfig({ ...config, ...value }) setUserConfig(value) } useEffect(() => { getUserConfig().then((config) => { setConfig(config) setCurrentVersion(Browser.runtime.getManifest().version.replace('v', '')) fetch('https://api.github.com/repos/josstorer/chatGPTBox/releases/latest').then((response) => response.json().then((data) => { setLatestVersion(data.tag_name.replace('v', '')) }), ) }) }, []) useEffect(() => { document.documentElement.dataset.theme = config.themeMode === 'auto' ? theme : config.themeMode }, [config.themeMode, theme]) return (
General Selection Tools Sites Advanced {isSafari() ? null : Donate} {isSafari() ? null : ( )}

) } export default Popup