| duration, | duration, | ||||
| className, | className, | ||||
| customComponent, | customComponent, | ||||
| }: Pick<IToastProps, 'type' | 'size' | 'message' | 'duration' | 'className' | 'customComponent'>) => { | |||||
| onClose, | |||||
| }: Pick<IToastProps, 'type' | 'size' | 'message' | 'duration' | 'className' | 'customComponent' | 'onClose'>) => { | |||||
| const defaultDuring = (type === 'success' || type === 'info') ? 3000 : 6000 | const defaultDuring = (type === 'success' || type === 'info') ? 3000 : 6000 | ||||
| if (typeof window === 'object') { | if (typeof window === 'object') { | ||||
| const holder = document.createElement('div') | const holder = document.createElement('div') | ||||
| root.render( | root.render( | ||||
| <ToastContext.Provider value={{ | <ToastContext.Provider value={{ | ||||
| notify: () => {}, | |||||
| notify: () => { }, | |||||
| close: () => { | close: () => { | ||||
| if (holder) { | if (holder) { | ||||
| root.unmount() | root.unmount() | ||||
| holder.remove() | holder.remove() | ||||
| } | } | ||||
| onClose?.() | |||||
| }, | }, | ||||
| }}> | }}> | ||||
| <Toast type={type} size={size} message={message} duration={duration} className={className} customComponent={customComponent} /> | <Toast type={type} size={size} message={message} duration={duration} className={className} customComponent={customComponent} /> | ||||
| root.unmount() | root.unmount() | ||||
| holder.remove() | holder.remove() | ||||
| } | } | ||||
| onClose?.() | |||||
| }, duration || defaultDuring) | }, duration || defaultDuring) | ||||
| } | } | ||||
| } | } |
| import { createContext, useContext, useContextSelector } from 'use-context-selector' | import { createContext, useContext, useContextSelector } from 'use-context-selector' | ||||
| import useSWR from 'swr' | import useSWR from 'swr' | ||||
| import { useEffect, useState } from 'react' | import { useEffect, useState } from 'react' | ||||
| import dayjs from 'dayjs' | |||||
| import { useTranslation } from 'react-i18next' | |||||
| import { | import { | ||||
| fetchModelList, | fetchModelList, | ||||
| fetchModelProviders, | fetchModelProviders, | ||||
| fetchSupportRetrievalMethods, | fetchSupportRetrievalMethods, | ||||
| } from '@/service/common' | } from '@/service/common' | ||||
| import { | import { | ||||
| CurrentSystemQuotaTypeEnum, | |||||
| ModelStatusEnum, | ModelStatusEnum, | ||||
| ModelTypeEnum, | ModelTypeEnum, | ||||
| } from '@/app/components/header/account-setting/model-provider-page/declarations' | } from '@/app/components/header/account-setting/model-provider-page/declarations' | ||||
| import { fetchCurrentPlanInfo } from '@/service/billing' | import { fetchCurrentPlanInfo } from '@/service/billing' | ||||
| import { parseCurrentPlan } from '@/app/components/billing/utils' | import { parseCurrentPlan } from '@/app/components/billing/utils' | ||||
| import { defaultPlan } from '@/app/components/billing/config' | import { defaultPlan } from '@/app/components/billing/config' | ||||
| import Toast from '@/app/components/base/toast' | |||||
| type ProviderContextState = { | type ProviderContextState = { | ||||
| modelProviders: ModelProvider[] | modelProviders: ModelProvider[] | ||||
| fetchPlan() | fetchPlan() | ||||
| }, []) | }, []) | ||||
| const { t } = useTranslation() | |||||
| useEffect(() => { | |||||
| if (localStorage.getItem('anthropic_quota_notice') === 'true') | |||||
| return | |||||
| if (dayjs().isAfter(dayjs('2025-03-10'))) | |||||
| return | |||||
| if (providersData?.data && providersData.data.length > 0) { | |||||
| const anthropic = providersData.data.find(provider => provider.provider === 'anthropic') | |||||
| if (anthropic && anthropic.system_configuration.current_quota_type === CurrentSystemQuotaTypeEnum.trial) { | |||||
| const quota = anthropic.system_configuration.quota_configurations.find(item => item.quota_type === anthropic.system_configuration.current_quota_type) | |||||
| if (quota && quota.is_valid && quota.quota_used < quota.quota_limit) { | |||||
| Toast.notify({ | |||||
| type: 'info', | |||||
| message: t('common.provider.anthropicHosted.trialQuotaTip'), | |||||
| duration: 6000, | |||||
| onClose: () => { | |||||
| localStorage.setItem('anthropic_quota_notice', 'true') | |||||
| }, | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | |||||
| }, [providersData, t]) | |||||
| return ( | return ( | ||||
| <ProviderContext.Provider value={{ | <ProviderContext.Provider value={{ | ||||
| modelProviders: providersData?.data || [], | modelProviders: providersData?.data || [], |
| usedUp: 'Trial quota used up. Add own Model Provider.', | usedUp: 'Trial quota used up. Add own Model Provider.', | ||||
| useYourModel: 'Currently using own Model Provider.', | useYourModel: 'Currently using own Model Provider.', | ||||
| close: 'Close', | close: 'Close', | ||||
| trialQuotaTip: 'Your Anthropic trial quota will expire on 2025/03/10 and will no longer be available thereafter. Please make use of it in time.', | |||||
| }, | }, | ||||
| anthropic: { | anthropic: { | ||||
| using: 'The embedding capability is using', | using: 'The embedding capability is using', |
| usedUp: 'トライアルクォータが使い果たされました。独自のモデルプロバイダを追加してください。', | usedUp: 'トライアルクォータが使い果たされました。独自のモデルプロバイダを追加してください。', | ||||
| useYourModel: '現在、独自のモデルプロバイダを使用しています。', | useYourModel: '現在、独自のモデルプロバイダを使用しています。', | ||||
| close: '閉じる', | close: '閉じる', | ||||
| trialQuotaTip: 'お客様の Anthropic 試用枠は 2025/03/10 に失効し、その後は利用できなくなります。お早めにご利用ください。', | |||||
| }, | }, | ||||
| anthropic: { | anthropic: { | ||||
| using: '埋め込み機能は使用中です', | using: '埋め込み機能は使用中です', |
| usedUp: '试用额度已用完,请在下方添加自己的模型供应商', | usedUp: '试用额度已用完,请在下方添加自己的模型供应商', | ||||
| useYourModel: '当前正在使用你自己的模型供应商。', | useYourModel: '当前正在使用你自己的模型供应商。', | ||||
| close: '关闭', | close: '关闭', | ||||
| trialQuotaTip: '您的 Anthropic 体验额度将于 2025/03/10 过期,过期后将无法使用,请尽快体验。', | |||||
| }, | }, | ||||
| anthropic: { | anthropic: { | ||||
| using: '嵌入能力正在使用', | using: '嵌入能力正在使用', |